aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2014-09-01 15:08:49 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2015-12-19 17:05:28 -0200
commit844228b4060c77a41db6232103d8a5a20cd2bf95 (patch)
tree50aa3427c700318e3932b92702aac91a3dec586d
parentEvas textblock: Fix some indentation and formatting. (diff)
downloadefl-844228b4060c77a41db6232103d8a5a20cd2bf95.tar.gz
efl-js: JavaScript Eolian bindingdevs/felipealmeida/js-20151219
To configure efl sources with bindings to use in nodejs add ––with-js=nodejs in configure flags to generate node files $ configure --with-js=nodejs and compile normally with: $ make $ make install To use, you have to require efl: efl = require('efl') The bindings is divided in two parts: generated and manually written. The generation uses the Eolian library for parsing Eo files and generate C++ code that is compiled against V8 interpreter library to create a efl.node file that can be required in a node.js instance. @feature
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am8
-rw-r--r--configure.ac272
-rw-r--r--pc/.gitignore3
-rw-r--r--pc/efl-js.pc.in15
-rw-r--r--pc/eina-js.pc.in14
-rw-r--r--pc/eo-js.pc.in15
-rw-r--r--pc/eolian-js.pc.in14
-rw-r--r--pc/evas.pc.in2
-rw-r--r--src/Makefile.am16
-rw-r--r--src/Makefile_Ecore.am10
-rw-r--r--src/Makefile_Ecore_Audio.am11
-rw-r--r--src/Makefile_Ecore_Con.am10
-rw-r--r--src/Makefile_Ecore_Js.am19
-rw-r--r--src/Makefile_Edje.am12
-rw-r--r--src/Makefile_Efl.am10
-rw-r--r--src/Makefile_Efl_Js.am319
-rw-r--r--src/Makefile_Eina_Cxx.am4
-rw-r--r--src/Makefile_Emotion.am11
-rw-r--r--src/Makefile_Eo.am10
-rw-r--r--src/Makefile_Eolian_Js.am118
-rw-r--r--src/Makefile_Eolian_Js_Helper.am18
-rw-r--r--src/Makefile_Evas.am10
-rwxr-xr-xsrc/bin/efl_js/efljslaunch139
-rw-r--r--src/bin/efl_js/efljslaunch.desktop7
-rw-r--r--src/bin/efl_js/efljslaunch.xml7
-rwxr-xr-xsrc/bin/efl_js/efljspack251
-rw-r--r--src/bin/efl_js/launcher_main.cc156
-rw-r--r--src/bin/eolian_js/.gitignore1
-rw-r--r--src/bin/eolian_js/eolian/class.hh139
-rw-r--r--src/bin/eolian_js/eolian/js/domain.hh8
-rw-r--r--src/bin/eolian_js/eolian/js/format.hh44
-rw-r--r--src/bin/eolian_js/main.cc1076
-rw-r--r--src/bindings/ecore_js/Ecore_Js.hh58
-rw-r--r--src/bindings/ecore_js/ecore_js_animator.cc728
-rw-r--r--src/bindings/ecore_js/ecore_js_event.cc772
-rw-r--r--src/bindings/ecore_js/ecore_js_file.cc1457
-rw-r--r--src/bindings/ecore_js/ecore_js_idle.cc294
-rw-r--r--src/bindings/ecore_js/ecore_js_init.cc77
-rw-r--r--src/bindings/ecore_js/ecore_js_job.cc83
-rw-r--r--src/bindings/ecore_js/ecore_js_mainloop.cc207
-rw-r--r--src/bindings/ecore_js/ecore_js_poller.cc190
-rw-r--r--src/bindings/ecore_js/ecore_js_throttle.cc63
-rw-r--r--src/bindings/ecore_js/ecore_js_timer.cc263
-rw-r--r--src/bindings/ecore_js/ecore_js_timer.hh38
-rw-r--r--src/bindings/eina_cxx/Eina.hh1
-rw-r--r--src/bindings/eina_cxx/eina_accessor.hh5
-rw-r--r--src/bindings/eina_cxx/eina_array.hh250
-rw-r--r--src/bindings/eina_cxx/eina_clone_allocators.hh3
-rw-r--r--src/bindings/eina_cxx/eina_function.hh26
-rw-r--r--src/bindings/eina_cxx/eina_integer_sequence.hh2
-rw-r--r--src/bindings/eina_cxx/eina_list.hh14
-rw-r--r--src/bindings/eina_cxx/eina_logical.hh34
-rw-r--r--src/bindings/eina_cxx/eina_pp.hh8
-rw-r--r--src/bindings/eina_cxx/eina_ptrarray.hh16
-rw-r--r--src/bindings/eina_cxx/eina_ptrlist.hh79
-rw-r--r--src/bindings/eina_cxx/eina_range_types.hh58
-rw-r--r--src/bindings/eina_cxx/eina_tuple.hh60
-rw-r--r--src/bindings/eina_cxx/eina_tuple_c.hh24
-rw-r--r--src/bindings/eina_cxx/eina_type_traits.hh16
-rw-r--r--src/bindings/eina_js/Eina_Js.hh50
-rw-r--r--src/bindings/eina_js/eina_js_accessor.cc34
-rw-r--r--src/bindings/eina_js/eina_js_accessor.hh87
-rw-r--r--src/bindings/eina_js/eina_js_array.hh119
-rw-r--r--src/bindings/eina_js/eina_js_compatibility.cc12
-rw-r--r--src/bindings/eina_js/eina_js_compatibility.hh918
-rw-r--r--src/bindings/eina_js/eina_js_container.cc495
-rw-r--r--src/bindings/eina_js/eina_js_container.hh351
-rw-r--r--src/bindings/eina_js/eina_js_error.cc24
-rw-r--r--src/bindings/eina_js/eina_js_error.hh25
-rw-r--r--src/bindings/eina_js/eina_js_get_value.hh449
-rw-r--r--src/bindings/eina_js/eina_js_get_value_from_c.hh261
-rw-r--r--src/bindings/eina_js/eina_js_iterator.cc32
-rw-r--r--src/bindings/eina_js/eina_js_iterator.hh81
-rw-r--r--src/bindings/eina_js/eina_js_list.hh132
-rw-r--r--src/bindings/eina_js/eina_js_log.cc742
-rw-r--r--src/bindings/eina_js/eina_js_log.hh133
-rw-r--r--src/bindings/eina_js/eina_js_node.hh14
-rw-r--r--src/bindings/eina_js/eina_js_value.cc132
-rw-r--r--src/bindings/eina_js/eina_js_value.hh142
-rw-r--r--src/bindings/eio_js/Eio_Js.hh44
-rw-r--r--src/bindings/eio_js/eio_js.cc1756
-rw-r--r--src/bindings/eldbus_cxx/eldbus_freedesktop.hh1
-rw-r--r--src/bindings/eldbus_js/Eldbus_Js.hh48
-rw-r--r--src/bindings/eldbus_js/eldbus_js_connection.cc543
-rw-r--r--src/bindings/eldbus_js/eldbus_js_core.cc183
-rw-r--r--src/bindings/eldbus_js/eldbus_js_message.cc103
-rw-r--r--src/bindings/eldbus_js/eldbus_js_object_mapper.cc100
-rw-r--r--src/bindings/eldbus_js/eldbus_js_util.hh836
-rw-r--r--src/bindings/eo_cxx/eo_concrete.hh7
-rw-r--r--src/bindings/eo_js/Eo_Js.hh15
-rw-r--r--src/bindings/eo_js/eo_js_call_function.hh288
-rw-r--r--src/bindings/eo_js/eo_js_construct_from_eo.hh39
-rw-r--r--src/bindings/eo_js/eo_js_constructor.hh136
-rw-r--r--src/bindings/eo_js/eo_js_direction.hh12
-rw-r--r--src/bindings/eo_js/eo_js_event.hh126
-rw-r--r--src/bindings/eo_js/eo_js_namespace.hh24
-rw-r--r--src/bindings/eo_js/eo_js_struct.hh106
-rw-r--r--src/bindings/ethumb_js/Ethumb_Js.hh48
-rw-r--r--src/bindings/ethumb_js/ethumb_js_client.cc571
-rw-r--r--src/lib/ecore/ecore.c1
-rw-r--r--src/lib/ecore/ecore_main.c525
-rw-r--r--src/lib/ecore/ecore_private.h2
-rw-r--r--src/lib/ecore_con/Ecore_Con_Eet.h11
-rw-r--r--src/lib/efl/interfaces/efl_model_base.eo2
-rw-r--r--src/lib/efl_js/Efl_Js.hh30
-rw-r--r--src/lib/efl_js/efl_js.cc243
-rw-r--r--src/lib/emotion/Emotion.h39
-rw-r--r--src/lib/emotion/emotion_smart.c1
-rw-r--r--src/lib/eo/Eo.h10
-rw-r--r--src/tests/.gitignore1
-rw-r--r--src/tests/ecore/ecore_test_ecore.c34
-rw-r--r--src/tests/ecore/ecore_test_ecore_x.c6
-rw-r--r--src/tests/efl_js/benchmark_js_suite.cc7
-rwxr-xr-xsrc/tests/efl_js/benchmark_js_suite.js205
-rw-r--r--src/tests/efl_js/benchmark_object.eo24
-rw-r--r--src/tests/efl_js/benchmark_object_impl.cc110
-rw-r--r--src/tests/efl_js/ecore_js_suite.cc7
-rwxr-xr-xsrc/tests/efl_js/ecore_js_suite.js438
-rw-r--r--src/tests/efl_js/eina_js_containers_suite.cc7
-rwxr-xr-xsrc/tests/efl_js/eina_js_containers_suite.js552
-rw-r--r--src/tests/efl_js/eina_js_suite.cc7
-rwxr-xr-xsrc/tests/efl_js/eina_js_suite.js415
-rw-r--r--src/tests/efl_js/eio_js_suite.cc7
-rwxr-xr-xsrc/tests/efl_js/eio_js_suite.js89
-rw-r--r--src/tests/efl_js/eldbus_js_suite.cc7
-rwxr-xr-xsrc/tests/efl_js/eldbus_js_suite.js114
-rw-r--r--src/tests/efl_js/ethumb_js_suite.cc7
-rwxr-xr-xsrc/tests/efl_js/ethumb_js_suite.js93
-rw-r--r--src/tests/efl_js/suite_runner.hh147
-rw-r--r--src/tests/efl_js/testproj/hello.project9
-rw-r--r--src/tests/efl_js/testproj/hello.txt1
-rw-r--r--src/tests/efl_js/testproj/main.js5
-rw-r--r--src/tests/efl_js/timer.js33
-rw-r--r--src/tests/eolian_js/constructor_method_class.eo59
-rw-r--r--src/tests/eolian_js/eolian_js_suite.cc61
-rwxr-xr-xsrc/tests/eolian_js/eolian_js_suite.js796
-rw-r--r--src/tests/eolian_js/eolian_js_test_constructor_method_impl.c147
-rw-r--r--src/tests/eolian_js/eolian_js_test_eolian_js_binding.cc44
-rw-r--r--src/tests/eolian_js/eolian_js_test_evas_box.cc151
-rw-r--r--src/tests/eolian_js/eolian_js_test_test_object_impl.c620
-rw-r--r--src/tests/eolian_js/test_object.eo305
142 files changed, 22030 insertions, 137 deletions
diff --git a/.gitignore b/.gitignore
index d93f853e29..c779341a62 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@ tags
*.eo.legacy.h
*.eo.hh
*.eo.impl.hh
+*.eo.js.cc
*.eo.lua
*.luac
.dir-locals.el
diff --git a/Makefile.am b/Makefile.am
index 8363720df2..2e90bf3cd5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -172,6 +172,14 @@ if HAVE_ELUA
pkgconfig_DATA += pc/elua.pc
endif
+if HAVE_JS
+pkgconfig_DATA += \
+pc/eolian-js.pc \
+pc/efl-js.pc \
+pc/eo-js.pc \
+pc/eina-js.pc
+endif
+
if BUILD_ENGINE_SOFTWARE_X11
pkgconfig_DATA += pc/evas-software-x11.pc
endif
diff --git a/configure.ac b/configure.ac
index 08976a5645..972ac1c1aa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1051,6 +1051,191 @@ EFL_EVAL_PKGS([EINA_CXX])
EFL_LIB_END([Eina_Cxx])
#### End of Eina CXX
+AC_ARG_WITH([js],
+ [AS_HELP_STRING([--with-js=@<:@nodejs/libv8/libuv/none@:>@],[enable JavaScript bindings using nodejs or libv8/libuv as build dependencies. The libuv option implies libv8. @<:@default=none@:>@])],
+ [want_js="${withval}"], [want_js="none"])
+
+EFLJS_CXXFLAGS=""
+AC_LANG_PUSH([C++])
+case "$want_js" in
+ nodejs)
+ AC_CHECK_HEADERS([node/v8.h nodejs/deps/v8/v8.h nodejs/deps/v8/include/v8.h nodejs/src/v8.h v8.h],
+ [
+ v8_header=AC_header
+ v8_header_define=AS_TR_CPP([HAVE_]AC_header)
+ EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -D$v8_header_define"
+ break
+ ]
+ [AC_MSG_ERROR([Could not find v8 include headers from nodejs.])])
+ AC_CHECK_HEADERS([node/node.h nodejs/deps/node/node.h nodejs/deps/node/include/node.h nodejs/src/node.h node.h],
+ [
+ node_header_define=AS_TR_CPP([HAVE_]AC_header)
+ EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -D$node_header_define"
+ break
+ ]
+ [AC_MSG_ERROR([Could not find node include headers from nodejs.])])
+ AC_CHECK_HEADERS([node/uv.h nodejs/deps/uv/uv.h nodejs/deps/uv/include/uv.h nodejs/src/uv.h uv.h],
+ [
+ uv_header_define=AS_TR_CPP([HAVE_]AC_header)
+ EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -D$uv_header_define"
+ break
+ ]
+ [AC_MSG_ERROR([Could not find uv include headers from nodejs.])])
+ ;;
+ libv8)
+ AC_CHECK_HEADERS([v8.h],
+ [
+ v8_header=AC_header
+ break
+ ]
+ [AC_MSG_ERROR([Could not find v8 include headers from libv8.])])
+ ;;
+ libuv)
+ AC_CHECK_HEADERS([v8.h],
+ [
+ v8_header=AC_header
+ break
+ ]
+ [AC_MSG_ERROR([Could not find v8 include headers from libv8.])])
+ AC_CHECK_HEADERS([uv.h],
+ [break]
+ [AC_MSG_ERROR([Could not find uv include headers from libuv.])])
+ ;;
+ none)
+ ;;
+ *) AC_MSG_ERROR([Invalid javascript dependency (${want_js}): must be none, nodejs, libv8 or libuv]) ;;
+esac
+
+have_v8_global="no"
+have_v8_create_params="no"
+if test "$want_js" != "none" ; then
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include "$v8_header"
+ ]],
+ [[
+v8::Isolate::CreateParams create_params; create_params.array_buffer_allocator = nullptr;
+ ]])
+ ],
+ [
+ AC_DEFINE(HAVE_V8_CREATE_PARAMS, 1, [Define to 1 if you must pass create_params explicitly.])
+ have_v8_create_params="yes"
+ AC_MSG_NOTICE([checking for v8::Isolate::CreateParams... yes])
+ ],
+ [
+ AC_MSG_NOTICE([checking for v8::Isolate::CreateParams... no])
+ ])
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include "$v8_header"
+#include <type_traits>
+ ]],
+ [[
+ static_assert((std::is_same< ::v8::Global<void>, ::v8::UniquePersistent<void>>::value), "");
+ ]])
+ ],
+ [
+ AC_DEFINE(HAVE_V8_GLOBAL, 1, [Define to 1 if you must pass create_params explicitly.])
+ have_v8_global="yes"
+ AC_MSG_NOTICE([checking for v8::Global<T> class... yes])
+ ],
+ [
+ AC_MSG_NOTICE([checking for v8::Global<T> class... no])
+ ])
+fi
+AM_CONDITIONAL([HAVE_V8_CREATE_PARAMS], [test "x${have_v8_create_params}" = "xyes"])
+AM_CONDITIONAL([HAVE_V8_GLOBAL], [test "x${have_v8_global}" = "xyes"])
+AC_SUBST([HAVE_V8_CREATE_PARAMS])
+AC_SUBST([HAVE_V8_GLOBAL])
+AC_LANG_POP([C++])
+
+AM_CONDITIONAL([HAVE_NODEJS], [test "x${want_js}" = "xnodejs"])
+AC_DEFINE_IF([HAVE_NODEJS], [test "x${want_js}" = "xnodejs"],
+ [1], [Using NodeJS])
+AC_SUBST([want_js])
+AC_SUBST([HAVE_NODEJS])
+
+have_js="no"
+if test "x${want_js}" != "xnone" ; then
+ have_js="yes"
+fi
+AM_CONDITIONAL([HAVE_JS], [test "x${have_js}" = "xyes"])
+AC_DEFINE_IF([HAVE_JS], [test "x${have_js}" = "xyes"], [1], [Compiling bindings for JavaScript])
+AC_SUBST([HAVE_JS])
+
+AM_CONDITIONAL([HAVE_LIBUV], [test "x${want_js}" = "xnodejs" -o "x${want_js}" = "xlibuv"])
+AC_DEFINE_IF([HAVE_LIBUV], [test "x${want_js}" = "xnodejs" -o "x${want_js}" = "xlibuv"],
+ [1], [Compiling libuv event loop integration])
+AC_SUBST([HAVE_LIBUV])
+
+# For efljspack mime handling
+AM_CONDITIONAL([HAVE_XDG_DATA_HOME], [test "x${XDG_DATA_HOME}" != "x"])
+AM_COND_IF([HAVE_XDG_DATA_HOME], [AC_SUBST([XDG_DATA_HOME])], [AC_SUBST([XDG_DATA_HOME], "$HOME/.local/share")])
+
+#### Eina JS
+EFL_LIB_START_OPTIONAL([Eina_Js], [test "x${have_js}" = "xyes"])
+EFL_INTERNAL_DEPEND_PKG([EINA_JS], [Eina])
+EFL_INTERNAL_DEPEND_PKG([EINA_JS], [Eo])
+EFL_ADD_CFLAGS([EINA_JS], [${EFL_PTHREAD_CFLAGS}])
+EFL_EVAL_PKGS([EINA_JS])
+
+EFL_LIB_END_OPTIONAL([Eina_Js])
+#### End of Eina JS
+
+#### Ecore JS
+EFL_LIB_START_OPTIONAL([Ecore_Js], [test "x${have_js}" = "xyes"])
+
+EFL_INTERNAL_DEPEND_PKG([ECORE_JS], [ecore])
+EFL_INTERNAL_DEPEND_PKG([ECORE_JS], [ecore_file])
+EFL_ADD_CFLAGS([ECORE_JS], [${EFL_PTHREAD_CFLAGS}])
+EFL_EVAL_PKGS([ECORE_JS])
+
+EFL_LIB_END_OPTIONAL([Ecore_Js])
+#### End of Ecore JS
+
+#### Eio JS
+EFL_LIB_START_OPTIONAL([Eio_Js], [test "x${have_js}" = "xyes"])
+
+EFL_INTERNAL_DEPEND_PKG([EIO_JS], [eio])
+EFL_ADD_CFLAGS([EIO_JS], [${EFL_PTHREAD_CFLAGS}])
+EFL_EVAL_PKGS([EIO_JS])
+
+EFL_LIB_END_OPTIONAL([Eio_Js])
+#### End of Eio JS
+
+#### Ethumb JS
+EFL_LIB_START_OPTIONAL([Ethumb_Js], [test "x${have_js}" = "xyes"])
+
+EFL_INTERNAL_DEPEND_PKG([ETHUMB_JS], [ethumb])
+EFL_INTERNAL_DEPEND_PKG([ETHUMB_JS], [ethumb_client])
+EFL_ADD_CFLAGS([ETHUMB_JS], [${EFL_PTHREAD_CFLAGS}])
+EFL_EVAL_PKGS([ETHUMB_JS])
+
+EFL_LIB_END_OPTIONAL([Ethumb_Js])
+#### End of Ethumb JS
+
+#### Eldbus JS
+EFL_LIB_START_OPTIONAL([Eldbus_Js], [test "x${have_js}" = "xyes"])
+
+EFL_INTERNAL_DEPEND_PKG([ELDBUS_JS], [eldbus])
+EFL_ADD_CFLAGS([ELDBUS_JS], [${EFL_PTHREAD_CFLAGS}])
+EFL_EVAL_PKGS([ELDBUS_JS])
+
+EFL_LIB_END_OPTIONAL([Eldbus_Js])
+#### End of Eldbus JS
+
+#### Eo JS
+EFL_LIB_START_OPTIONAL([Eo_Js], [test "x${have_js}" = "xyes"])
+
+EFL_INTERNAL_DEPEND_PKG([EO_JS], [eina])
+EFL_ADD_CFLAGS([EO_JS], [${EFL_PTHREAD_CFLAGS}])
+EFL_EVAL_PKGS([EO_JS])
+
+EFL_LIB_END_OPTIONAL([Eo_Js])
+#### End of Eo JS
+
#### Eo
EFL_LIB_START([Eo])
@@ -1244,6 +1429,15 @@ EFL_INTERNAL_DEPEND_PKG([EOLIAN], [eina])
EFL_LIB_END([Eolian])
#### End of Eolian
+EFL_LIB_START_OPTIONAL([Eolian_Js], [test "${have_js}" = "yes"])
+
+EFL_INTERNAL_DEPEND_PKG([EOLIAN_JS], [eina])
+EFL_INTERNAL_DEPEND_PKG([EOLIAN_JS], [eolian])
+
+EFL_LIB_END_OPTIONAL([Eolian_Js])
+#### End of Eolian
+
+
EFL_LIB_START([Eolian_Cxx])
### Default values
@@ -2322,6 +2516,17 @@ AC_ARG_ENABLE([g-main-loop],
fi
],
[want_g_main_loop="no"])
+AC_ARG_ENABLE([libuv],
+ [AS_HELP_STRING([--enable-libuv],[enable ecore_main_loop based on libuv. @<:@default=disabled@:>@])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ want_libuv="yes"
+ CFOPT_WARNING="xyes"
+ else
+ want_libuv="no"
+ fi
+ ],
+ [want_libuv="no"])
AC_ARG_ENABLE([gstreamer],
[AS_HELP_STRING([--enable-gstreamer],[enable gstreamer 0.10 support. @<:@default=disabled@:>@])],
@@ -2410,6 +2615,7 @@ EFL_OPTIONAL_DEPEND_PKG([ECORE], [${want_systemd}], [SYSTEMD], [libsystemd])
EFL_ADD_FEATURE([ECORE], [systemd-daemon], [${want_systemd}])
EFL_ADD_FEATURE([ECORE], [glib])
EFL_ADD_FEATURE([ECORE], [g-main-loop])
+EFL_ADD_FEATURE([ECORE], [libuv])
want_glib_integration_always=no
if test "x${with_glib}" = "xalways" ; then
@@ -4007,7 +4213,7 @@ EFL_INTERNAL_DEPEND_PKG([ECORE_EVAS], [emile])
ECORE_EVAS_MODULE([extn], [${want_ecore_evas_extn}])
ECORE_EVAS_MODULE([ews], [yes])
ECORE_EVAS_MODULE([fb], [${want_fb}])
-ECORE_EVAS_MODULE([drm], [${want_drm}],
+ECORE_EVAS_MODULE([drm], [${want_drm}],
[EFL_OPTIONAL_INTERNAL_DEPEND_PKG([ECORE_EVAS], [${want_drm}], [ecore-drm])])
ECORE_EVAS_MODULE([gl-drm], [${want_gl_drm}],
[EFL_OPTIONAL_INTERNAL_DEPEND_PKG([ECORE_EVAS], [${want_gl_drm}], [ecore-drm])])
@@ -4677,6 +4883,63 @@ EFL_ADD_LIBS([ELOCATION], [-lm])
EFL_LIB_END([Elocation])
#### End of Elocation
+
+
+#### Efl_Js
+EFL_LIB_START_OPTIONAL([Efl_Js], [test "x${have_js}" = "xyes"])
+
+### Default values
+
+### Additional options to configure
+
+### Checks for programs
+
+### Checks for libraries
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Eina])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Eo])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Ecore])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Eet])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Ecore_Evas])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Ecore_Con])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Ecore_Audio])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Efl])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Evas])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Edje])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Emotion])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Eldbus])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Emile])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Ethumb_Client])
+EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Eio])
+
+AM_COND_IF([HAVE_NODEJS], [], [ EFL_ADD_LIBS([EFL_JS], [-lv8]) ])
+
+EFL_EVAL_PKGS([EFL_JS])
+
+AM_COND_IF([HAVE_NODEJS], [EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -DHAVE_NODEJS"], [])
+AM_COND_IF([HAVE_LIBUV], [EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -DHAVE_LIBUV"], [])
+AM_COND_IF([HAVE_JS], [EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -DHAVE_JS"], [])
+
+AM_COND_IF([HAVE_V8_CREATE_PARAMS], [EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -DHAVE_V8_CREATE_PARAMS"], [])
+AM_COND_IF([HAVE_V8_GLOBAL], [EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -DHAVE_V8_GLOBAL"], [])
+AC_SUBST([EFLJS_CXXFLAGS])
+
+### Checks for header files
+
+### Checks for types
+
+### Checks for structures
+
+### Checks for compiler characteristics
+
+### Checks for linker characteristics
+
+### Checks for library functions
+
+### Check availability
+
+EFL_LIB_END_OPTIONAL([Efl_Js])
+#### End of Efl_Js
+
### Add Wayland server library if test is enabled
if test "x${want_tests}" = "xyes" -a "x${want_wayland}" = "xyes"; then
EFL_DEPEND_PKG([ECORE_WAYLAND_SRV], [WAYLAND], [wayland-server >= 1.8.0])
@@ -4809,6 +5072,10 @@ pc/eo.pc
pc/eo-cxx.pc
pc/eolian.pc
pc/eolian-cxx.pc
+pc/eina-js.pc
+pc/efl-js.pc
+pc/eolian-js.pc
+pc/eo-js.pc
pc/efl.pc
pc/efl-cxx.pc
pc/evas-fb.pc
@@ -4991,6 +5258,8 @@ echo " Cryptography..: ${build_crypto}"
echo " X11...........: ${with_x11}"
echo " OpenGL........: ${with_opengl}"
echo " C++11.........: ${have_cxx11}"
+echo " JavaScript....: ${want_js}"
+echo " JavaScript flg: $EINA_JS_LIBS"
echo "Eina............: yes (${features_eina} unwind=$have_unwind)"
echo "Eo..............: yes (${features_eo})"
echo "Eolian..........: yes (${features_eolian})"
@@ -5052,6 +5321,7 @@ echo " CPPFLAGS......: $CPPFLAGS"
echo " CFLAGS........: $CFLAGS"
echo " CXXFLAGS......: $CXXFLAGS"
echo " LDFLAGS.......: $LDFLAGS"
+echo " EFLJS_CXXFLAGS: $EFLJS_CXXFLAGS"
if test "x${with_binary_edje_cc}" != "x"; then
echo " edje_cc.......: ${with_binary_edje_cc}"
diff --git a/pc/.gitignore b/pc/.gitignore
index c6b8eb4447..1858516cab 100644
--- a/pc/.gitignore
+++ b/pc/.gitignore
@@ -28,6 +28,7 @@
/efreet.pc
/eina.pc
/eina-cxx.pc
+/eina-js.pc
/eet-cxx.pc
/eio.pc
/eio-cxx.pc
@@ -36,6 +37,7 @@
/embryo.pc
/emotion.pc
/eo.pc
+/eo-js.pc
/ephysics.pc
/escape.pc
/ethumb.pc
@@ -57,6 +59,7 @@
/evil.pc
/eolian.pc
/eolian-cxx.pc
+/eolian-js.pc
/eo-cxx.pc
/evas-cxx.pc
/ecore-cxx.pc
diff --git a/pc/efl-js.pc.in b/pc/efl-js.pc.in
new file mode 100644
index 0000000000..0c1e00c00c
--- /dev/null
+++ b/pc/efl-js.pc.in
@@ -0,0 +1,15 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@datarootdir@
+datadir=@datadir@
+want_js=@want_js@
+
+Name: EFL JavaScript
+Description: JavaScript C++ helpers for data structures
+Version: @PACKAGE_VERSION@
+Requires.private: @requirements_pc_eina@
+Libs.private: @requirements_libs_eina@
+Libs: -L${libdir} -lefl_js
+Cflags: -I${includedir}/efl-js-@VMAJ@ @EFLJS_CXXFLAGS@
diff --git a/pc/eina-js.pc.in b/pc/eina-js.pc.in
new file mode 100644
index 0000000000..6aab608ceb
--- /dev/null
+++ b/pc/eina-js.pc.in
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@datarootdir@
+datadir=@datadir@
+want_js=@want_js@
+
+Name: Eina JavaScript
+Description: JavaScript C++ helpers for data structures
+Version: @PACKAGE_VERSION@
+Requires.private: @requirements_pc_eina@
+Libs.private: @requirements_libs_eina@
+Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eina-@VMAJ@ -I${includedir}/eina-js-@VMAJ@ \ No newline at end of file
diff --git a/pc/eo-js.pc.in b/pc/eo-js.pc.in
new file mode 100644
index 0000000000..3dedf5c265
--- /dev/null
+++ b/pc/eo-js.pc.in
@@ -0,0 +1,15 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@datarootdir@
+datadir=@datadir@
+eoincludedir=@datadir@/eolian/include
+eolian_flags=-I${eoincludedir}/eo-@VMAJ@
+
+Name: Eo JavaScript
+Description: JavaScript C++ helpers for bindings for EFL's generic object system.
+Version: @PACKAGE_VERSION@
+Requires.private: @requirements_pc_eo@
+Libs.private: @requirements_libs_eo@
+Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eo-@VMAJ@ -I${includedir}/eo-js-@VMAJ@ \ No newline at end of file
diff --git a/pc/eolian-js.pc.in b/pc/eolian-js.pc.in
new file mode 100644
index 0000000000..2dbc1cac73
--- /dev/null
+++ b/pc/eolian-js.pc.in
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@datarootdir@
+datadir=@datadir@
+
+Name: Eolian-JS
+Description: EFL's JavaScript bindings generator.
+Version: @VERSION@
+Require.private: @requirements_pc_eolian@
+Libs: -L${libdir}
+Libs.private: @requirements_libs_eolian@
+Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eolian-js-@VMAJ@
diff --git a/pc/evas.pc.in b/pc/evas.pc.in
index 4fd66b99d3..c49c058635 100644
--- a/pc/evas.pc.in
+++ b/pc/evas.pc.in
@@ -13,4 +13,4 @@ Requires.private: @requirements_pc_evas@
Version: @VERSION@
Libs: -L${libdir} -levas
Libs.private: @requirements_libs_evas@
-Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/evas-@VMAJ@
+Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/evas-@VMAJ@ -I${includedir}/evas-@VMAJ@/canvas
diff --git a/src/Makefile.am b/src/Makefile.am
index 6ac8dc7580..248711bc34 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,6 +15,7 @@ check_PROGRAMS =
TESTS =
EXTRA_DIST =
+GENERATED_JS_BINDINGS =
EFL_INSTALL_EXEC_HOOK=
@@ -76,6 +77,21 @@ include Makefile_Eio_Cxx.am
include Makefile_Elua.am
include Makefile_Elocation.am
+if HAVE_JS
+AM_V_CP = $(am__v_CP_@AM_V@)
+am__v_CP_ = $(am__v_CP_@AM_DEFAULT_V@)
+am__v_CP_0 = @echo " CP " $@;
+CP = cp
+if EFL_ENABLE_TESTS
+if HAVE_NODEJS
+AM_TESTS_ENVIRONMENT = NODE_PATH='$(abs_builddir)/lib/efl_js:$(abs_builddir)/tests/eolian_js:$(abs_builddir)/tests/efl_js'; export NODE_PATH;
+endif
+endif
+endif
+
+include Makefile_Eolian_Js.am
+include Makefile_Efl_Js.am
+
.PHONY: benchmark examples
BENCHMARK_SUBDIRS = \
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am
index b7e0b6b74d..13e5473a21 100644
--- a/src/Makefile_Ecore.am
+++ b/src/Makefile_Ecore.am
@@ -271,3 +271,13 @@ installed_ecoreluadir = $(datadir)/elua/modules/ecore
nodist_installed_ecorelua_DATA = $(generated_ecore_lua_all)
endif
+
+if HAVE_JS
+
+generated_ecore_js_bindings = $(ecore_eolian_files:%.eo=%.eo.js.cc)
+
+CLEANFILES += $(generated_ecore_js_bindings)
+
+GENERATED_JS_BINDINGS += $(generated_ecore_js_bindings)
+
+endif
diff --git a/src/Makefile_Ecore_Audio.am b/src/Makefile_Ecore_Audio.am
index ccce8f7fc0..b500118736 100644
--- a/src/Makefile_Ecore_Audio.am
+++ b/src/Makefile_Ecore_Audio.am
@@ -104,4 +104,15 @@ nodist_installed_ecoreaudiolua_DATA = $(generated_ecore_audio_lua_all)
endif
+if HAVE_JS
+
+generated_ecore_audio_js_bindings = $(ecore_audio_eolian_files:%.eo=%.eo.js.cc)
+
+CLEANFILES += $(generated_ecore_audio_js_bindings)
+
+GENERATED_JS_BINDINGS += $(generated_ecore_audio_js_bindings)
+
endif
+
+endif
+
diff --git a/src/Makefile_Ecore_Con.am b/src/Makefile_Ecore_Con.am
index 87ad889b26..544e6d949f 100644
--- a/src/Makefile_Ecore_Con.am
+++ b/src/Makefile_Ecore_Con.am
@@ -143,3 +143,13 @@ installed_ecoreconluadir = $(datadir)/elua/modules/ecore_con
nodist_installed_ecoreconlua_DATA = $(generated_ecore_con_lua_all)
endif
+
+if HAVE_JS
+
+generated_ecore_con_js_bindings = $(ecore_con_eolian_files:%.eo=%.eo.js.cc)
+
+CLEANFILES += $(generated_ecore_con_js_bindings)
+
+GENERATED_JS_BINDINGS += $(generated_ecore_con_js_bindings)
+
+endif
diff --git a/src/Makefile_Ecore_Js.am b/src/Makefile_Ecore_Js.am
new file mode 100644
index 0000000000..3ae483c375
--- /dev/null
+++ b/src/Makefile_Ecore_Js.am
@@ -0,0 +1,19 @@
+
+### Library
+
+if HAVE_JS
+installed_ecorejsheadersdir = $(includedir)/ecore-js-@VMAJ@
+dist_installed_ecorejsheaders_DATA = \
+bindings/ecore_js/Ecore_Js.hh \
+bindings/ecore_js/ecore_js_init.hh \
+bindings/ecore_js/ecore_js_mainloop.hh \
+bindings/ecore_js/ecore_js_timer.hh \
+bindings/ecore_js/ecore_js_event.hh \
+bindings/ecore_js/ecore_js_job.hh \
+bindings/ecore_js/ecore_js_idle.hh \
+bindings/ecore_js/ecore_js_animator.hh \
+bindings/ecore_js/ecore_js_poller.hh \
+bindings/ecore_js/ecore_js_throttle.hh \
+bindings/ecore_js/ecore_js_file.hh
+endif
+
diff --git a/src/Makefile_Edje.am b/src/Makefile_Edje.am
index ca0eefc463..4fa0ecf09f 100644
--- a/src/Makefile_Edje.am
+++ b/src/Makefile_Edje.am
@@ -130,7 +130,7 @@ if HAVE_WIN32
USE_EDJE_BIN_LIBS = -L$(top_builddir)/src/lib/evil @USE_EDJE_LIBS@
else
USE_EDJE_BIN_LIBS = @USE_EDJE_LIBS@
-endif
+endif
bin_PROGRAMS += \
bin/edje/edje_cc \
@@ -334,3 +334,13 @@ installed_edjeluadir = $(datadir)/elua/modules/edje
nodist_installed_edjelua_DATA = $(generated_edje_lua_all)
endif
+
+if HAVE_JS
+
+generated_edje_js_bindings = $(edje_eolian_files:%.eo=%.eo.js.cc)
+
+CLEANFILES += $(generated_edje_js_bindings)
+
+GENERATED_JS_BINDINGS += $(generated_edje_js_bindings)
+
+endif
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am
index f6b1c288c6..9e59bf22bf 100644
--- a/src/Makefile_Efl.am
+++ b/src/Makefile_Efl.am
@@ -80,6 +80,16 @@ nodist_installed_efllua_DATA = $(generated_efl_lua_all)
endif
+if HAVE_JS
+
+generated_efl_js_bindings = $(efl_eolian_files:%.eo=%.eo.js.cc)
+
+CLEANFILES += $(generated_efl_js_bindings)
+
+GENERATED_JS_BINDINGS += $(generated_efl_js_bindings)
+
+endif
+
### Binary
bin_PROGRAMS += \
diff --git a/src/Makefile_Efl_Js.am b/src/Makefile_Efl_Js.am
new file mode 100644
index 0000000000..ada25b9ad5
--- /dev/null
+++ b/src/Makefile_Efl_Js.am
@@ -0,0 +1,319 @@
+if HAVE_JS
+
+lib_LTLIBRARIES += lib/efl_js/libefl_js.la
+
+if HAVE_NODEJS
+
+lib_LTLIBRARIES += lib/efl_js/libefl_node_js.la
+
+$(top_builddir)/src/lib/efl_js/efl.node: lib/efl_js/libefl_node_js.la
+ $(AM_V_CP)$(CP) $(top_builddir)/src/lib/efl_js/.libs/libefl_node_js.so $(top_builddir)/src/lib/efl_js/efl.node
+
+eflnodedir = $(libdir)
+eflnode_DATA = $(top_builddir)/src/lib/efl_js/efl.node
+
+CLEANFILES += ${eflnodedir_DATA}
+EXTRA_DIST += ${eflnodedir_DATA}
+
+efljsmimedir = @XDG_DATA_HOME@/mime/packages
+efljsmime_DATA = bin/efl_js/efljslaunch.xml
+
+efljsdesktopdir = @XDG_DATA_HOME@/applications
+efljsdesktop_DATA = bin/efl_js/efljslaunch.desktop
+
+bin_SCRIPTS += \
+ bin/efl_js/efljslaunch \
+ bin/efl_js/efljspack
+
+else
+
+bin_PROGRAMS += bin/efl_js/eflv8js
+
+bin_efl_js_eflv8js_SOURCES = \
+ bin/efl_js/launcher_main.cc
+
+bin_efl_js_eflv8js_CPPFLAGS = \
+ -I$(top_builddir)/src/lib/efl \
+ -I$(top_srcdir)/src/lib/efl_js \
+ @CHECK_CFLAGS@ \
+ @EINA_CXX_CFLAGS@ \
+ @EO_CXX_CFLAGS@ \
+ @EMILE_CFLAGS@ \
+ @ECORE_CFLAGS@ \
+ @EET_CFLAGS@ \
+ @EO_CFLAGS@ \
+ @EFL_JS_CFLAGS@ \
+ @EINA_JS_CFLAGS@ \
+ @EO_JS_CFLAGS@
+
+bin_efl_js_eflv8js_LDFLAGS = \
+ -lv8 \
+ @EFL_JS_INTERNAL_LIBS@
+
+bin_efl_js_eflv8js_LDADD = \
+ lib/efl_js/libefl_js.la
+
+endif
+
+lib/efl_js/eolian_js_bindings.cc: $(GENERATED_JS_BINDINGS)
+ @echo @ECHO_E@ "#ifdef HAVE_CONFIG_H" > $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @echo @ECHO_E@ "#include \"config.h\"" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @echo @ECHO_E@ "#endif\n" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @echo @ECHO_E@ "#include <Efl.h>" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @echo @ECHO_E@ "#include <Efl_Config.h>" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @echo @ECHO_E@ "#include <Ecore.h>" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @echo @ECHO_E@ "#include <Eo.h>" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @echo @ECHO_E@ "#include <Ecore_Con.h>" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @echo @ECHO_E@ "#include <Ecore_Audio.h>" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @echo @ECHO_E@ "#include <Evas.h>" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @echo @ECHO_E@ "#include <Edje.h>" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @echo @ECHO_E@ "#include <Ecore_Con_Eet.h>" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @echo @ECHO_E@ "#include <Emotion.h>\n" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc
+ @for i in $(GENERATED_JS_BINDINGS); do echo "#include <$$i>" >> $(top_builddir)/src/lib/efl_js/eolian_js_bindings.cc; done
+
+CLEANFILES += lib/efl_js/eolian_js_bindings.cc
+
+## Install Ecore-JS headers
+installed_ecorejsheadersdir = $(includedir)/ecore-js-@VMAJ@
+dist_installed_ecorejsheaders_DATA = \
+bindings/ecore_js/Ecore_Js.hh
+
+## Install Eio-JS headers
+installed_eiojsheadersdir = $(includedir)/eio-js-@VMAJ@
+dist_installed_eiojsheaders_DATA = \
+bindings/eio_js/Eio_Js.hh
+
+## Install Ethumb-JS headers
+installed_ethumbjsheadersdir = $(includedir)/ethumb-js-@VMAJ@
+dist_installed_ethumbjsheaders_DATA = \
+bindings/ethumb_js/Ethumb_Js.hh
+
+## Install Eldbus-JS headers
+installed_eldbusjsheadersdir = $(includedir)/eldbus-js-@VMAJ@
+dist_installed_eldbusjsheaders_DATA = \
+bindings/eldbus_js/Eldbus_Js.hh
+
+## Install Eo-JS headers
+installed_eojsmainheadersdir = $(includedir)/eo-js-@VMAJ@
+dist_installed_eojsmainheaders_DATA = \
+bindings/eo_js/eo_js_call_function.hh \
+bindings/eo_js/eo_js_constructor.hh \
+bindings/eo_js/eo_js_direction.hh \
+bindings/eo_js/eo_js_event.hh \
+bindings/eo_js/eo_js_namespace.hh \
+bindings/eo_js/eo_js_struct.hh \
+bindings/eo_js/eo_js_construct_from_eo.hh \
+bindings/eo_js/Eo_Js.hh
+
+## Install Eina-JS headers
+installed_einajsheadersdir = $(includedir)/eina-js-@VMAJ@
+dist_installed_einajsheaders_DATA = \
+bindings/eina_js/Eina_Js.hh \
+bindings/eina_js/eina_js_accessor.hh \
+bindings/eina_js/eina_js_array.hh \
+bindings/eina_js/eina_js_compatibility.hh \
+bindings/eina_js/eina_js_container.hh \
+bindings/eina_js/eina_js_error.hh \
+bindings/eina_js/eina_js_get_value_from_c.hh \
+bindings/eina_js/eina_js_get_value.hh \
+bindings/eina_js/eina_js_iterator.hh \
+bindings/eina_js/eina_js_list.hh \
+bindings/eina_js/eina_js_log.hh \
+bindings/eina_js/eina_js_node.hh \
+bindings/eina_js/eina_js_value.hh
+
+installed_efljsheadersdir = $(includedir)/efl-js-@VMAJ@
+dist_installed_efljsheaders_DATA = \
+lib/efl_js/Efl_Js.hh
+
+lib_efl_js_libefl_js_la_SOURCES = \
+lib/efl_js/eolian_js_bindings.cc \
+bindings/eina_js/eina_js_container.cc \
+bindings/eina_js/eina_js_value.cc \
+bindings/eina_js/eina_js_error.cc \
+bindings/eina_js/eina_js_accessor.cc \
+bindings/eina_js/eina_js_log.cc \
+bindings/eina_js/eina_js_iterator.cc \
+bindings/eina_js/eina_js_compatibility.cc \
+bindings/ecore_js/ecore_js_init.cc \
+bindings/ecore_js/ecore_js_mainloop.cc \
+bindings/ecore_js/ecore_js_timer.cc \
+bindings/ecore_js/ecore_js_event.cc \
+bindings/ecore_js/ecore_js_job.cc \
+bindings/ecore_js/ecore_js_idle.cc \
+bindings/ecore_js/ecore_js_animator.cc \
+bindings/ecore_js/ecore_js_poller.cc \
+bindings/ecore_js/ecore_js_throttle.cc \
+bindings/ecore_js/ecore_js_file.cc \
+bindings/eldbus_js/eldbus_js_core.cc \
+bindings/eldbus_js/eldbus_js_connection.cc \
+bindings/eldbus_js/eldbus_js_message.cc \
+bindings/eldbus_js/eldbus_js_object_mapper.cc \
+bindings/eio_js/eio_js.cc \
+bindings/ethumb_js/ethumb_js_client.cc
+
+lib/efl_js/efl_js.cc $(lib_efl_js_libefl_js_la_SOURCES): $(generated_ecore_cxx_all) $(generated_eo_cxx_bindings) $(generated_efl_cxx_all)
+
+lib_efl_js_libefl_js_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
+-I$(top_srcdir)/src/lib/efl \
+-I$(top_builddir)/src/lib/efl/interfaces/ \
+-I$(top_builddir)/src/lib/evas/canvas/ \
+@EFL_JS_CFLAGS@ \
+@EO_JS_CFLAGS@ \
+@ECORE_CXX_CFLAGS@ \
+@EO_CXX_CFLAGS@ \
+@ECORE_JS_CFLAGS@ \
+@EINA_JS_CFLAGS@ \
+@ELDBUS_JS_CFLAGS@ \
+@EIO_JS_CFLAGS@ \
+@ETHUMB_JS_CFLAGS@ \
+@EINA_CXX_CFLAGS@
+lib_efl_js_libefl_js_la_LIBADD = @EFL_JS_LIBS@
+lib_efl_js_libefl_js_la_DEPENDENCIES = @EFL_JS_INTERNAL_LIBS@
+lib_efl_js_libefl_js_la_LIBTOOLFLAGS = --tag=disable-static
+
+if HAVE_NODEJS
+lib_efl_js_libefl_js_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
+
+lib_efl_js_libefl_node_js_la_SOURCES = \
+lib/efl_js/efl_js.cc
+
+lib_efl_js_libefl_node_js_la_CPPFLAGS = $(lib_efl_js_libefl_js_la_CPPFLAGS)
+lib_efl_js_libefl_node_js_la_LIBADD = $(lib_efl_js_libefl_js_la_LIBADD) lib/efl_js/libefl_js.la
+lib_efl_js_libefl_node_js_la_DEPENDENCIES = $(lib_efl_js_libefl_js_la_DEPENDENCIES) lib/efl_js/libefl_js.la
+lib_efl_js_libefl_node_js_la_LIBTOOLFLAGS = $(lib_efl_js_libefl_js_la_LIBTOOLFLAGS)
+else
+lib_efl_js_libefl_js_la_SOURCES += \
+lib/efl_js/efl_js.cc
+endif
+
+if EFL_ENABLE_TESTS
+
+SUITE_RUNNER_CXXFLAGS = -I$(top_builddir)/src/lib/efl \
+-DTESTS_WD=\"`pwd`\" \
+-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/efl_js\" \
+-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/efl_js\" \
+-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/efl_js\" \
+@CHECK_CFLAGS@ \
+@EFL_JS_CFLAGS@ \
+@EINA_CXX_CFLAGS@ \
+@EO_CXX_CFLAGS@ \
+@EO_CFLAGS@ \
+@ECORE_CFLAGS@ \
+@ECORE_CXX_CFLAGS@ \
+@ECORE_JS_CFLAGS@ \
+@EINA_JS_CFLAGS@
+
+if HAVE_NODEJS
+TESTS += tests/efl_js/eina_js_suite.js \
+tests/efl_js/eina_js_containers_suite.js \
+tests/efl_js/ecore_js_suite.js \
+tests/efl_js/eldbus_js_suite.js \
+tests/efl_js/ethumb_js_suite.js \
+tests/efl_js/eio_js_suite.js \
+tests/efl_js/benchmark_js_suite.js
+
+check_LTLIBRARIES += tests/efl_js/libbenchmark_object.la
+
+tests/efl_js/eina_js_suite.js tests/efl_js/eina_js_containers_suite.js tests/efl_js/ecore_js_suite.js tests/efl_js/eldbus_js_suite.js tests/efl_js/eio_js_suite.js tests/efl_js/ethumb_js_suite.js: $(top_builddir)/src/lib/efl_js/efl.node
+
+tests/efl_js/benchmark_object.node: tests/efl_js/libbenchmark_object.la
+ $(AM_V_CP)$(CP) $(top_builddir)/src/tests/efl_js/.libs/libbenchmark_object.so $(top_builddir)/src/tests/efl_js/benchmark_object.node
+tests/efl_js/benchmark_js_suite.js: $(top_builddir)/src/lib/efl_js/efl.node tests/efl_js/benchmark_object.node
+
+tests_efl_js_libbenchmark_object_la_SOURCES = tests/efl_js/benchmark_object_impl.cc
+tests_efl_js_libbenchmark_object_la_CXXFLAGS = \
+-I$(top_builddir)/src/lib/efl \
+-I$(top_srcdir)/src/bindings/efl_js \
+-I$(top_builddir)/src/tests/efl_js \
+-DTESTS_WD=\"`pwd`\" \
+-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/efl_js\" \
+-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/efl_js\" \
+-DPACKAGE_DATA_DIR=\"$(datadir)/efl_js\" \
+-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/efl_js\" \
+@CHECK_CFLAGS@ @EOLIAN_CXX_CFLAGS@ @EINA_JS_CFLAGS@ @EO_JS_CFLAGS@ \
+@EOLIAN_CFLAGS@ @EINA_CFLAGS@ @EO_CFLAGS@ @ECORE_CFLAGS@ @EINA_CXX_CFLAGS@ \
+@EO_JS_CFLAGS@ @EO_CXX_CFLAGS@
+tests_efl_js_libbenchmark_object_la_LIBADD = \
+@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
+tests_efl_js_libbenchmark_object_la_LDFLAGS = -rpath $(abs_top_builddir)/tests/eolian_js
+tests_efl_js_libbenchmark_object_la_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
+tests_efl_js_libbenchmark_object_la_CFLAGS = $(tests_efl_js_libbenchmark_object_la_CXXFLAGS)
+
+tests/efl_js/tests_efl_js_libbenchmark_object_la-benchmark_object_impl.l$(OBJEXT): tests/efl_js/benchmark_object.eo.js.cc tests/efl_js/benchmark_object.eo.c tests/efl_js/benchmark_object.eo.h
+else
+check_PROGRAMS += \
+tests/efl_js/eina_js_suite \
+tests/efl_js/eina_js_containers_suite \
+tests/efl_js/ecore_js_suite \
+tests/efl_js/eldbus_js_suite \
+tests/efl_js/ethumb_js_suite \
+tests/efl_js/eio_js_suite \
+tests/efl_js/benchmark_js_suite
+TESTS += tests/efl_js/eina_js_suite \
+tests/efl_js/ecore_js_suite \
+tests/efl_js/eldbus_js_suite \
+tests/efl_js/ethumb_js_suite \
+tests/efl_js/eio_js_suite \
+tests/efl_js/benchmark_js_suite
+
+tests_efl_js_eina_js_suite_SOURCES = \
+tests/efl_js/eina_js_suite.cc
+
+tests_efl_js_eina_js_suite_CXXFLAGS = $(SUITE_RUNNER_CXXFLAGS)
+tests_efl_js_eina_js_suite_LDADD = \
+@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
+tests_efl_js_eina_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
+
+tests_efl_js_eina_js_containers_suite_SOURCES = \
+tests/efl_js/eina_js_containers_suite.cc
+
+tests_efl_js_eina_js_containers_suite_CXXFLAGS = $(SUITE_RUNNER_CXXFLAGS)
+tests_efl_js_eina_js_containers_suite_LDADD = \
+@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
+tests_efl_js_eina_js_containers_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
+
+tests_efl_js_ecore_js_suite_SOURCES = \
+tests/efl_js/ecore_js_suite.cc
+
+tests_efl_js_ecore_js_suite_CXXFLAGS = $(SUITE_RUNNER_CXXFLAGS)
+tests_efl_js_ecore_js_suite_LDADD = \
+@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
+tests_efl_js_ecore_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
+
+tests_efl_js_eldbus_js_suite_SOURCES = \
+tests/efl_js/eldbus_js_suite.cc
+
+tests_efl_js_eldbus_js_suite_CXXFLAGS = $(SUITE_RUNNER_CXXFLAGS)
+tests_efl_js_eldbus_js_suite_LDADD = \
+@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
+tests_efl_js_eldbus_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
+
+tests_efl_js_ethumb_js_suite_SOURCES = \
+tests/efl_js/ethumb_js_suite.cc
+
+tests_efl_js_ethumb_js_suite_CXXFLAGS = $(SUITE_RUNNER_CXXFLAGS)
+tests_efl_js_ethumb_js_suite_LDADD = \
+@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
+tests_efl_js_ethumb_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
+
+tests_efl_js_eio_js_suite_SOURCES = \
+tests/efl_js/eio_js_suite.cc
+
+tests_efl_js_eio_js_suite_CXXFLAGS = $(SUITE_RUNNER_CXXFLAGS)
+tests_efl_js_eio_js_suite_LDADD = \
+@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
+tests_efl_js_eio_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
+
+tests_efl_js_benchmark_js_suite_SOURCES = \
+tests/efl_js/benchmark_js_suite.cc
+
+tests_efl_js_benchmark_js_suite_CXXFLAGS = $(SUITE_RUNNER_CXXFLAGS)
+tests_efl_js_benchmark_js_suite_LDADD = \
+@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
+tests_efl_js_benchmark_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
+endif
+endif
+
+
+endif
diff --git a/src/Makefile_Eina_Cxx.am b/src/Makefile_Eina_Cxx.am
index 70ef18a7bd..e9f7c13eb9 100644
--- a/src/Makefile_Eina_Cxx.am
+++ b/src/Makefile_Eina_Cxx.am
@@ -14,6 +14,7 @@ bindings/eina_cxx/eina_clone_allocators.hh \
bindings/eina_cxx/eina_error.hh \
bindings/eina_cxx/eina_eo_concrete_fwd.hh \
bindings/eina_cxx/eina_fold.hh \
+bindings/eina_cxx/eina_function.hh \
bindings/eina_cxx/eina_inarray.hh \
bindings/eina_cxx/eina_inlist.hh \
bindings/eina_cxx/eina_integer_sequence.hh \
@@ -21,7 +22,9 @@ bindings/eina_cxx/eina_iterator.hh \
bindings/eina_cxx/eina_lists_auxiliary.hh \
bindings/eina_cxx/eina_list.hh \
bindings/eina_cxx/eina_log.hh \
+bindings/eina_cxx/eina_logical.hh \
bindings/eina_cxx/eina_optional.hh \
+bindings/eina_cxx/eina_pp.hh \
bindings/eina_cxx/eina_ptrarray.hh \
bindings/eina_cxx/eina_ptrlist.hh \
bindings/eina_cxx/eina_range_types.hh \
@@ -31,6 +34,7 @@ bindings/eina_cxx/eina_string_view.hh \
bindings/eina_cxx/eina_thread.hh \
bindings/eina_cxx/eina_throw.hh \
bindings/eina_cxx/eina_tuple.hh \
+bindings/eina_cxx/eina_tuple_c.hh \
bindings/eina_cxx/eina_tuple_unwrap.hh \
bindings/eina_cxx/eina_type_traits.hh \
bindings/eina_cxx/eina_value.hh
diff --git a/src/Makefile_Emotion.am b/src/Makefile_Emotion.am
index f16a4a4c3d..4da5224060 100644
--- a/src/Makefile_Emotion.am
+++ b/src/Makefile_Emotion.am
@@ -347,3 +347,14 @@ installed_emotionluadir = $(datadir)/elua/modules/emotion
nodist_installed_emotionlua_DATA = $(generated_emotion_lua_all)
endif
+
+# TODO: gives undefined reference to emotion_object_class_get()
+if HAVE_JS
+
+generated_emotion_js_bindings = $(emotion_eolian_files:%.eo=%.eo.js.cc)
+
+CLEANFILES += $(generated_emotion_js_bindings)
+
+GENERATED_JS_BINDINGS += $(generated_emotion_js_bindings)
+
+endif
diff --git a/src/Makefile_Eo.am b/src/Makefile_Eo.am
index 57b096e795..51924feeff 100644
--- a/src/Makefile_Eo.am
+++ b/src/Makefile_Eo.am
@@ -197,3 +197,13 @@ endif
EXTRA_DIST += tests/eo/eunit_tests.h lib/eo/eo_ptr_indirection.x
+
+if HAVE_JS
+
+generated_eo_js_bindings = $(eo_eolian_files:%.eo=%.eo.js.cc)
+
+CLEANFILES += $(generated_eo_js_bindings)
+
+GENERATED_JS_BINDINGS += $(generated_eo_js_bindings)
+
+endif
diff --git a/src/Makefile_Eolian_Js.am b/src/Makefile_Eolian_Js.am
new file mode 100644
index 0000000000..091e4efa20
--- /dev/null
+++ b/src/Makefile_Eolian_Js.am
@@ -0,0 +1,118 @@
+
+if HAVE_JS
+
+### Binary
+bin_PROGRAMS += bin/eolian_js/eolian_js
+
+bin_eolian_js_eolian_js_SOURCES = \
+ bin/eolian_js/main.cc
+
+bin_eolian_js_eolian_js_CXXFLAGS = -I$(top_builddir)/src/lib/efl \
+-I$(top_srcdir)/src/bin/eolian_js \
+@EOLIAN_JS_CFLAGS@ \
+@EINA_CXX_CFLAGS@ \
+@EOLIAN_CXX_CFLAGS@
+
+bin_eolian_js_eolian_js_LDADD = @USE_EO_LIBS@ @USE_EOLIAN_LIBS@
+bin_eolian_js_eolian_js_DEPENDENCIES = @USE_EO_INTERNAL_LIBS@ @USE_EOLIAN_INTERNAL_LIBS@
+
+include Makefile_Eolian_Js_Helper.am
+
+### Unit tests
+
+if EFL_ENABLE_TESTS
+if HAVE_NODEJS
+
+TESTS += tests/eolian_js/eolian_js_suite.js
+
+check_LTLIBRARIES += tests/eolian_js/libeolian_js_suite.la
+
+tests/eolian_js/eolian_js_suite.js: tests/eolian_js/eolian_js_suite_mod.node
+tests/eolian_js/eolian_js_suite_mod.node: tests/eolian_js/libeolian_js_suite.la
+ $(AM_V_CP)$(CP) $(top_builddir)/src/tests/eolian_js/.libs/libeolian_js_suite.so $(top_builddir)/src/tests/eolian_js/eolian_js_suite_mod.node
+
+tests_eolian_js_libeolian_js_suite_la_SOURCES = \
+tests/eolian_js/eolian_js_suite.cc \
+tests/eolian_js/eolian_js_test_eolian_js_binding.cc \
+tests/eolian_js/eolian_js_test_constructor_method_impl.c \
+tests/eolian_js/eolian_js_test_test_object_impl.c
+
+tests_eolian_js_libeolian_js_suite_la_CXXFLAGS = \
+-I$(top_builddir)/src/lib/efl \
+-I$(top_srcdir)/src/bin/eolian_js \
+-I$(top_builddir)/src/tests/eolian_js \
+-DTESTS_WD=\"`pwd`\" \
+-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eolian_js\" \
+-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/eolian_js\" \
+-DPACKAGE_DATA_DIR=\"$(datadir)/eolian_js\" \
+-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eolian_js\" \
+@CHECK_CFLAGS@ @EOLIAN_CXX_CFLAGS@ @EINA_JS_CFLAGS@ @EO_JS_CFLAGS@ \
+@EOLIAN_CFLAGS@ @EINA_CFLAGS@ @EO_CFLAGS@ @ECORE_CFLAGS@ @EINA_CXX_CFLAGS@ \
+@EO_JS_CFLAGS@ @EO_CXX_CFLAGS@
+tests_eolian_js_libeolian_js_suite_la_LIBADD = \
+@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
+tests_eolian_js_libeolian_js_suite_la_LDFLAGS = -rpath $(abs_top_builddir)/tests/eolian_js
+tests_eolian_js_libeolian_js_suite_la_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ #@USE_EFL_JS_INTERNAL_LIBS@
+tests_eolian_js_libeolian_js_suite_la_CFLAGS = $(tests_eolian_js_libeolian_js_suite_la_CXXFLAGS)
+
+# if compiler_o_lo == yes, lo, otherwise $(OBJEXT)
+
+tests/eolian_js/tests_eolian_js_libeolian_js_suite_la-eolian_js_test_eolian_js_binding.l$(OBJEXT): tests/eolian_js/constructor_method_class.eo.js.cc tests/eolian_js/constructor_method_class.eo.h tests/eolian_js/test_object.eo.js.cc tests/eolian_js/test_object.eo.h
+tests/eolian_js/tests_eolian_js_libeolian_js_suite_la-eolian_js_test_constructor_method_impl.l$(OBJEXT): tests/eolian_js/constructor_method_class.eo.c
+tests/eolian_js/tests_eolian_js_libeolian_js_suite_la-eolian_js_test_test_object_impl.l$(OBJEXT): tests/eolian_js/test_object.eo.c
+
+CLEANFILES += \
+tests/eolian_js/constructor_method_class.eo.js.cc \
+tests/eolian_js/constructor_method_class.eo.c \
+tests/eolian_js/constructor_method_class.eo.h \
+tests/eolian_js/test_object.eo.js.cc \
+tests/eolian_js/test_object.eo.c \
+tests/eolian_js/test_object.eo.h
+else
+check_PROGRAMS += tests/eolian_js/eolian_js_suite
+TESTS += tests/eolian_js/eolian_js_suite
+
+tests_eolian_js_eolian_js_suite_SOURCES = \
+tests/eolian_js/eolian_js_suite.cc \
+tests/eolian_js/eolian_js_test_eolian_js_binding.cc \
+tests/eolian_js/eolian_js_test_constructor_method_impl.c \
+tests/eolian_js/eolian_js_test_test_object_impl.c
+
+tests/eolian_js/tests_eolian_js_eolian_js_suite-eolian_js_test_eolian_js_binding.$(OBJEXT): tests/eolian_js/constructor_method_class.eo.js.cc tests/eolian_js/constructor_method_class.eo.h tests/eolian_js/test_object.eo.js.cc tests/eolian_js/test_object.eo.h
+tests/eolian_js/tests_eolian_js_eolian_js_suite-eolian_js_test_constructor_method_impl.$(OBJEXT): tests/eolian_js/constructor_method_class.eo.c
+tests/eolian_js/tests_eolian_js_eolian_js_suite-eolian_js_test_test_object_impl.$(OBJEXT): tests/eolian_js/test_object.eo.c
+
+CLEANFILES += \
+tests/eolian_js/constructor_method_class.eo.js.cc \
+tests/eolian_js/constructor_method_class.eo.c \
+tests/eolian_js/constructor_method_class.eo.h \
+tests/eolian_js/test_object.eo.js.cc \
+tests/eolian_js/test_object.eo.c \
+tests/eolian_js/test_object.eo.h
+
+tests_eolian_js_eolian_js_suite_CXXFLAGS = \
+-I$(top_builddir)/src/lib/efl \
+-I$(top_srcdir)/src/bin/eolian_js \
+-I$(top_builddir)/src/tests/eolian_js \
+-I$(top_srcdir)/src/tests/efl_js \
+-DTESTS_WD=\"`pwd`\" \
+-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eolian_js\" \
+-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/eolian_js\" \
+-DPACKAGE_DATA_DIR=\"$(datadir)/eolian_js\" \
+-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eolian_js\" \
+@CHECK_CFLAGS@ @EOLIAN_CXX_CFLAGS@ @EINA_JS_CFLAGS@ @EO_JS_CFLAGS@ @EFL_JS_CFLAGS@ \
+@EOLIAN_CFLAGS@ @EINA_CFLAGS@ @EO_CFLAGS@ @ECORE_CFLAGS@ @EINA_CXX_CFLAGS@ \
+@EO_JS_CFLAGS@ @EO_CXX_CFLAGS@ @EFL_JS_CFLAGS@
+
+tests_eolian_js_eolian_js_suite_CFLAGS = ${tests_eolian_js_eolian_js_suite_CXXFLAGS}
+tests_eolian_js_eolian_js_suite_CPPFLAGS = ${tests_eolian_js_eolian_js_suite_CXXFLAGS}
+tests_eolian_js_eolian_js_suite_LDADD = \
+@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@ @USE_EVAS_LIBS@ @USE_EFL_JS_LIBS@
+tests_eolian_js_eolian_js_suite_DEPENDENCIES = @USE_EOLIAN_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@ @USE_EVAS_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
+endif
+endif
+
+endif
+
+
+
diff --git a/src/Makefile_Eolian_Js_Helper.am b/src/Makefile_Eolian_Js_Helper.am
new file mode 100644
index 0000000000..fcc523153f
--- /dev/null
+++ b/src/Makefile_Eolian_Js_Helper.am
@@ -0,0 +1,18 @@
+#if HAVE_EOLIAN_JS
+#EOLIAN_JS = @eolian_js@
+#_EOLIAN_JS_DEP = @eolian_js@
+#else
+EOLIAN_JS = EFL_RUN_IN_TREE=1 $(top_builddir)/src/bin/eolian_js/eolian_js${EXEEXT}
+_EOLIAN_JS_DEP = bin/eolian_js/eolian_js${EXEEXT}
+#endif
+
+AM_V_EOLJS = $(am__v_EOLJS_@AM_V@)
+am__v_EOLJS_ = $(am__v_EOLJS_@AM_DEFAULT_V@)
+am__v_EOLJS_0 = @echo " EOLJS " $@;
+
+SUFFIXES += .eo.js.cc
+
+%.eo.js.cc: %.eo $(_EOLIAN_JS_DEP)
+ $(AM_V_EOLJS)$(EOLIAN_JS) $(EOLIAN_FLAGS) -o $@ $<
+
+CLEANFILES += $(BUILT_SOURCES)
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index 3f7dd3941b..ebc5480151 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -2221,3 +2221,13 @@ $(NULL)
installed_evasfiltersdir = $(datadir)/evas/filters/lua
dist_installed_evasfilters_DATA = $(evas_filters_lua)
+
+if HAVE_JS
+
+generated_evas_js_bindings = $(evas_eolian_files:%.eo=%.eo.js.cc)
+
+CLEANFILES += $(generated_evas_js_bindings)
+
+GENERATED_JS_BINDINGS += $(generated_evas_js_bindings)
+
+endif
diff --git a/src/bin/efl_js/efljslaunch b/src/bin/efl_js/efljslaunch
new file mode 100755
index 0000000000..785c30e3e3
--- /dev/null
+++ b/src/bin/efl_js/efljslaunch
@@ -0,0 +1,139 @@
+#!/bin/sh
+':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@"
+
+// Core node modules
+var path = require('path');
+var os = require('os');
+var zlib = require('zlib');
+var child_process = require('child_process');
+
+// 3rd party modules
+var fs = require('fs-extra');
+var getopt = require('node-getopt');
+var tar = require('tar');
+
+function make_error_cb(message)
+{
+ return function(e) {
+ console.error("Error %s: %s", message, e);
+ process.exit(1);
+ };
+}
+
+function remove_files(options)
+{
+ if (options.verbose)
+ console.log("Removing temporary files");
+
+ fs.remove(options.project_folder);
+}
+
+function run_project(options)
+{
+ if (options.verbose)
+ console.log("Running the project");
+
+ var current_dir = process.cwd();
+ process.chdir(options.project_root);
+
+ var proc = child_process.fork(options.metadata.Entry);
+ proc.on('exit', function(code){
+ if (options.verbose)
+ console.log('Child exited with code %s', code);
+ process.chdir(current_dir);
+ if (!options.keep)
+ remove_files(options);
+ });
+
+}
+
+function unpack_project_data(options)
+{
+ if (options.verbose)
+ console.log("Unpacking project sources and assets");
+
+ var datafile = path.join(options.project_folder, "data.tar.gz");
+ var project_root = path.join(options.project_folder, "root");
+
+ options.project_root = project_root;
+
+ var input = fs.createReadStream(datafile);
+ var unzipper = zlib.createGunzip();
+ var extractor = tar.Extract({path: project_root, strip: 0});
+
+ input.on('error', make_error_cb("reading package data file."));
+ extractor.on('error', make_error_cb("unpacking package data file."));
+ if (!("only-extract" in options))
+ extractor.on('end', function(){ run_project(options); });
+
+ input.pipe(unzipper)
+ unzipper.pipe(extractor);
+}
+
+function read_metadata(options)
+{
+ if (options.verbose)
+ console.log("Reading project metadata");
+
+ var project_folder = options.project_folder;
+ var metadata = JSON.parse(fs.readFileSync(path.join(project_folder, "meta.json")));
+
+ if (options.verbose)
+ console.log("Project: %s\nVersion: %s\nEntry point: %s", metadata.Name, metadata.Version, metadata.Entry);
+ if ("only-dump" in options)
+ process.exit(0);
+
+ options.metadata = metadata;
+
+ unpack_project_data(options);
+}
+
+function extract(filename, options)
+{
+ if (options.verbose)
+ console.log("Extracting ", filename, "with options ", options);
+
+ var project_id = path.basename(filename, ".epk");
+ var project_folder = path.join(options['temp-dir'], project_id);
+
+ options.project_folder = project_folder;
+ options.project_id = project_id;
+
+ var input = fs.createReadStream(filename);
+ var extractor = tar.Extract({path: options['temp-dir'], strip: 0});
+
+ input.on('error', make_error_cb("reading package file."));
+ extractor.on('error', make_error_cb("unpacking package file."));
+ extractor.on('end', function(){ read_metadata(options); });
+
+ input.pipe(extractor);
+}
+
+function main() {
+ var options = getopt.create([
+ ['d', 'only-dump', 'Only dump information about the package'],
+ ['e', 'only-extract', 'Only extract the package, do not run'],
+ ['h', 'help', 'Display this help'],
+ ['k', 'keep', 'Do not remove the files after exiting'],
+ ['t', 'temp-dir=ARG', 'Temporary dir to extract files'],
+ ['v', 'verbose', 'Print information messages'],
+ ]).bindHelp().parseSystem();
+
+ var filename = options.argv[0];
+ if (filename === undefined)
+ {
+ console.error("Must provide a package file.");
+ process.exit(1);
+ }
+
+ if (!('temp-dir' in options.options))
+ {
+ options.options["temp-dir"] = path.join(os.tmpdir(), "efljs_apps");
+ if (options.verbose)
+ console.log("Defaulting temp dir to ", options.options["temp-dir"]);
+ }
+
+ extract(filename, options.options);
+}
+
+main();
diff --git a/src/bin/efl_js/efljslaunch.desktop b/src/bin/efl_js/efljslaunch.desktop
new file mode 100644
index 0000000000..53371cba97
--- /dev/null
+++ b/src/bin/efl_js/efljslaunch.desktop
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Name=EFL JS package launcher
+Exec=efljslaunch %f
+Type=Application
+Categories=EFL
+Terminal=true
+MimeType=application/x-efljspackage;
diff --git a/src/bin/efl_js/efljslaunch.xml b/src/bin/efl_js/efljslaunch.xml
new file mode 100644
index 0000000000..b1db6841b2
--- /dev/null
+++ b/src/bin/efl_js/efljslaunch.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+ <mime-type type="application/x-efljspackage">
+ <comment xml:lang="en">EFL JS package</comment>
+ <glob pattern="*.epk"/>
+ </mime-type>
+</mime-info> \ No newline at end of file
diff --git a/src/bin/efl_js/efljspack b/src/bin/efl_js/efljspack
new file mode 100755
index 0000000000..50e27b6ac4
--- /dev/null
+++ b/src/bin/efl_js/efljspack
@@ -0,0 +1,251 @@
+#!/bin/sh
+':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@"
+
+var zlib = require('zlib');
+var path = require('path');
+
+// external dependencies
+var fs = require('fs-extra');
+var tar = require('tar');
+var fstream = require('fstream');
+var getopt = require('node-getopt');
+
+/*
+ * Packing a project.
+ * The efljs package has a similar format to debian packages. It is a
+ * tar package containing two files:
+ *
+ * meta.txt: Metadata information about this package.
+ * data.tar.gz: Gzipped data, with the project tree ready to be decompressed
+ * and run by the package launcher.
+ *
+ * During the build, a out/ directory is created in the project root to
+ * store the package and temporary files.
+ */
+
+// Creates a stub .project file and packs it.
+function pack_single(sourcepath, options)
+{
+ if (options.verbose)
+ console.log("Creating project file for single file app", sourcepath);
+
+ var dir_name = path.dirname(fs.realpathSync(sourcepath));
+ var filename = path.basename(sourcepath);
+ var projectRegex = /^(.*).js$/g;
+ var project_name = projectRegex.exec(filename)[1];
+
+ if (!validade_project_name(project_name))
+ {
+ console.error("Invalid project name. Must start with a letter.");
+ process.exit(0);
+ }
+
+ var project_filename = path.join(dir_name, project_name + ".project");
+
+ var fd = fs.openSync(project_filename, 'w');
+
+ var jsonData = {};
+
+ jsonData["Name"] = project_name;
+ jsonData["Entry"] = filename;
+ jsonData["Sources"] = [[filename, '.']];
+ jsonData["Version"] = "0.1";
+
+ fs.writeSync(fd, JSON.stringify(jsonData, null, 2));
+
+ fs.closeSync(fd);
+
+ pack_project(project_filename, options);
+
+}
+
+function generate_build_info(configuration, project_file, options)
+{
+ build_info = {};
+
+ // project == project_dir
+ // /out == build_dir
+ // /data == data_dir
+ // /name-version == package_dir
+
+ build_info.package_id = configuration.Name + "-" + configuration.Version;
+ build_info.project_dir = path.dirname(project_file);
+ build_info.build_dir = path.join(build_info.project_dir, "out");
+ build_info.data_dir = path.join(build_info.build_dir, "data");
+ build_info.package_dir = path.join(build_info.build_dir, build_info.package_id);
+ build_info.data_file = path.join(build_info.package_dir, "data.tar.gz");
+ build_info.package_file = path.join(build_info.build_dir, build_info.package_id + ".epk")
+ build_info.metadata_file = path.join(build_info.package_dir, "meta.json");
+
+ if (options.verbose)
+ {
+ console.log("Project id: ", build_info.package_id);
+ console.log("Project source dir: ", build_info.project_dir);
+ console.log("Project build dir: ", build_info.build_dir);
+ console.log("Project data dir:", build_info.data_dir);
+ console.log("Project package dir:", build_info.package_dir);
+ }
+
+ return build_info;
+
+}
+
+// Project names must start with a letter and contain only
+// letters, digits and underscores.
+function validade_project_name(name)
+{
+ return (/^[a-zA-Z][\w-]*$/).test(name)
+}
+
+function pack_project(project_file, options)
+{
+ if (options.verbose)
+ console.log("Packing project from project file ", project_file);
+
+ var configuration = JSON.parse(fs.readFileSync(project_file));
+
+ if (!validade_project_name(configuration.Name))
+ {
+ console.error("Invalid project name. Must start with a letter.");
+ process.exit(0);
+ }
+
+ var build_info = generate_build_info(configuration, project_file, options);
+
+ try
+ {
+ fs.mkdirSync(build_info.build_dir);
+ fs.mkdirSync(build_info.data_dir);
+ fs.mkdirSync(build_info.package_dir);
+ }
+ catch (e)
+ {
+ console.warn("Warning: Project output directories not empty.");
+ }
+
+ create_metadata_file(configuration, build_info, options);
+
+ // If not explicitly named on configuration, add the entire directory
+ if (!('Sources' in configuration))
+ {
+ generate_source_list(configuration, build_info.project_dir, options);
+ }
+
+ create_project_tree(configuration.Sources, build_info, options);
+
+ pack_data_dir(build_info, options);
+}
+
+function create_project_tree(sources, build_info, options)
+{
+ for (var i = sources.length - 1; i >= 0; i--) {
+ if (options.verbose)
+ console.log("Adding file ", sources[i], "to package.");
+ var source_file = path.join(build_info.project_dir, sources[i][0]);
+ var destination_dir = path.join(build_info.data_dir, sources[i][1]);
+ var destination_filename = path.basename(source_file);
+ var destination_file = path.join(destination_dir, destination_filename);
+
+ fs.copySync(source_file, destination_file);
+ };
+}
+
+function generate_source_list(configuration, project_dir, options)
+{
+ console.log("Generating source list for project dir", build_info.project_dir);
+ var dir_entries = fs.readdirSync(project_dir);
+ var sources = [];
+
+ dir_entries.forEach(function(entry){
+ if (entry == "out")
+ return;
+ sources.push([entry, "."]);
+ });
+ configuration.Sources = sources;
+}
+
+function create_metadata_file(configuration, build_info, options)
+{
+ if (options.verbose)
+ console.log("Creating metadata file", build_info.metadata_file);
+
+ var metadata = {};
+
+ metadata.Name = configuration.Name;
+ metadata.Entry = configuration.Entry;
+ metadata.Version = configuration.Version;
+
+ var output = fs.createWriteStream(build_info.metadata_file);
+ output.write(JSON.stringify(metadata, null, 2));
+ output.close();
+}
+
+function pack_data_dir(build_info, options)
+{
+ if (options.verbose)
+ console.log("Packing data...");
+
+ pack_directory(build_info.data_dir, build_info.data_file, true, true, function(){
+ if (options.verbose)
+ console.log("Packed data");
+ pack_final_package(build_info, options);
+ });
+}
+
+function pack_final_package(build_info, options)
+{
+ if (options.verbose)
+ console.log("Creating package ", build_info.package_file);
+ pack_directory(build_info.package_dir, build_info.package_file, false, false, function(){
+ if (options.verbose)
+ console.log("Created project package.");
+ });
+}
+
+function pack_directory(source_dir, target_file, strip_base_dir, should_gzip, callback)
+{
+ var output = fs.createWriteStream(target_file);
+ var packer = tar.Pack({fromBase: strip_base_dir == true});
+ if (callback != undefined)
+ output.on('close', callback);
+
+ var reader = fstream.Reader({path: source_dir, type: "Directory"});
+ var destStr = reader.pipe(packer);
+ if(should_gzip)
+ destStr = destStr.pipe(zlib.createGzip());
+ destStr.pipe(output);
+}
+
+function main()
+{
+
+ var options = getopt.create([
+ ['v', 'verbose', 'Explain what is being done'],
+ ['h', 'help', 'Display this help']
+ ]).bindHelp().parseSystem();
+
+ filename = options.argv[0];
+
+ if (typeof filename === 'undefined')
+ {
+ console.error('Must provide a valid js or project file.');
+ process.exit(1);
+ }
+
+ if (endsWith(filename, ".js"))
+ {
+ pack_single(filename, options.options);
+ }
+ else if (endsWith(filename, ".project"))
+ {
+ pack_project(filename, options.options);
+ }
+}
+
+main();
+
+//// Helper functions
+function endsWith(str, suffix)
+{
+ return str.indexOf(suffix, str.length - suffix.length) !== -1;
+}
diff --git a/src/bin/efl_js/launcher_main.cc b/src/bin/efl_js/launcher_main.cc
new file mode 100644
index 0000000000..680f16ca52
--- /dev/null
+++ b/src/bin/efl_js/launcher_main.cc
@@ -0,0 +1,156 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <cerrno>
+
+#include <Eo_Js.hh>
+#include <Eina.hh>
+#include <Eo.hh>
+// #include <efl_js.hh>
+
+using namespace std;
+using namespace v8;
+
+const char PATH_SEPARATOR =
+#ifdef _WIN32
+ '\\';
+#else
+ '/';
+#endif
+
+static std::string get_file_contents(const char *filename) {
+ std::ifstream in(filename, std::ios::in);
+ if (in) {
+ std::ostringstream contents;
+ contents << in.rdbuf();
+ in.close();
+ return contents.str();
+ } else {
+ throw(errno);
+ }
+}
+
+static std::string get_filename(std::string path)
+{
+ int beginIdx = path.rfind(PATH_SEPARATOR);
+ return path.substr(beginIdx + 1);
+}
+
+static void show_usage(std::string name)
+{
+ std::cerr << "Usage: " << get_filename(name) << " <option(s)> [SOURCE]\n" << std::endl
+ << "Options:" << std::endl
+ << "\t-h, --help\t\t Show this help message" << std::endl;
+}
+
+/*
+ * Basic console.log implementation with space-separated values,
+ * no substitution
+ */
+void Log(const FunctionCallbackInfo<Value>& args)
+{
+ Isolate* isolate = Isolate::GetCurrent();
+ HandleScope scope(isolate);
+
+ for (int i=0; i < args.Length(); i++)
+ {
+ if (i != 0)
+ std::cout << " ";
+ String::Utf8Value string(args[i]);
+ std::cout << *string;
+ }
+
+ std::cout << std::endl;
+
+ args.GetReturnValue().Set(v8::Null(isolate));
+}
+
+
+int main(int argc, char* argv[])
+{
+
+ std::string script_source;
+ char *filename = 0;
+
+ for (int i=1; i < argc; i++)
+ {
+ if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0))
+ {
+ show_usage(argv[0]);
+ return 0;
+ }
+ else
+ {
+ filename = argv[i];
+ }
+ }
+
+ if (!filename)
+ {
+ std::cerr << "Error: No source provided." << std::endl;
+ show_usage(argv[0]);
+ return 1;
+ }
+
+ try
+ {
+ script_source = get_file_contents(filename);
+ } catch (int errno)
+ {
+ perror("Error: ");
+ return 1;
+ }
+
+
+ efl::eina::js::compatibility_initialize();
+ v8::V8::SetFlagsFromCommandLine(&argc, const_cast<char**>(argv), true);
+
+ v8::Isolate* isolate = efl::eina::js::compatibility_isolate_new();
+ {
+ Isolate::Scope isolate_scope(isolate);
+ HandleScope handleScope(isolate);
+
+ Local<Context> context = Context::New(isolate, NULL);
+ Context::Scope context_scope(context);
+ context->Enter();
+
+ // Setup the console and log
+ Local<Object> console = Object::New(isolate);
+ Local<FunctionTemplate> log = FunctionTemplate::New(isolate, Log);
+ console->Set(String::NewFromUtf8(isolate, "log"), log->GetFunction());
+
+ Local<Object> global = context->Global();
+ global->Set(String::NewFromUtf8(isolate, "console"), console);
+
+ // Set up the efl exports; Needed to enter the context before this
+ // due to creating Objects instead of Objects Templates
+ // WIP: Commented out due to potential missing v8 platform implementation issues
+ // Local<Object> efl_exports = Object::New(isolate);
+ // global->Set(String::NewFromUtf8(isolate, "efl"), efl_exports);
+ // efl_js::init(efl_exports);
+
+ // And now the user's script
+ Local<String> source = String::NewFromUtf8(isolate, script_source.c_str());
+
+ Local<Script> script = Script::Compile(source);
+
+ TryCatch tryCatch(isolate);
+ Local<Value> result = script->Run();
+
+ if (result.IsEmpty())
+ {
+ Local<Value> exception = tryCatch.Exception();
+ String::Utf8Value exception_str(exception);
+ printf("Exception: %s\n", *exception_str);
+ }
+
+ }
+
+ V8::Dispose();
+ return 0;
+}
diff --git a/src/bin/eolian_js/.gitignore b/src/bin/eolian_js/.gitignore
new file mode 100644
index 0000000000..631f68aa1f
--- /dev/null
+++ b/src/bin/eolian_js/.gitignore
@@ -0,0 +1 @@
+/eolian_js
diff --git a/src/bin/eolian_js/eolian/class.hh b/src/bin/eolian_js/eolian/class.hh
new file mode 100644
index 0000000000..bd04d5fedd
--- /dev/null
+++ b/src/bin/eolian_js/eolian/class.hh
@@ -0,0 +1,139 @@
+#ifndef EOLIAN_KLASS_HH
+#define EOLIAN_KLASS_HH
+
+#include <Eina.hh>
+
+#include <eolian/js/domain.hh>
+
+#include <ostream>
+
+inline std::string name(Eolian_Class const* klass)
+{
+ return ::eolian_class_name_get(klass);
+}
+
+inline std::string full_name(Eolian_Class const* klass)
+{
+ return ::eolian_class_full_name_get(klass);
+}
+
+inline std::string full_name_transformed(Eolian_Class const* klass)
+{
+ auto r = full_name(klass);
+ std::replace(r.begin(), r.end(), '.', '_');
+ return r;
+}
+
+inline std::size_t namespace_size(Eolian_Class const* klass)
+{
+ std::size_t size = 0;
+ for(efl::eina::iterator<const char> first (::eolian_class_namespaces_get(klass))
+ , last; first != last; ++first)
+ ++size;
+ return size;
+}
+
+inline std::string type_class_name(Eolian_Type const* tp)
+{
+ if (tp)
+ {
+ Eolian_Type_Type tpt = ::eolian_type_type_get(tp);
+ if (tpt == EOLIAN_TYPE_POINTER || tpt == EOLIAN_TYPE_ALIAS || tpt == EOLIAN_TYPE_REGULAR)
+ {
+ return type_class_name(::eolian_type_base_type_get(tp));
+ }
+ else if(tpt == EOLIAN_TYPE_CLASS)
+ {
+ Eolian_Class const* klass = ::eolian_type_class_get(tp);
+ if (klass)
+ {
+ Eina_Stringshare* klass_name = ::eolian_class_full_name_get(klass);
+ if (!klass_name)
+ throw std::runtime_error("Could not get Eo class name");
+
+ return klass_name;
+ } // TODO: else should throw std::runtime_error("Could not get Eo class");
+ }
+ else if(tpt == EOLIAN_TYPE_STRUCT)
+ {
+ auto struct_type_full_name = ::eolian_type_full_name_get(tp);
+ if (!struct_type_full_name)
+ throw std::runtime_error("Could not get struct name");
+ return struct_type_full_name;
+ }
+ }
+ return "";
+}
+
+inline void print_lower_case_namespace(Eolian_Class const* klass, std::ostream& os)
+{
+ std::vector<std::string> namespace_;
+ for(efl::eina::iterator<const char> first (::eolian_class_namespaces_get(klass))
+ , last; first != last; ++first)
+ namespace_.push_back(&*first);
+ for(auto first = namespace_.begin(), last = namespace_.end()
+ ; first != last; ++first)
+ {
+ std::string lower(*first);
+ std::transform(lower.begin(), lower.end(), lower.begin(), tolower);
+ os << lower;
+ if(std::next(first) != last) os << "::";
+ }
+}
+
+inline void print_eo_class(Eolian_Class const* klass, std::ostream& os)
+{
+ assert(klass != 0);
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "print_eo_class";
+
+ auto toupper = [] (unsigned char c) { return std::toupper(c); };
+
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "print_eo_class";
+ std::vector<std::string> namespace_;
+ for(efl::eina::iterator<const char> first (::eolian_class_namespaces_get(klass))
+ , last; first != last; ++first)
+ namespace_.push_back(&*first);
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "namespace";
+ namespace_.push_back(name(klass));
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "class";
+ switch(eolian_class_type_get(klass))
+ {
+ case EOLIAN_CLASS_REGULAR:
+ case EOLIAN_CLASS_ABSTRACT:
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "";
+ namespace_.push_back("CLASS");
+ break;
+ case EOLIAN_CLASS_INTERFACE:
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "";
+ namespace_.push_back("INTERFACE");
+ break;
+ case EOLIAN_CLASS_MIXIN:
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "";
+ namespace_.push_back("MIXIN");
+ break;
+ default:
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "default ?";
+ std::abort();
+ }
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "";
+ for(auto first = namespace_.begin(), last = namespace_.end()
+ ; first != last; ++first)
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "";
+ std::string upper(*first);
+ std::transform(upper.begin(), upper.end(), upper.begin(), toupper);
+ os << upper;
+ if(std::next(first) != last) os << "_";
+ }
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "";
+}
+
+inline bool is_evas(Eolian_Class const* klass)
+{
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "is_evas";
+ efl::eina::iterator<const char> first (::eolian_class_namespaces_get(klass));
+ return first != efl::eina::iterator<const char>()
+ && std::strcmp(&*first, "Evas") == 0;
+}
+
+#endif
diff --git a/src/bin/eolian_js/eolian/js/domain.hh b/src/bin/eolian_js/eolian/js/domain.hh
new file mode 100644
index 0000000000..38cf542873
--- /dev/null
+++ b/src/bin/eolian_js/eolian/js/domain.hh
@@ -0,0 +1,8 @@
+
+#include <Eina.hh>
+
+namespace eolian { namespace js {
+
+extern efl::eina::log_domain domain;
+
+} }
diff --git a/src/bin/eolian_js/eolian/js/format.hh b/src/bin/eolian_js/eolian/js/format.hh
new file mode 100644
index 0000000000..a07d541e14
--- /dev/null
+++ b/src/bin/eolian_js/eolian/js/format.hh
@@ -0,0 +1,44 @@
+#ifndef EOLIAN_JS_FORMAT_HH
+#define EOLIAN_JS_FORMAT_HH
+
+#include <eolian/js/domain.hh>
+
+#include <algorithm>
+#include <string>
+#include <cctype>
+
+namespace eolian { namespace js {
+
+namespace format {
+
+std::string generic(std::string const& in)
+{
+ std::string s = in;
+ auto i = s.find('_');
+ while (i != std::string::npos)
+ {
+ if (i <= 0 || i+1 >= s.size() ||
+ !::isalnum(s[i-1]) || !::isalnum(s[i+1]))
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "Entity '" << in
+ << "' can't be conveniently converted to a JavaScript name.";
+ return in;
+ }
+ s[i+1] = static_cast<char>(::toupper(s[i+1]));
+ s.erase(i, 1);
+ i = s.find('_', i);
+ }
+ return s;
+}
+
+std::string constant(std::string in)
+{
+ std::transform(in.begin(), in.end(), in.begin(), ::toupper);
+ return in;
+}
+
+}
+
+} }
+
+#endif
diff --git a/src/bin/eolian_js/main.cc b/src/bin/eolian_js/main.cc
new file mode 100644
index 0000000000..7f3cfd2e59
--- /dev/null
+++ b/src/bin/eolian_js/main.cc
@@ -0,0 +1,1076 @@
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Eolian.h>
+#include <Eina.hh>
+
+#include <eolian/js/domain.hh>
+#include <eolian/js/format.hh>
+#include <eolian/class.hh>
+
+#include <iostream>
+#include <fstream>
+#include <unordered_map>
+#include <sstream>
+#include <stdexcept>
+
+#include <libgen.h>
+#include <getopt.h>
+#include <cstdlib>
+#include <vector>
+#include <set>
+
+namespace eolian { namespace js {
+
+efl::eina::log_domain domain("eolian_js");
+
+struct incomplete_complex_type_error : public std::exception
+{
+ explicit incomplete_complex_type_error(std::string const& msg_arg)
+ : msg(msg_arg)
+ {}
+ virtual ~incomplete_complex_type_error() {}
+ virtual const char* what() const noexcept { return msg.c_str(); }
+
+ std::string msg;
+};
+
+} }
+
+
+std::string
+_lowercase(std::string str)
+{
+ transform(begin(str), end(str), begin(str), tolower);
+ return str;
+}
+
+std::string
+_uppercase(std::string str)
+{
+ transform(begin(str), end(str), begin(str), toupper);
+ return str;
+}
+
+std::string
+_class_name_getter(std::string const& caller_class_prefix, std::string class_name)
+{
+ std::replace(class_name.begin(), class_name.end(), '.', '_');
+ return caller_class_prefix + "_" + class_name + "_cls_name_getter";
+}
+
+void
+_final_type_and_type_type_get(Eolian_Type const* tp_in, Eolian_Type const*& tp_out, Eolian_Type_Type& tpt_out)
+{
+ tp_out = tp_in;
+ tpt_out = eolian_type_type_get(tp_in);
+ while ((tpt_out == EOLIAN_TYPE_REGULAR || tpt_out == EOLIAN_TYPE_ALIAS) && !eolian_type_is_extern(tp_out))
+ {
+ auto t = eolian_type_base_type_get(tp_out);
+ // TODO: shouldn't __undefined_type be flagged as external???
+ if (!t || !eolian_type_full_name_get(t) || strcmp(eolian_type_full_name_get(t), "__undefined_type") == 0) break;
+ tp_out = t;
+ tpt_out = eolian_type_type_get(t);
+ }
+}
+
+std::string
+_eolian_type_cpp_type_named_get(const Eolian_Type *tp, std::string const& caller_class_prefix, std::set<std::string>& need_name_getter)
+{
+ const auto is_const = eolian_type_is_const(tp);
+
+ Eolian_Type_Type tpt = EOLIAN_TYPE_UNKNOWN_TYPE;
+ _final_type_and_type_type_get(tp, tp, tpt);
+
+ if (tpt == EOLIAN_TYPE_UNKNOWN_TYPE)
+ return "error";
+
+ std::string result;
+
+ if ((tpt == EOLIAN_TYPE_VOID
+ || tpt == EOLIAN_TYPE_REGULAR
+ || tpt == EOLIAN_TYPE_COMPLEX
+ || tpt == EOLIAN_TYPE_STRUCT
+ || tpt == EOLIAN_TYPE_STRUCT_OPAQUE
+ || tpt == EOLIAN_TYPE_ENUM
+ || tpt == EOLIAN_TYPE_ALIAS
+ || tpt == EOLIAN_TYPE_CLASS)
+ && is_const)
+ {
+ result += "const ";
+ }
+
+
+ if (tpt == EOLIAN_TYPE_REGULAR
+ || tpt == EOLIAN_TYPE_COMPLEX
+ || tpt == EOLIAN_TYPE_STRUCT
+ || tpt == EOLIAN_TYPE_STRUCT_OPAQUE
+ || tpt == EOLIAN_TYPE_ENUM
+ || tpt == EOLIAN_TYPE_ALIAS
+ || tpt == EOLIAN_TYPE_CLASS)
+ {
+ for (efl::eina::iterator<const char> first(::eolian_type_namespaces_get(tp)), last; first != last; ++first)
+ {
+ std::string np(&*first);
+ result += np + "_"; // TODO: transform it to the C++ equivalent?
+ }
+
+ // this comes from ctypes at eo_lexer.c and KEYWORDS at eo_lexer.h
+ const static std::unordered_map<std::string, std::string> type_map = {
+ {"byte", "signed char"},
+ {"ubyte", "unsigned char"},
+ {"char", "char"},
+ {"short", "short"},
+ {"ushort", "unsigned short"},
+ {"int", "int"},
+ {"uint", "unsigned int"},
+ {"long", "long"},
+ {"ulong", "unsigned long"},
+ {"llong", "long long"},
+ {"ullong", "unsigned long long"},
+ {"int8", "int8_t"},
+ {"uint8", "uint8_t"},
+ {"int16", "int16_t"},
+ {"uint16", "uint16_t"},
+ {"int32", "int32_t"},
+ {"uint32", "uint32_t"},
+ {"int64", "int64_t"},
+ {"uint64", "uint64_t"},
+ {"int128", "int128_t"},
+ {"uint128", "uint128_t"},
+ {"size", "size_t"},
+ {"ssize", "ssize_t"},
+ {"intptr", "intptr_t"},
+ {"uintptr", "uintptr_t"},
+ {"ptrdiff", "ptrdiff_t"},
+ {"time", "time_t"},
+ {"float", "float"},
+ {"double", "double"},
+ {"bool", "Eina_Bool"},
+ {"void", "void"},
+ {"generic_value", "Eina_Value"},
+ {"accessor", "Eina_Accessor"},
+ {"array", "Eina_Array"},
+ {"iterator", "Eina_Iterator"},
+ {"hash", "Eina_Hash"},
+ {"list", "Eina_List"}
+ };
+
+ std::string type_name = eolian_type_name_get(tp);
+ auto it = type_map.find(type_name);
+ if (it != end(type_map))
+ type_name = it->second;
+ result += type_name;
+
+ if (tpt == EOLIAN_TYPE_STRUCT)
+ {
+ result = "efl::eina::js::make_struct_tag<" + result + ">";
+ }
+ }
+ else if (tpt == EOLIAN_TYPE_VOID)
+ result += "void";
+ else // tpt == EOLIAN_TYPE_POINTER
+ {
+ auto btp = eolian_type_base_type_get(tp);
+ result += _eolian_type_cpp_type_named_get(btp, caller_class_prefix, need_name_getter);
+
+ const auto base_is_const = eolian_type_is_const(btp);
+
+ Eolian_Type_Type btpt = EOLIAN_TYPE_UNKNOWN_TYPE;
+ _final_type_and_type_type_get(btp, btp, btpt);
+
+ if (btpt == EOLIAN_TYPE_STRUCT)
+ {
+ std::string f = "::make_struct_tag";
+ auto p = result.find(f);
+ if (p == std::string::npos)
+ throw std::runtime_error("missing struct type tag");
+ result.replace(p, f.size(), "::make_struct_ptr_tag");
+ result.pop_back();
+ result += " *";
+ if (is_const) result += " const";
+ result += ">";
+ }
+ else
+ {
+ if (btpt != EOLIAN_TYPE_POINTER || base_is_const)
+ result += ' ';
+ result += '*';
+ if (is_const) result += " const";
+ }
+
+ if (btpt == EOLIAN_TYPE_COMPLEX)
+ {
+ result = "efl::eina::js::make_complex_tag<" + result;
+
+ bool has_subtypes = false;
+ auto subtypes = eolian_type_subtypes_get(btp);
+ const Eolian_Type *subtype;
+ EINA_ITERATOR_FOREACH(subtypes, subtype)
+ {
+ auto t = _eolian_type_cpp_type_named_get(subtype, caller_class_prefix, need_name_getter);
+ auto k = type_class_name(subtype);
+ if (!k.empty())
+ {
+ result += ", " + t + ", " + _class_name_getter(caller_class_prefix, k);
+ need_name_getter.insert(k);
+ }
+ else
+ {
+ result += ", " + t + ", ::efl::eina::js::nonclass_cls_name_getter";
+ }
+ has_subtypes = true;
+ }
+
+ if (!has_subtypes)
+ throw eolian::js::incomplete_complex_type_error("Incomplete complex type");
+
+ result += ">";
+ }
+ }
+
+ /*if (!name.empty())
+ {
+ if (tpt != EOLIAN_TYPE_POINTER)
+ result += ' ';
+ result += name;
+ }*/
+
+ return result;
+}
+
+using ParametersIterator = efl::eina::iterator<const ::Eolian_Function_Parameter>;
+
+std::vector<const ::Eolian_Function_Parameter*>
+_eolian_function_keys_get(const Eolian_Function *function_id, Eolian_Function_Type ftype)
+{
+ std::vector<const ::Eolian_Function_Parameter*> keys;
+
+ for(ParametersIterator it(::eolian_property_keys_get(function_id, ftype)), last; it != last; ++it)
+ keys.push_back(&*it);
+
+ return keys;
+}
+
+std::vector<const ::Eolian_Function_Parameter*>
+_eolian_function_parameters_get(const Eolian_Function *function_id, Eolian_Function_Type function_type)
+{
+ std::vector<const ::Eolian_Function_Parameter*> parameters;
+
+ ParametersIterator it { (function_type == EOLIAN_METHOD) ?
+ ::eolian_function_parameters_get(function_id) :
+ ::eolian_property_values_get(function_id, function_type)
+ }, last;
+
+ for(; it != last; ++it)
+ parameters.push_back(&*it);
+
+ return parameters;
+}
+
+bool
+_function_return_is_missing(Eolian_Function const* func, Eolian_Function_Type func_type)
+{
+ // XXX This function shouldn't exist. Eolian should
+ // forge functions a priori. Bindings generators
+ // shouldn't be required to convert such thing.
+ Eolian_Type const* type =
+ ::eolian_function_return_type_get(func, func_type);
+ return !type;
+}
+
+int main(int argc, char** argv)
+{
+ namespace format = eolian::js::format;
+
+ std::vector<std::string> include_paths;
+ std::string out_file, in_file;
+
+ efl::eina::eina_init eina_init;
+ struct eolian_init
+ {
+ eolian_init() { ::eolian_init(); }
+ ~eolian_init() { ::eolian_shutdown(); }
+ } eolian_init;
+
+ const struct option long_options[] =
+ {
+ { "in", required_argument, 0, 'I' },
+ { "out-file", required_argument, 0, 'o' },
+ { "version", no_argument, 0, 'v' },
+ { "help", no_argument, 0, 'h' },
+ { 0, 0, 0, 0 }
+ };
+ const char* options = "I:D:o:c:arvh";
+
+ int c, idx;
+ while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1)
+ {
+ if (c == 'I')
+ {
+ include_paths.push_back(optarg);
+ }
+ else if (c == 'o')
+ {
+ if(!out_file.empty())
+ {
+ // _usage(argv[0]);
+ return 1;
+ }
+ out_file = optarg;
+ }
+ else if (c == 'h')
+ {
+ // _usage(argv[0]);
+ return 1;
+ }
+ else if (c == 'v')
+ {
+ // _print_version();
+ // if (argc == 2) exit(EXIT_SUCCESS);
+ }
+ }
+
+ if (optind == argc-1)
+ {
+ in_file = argv[optind];
+ }
+
+
+ for(auto src : include_paths)
+ if (!::eolian_directory_scan(src.c_str()))
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain)
+ << "Couldn't load eolian from '" << src << "'.";
+ }
+ if (!::eolian_all_eot_files_parse())
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain)
+ << "Eolian failed parsing eot files";
+ assert(false && "Error parsing eot files");
+ }
+ if (!::eolian_file_parse(in_file.c_str()))
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain)
+ << "Failed parsing: " << in_file << ".";
+ assert(false && "Error parsing input file");
+ }
+
+ std::string file_basename;
+ const Eolian_Class *klass = NULL;
+ {
+ char* dup = strdup(in_file.c_str());
+ char *bn = basename(dup);
+ klass = ::eolian_class_get_by_file(bn);
+ file_basename = bn;
+ free(dup);
+ }
+ if(!klass)
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "could not find any class defined in this eo file";
+ return -1;
+ }
+
+ std::vector<Eolian_Function const*> constructor_functions;
+ std::vector<Eolian_Function const*> normal_functions;
+
+ std::set<Eolian_Class const*> classes;
+
+ auto separate_functions = [&] (Eolian_Class const* klass, Eolian_Function_Type t
+ , bool ignore_constructors)
+ {
+ efl::eina::iterator<Eolian_Function> first ( ::eolian_class_functions_get(klass, t) )
+ , last;
+ for(; first != last; ++first)
+ {
+ Eolian_Function const* function = &*first;
+ if(eolian_function_scope_get(function) == EOLIAN_SCOPE_PUBLIC)
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << ::eolian_function_full_c_name_get(function, t, EINA_FALSE);
+ if(strcmp("elm_obj_entry_input_panel_imdata_get", ::eolian_function_full_c_name_get(function, t, EINA_FALSE)) != 0 &&
+ !eolian_function_is_beta(function) &&
+ // strcmp("data_callback", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("property", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("part_text_anchor_geometry_get", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("children_iterator_new", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("inputs_get", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("constructor", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("render_updates", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("render2_updates", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("event_callback_priority_add", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("event_callback_array_priority_add", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("event_callback_array_del", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("event_callback_call", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("event_callback_forwarder_add", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("event_callback_forwarder_del", ::eolian_function_name_get(function)) != 0 && // TODO: remove this
+ strcmp("event_callback_del", ::eolian_function_name_get(function)) != 0)
+ {
+ if( ::eolian_function_is_constructor(function, klass))
+ {
+ if(!ignore_constructors)
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "is a constructor";
+ constructor_functions.push_back(function);
+ }
+ else
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "ignoring parent's constructors";
+ }
+ }
+ else /*if( std::strcmp( ::eolian_function_full_c_name_get(function, t, EINA_FALSE)
+ , "eo_parent") != 0)*/
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "is a NOT constructor "
+ << ::eolian_function_full_c_name_get(function, t, EINA_FALSE);
+ normal_functions.push_back(function);
+ }
+ // else
+ // {
+ // EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "parent_set as first constructor";
+ // constructor_functions.insert(constructor_functions.begin(), function);
+ // normal_functions.push_back(function);
+ // }
+ }
+ }
+ }
+ };
+ separate_functions(klass, EOLIAN_METHOD, false);
+ separate_functions(klass, EOLIAN_PROPERTY, false);
+
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "functions were separated";
+
+ std::function<void(Eolian_Class const*, std::function<void(Eolian_Class const*)>)>
+ recurse_inherits
+ = [&] (Eolian_Class const* klass, std::function<void(Eolian_Class const*)> function)
+ {
+ for(efl::eina::iterator<const char> first ( ::eolian_class_inherits_get(klass))
+ , last; first != last; ++first)
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << &*first << std::endl;
+ Eolian_Class const* base = ::eolian_class_get_by_name(&*first);
+ function(base);
+ recurse_inherits(base, function);
+ }
+ };
+
+ auto save_functions = [&](Eolian_Class const* klass)
+ {
+ if(classes.find(klass) == classes.end())
+ {
+ classes.insert(klass);
+ separate_functions(klass, EOLIAN_METHOD, true);
+ separate_functions(klass, EOLIAN_PROPERTY, true);
+ }
+ };
+ recurse_inherits(klass, save_functions);
+
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "inherits were recursed";
+
+ std::ofstream os (out_file.c_str());
+ if(!os.is_open())
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "Couldn't open output file " << out_file;
+ return -1;
+ }
+
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "output was opened";
+
+ std::string class_name(name(klass)),
+ class_full_name(full_name(klass)),
+ upper_case_class_name(_uppercase(class_name)),
+ lower_case_class_name(_lowercase(class_name));
+
+ if (getenv("EFL_RUN_IN_TREE"))
+ {
+ os << "#ifdef HAVE_CONFIG_H\n";
+ os << "#include \"config.h\"\n";
+ os << "#endif\n";
+
+ os << "#include <Efl.h>\n";
+ os << "#include <Ecore.h>\n";
+ os << "#include <Eo.h>\n\n";
+ }
+ else
+ {
+ os << "#ifdef HAVE_CONFIG_H\n";
+ os << "#include \"elementary_config.h\"\n";
+ os << "#endif\n";
+
+ os << "#include <Efl.h>\n";
+ os << "#include <Ecore.h>\n";
+ os << "#include <Eo.h>\n";
+ os << "#include <Evas.h>\n";
+ os << "#include <Edje.h>\n";
+
+ os << "#include <Elementary.h>\n\n";
+ os << "extern \"C\" {\n";
+ os << "#include <elm_widget.h>\n";
+ os << "}\n\n";
+ }
+ os << "#include <Eina_Js.hh>\n\n";
+ os << "#include <Eo_Js.hh>\n\n";
+ os << "#ifdef EAPI\n";
+ os << "# undef EAPI\n";
+ os << "#endif\n";
+
+ os << "#ifdef _WIN32\n";
+ os << "# define EAPI __declspec(dllimport)\n";
+ os << "#else\n";
+ os << "# ifdef __GNUC__\n";
+ os << "# if __GNUC__ >= 4\n";
+ os << "# define EAPI __attribute__ ((visibility(\"default\")))\n";
+ os << "# else\n";
+ os << "# define EAPI\n";
+ os << "# endif\n";
+ os << "# else\n";
+ os << "# define EAPI\n";
+ os << "# endif\n";
+ os << "#endif /* ! _WIN32 */\n\n";
+ os << "extern \"C\" {\n";
+
+ if(is_evas(klass))
+ os << "#include <Evas.h>\n";
+
+ auto includes_fun = [&os] (Eolian_Class const* klass)
+ {
+ os << "#include <" << eolian_class_file_get(klass) << ".h>\n\n";
+ };
+ recurse_inherits(klass, includes_fun);
+ os << "#include <" << eolian_class_file_get(klass) << ".h>\n\n";
+
+ os << "}\n\n";
+
+ os << "#ifdef _WIN32\n";
+ os << "# undef EAPI\n";
+ os << "# define EAPI __declspec(dllexport)\n";
+ os << "#endif /* ! _WIN32 */\n\n";
+
+ os << "#include <array>\n\n";
+
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "includes added";
+
+ if(namespace_size(klass))
+ {
+ std::string space = "";
+ for(efl::eina::iterator<const char> first(::eolian_class_namespaces_get(klass)), last; first != last; ++first)
+ {
+ std::string lower(_lowercase(&*first));
+ os << "namespace " << lower << " {" << space;
+ space = " ";
+ }
+
+ os << "\n";
+ }
+
+ std::string event_map = class_name;
+ event_map += "_ev_info_map";
+
+ os << "namespace {\n";
+ os << "::efl::eo::js::event_information_map " << event_map << ";\n";
+ os << "}\n";
+
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "namespace";
+
+ std::set<std::string> need_name_getter;
+
+ std::stringstream structs_ss;
+ for (efl::eina::iterator<Eolian_Type> first(::eolian_type_structs_get_by_file(file_basename.c_str()))
+ , last; first != last; ++first)
+ {
+ std::stringstream ss;
+ auto tp = &*first;
+ if (::eolian_type_type_get(tp) == EOLIAN_TYPE_STRUCT_OPAQUE)
+ continue;
+
+ auto struct_name = ::eolian_type_name_get(tp);
+ auto struct_type_full_name = ::eolian_type_full_name_get(tp);
+ if (!struct_name || !struct_type_full_name)
+ {
+ EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Could not get struct type name";
+ continue;
+ }
+ else if(strcmp(struct_type_full_name, "Eo.Callback_Array_Item") == 0)
+ continue;
+ std::string struct_c_name = struct_type_full_name;
+ std::replace(struct_c_name.begin(), struct_c_name.end(), '.', '_');
+ ss << " {\n";
+ ss << " auto fields_func = [](v8::Isolate* isolate_, v8::Local<v8::ObjectTemplate> prototype_)\n";
+ ss << " {\n";
+ for (efl::eina::iterator<Eolian_Struct_Type_Field> sf(::eolian_type_struct_fields_get(tp))
+ , sf_end; sf != sf_end; ++sf)
+ {
+ auto field_type = ::eolian_type_struct_field_type_get(&*sf);
+ auto field_name = ::eolian_type_struct_field_name_get(&*sf);
+ if (!field_name)
+ {
+ EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Could not get struct field name";
+ continue;
+ }
+ std::string field_type_tag_name;
+ try
+ {
+ field_type_tag_name = _eolian_type_cpp_type_named_get(field_type, class_name, need_name_getter);
+ }
+ catch(eolian::js::incomplete_complex_type_error const& e)
+ {
+ EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Exception while generating '" << field_name << "' fielf of '" << struct_type_full_name << "' struct: " << e.what();
+ continue;
+ }
+ std::string member_ref = struct_c_name;
+ member_ref += "::";
+ member_ref += field_name;
+
+ auto k = type_class_name(field_type);
+ if (!k.empty())
+ {
+ need_name_getter.insert(k);
+ k = _class_name_getter(class_name, k);
+ }
+ else
+ {
+ k = "::efl::eina::js::nonclass_cls_name_getter";
+ }
+ ss << " prototype_->SetAccessor(::efl::eina::js::compatibility_new<v8::String>(isolate_, \"" << format::generic(field_name) << "\"),\n";
+ ss << " static_cast<v8::AccessorGetterCallback>(&::efl::eo::js::get_struct_member<" << struct_c_name << ", decltype(" << member_ref << "), &" << member_ref << ", " << k << ">),\n";
+ ss << " static_cast<v8::AccessorSetterCallback>(&::efl::eo::js::set_struct_member<" << struct_c_name << ", " << field_type_tag_name << ", decltype(" << member_ref << "), &" << member_ref << ", " << k << ">));\n";
+ }
+ ss << " };\n";
+ ss << " auto to_export = ::efl::eo::js::get_namespace({";
+ bool comma = false;
+ for (efl::eina::iterator<const char> ns_it(::eolian_type_namespaces_get(tp)), ns_end; ns_it != ns_end; ++ns_it)
+ {
+ if (comma)
+ ss << ", ";
+ comma = true;
+ ss << '"' << format::generic(&*ns_it) << '"';
+ }
+ ss << "}, isolate, global);\n";
+ ss << " ::efl::eo::js::register_struct<" << struct_c_name << ">(isolate, \""
+ << format::generic(struct_name) << "\", \"" << struct_type_full_name << "\", to_export, fields_func);\n";
+ ss << " }\n";
+
+ structs_ss << ss.str();
+ }
+
+
+ std::stringstream register_from_constructor_begin_ss;
+ register_from_constructor_begin_ss
+ << "EAPI v8::Local<v8::ObjectTemplate>\n"
+ << "register_" << lower_case_class_name << "_from_constructor\n"
+ << "(v8::Isolate* isolate, v8::Handle<v8::FunctionTemplate> constructor, ::efl::eina::js::global_ref<v8::Function>* constructor_from_eo)\n"
+ << "{\n"
+ << " v8::Local<v8::ObjectTemplate> instance = constructor->InstanceTemplate();\n"
+ << " instance->SetInternalFieldCount(1);\n"
+ << " v8::Handle<v8::ObjectTemplate> prototype = constructor->PrototypeTemplate();\n";
+
+ std::stringstream functions_ss;
+ std::set<std::string> member_names;
+ std::set<std::string> event_member_names;
+ for(auto function : normal_functions)
+ {
+ std::vector<Eolian_Function_Type> function_types;
+ switch (eolian_function_type_get(function))
+ {
+ case EOLIAN_METHOD:
+ function_types = {EOLIAN_METHOD};
+ break;
+ case EOLIAN_PROPERTY:
+ function_types = {EOLIAN_PROP_GET, EOLIAN_PROP_SET};
+ break;
+ case EOLIAN_PROP_GET:
+ function_types = {EOLIAN_PROP_GET};
+ break;
+ case EOLIAN_PROP_SET:
+ function_types = {EOLIAN_PROP_SET};
+ break;
+ default:
+ EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Unresolved function type";
+ continue;
+ }
+
+ for (const auto function_type : function_types)
+ {
+ try
+ {
+ std::string member_name;
+ switch (function_type)
+ {
+ case EOLIAN_METHOD:
+ member_name = eolian_function_name_get(function);
+ break;
+ case EOLIAN_PROP_SET:
+ member_name = std::string("set_") + eolian_function_name_get(function);
+ break;
+ case EOLIAN_PROP_GET:
+ member_name = std::string("get_") + eolian_function_name_get(function);
+ break;
+ case EOLIAN_PROPERTY:
+ EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "EOLIAN_PROPERTY function type is invalid at this point";
+ return -1;
+ case EOLIAN_UNRESOLVED:
+ default:
+ EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Unresolved function type";
+ return -1;
+ }
+
+ if(member_names.find(member_name) == member_names.end())
+ {
+ member_names.insert(member_name);
+ std::stringstream ss;
+ auto output_begin = [&] (std::string name)
+ {
+ if(! ::eolian_function_is_constructor(function, klass))
+ ss << " prototype->Set( ::efl::eina::js::compatibility_new<v8::String>(isolate, \""
+ << format::generic(name) << "\")\n"
+ << " , ::efl::eina::js::compatibility_new<v8::FunctionTemplate>(isolate, &efl::eo::js::call_function\n"
+ << " , efl::eo::js::call_function_data<\n"
+ << " ::efl::eina::_mpl::tuple_c<std::size_t";
+ };
+
+ output_begin(member_name);
+
+ const auto key_params = _eolian_function_keys_get(function, function_type);
+ const auto parameters = _eolian_function_parameters_get(function, function_type);
+
+ std::vector<const ::Eolian_Function_Parameter*> full_params;
+ full_params.insert(end(full_params), begin(key_params), end(key_params));
+ // only one property_get parameter is translated as the function return in C
+ const auto param_as_return = (EOLIAN_PROP_GET == function_type) && (parameters.size() == 1)
+ && _function_return_is_missing(function, function_type);
+ if (!param_as_return)
+ full_params.insert(end(full_params), begin(parameters), end(parameters));
+
+ // call_function_data Ins
+ std::size_t i = 0;
+ for (auto parameter : full_params)
+ {
+ // TODO: REVIEW THIS!!! IT IS TOO STRANGE...
+ // properties doesn't support in/out/inout
+ if (EOLIAN_PROP_SET == function_type)
+ ss << ", " << i;
+ else
+ if (EOLIAN_METHOD == function_type)
+ {
+ switch (eolian_parameter_direction_get(parameter))
+ {
+ case EOLIAN_IN_PARAM:
+ case EOLIAN_INOUT_PARAM:
+ ss << ", " << i;
+ default: break;
+ }
+ }
+ ++i;
+ }
+
+ // call_function_data Outs
+ ss << ">\n , ::efl::eina::_mpl::tuple_c<std::size_t";
+ auto key_count = key_params.size();
+ i = 0;
+ for (auto parameter : full_params)
+ {
+ // TODO: THIS TOO!!!
+ // ignore keys
+ if (key_count > 0)
+ {
+ --key_count;
+ ++i;
+ continue;
+ }
+
+ // properties doesn't support in/out/inout
+ if (EOLIAN_PROP_GET == function_type)
+ ss << ", " << i;
+ else
+ if (EOLIAN_METHOD == function_type)
+ {
+ switch (eolian_parameter_direction_get(parameter))
+ {
+ case EOLIAN_OUT_PARAM:
+ case EOLIAN_INOUT_PARAM:
+ ss << ", " << i;
+ default: break;
+ }
+ }
+ ++i;
+ }
+
+ // call_function_data Ownership
+ ss << ">\n , std::tuple<\n";
+ auto sep = "";
+ for (auto parameter : full_params)
+ {
+ auto type = eolian_parameter_type_get(parameter);
+ if(eolian_type_is_own(type))
+ ss << sep << " ::std::true_type";
+ else
+ ss << sep << " ::std::false_type";
+ sep = ",\n";
+ }
+
+
+ // call_function_data Return
+ ss << ">\n , ";
+
+ const Eolian_Type *return_type = nullptr;
+ if (param_as_return)
+ {
+ return_type = eolian_parameter_type_get(parameters[0]);
+ }
+ else
+ {
+ return_type = ::eolian_function_return_type_get(function, function_type);
+ }
+ std::string param = "void";
+ if (nullptr != return_type)
+ {
+ param = _eolian_type_cpp_type_named_get(return_type, class_name, need_name_getter);
+ }
+ ss << param;
+
+
+ // call_function_data Parameters
+ ss << "\n , std::tuple<\n";
+ sep = " ";
+ key_count = key_params.size();
+ for (auto parameter : full_params)
+ {
+ // TODO: REVIEW ALL THIS TOO!!!
+ auto type = eolian_parameter_type_get(parameter);
+ auto param = _eolian_type_cpp_type_named_get(type, class_name, need_name_getter);
+
+ if (!key_count && EOLIAN_PROP_GET == function_type)
+ param += "*";
+ else
+ {
+ switch(eolian_parameter_direction_get(parameter))
+ {
+ case EOLIAN_OUT_PARAM:
+ case EOLIAN_INOUT_PARAM:
+ param += "*";
+ default: break;
+ }
+ }
+
+ ss << sep << param;
+ sep = ",\n ";
+
+ if (key_count > 0) --key_count;
+ }
+
+
+ std::string param_class_names;
+ for (auto parameter : full_params)
+ {
+ param_class_names += '"' + type_class_name(::eolian_parameter_type_get(parameter)) + "\", ";
+ }
+ param_class_names += '"' + type_class_name(return_type) + '"';
+
+ std::string param_class_names_array = "std::array<const char*, ";
+ param_class_names_array += std::to_string(full_params.size() + 1);
+ param_class_names_array += ">{{" + param_class_names + "}}";
+
+ // // ss << __func__ << ":" << __LINE__;
+ auto output_end = [&] (std::string const& name)
+ {
+ ss << "> >(isolate, " << param_class_names_array << ", & ::" << name << ")));\n";
+ };
+ switch (function_type)
+ {
+ case EOLIAN_METHOD:
+ output_end(eolian_function_full_c_name_get(function, function_type, EINA_FALSE));
+ break;
+ case EOLIAN_PROP_SET:
+ output_end(eolian_function_full_c_name_get(function, function_type, EINA_FALSE) /*+ std::string("_set")*/);
+ break;
+ case EOLIAN_PROP_GET:
+ output_end(eolian_function_full_c_name_get(function, function_type, EINA_FALSE) /*+ std::string("_get")*/);
+ break;
+ case EOLIAN_PROPERTY:
+ EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "EOLIAN_PROPERTY function type is invalid at this point";
+ return -1;
+ case EOLIAN_UNRESOLVED:
+ default:
+ EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Unresolved function type";
+ return -1;
+ }
+
+ // Write function to functions stream
+ functions_ss << ss.str();
+ }
+ }
+ catch(eolian::js::incomplete_complex_type_error const& e)
+ {
+ EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Exception while generating '" << eolian_function_name_get(function) << "': " << e.what();
+ }
+ }
+ }
+
+ std::stringstream events_ss;
+ auto generate_events = [&] (Eolian_Class const* klass)
+ {
+ std::stringstream ss;
+ for(efl::eina::iterator< ::Eolian_Event> first ( ::eolian_class_events_get(klass))
+ , last; first != last; ++first)
+ {
+ std::string event_name (::eolian_event_name_get(&*first));
+ std::replace(event_name.begin(), event_name.end(), ',', '_');
+
+ if (!eolian_event_is_beta(&*first) &&
+ event_member_names.find(event_name) == event_member_names.end())
+ {
+ auto tp = eolian_event_type_get(&*first);
+ ss << " {\n";
+ ss << " static efl::eo::js::event_information ev_info{&constructor_from_eo, " << eolian_event_c_name_get(&*first);
+ ss << ", &efl::eo::js::event_callback<";
+ ss << (tp ? _eolian_type_cpp_type_named_get(tp, class_name, need_name_getter) : "void");
+ ss << ">, \"" << type_class_name(tp) << "\"};\n";
+ ss << " " << event_map << "[\"" << event_name << "\"] = &ev_info;\n";
+ ss << " }\n";
+ event_member_names.insert(event_name);
+ }
+ }
+ events_ss << ss.str();
+ };
+ generate_events(klass);
+ recurse_inherits(klass, generate_events);
+
+ std::stringstream register_from_constructor_end_ss;
+ register_from_constructor_end_ss
+ << " prototype->Set(::efl::eina::js::compatibility_new<v8::String>(isolate, \"on\")\n"
+ << " , ::efl::eina::js::compatibility_new<v8::FunctionTemplate>(isolate, &efl::eo::js::on_event\n"
+ << " , ::efl::eina::js::compatibility_new<v8::External>(isolate, &" << event_map << ")));\n"
+ << " static_cast<void>(prototype); /* avoid warnings */\n"
+ << " static_cast<void>(isolate); /* avoid warnings */\n"
+ << " static_cast<void>(constructor_from_eo); /* avoid warnings */\n"
+ << " return instance;\n"
+ << "}\n\n";
+
+ std::stringstream name_getters_ss;
+ for (auto const& k : need_name_getter)
+ {
+ name_getters_ss << " struct " << _class_name_getter(class_name, k) << " { static char const* class_name() { return \"" << k << "\"; } };\n";
+ }
+
+ os << "namespace {\n";
+ os << name_getters_ss.str();
+ os << "}\n\n";
+
+ os << register_from_constructor_begin_ss.str();
+ os << functions_ss.str();
+ os << register_from_constructor_end_ss.str();
+
+
+ os << "EAPI void register_" << lower_case_class_name
+ << "(v8::Handle<v8::Object> global, v8::Isolate* isolate)\n";
+ os << "{\n";
+ os << " v8::Handle<v8::FunctionTemplate> constructor = ::efl::eina::js::compatibility_new<v8::FunctionTemplate>\n";
+ os << " (isolate, efl::eo::js::constructor\n"
+ << " , efl::eo::js::constructor_data(isolate\n"
+ " , ";
+
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "before print eo_class";
+
+ print_eo_class(klass, os);
+
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "print eo_class";
+
+ for(auto function : constructor_functions)
+ {
+ auto ftype = eolian_function_type_get(function);
+ if(ftype == EOLIAN_PROPERTY)
+ ftype = EOLIAN_PROP_SET;
+ os << "\n , & ::"
+ << eolian_function_full_c_name_get(function, ftype, EINA_FALSE);
+ }
+
+ os << "));\n";
+
+ os << " static ::efl::eina::js::global_ref<v8::Function> constructor_from_eo;\n";
+ os << events_ss.str();
+ os << " register_" << lower_case_class_name << "_from_constructor(isolate, constructor, &constructor_from_eo);\n";
+
+ os << " constructor->SetClassName( ::efl::eina::js::compatibility_new<v8::String>(isolate, \""
+ << format::generic(class_name)
+ << "\"));\n";
+
+ os << " auto to_export = ::efl::eo::js::get_namespace({";
+ if (namespace_size(klass))
+ {
+ bool comma = false;
+ for (efl::eina::iterator<const char> ns_it(::eolian_class_namespaces_get(klass)), ns_end; ns_it != ns_end; ++ns_it)
+ {
+ if (comma)
+ os << ", ";
+ comma = true;
+ os << '"' << format::generic(&*ns_it) << '"';
+ }
+ }
+ os << "}, isolate, global);\n";
+
+ os << " to_export->Set( ::efl::eina::js::compatibility_new<v8::String>(isolate, \""
+ << format::generic(class_name) << "\")"
+ << ", constructor->GetFunction());\n";
+
+
+ os << " {\n";
+ os << " v8::Handle<v8::FunctionTemplate> constructor = ::efl::eina::js::compatibility_new<v8::FunctionTemplate>\n";
+ os << " (isolate, &efl::eo::js::construct_from_eo);\n";
+ os << " constructor->SetClassName( ::efl::eina::js::compatibility_new<v8::String>(isolate, \""
+ << format::generic(class_name)
+ << "\"));\n";
+ os << " v8::Local<v8::ObjectTemplate> instance = "
+ << "register_" << lower_case_class_name << "_from_constructor(isolate, constructor, &constructor_from_eo);\n";
+ os << " ::efl::eina::js::make_persistent(isolate, instance);\n";
+ os << " constructor_from_eo = {isolate, constructor->GetFunction()};\n";
+ os << " ::efl::eina::js::register_class_constructor(\"" << class_full_name << "\", constructor_from_eo.handle());\n";
+ os << " }\n";
+
+ os << structs_ss.str();
+
+ for (efl::eina::iterator<Eolian_Type> first(::eolian_type_enums_get_by_file(file_basename.c_str()))
+ , last; first != last; ++first)
+ {
+ auto tp = &*first;
+ if (::eolian_type_is_extern(tp))
+ continue;
+ std::string enum_name = ::eolian_type_name_get(tp);
+ os << " {\n";
+ os << " auto to_export = ::efl::eo::js::get_namespace({";
+ bool comma = false;
+ for (efl::eina::iterator<const char> ns_it(::eolian_type_namespaces_get(tp)), ns_end; ns_it != ns_end; ++ns_it)
+ {
+ if (comma)
+ os << ", ";
+ comma = true;
+ os << '"' << format::generic(&*ns_it) << '"';
+ }
+ os << "}, isolate, global);\n";
+ os << " v8::Handle<v8::Object> enum_obj = efl::eina::js::compatibility_new<v8::Object>(isolate);\n";
+ os << " to_export->Set(efl::eina::js::compatibility_new<v8::String>(isolate, \""
+ << format::generic(enum_name) << "\"), enum_obj);\n";
+ for (efl::eina::iterator<Eolian_Enum_Type_Field> ef(::eolian_type_enum_fields_get(tp))
+ , ef_end; ef != ef_end; ++ef)
+ {
+ auto field_name = ::eolian_type_enum_field_name_get(&*ef);
+ auto field_c_name = ::eolian_type_enum_field_c_name_get(&*ef);
+ if (!field_name || !field_c_name)
+ {
+ EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Could not get enum field name";
+ continue;
+ }
+ os << " enum_obj->Set(efl::eina::js::compatibility_new<v8::String>(isolate, \"" << format::constant(field_name) << "\"),\n";
+ os << " efl::eina::js::compatibility_new<v8::Int32>(isolate, static_cast<int32_t>(::" << field_c_name << ")));\n";
+ }
+ os << " }\n";
+ }
+
+ os << "}\n\n";
+
+ for(std::size_t i = 0, j = namespace_size(klass); i != j; ++i)
+ os << "}";
+ os << "\n";
+
+
+}
diff --git a/src/bindings/ecore_js/Ecore_Js.hh b/src/bindings/ecore_js/Ecore_Js.hh
new file mode 100644
index 0000000000..3f877f3fc8
--- /dev/null
+++ b/src/bindings/ecore_js/Ecore_Js.hh
@@ -0,0 +1,58 @@
+
+#ifndef EFL_ECORE_JS_HH
+#define EFL_ECORE_JS_HH
+
+#include <Ecore.hh>
+#include <Ecore_File.h>
+#include <Eina_Js.hh>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ECORE_JS_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+namespace efl { namespace ecore { namespace js {
+
+using ::efl::eina::js::compatibility_new;
+using ::efl::eina::js::compatibility_return_type;
+using ::efl::eina::js::compatibility_callback_info_type;
+using ::efl::eina::js::compatibility_return;
+using ::efl::eina::js::compatibility_get_pointer_internal_field;
+using ::efl::eina::js::compatibility_set_pointer_internal_field;
+
+EAPI void register_ecore_animator(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
+EAPI void register_ecore_event(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
+EAPI void register_ecore_file(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
+EAPI void register_ecore_idle(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
+EAPI void register_ecore_job(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
+EAPI void register_ecore_mainloop(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
+EAPI void register_ecore_poller(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
+EAPI void register_ecore_throttle(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
+EAPI void register_ecore_timer(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
+
+EAPI void register_ecore(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
+
+} } }
+
+#endif
diff --git a/src/bindings/ecore_js/ecore_js_animator.cc b/src/bindings/ecore_js/ecore_js_animator.cc
new file mode 100644
index 0000000000..52f8576dee
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_animator.cc
@@ -0,0 +1,728 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Ecore_Js.hh>
+
+namespace efl { namespace ecore { namespace js {
+
+static Ecore_Animator* extract_animator(v8::Local<v8::Object> object)
+{
+ auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
+ return reinterpret_cast<Ecore_Animator*>(ptr);
+}
+
+static v8::Local<v8::Object> wrap_animator(Ecore_Animator *animator,
+ v8::Isolate *isolate)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_animator_del(extract_animator(info.This()));
+ return compatibility_return();
+ };
+
+ auto freeze = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_animator_freeze(extract_animator(info.This()));
+ return compatibility_return();
+ };
+
+ auto thaw = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_animator_thaw(extract_animator(info.This()));
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+ ret->Set(compatibility_new<String>(isolate, "freeze"),
+ compatibility_new<FunctionTemplate>(isolate, freeze)
+ ->GetFunction());
+ ret->Set(compatibility_new<String>(isolate, "thaw"),
+ compatibility_new<FunctionTemplate>(isolate, thaw)->GetFunction());
+
+ ret->SetInternalField(0, compatibility_new<v8::External>(isolate,
+ animator));
+
+ return ret;
+}
+
+void register_pos_map_linear(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_POS_MAP_LINEAR));
+}
+
+void register_pos_map_accelerate(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_POS_MAP_ACCELERATE));
+}
+
+void register_pos_map_decelerate(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_POS_MAP_DECELERATE));
+}
+
+void register_pos_map_sinusoidal(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_POS_MAP_SINUSOIDAL));
+}
+
+void register_pos_map_accelerate_factor(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_POS_MAP_ACCELERATE_FACTOR));
+}
+
+void register_pos_map_decelerate_factor(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_POS_MAP_DECELERATE_FACTOR));
+}
+
+void register_pos_map_sinusoidal_factor(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_POS_MAP_SINUSOIDAL_FACTOR));
+}
+
+void register_pos_map_divisor_interp(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_POS_MAP_DIVISOR_INTERP));
+}
+
+void register_pos_map_bounce(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_POS_MAP_BOUNCE));
+}
+
+void register_pos_map_spring(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_POS_MAP_SPRING));
+}
+
+void register_pos_map_cubic_bezier(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_POS_MAP_CUBIC_BEZIER));
+}
+
+void register_animator_source_timer(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_ANIMATOR_SOURCE_TIMER));
+}
+
+void register_animator_source_custom(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_ANIMATOR_SOURCE_CUSTOM));
+}
+
+void register_animator_frametime_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ ecore_animator_frametime_set(args[0]->NumberValue());
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_animator_frametime_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Number;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_animator_frametime_get();
+ return compatibility_return(compatibility_new<Number>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_animator_pos_map(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Number;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 4 || !args[0]->IsNumber() || !args[1]->IsNumber()
+ || !args[2]->IsNumber() || !args[3]->IsNumber())
+ return compatibility_return();
+
+ Ecore_Pos_Map map;
+
+ switch ((int)(args[1]->NumberValue())) {
+ case ECORE_POS_MAP_LINEAR:
+ map = ECORE_POS_MAP_LINEAR;
+ break;
+ case ECORE_POS_MAP_ACCELERATE:
+ map = ECORE_POS_MAP_ACCELERATE;
+ break;
+ case ECORE_POS_MAP_DECELERATE:
+ map = ECORE_POS_MAP_DECELERATE;
+ break;
+ case ECORE_POS_MAP_SINUSOIDAL:
+ map = ECORE_POS_MAP_SINUSOIDAL;
+ break;
+ case ECORE_POS_MAP_ACCELERATE_FACTOR:
+ map = ECORE_POS_MAP_ACCELERATE_FACTOR;
+ break;
+ case ECORE_POS_MAP_DECELERATE_FACTOR:
+ map = ECORE_POS_MAP_DECELERATE_FACTOR;
+ break;
+ case ECORE_POS_MAP_SINUSOIDAL_FACTOR:
+ map = ECORE_POS_MAP_SINUSOIDAL_FACTOR;
+ break;
+ case ECORE_POS_MAP_DIVISOR_INTERP:
+ map = ECORE_POS_MAP_DIVISOR_INTERP;
+ break;
+ case ECORE_POS_MAP_BOUNCE:
+ map = ECORE_POS_MAP_BOUNCE;
+ break;
+ case ECORE_POS_MAP_SPRING:
+ map = ECORE_POS_MAP_SPRING;
+ break;
+ case ECORE_POS_MAP_CUBIC_BEZIER:
+ map = ECORE_POS_MAP_CUBIC_BEZIER;
+ break;
+ default:
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_animator_pos_map(args[0]->NumberValue(), map,
+ args[2]->NumberValue(),
+ args[3]->NumberValue());
+ return compatibility_return(compatibility_new<Number>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_animator_pos_map_n(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Number;
+ using v8::NumberObject;
+ using v8::FunctionTemplate;
+ using v8::Array;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 3 || !args[0]->IsNumber() || !args[1]->IsNumber()
+ || !args[2]->IsArray())
+ return compatibility_return();
+
+ Ecore_Pos_Map map;
+
+ switch ((int)(args[1]->NumberValue())) {
+ case ECORE_POS_MAP_LINEAR:
+ map = ECORE_POS_MAP_LINEAR;
+ break;
+ case ECORE_POS_MAP_ACCELERATE:
+ map = ECORE_POS_MAP_ACCELERATE;
+ break;
+ case ECORE_POS_MAP_DECELERATE:
+ map = ECORE_POS_MAP_DECELERATE;
+ break;
+ case ECORE_POS_MAP_SINUSOIDAL:
+ map = ECORE_POS_MAP_SINUSOIDAL;
+ break;
+ case ECORE_POS_MAP_ACCELERATE_FACTOR:
+ map = ECORE_POS_MAP_ACCELERATE_FACTOR;
+ break;
+ case ECORE_POS_MAP_DECELERATE_FACTOR:
+ map = ECORE_POS_MAP_DECELERATE_FACTOR;
+ break;
+ case ECORE_POS_MAP_SINUSOIDAL_FACTOR:
+ map = ECORE_POS_MAP_SINUSOIDAL_FACTOR;
+ break;
+ case ECORE_POS_MAP_DIVISOR_INTERP:
+ map = ECORE_POS_MAP_DIVISOR_INTERP;
+ break;
+ case ECORE_POS_MAP_BOUNCE:
+ map = ECORE_POS_MAP_BOUNCE;
+ break;
+ case ECORE_POS_MAP_SPRING:
+ map = ECORE_POS_MAP_SPRING;
+ break;
+ case ECORE_POS_MAP_CUBIC_BEZIER:
+ map = ECORE_POS_MAP_CUBIC_BEZIER;
+ break;
+ default:
+ return compatibility_return();
+ }
+
+ std::vector<double> v;
+ {
+ auto array = Array::Cast(*args[2]);
+ auto s = array->Length();
+ v.reserve(s);
+ for (decltype(s) i = 0;i != s;++i) {
+ auto e = array->Get(i);
+ if (!e->IsNumber())
+ return compatibility_return();
+
+ v.push_back(e->NumberValue());
+ }
+ }
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_animator_pos_map_n(args[0]->NumberValue(), map,
+ v.size(), v.data());
+ return compatibility_return(compatibility_new<Number>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_animator_source_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ Ecore_Animator_Source source;
+
+ switch ((int)(args[0]->NumberValue())) {
+ case ECORE_ANIMATOR_SOURCE_TIMER:
+ source = ECORE_ANIMATOR_SOURCE_TIMER;
+ break;
+ case ECORE_ANIMATOR_SOURCE_CUSTOM:
+ source = ECORE_ANIMATOR_SOURCE_CUSTOM;
+ break;
+ default:
+ return compatibility_return();
+ }
+
+ ecore_animator_source_set(source);
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_animator_source_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_animator_source_get();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+static
+efl::eina::js::global_ref<v8::Value> animator_custom_source_tick_begin_cb_data;
+static
+efl::eina::js::global_ref<v8::Value> animator_custom_source_tick_end_cb_data;
+
+void
+register_animator_custom_source_tick_begin_callback_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object>
+ global,
+ v8::Handle<v8::String>
+ name)
+{
+ using v8::FunctionCallbackInfo;
+ using v8::Value;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args) {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ animator_custom_source_tick_begin_cb_data
+ = efl::eina::js::global_ref<Value>(args.GetIsolate(), args[0]);
+ ecore_animator_custom_source_tick_begin_callback_set([](void*) {
+ using v8::Function;
+ using v8::Undefined;
+ using v8::Isolate;
+
+ auto o = animator_custom_source_tick_begin_cb_data.handle();
+ Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
+ }, NULL);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void
+register_animator_custom_source_tick_end_callback_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object>
+ global,
+ v8::Handle<v8::String>
+ name)
+{
+ using v8::FunctionCallbackInfo;
+ using v8::Value;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args) {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ efl::eina::js::global_ref<v8::Value>* data
+ = new efl::eina::js::global_ref<v8::Value>(args.GetIsolate(), args[0]);
+ ecore_animator_custom_source_tick_end_callback_set([](void* data) {
+ using v8::Function;
+ using v8::Undefined;
+ using v8::Isolate;
+
+ efl::eina::js::global_ref<v8::Value>*
+ d = static_cast<efl::eina::js::global_ref<v8::Value>*>(data);
+ auto o = d->handle();
+ Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
+ d->dispose();
+ delete d;
+ }, data);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void
+register_animator_custom_tick(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::FunctionCallbackInfo;
+ using v8::Value;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args) {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ ecore_animator_custom_tick();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_animator_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Local;
+ using v8::Value;
+ using v8::Undefined;
+ using v8::Function;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto f = new efl::eina::js::global_ref<Value>(isolate, args[0]);
+
+ auto cb = [](void *data) -> Eina_Bool {
+ auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
+ auto o = persistent->handle();
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ if (!bret)
+ {
+ persistent->dispose();
+ delete persistent;
+ }
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+
+ auto ret = ecore_animator_add(cb, f);
+ return compatibility_return(wrap_animator(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_animator_timeline_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Handle;
+ using v8::Local;
+ using v8::Value;
+ using v8::Undefined;
+ using v8::Function;
+ using v8::FunctionTemplate;
+ using v8::Number;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsNumber()
+ || !args[1]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[1]);
+
+ auto cb = [](void *data, double pos) -> Eina_Bool {
+ auto persistent
+ = reinterpret_cast<efl::eina::js::global_ref<Value>*>(data);
+ auto o = persistent->handle();
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args = compatibility_new<Number>(isolate, pos);
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ if (!bret)
+ {
+ persistent->dispose();
+ delete persistent;
+ }
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+
+ auto ret = ecore_animator_timeline_add(args[0]->NumberValue(), cb, f);
+ return compatibility_return(wrap_animator(ret, args.GetIsolate()),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_ecore_animator(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
+{
+ register_pos_map_linear(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_POS_MAP_LINEAR"));
+ register_pos_map_accelerate(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_POS_MAP"
+ "_ACCELERATE"));
+ register_pos_map_decelerate(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_POS_MAP"
+ "_DECELERATE"));
+ register_pos_map_sinusoidal(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_POS_MAP"
+ "_SINUSOIDAL"));
+ register_pos_map_accelerate_factor(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_POS_MAP"
+ "_ACCELERATE"
+ "_FACTOR"));
+ register_pos_map_decelerate_factor(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_POS_MAP"
+ "_DECELERATE"
+ "_FACTOR"));
+ register_pos_map_sinusoidal_factor(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_POS_MAP"
+ "_SINUSOIDAL"
+ "_FACTOR"));
+ register_pos_map_divisor_interp(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_POS_MAP"
+ "_DIVISOR_INTERP"));
+ register_pos_map_bounce(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_POS_MAP_BOUNCE"));
+ register_pos_map_spring(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_POS_MAP_SPRING"));
+ register_pos_map_cubic_bezier(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_POS_MAP_CUBIC"
+ "_BEZIER"));
+ register_animator_source_timer(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_ANIMATOR"
+ "_SOURCE_TIMER"));
+ register_animator_source_custom(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_ANIMATOR"
+ "_SOURCE_CUSTOM"));
+ register_animator_frametime_set(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_animator"
+ "_frametime_set"));
+ register_animator_frametime_get(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_animator"
+ "_frametime_get"));
+ register_animator_pos_map(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_animator_pos"
+ "_map"));
+ register_animator_pos_map_n(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_animator_pos_map"
+ "_n"));
+ register_animator_source_set(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_animator_source"
+ "_set"));
+ register_animator_source_get(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_animator_source"
+ "_get"));
+ register_animator_custom_source_tick_begin_callback_set
+ (isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_animator_custom_source_tick_begin"
+ "_callback_set"));
+ register_animator_custom_source_tick_end_callback_set
+ (isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_animator_custom_source_tick_end"
+ "_callback_set"));
+ register_animator_custom_tick(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_animator"
+ "_custom_tick"));
+ register_animator_add(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_animator_add"));
+ register_animator_timeline_add(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_animator"
+ "_timeline_add"));
+}
+
+} } } // namespace efl { namespace js {
diff --git a/src/bindings/ecore_js/ecore_js_event.cc b/src/bindings/ecore_js/ecore_js_event.cc
new file mode 100644
index 0000000000..a086d989d6
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_event.cc
@@ -0,0 +1,772 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Ecore_Js.hh>
+
+namespace efl { namespace ecore { namespace js {
+
+static Ecore_Event *extract_event(v8::Local<v8::Object> object)
+{
+ return compatibility_get_pointer_internal_field<Ecore_Event*>(object, 0);
+}
+
+static v8::Local<v8::Object> wrap_event(Ecore_Event *event,
+ v8::Isolate *isolate)
+{
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_event_del(extract_event(info.This()));
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+
+ compatibility_set_pointer_internal_field(ret, 0, event);
+
+ return ret;
+}
+
+static Ecore_Event_Handler *extract_event_handler(v8::Local<v8::Object> object)
+{
+ return compatibility_get_pointer_internal_field<Ecore_Event_Handler*>
+ (object, 0);
+}
+
+static v8::Local<v8::Object> wrap_event_handler(Ecore_Event_Handler *handler,
+ v8::Isolate *isolate)
+{
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+ using v8::Value;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ auto p = ecore_event_handler_del(extract_event_handler(info.This()));
+
+ delete static_cast<efl::eina::js::global_ref<Value>*>(p);
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+
+ compatibility_set_pointer_internal_field(ret, 0, handler);
+
+ return ret;
+}
+
+static Ecore_Event_Filter *extract_event_filter(v8::Local<v8::Object> object)
+{
+ return compatibility_get_pointer_internal_field<Ecore_Event_Filter*>
+ (object, 0);
+}
+
+static v8::Local<v8::Object> wrap_event_filter(Ecore_Event_Filter *filter,
+ v8::Isolate *isolate)
+{
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+ using v8::Value;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ auto p = ecore_event_filter_del(extract_event_filter(info.This()));
+ delete[] static_cast<efl::eina::js::global_ref<Value>*>(p);
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+
+ compatibility_set_pointer_internal_field(ret, 0, filter);
+
+ return ret;
+}
+
+EAPI
+void register_event_none(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_EVENT_NONE));
+}
+
+EAPI
+void register_event_signal_user(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_EVENT_SIGNAL_USER));
+}
+
+EAPI
+void register_event_signal_hup(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_EVENT_SIGNAL_HUP));
+}
+
+EAPI
+void register_event_signal_exit(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_EVENT_SIGNAL_EXIT));
+}
+
+EAPI
+void register_event_signal_power(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_EVENT_SIGNAL_POWER));
+}
+
+EAPI
+void register_event_signal_realtime(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_EVENT_SIGNAL_REALTIME));
+}
+
+EAPI
+void register_event_memory_state(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_EVENT_MEMORY_STATE));
+}
+
+EAPI
+void register_event_power_state(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_EVENT_POWER_STATE));
+}
+
+EAPI
+void register_event_locale_changed(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_EVENT_LOCALE_CHANGED));
+}
+
+EAPI
+void register_event_hostname_changed(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_EVENT_HOSTNAME_CHANGED));
+}
+
+EAPI
+void register_event_system_timedate_changed(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED));
+}
+
+EAPI
+void register_event_type_new(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_event_type_new();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_event_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_event_add(args[0]->NumberValue(), NULL, NULL, NULL);
+ return compatibility_return(wrap_event(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_event_handler_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::Value;
+ using v8::Function;
+ using v8::Handle;
+ using v8::Local;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsNumber()
+ || !args[1]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+
+ auto p = new efl::eina::js::global_ref<Value>(isolate, args[1]);
+
+ auto cb = [](void *d, int type, void */*event*/) -> Eina_Bool {
+ auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(d);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+ Handle<Value> args = compatibility_new<Integer>(isolate, type);
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+
+ auto ret = ecore_event_handler_add(args[0]->Int32Value(), cb, p);
+ return compatibility_return(wrap_event_handler(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_event_filter_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::Value;
+ using v8::Function;
+ using v8::Handle;
+ using v8::Local;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 3 || !args[0]->IsFunction()
+ || !args[1]->IsFunction() || !args[2]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+
+ auto p = new efl::eina::js::global_ref<Value>[3]{{isolate, args[0]},
+ {isolate, args[1]},
+ {isolate, args[2]}};
+
+ auto start_cb = [](void *data) -> void* {
+ auto p = static_cast<efl::eina::js::global_ref<Value>*>(data);
+ auto isolate = v8::Isolate::GetCurrent();
+ auto o = p->handle();
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
+ return new efl::eina::js::global_ref<Value>{isolate, ret};
+ };
+
+ auto filter_cb = [](void *data, void *loop_data, int type,
+ void */*event*/) -> Eina_Bool {
+ typedef efl::eina::js::global_ref<Value> p_t;
+
+ auto p = static_cast<p_t*>(data) + 1;
+ auto isolate = v8::Isolate::GetCurrent();
+ auto o = p->handle();
+
+ Handle<Value> args[2]{
+ static_cast<p_t*>(loop_data)->handle(),
+ compatibility_new<Integer>(isolate, type)
+ };
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+
+ auto end_cb = [](void *user_data, void *func_data) -> void {
+ typedef efl::eina::js::global_ref<Value> p_t;
+
+ auto loop_data = std::unique_ptr<p_t>(static_cast<p_t*>
+ (func_data));
+ auto p = static_cast<p_t*>(user_data) + 2;
+ auto o = p->handle();
+
+ Handle<Value> args = p->handle();
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+ };
+
+ auto ret = ecore_event_filter_add(start_cb, filter_cb, end_cb, p);
+ return compatibility_return(wrap_event_filter(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_event_current_type_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_event_current_type_get();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_memory_state_normal(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_MEMORY_STATE_NORMAL));
+}
+
+EAPI
+void register_memory_state_low(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_MEMORY_STATE_LOW));
+}
+
+EAPI
+void register_power_state_mains(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_POWER_STATE_MAINS));
+}
+
+EAPI
+void register_power_state_battery(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_POWER_STATE_BATTERY));
+}
+
+EAPI
+void register_power_state_low(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_POWER_STATE_LOW));
+}
+
+EAPI
+void register_memory_state_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_memory_state_get();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_power_state_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_power_state_get();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_event_signal_user_handler_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::String;
+ using v8::Value;
+ using v8::Object;
+ using v8::Function;
+ using v8::Handle;
+ using v8::Local;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+
+ auto p = new efl::eina::js::global_ref<Value>(isolate, args[0]);
+
+ auto cb = [](void *d, int type, void *event) -> Eina_Bool {
+ auto p = static_cast<efl::eina::js::global_ref<Value>*>(d);
+ auto isolate = v8::Isolate::GetCurrent();
+ auto o = p->handle();
+
+ auto wrapped_event = compatibility_new<Object>(isolate);
+
+ {
+ auto n
+ = reinterpret_cast<Ecore_Event_Signal_User*>(event)->number;
+ wrapped_event->Set(compatibility_new<String>(isolate, "number"),
+ compatibility_new<Integer>(isolate, n));
+ }
+
+ Handle<Value> args[2]{
+ compatibility_new<Integer>(isolate, type),
+ wrapped_event
+ };
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+
+ auto ret = ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER, cb, p);
+ return compatibility_return(wrap_event_handler(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_event_signal_exit_handler_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::Boolean;
+ using v8::String;
+ using v8::Value;
+ using v8::Object;
+ using v8::Function;
+ using v8::Handle;
+ using v8::Local;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+
+ auto p = new efl::eina::js::global_ref<Value>(isolate, args[0]);
+
+ auto cb = [](void *d, int type, void *ev) -> Eina_Bool {
+ auto p = static_cast<efl::eina::js::global_ref<Value>*>(d);
+ auto isolate = v8::Isolate::GetCurrent();
+ auto o = p->handle();
+
+ auto wrapped_event = compatibility_new<Object>(isolate);
+
+ {
+ auto event = reinterpret_cast<Ecore_Event_Signal_Exit*>(ev);
+ auto interrupt = event->interrupt;
+ auto quit = event->quit;
+ auto terminate = event->terminate;
+
+ wrapped_event->Set(compatibility_new<String>(isolate,
+ "interrupt"),
+ compatibility_new<Boolean>(isolate,
+ interrupt));
+ wrapped_event->Set(compatibility_new<String>(isolate, "quit"),
+ compatibility_new<Boolean>(isolate, quit));
+ wrapped_event->Set(compatibility_new<String>(isolate,
+ "terminate"),
+ compatibility_new<Boolean>(isolate,
+ terminate));
+ }
+
+ Handle<Value> args[2]{
+ compatibility_new<Integer>(isolate, type),
+ wrapped_event
+ };
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+
+ auto ret = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, cb, p);
+ return compatibility_return(wrap_event_handler(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_event_signal_realtime_handler_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::String;
+ using v8::Value;
+ using v8::Object;
+ using v8::Function;
+ using v8::Handle;
+ using v8::Local;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+
+ auto p = new efl::eina::js::global_ref<Value>(isolate, args[0]);
+
+ auto cb = [](void *d, int type, void *ev) -> Eina_Bool {
+ auto p = static_cast<efl::eina::js::global_ref<Value>*>(d);
+ auto isolate = v8::Isolate::GetCurrent();
+ auto o = p->handle();
+
+ auto wrapped_event = compatibility_new<Object>(isolate);
+
+ {
+ auto n
+ = reinterpret_cast<Ecore_Event_Signal_Realtime*>(ev)->num;
+ wrapped_event->Set(compatibility_new<String>(isolate, "num"),
+ compatibility_new<Integer>(isolate, n));
+ }
+
+ Handle<Value> args[2]{
+ compatibility_new<Integer>(isolate, type),
+ wrapped_event
+ };
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+
+ auto ret = ecore_event_handler_add(ECORE_EVENT_SIGNAL_REALTIME, cb, p);
+ return compatibility_return(wrap_event_handler(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_ecore_event(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
+{
+ register_event_none(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_EVENT_NONE"));
+ register_event_signal_user(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_EVENT_SIGNAL_USER"));
+ register_event_signal_hup(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_EVENT_SIGNAL_HUP"));
+ register_event_signal_exit(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_EVENT_SIGNAL_EXIT"));
+ register_event_signal_power(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_EVENT_SIGNAL_POWER"));
+ register_event_signal_realtime(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_EVENT_SIGNAL_REALTIME"));
+ register_event_memory_state(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_EVENT_MEMORY_STATE"));
+ register_event_power_state(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_EVENT_POWER_STATE"));
+ register_event_locale_changed(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_EVENT_LOCALE_CHANGED"));
+ register_event_hostname_changed(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_EVENT_HOSTNAME_CHANGED"));
+ register_event_system_timedate_changed(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate,
+ "ECORE_EVENT_SYSTEM_TIMEDATE"
+ "_CHANGED"));
+ register_event_type_new(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_event_type_new"));
+ register_event_add(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_event_add"));
+ register_event_handler_add(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_event_handler_add"));
+ register_event_filter_add(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_event_filter_add"));
+ register_event_current_type_get(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_event_current_type_get"));
+ register_memory_state_normal(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_MEMORY_STATE_NORMAL"));
+ register_memory_state_low(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_MEMORY_STATE_LOW"));
+ register_power_state_mains(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_POWER_STATE_MAINS"));
+ register_power_state_battery(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_POWER_STATE_BATTERY"));
+ register_power_state_low(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_POWER_STATE_LOW"));
+ register_event_signal_user_handler_add(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate,
+ "ecore_event_signal_user_handler"
+ "_add"));
+ register_event_signal_exit_handler_add(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate,
+ "ecore_event_signal_exit_handler"
+ "_add"));
+ register_event_signal_realtime_handler_add(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate,
+ "ecore_event_signal_realtime"
+ "_handler_add"));
+}
+
+} } } // namespace efl { namespace js {
diff --git a/src/bindings/ecore_js/ecore_js_file.cc b/src/bindings/ecore_js/ecore_js_file.cc
new file mode 100644
index 0000000000..eea300f8dd
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_file.cc
@@ -0,0 +1,1457 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Ecore_Js.hh>
+
+#include <memory>
+#include <cstdlib>
+
+#include <unistd.h>
+
+namespace efl { namespace ecore { namespace js {
+
+namespace {
+
+Ecore_File_Monitor* extract_monitor(v8::Local<v8::Object> object)
+{
+ return compatibility_get_pointer_internal_field<Ecore_File_Monitor*>(object,
+ 0);
+}
+
+v8::Local<v8::Object> wrap_monitor(Ecore_File_Monitor *monitor,
+ v8::Isolate *isolate)
+{
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_file_monitor_del(extract_monitor(info.This()));
+ return compatibility_return();
+ };
+
+ auto path_get = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ auto ret = ecore_file_monitor_path_get(extract_monitor(info.This()));
+ return compatibility_return(compatibility_new<String>(info.GetIsolate(),
+ ret),
+ info);
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+ ret->Set(compatibility_new<String>(isolate, "path_get"),
+ compatibility_new<FunctionTemplate>(isolate, path_get)
+ ->GetFunction());
+
+ compatibility_set_pointer_internal_field(ret, 0, monitor);
+
+ return ret;
+}
+
+static Ecore_File_Download_Job *extract_download_job(v8::Local<v8::Object> o)
+{
+ return compatibility_get_pointer_internal_field<Ecore_File_Download_Job*>
+ (o, 0);
+}
+
+static
+v8::Local<v8::Object> wrap_download_job(Ecore_File_Download_Job *download_job,
+ v8::Isolate *isolate)
+{
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto abort = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_file_download_abort(extract_download_job(info.This()));
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "abort"),
+ compatibility_new<FunctionTemplate>(isolate, abort)
+ ->GetFunction());
+
+ compatibility_set_pointer_internal_field(ret, 0, download_job);
+
+ return ret;
+}
+
+void register_file_event_none(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ exports->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_FILE_EVENT_NONE));
+}
+
+void register_file_event_created_file(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ exports->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_FILE_EVENT_CREATED_FILE));
+}
+
+void register_file_event_created_directory(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ exports->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_FILE_EVENT_CREATED_DIRECTORY));
+}
+
+void register_file_event_deleted_file(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ exports->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_FILE_EVENT_DELETED_FILE));
+}
+
+void register_file_event_deleted_directory(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ exports->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_FILE_EVENT_DELETED_DIRECTORY));
+}
+
+void register_file_event_deleted_self(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ exports->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_FILE_EVENT_DELETED_SELF));
+}
+
+void register_file_event_modified(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ exports->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_FILE_EVENT_MODIFIED));
+}
+
+void register_file_event_closed(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ exports->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_FILE_EVENT_CLOSED));
+}
+
+void register_file_progress_continue(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ exports->Set(name,
+ compatibility_new<Integer>(isolate,
+ ECORE_FILE_PROGRESS_CONTINUE));
+}
+
+void register_file_progress_abort(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ exports->Set(name,
+ compatibility_new<Integer>(isolate, ECORE_FILE_PROGRESS_ABORT));
+}
+
+void register_file_init(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_init();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_shutdown(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_shutdown();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_mod_time(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Date;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+
+ /* TODO: be less ofensive on the comment below once the documentation of
+ `ecore_file_mod_time` is fixed. I'm planning to submit a patch. */
+ /* `ecore_file_mod_time` returns "the time of the last data
+ modification", which is one of the most useless descriptions of a
+ function I ever found. The return type is `long long`, but looking at
+ the implementation, I see the value is the number of seconds since
+ the Epoch.
+
+ v8's `Date` constructor takes the number of milliseconds since the
+ Epoch represented as a `double`. */
+ double ret = ecore_file_mod_time(*String::Utf8Value(args[0]));
+ ret *= 1000;
+
+ return compatibility_return(compatibility_new<Date>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_size(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_size(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_exists(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_exists(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_is_dir(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_is_dir(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_mkdir(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_mkdir(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_mkdirs(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::String;
+ using v8::Array;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsArray())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ std::vector<std::string> dirs_data;
+ std::vector<const char*> dirs;
+ {
+ auto array = Array::Cast(*args[0]);
+ auto s = array->Length();
+ dirs_data.reserve(s);
+ dirs.reserve(s + 1);
+ for (decltype(s) i = 0;i != s;++i) {
+ auto e = array->Get(i);
+ if (!e->IsString())
+ return compatibility_return();
+
+ dirs_data.push_back(*String::Utf8Value(e));
+ dirs.push_back(dirs_data.back().data());
+ }
+ }
+ dirs.push_back(NULL);
+ auto ret = ecore_file_mkdirs(dirs.data());
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_mksubdirs(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::String;
+ using v8::Array;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsArray())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ std::vector<std::string> subdirs_data;
+ std::vector<const char*> subdirs;
+ {
+ auto array = Array::Cast(*args[1]);
+ auto s = array->Length();
+ subdirs_data.reserve(s);
+ subdirs.reserve(s + 1);
+ for (decltype(s) i = 0;i != s;++i) {
+ auto e = array->Get(i);
+ if (!e->IsString())
+ return compatibility_return();
+
+ subdirs_data.push_back(*String::Utf8Value(e));
+ subdirs.push_back(subdirs_data.back().data());
+ }
+ }
+ subdirs.push_back(NULL);
+ auto ret = ecore_file_mksubdirs(*String::Utf8Value(args[0]),
+ subdirs.data());
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_rmdir(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_rmdir(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_unlink(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_unlink(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_remove(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_remove(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_recursive_rm(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_recursive_rm(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_mkpath(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_mkpath(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_mkpaths(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::String;
+ using v8::Array;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsArray())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ std::vector<std::string> paths_data;
+ std::vector<const char*> paths;
+ {
+ auto array = Array::Cast(*args[0]);
+ auto s = array->Length();
+ paths_data.reserve(s);
+ paths.reserve(s + 1);
+ for (decltype(s) i = 0;i != s;++i) {
+ auto e = array->Get(i);
+ if (!e->IsString())
+ return compatibility_return();
+
+ paths_data.push_back(*String::Utf8Value(e));
+ paths.push_back(paths_data.back().data());
+ }
+ }
+ paths.push_back(NULL);
+ auto ret = ecore_file_mkpaths(paths.data());
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_cp(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_cp(*String::Utf8Value(args[0]),
+ *String::Utf8Value(args[1]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_mv(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_mv(*String::Utf8Value(args[0]),
+ *String::Utf8Value(args[1]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_symlink(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_symlink(*String::Utf8Value(args[0]),
+ *String::Utf8Value(args[1]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_realpath(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+ using std::unique_ptr;
+ using std::free;
+
+ typedef unique_ptr<char, void(*)(char*)> guard_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto rp = guard_t(ecore_file_realpath(*String::Utf8Value(args[0])),
+ [](char *str) { free(str); });
+ auto ret = compatibility_new<String>(isolate, rp ? rp.get() : "");
+ return compatibility_return(ret, args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_file_get(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ String::Utf8Value str(args[0]);
+ auto ret = ecore_file_file_get(*str);
+ return compatibility_return(compatibility_new<String>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_dir_get(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+ using std::unique_ptr;
+ using std::free;
+
+ typedef unique_ptr<char, void(*)(char*)> guard_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto d = guard_t(ecore_file_dir_get(*String::Utf8Value(args[0])),
+ [](char *str) { free(str); });
+ auto ret = compatibility_new<String>(isolate, d ? d.get() : "");
+ return compatibility_return(ret, args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_can_read(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_can_read(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_can_write(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_can_write(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_can_exec(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_can_exec(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_readlink(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+ using std::unique_ptr;
+ using std::free;
+
+ typedef unique_ptr<char, void(*)(char*)> guard_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto l = guard_t(ecore_file_readlink(*String::Utf8Value(args[0])),
+ [](char *str) { free(str); });
+ auto ret = compatibility_new<String>(isolate, l ? l.get() : "");
+ return compatibility_return(ret, args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_ls(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Array;
+ using v8::String;
+ using v8::FunctionTemplate;
+ using std::unique_ptr;
+ using std::free;
+
+ typedef unique_ptr<Eina_List, Eina_List*(*)(Eina_List*)> guard_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto list = guard_t(ecore_file_ls(*String::Utf8Value(args[0])),
+ eina_list_free);
+ auto ret = compatibility_new<Array>(isolate);
+ {
+ uint32_t idx = 0;
+ for (Eina_List *l = list.get() ; l ; l = eina_list_next(l)) {
+ /* Not using idiomatic RAII here because it'd be a fake safety,
+ given that remaining objects would leak if an exception is
+ throw. It shouldn't be a problem because v8 doesn't use
+ exceptions (nor idiomatic C++). */
+ auto data = reinterpret_cast<char*>(eina_list_data_get(l));
+ ret->Set(idx++, compatibility_new<String>(isolate, data));
+ free(data);
+ }
+ }
+ return compatibility_return(ret, args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_app_exe_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+ using std::unique_ptr;
+ using std::free;
+
+ typedef unique_ptr<char, void(*)(char*)> guard_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto e = guard_t(ecore_file_app_exe_get(*String::Utf8Value(args[0])),
+ [](char *str) { free(str); });
+ auto ret = compatibility_new<String>(isolate, e ? e.get() : "");
+ return compatibility_return(ret, args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_escape_name(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+ using std::unique_ptr;
+ using std::free;
+
+ typedef unique_ptr<char, void(*)(char*)> guard_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto n = guard_t(ecore_file_escape_name(*String::Utf8Value(args[0])),
+ [](char *str) { free(str); });
+ auto ret = compatibility_new<String>(isolate, n ? n.get() : "");
+ return compatibility_return(ret, args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_strip_ext(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+ using std::unique_ptr;
+ using std::free;
+
+ typedef unique_ptr<char, void(*)(char*)> guard_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto n = guard_t(ecore_file_strip_ext(*String::Utf8Value(args[0])),
+ [](char *str) { free(str); });
+ auto ret = compatibility_new<String>(isolate, n ? n.get() : "");
+ return compatibility_return(ret, args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_dir_is_empty(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_dir_is_empty(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_monitor_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::FunctionTemplate;
+ using v8::Handle;
+ using v8::Value;
+ using v8::Function;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsString()
+ || !args[1]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[1]);
+
+ auto cb = [](void *data, Ecore_File_Monitor *em, Ecore_File_Event event,
+ const char *path) {
+ auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[3] = {
+ wrap_monitor(em, isolate),
+ compatibility_new<Integer>(isolate, event),
+ compatibility_new<String>(isolate, path)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 3, args);
+
+ persistent->dispose();
+ delete persistent;
+ };
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_monitor_add(*String::Utf8Value(args[0]), cb, f);
+ return compatibility_return(wrap_monitor(ret, isolate), args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_path_dir_exists(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ Eina_Bool ret = ecore_file_path_dir_exists(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret == EINA_TRUE ? true : false),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_app_installed(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_file_app_installed(*String::Utf8Value(args[0]));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_app_list(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Array;
+ using v8::String;
+ using v8::FunctionTemplate;
+ using std::unique_ptr;
+ using std::free;
+
+ typedef unique_ptr<Eina_List, Eina_List*(*)(Eina_List*)> guard_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto list = guard_t(ecore_file_app_list(), eina_list_free);
+ auto ret = compatibility_new<Array>(isolate);
+ {
+ uint32_t idx = 0;
+ for (Eina_List *l = list.get() ; l ; l = eina_list_next(l)) {
+ /* Not using idiomatic RAII here because it'd be a fake safety,
+ given that remaining objects would leak if an exception is
+ throw. It shouldn't be a problem because v8 doesn't use
+ exceptions (nor idiomatic C++). */
+ auto data = reinterpret_cast<char*>(eina_list_data_get(l));
+ ret->Set(idx++, compatibility_new<String>(isolate, data));
+ free(data);
+ }
+ }
+ return compatibility_return(ret, args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_download(v8::Isolate *isolate, v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::Integer;
+ using v8::String;
+ using v8::Object;
+ using v8::Function;
+ using v8::Value;
+ using v8::Handle;
+ using v8::FunctionTemplate;
+ using std::unique_ptr;
+ using std::free;
+
+ typedef unique_ptr<Eina_Hash, void(*)(Eina_Hash*)> guard_t;
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if ((args.Length() != 4 && args.Length() != 5) || !args[0]->IsString()
+ || !args[1]->IsString() || !args[2]->IsFunction()
+ || !args[3]->IsFunction()
+ || (args.Length() == 5 && !args[4]->IsObject()))
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+
+ auto cb_data = unique_ptr<persistent_t[]>(new persistent_t[2]);
+ cb_data[0] = persistent_t(isolate, args[2]);
+ cb_data[1] = persistent_t(isolate, args[3]);
+
+ String::Utf8Value url(args[0]);
+ String::Utf8Value dst(args[1]);
+ auto completion_cb = [](void *data, const char *file, int status) {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ compatibility_new<String>(isolate, file),
+ compatibility_new<Integer>(isolate, status)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] persistent;
+ };
+ auto progress_cb = [](void *data, const char *file, long int dltotal,
+ long int dlnow, long int ultotal,
+ long int ulnow) -> int {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 1;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[5] = {
+ compatibility_new<String>(isolate, file),
+ compatibility_new<Integer>(isolate, dltotal),
+ compatibility_new<Integer>(isolate, dlnow),
+ compatibility_new<Integer>(isolate, ultotal),
+ compatibility_new<Integer>(isolate, ulnow)
+ };
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 5, args);
+ auto iret = ret->IsNumber() ? int(ret->NumberValue()) : 0;
+ if (iret != ECORE_FILE_PROGRESS_CONTINUE)
+ delete[] (persistent - 1);
+
+ return iret;
+ };
+ Ecore_File_Download_Job *job_ret = NULL;
+ auto ret = compatibility_new<Object>(isolate);
+ bool bret;
+
+ if (args.Length() == 4) {
+ bret = ecore_file_download(*url, *dst, completion_cb, progress_cb,
+ cb_data.get(), &job_ret);
+ } else {
+ auto headers = guard_t(eina_hash_string_djb2_new(free),
+ eina_hash_free);
+ auto js_headers = Object::Cast(*args[4]);
+ auto keys = js_headers->GetOwnPropertyNames();
+ for (uint32_t i = 0;i != keys->Length();++i) {
+ auto key = keys->CloneElementAt(i);
+ if (!key->IsString())
+ return compatibility_return();
+
+ auto value = js_headers->Get(key);
+ if (!value->IsString())
+ return compatibility_return();
+
+ eina_hash_add(headers.get(), *String::Utf8Value(key),
+ strdup(*String::Utf8Value(value)));
+ }
+ bret = ecore_file_download_full(*url, *dst, completion_cb,
+ progress_cb, cb_data.get(),
+ &job_ret, headers.get());
+ }
+ if (bret)
+ cb_data.release();
+
+ ret->Set(compatibility_new<String>(isolate, "ok"),
+ compatibility_new<Boolean>(isolate, bret));
+
+ if (job_ret) {
+ ret->Set(compatibility_new<String>(isolate, "job"),
+ wrap_download_job(job_ret, isolate));
+ }
+
+ return compatibility_return(ret, args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_download_abort_all(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ ecore_file_download_abort_all();
+ return compatibility_return();
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_download_protocol_available(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ String::Utf8Value protocol(args[0]);
+ auto ret = ecore_file_download_protocol_available(*protocol);
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ args);
+ };
+
+ exports->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_mkstemp(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ v8::String::Utf8Value buffer(args[0]);
+ char* buf = (char*)malloc(std::strlen(*buffer)+1);
+ struct free_buf
+ {
+ free_buf(char* p) : p(p) {}
+ ~free_buf() { free(p); }
+ char* p;
+ } free_buf_(buf);
+ std::strcpy(buf, *buffer);
+ int fd = mkstemp(buf);
+
+ if(fd > 0)
+ {
+ close(fd);
+
+ return compatibility_return(compatibility_new<v8::String>(nullptr, buf), args);
+ }
+ else
+ return compatibility_return();
+ };
+ exports->Set(name, compatibility_new<v8::FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_file_environment_tmp(v8::Isolate *isolate,
+ v8::Handle<v8::Object> exports,
+ v8::Handle<v8::String> name)
+{
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+
+ return compatibility_return(compatibility_new<v8::String>(nullptr, eina_environment_tmp_get()), args);
+ };
+ exports->Set(name, compatibility_new<v8::FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+}
+
+EAPI
+void register_ecore_file(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
+{
+ register_file_event_none(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_FILE_EVENT_NONE"));
+ register_file_event_created_file(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_FILE_EVENT"
+ "_CREATED_FILE"));
+ register_file_event_created_directory(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate,
+ "ECORE_FILE_EVENT_CREATED_DIRECTORY"));
+ register_file_event_deleted_file(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_FILE_EVENT"
+ "_DELETED_FILE"));
+ register_file_event_deleted_directory(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate,
+ "ECORE_FILE_EVENT_DELETED_DIRECTORY"));
+ register_file_event_deleted_self(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_FILE_EVENT"
+ "_DELETED_SELF"));
+ register_file_event_modified(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_FILE_EVENT"
+ "_MODIFIED"));
+ register_file_event_closed(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ECORE_FILE_EVENT"
+ "_CLOSED"));
+ register_file_progress_continue(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_FILE_PROGRESS_CONTINUE"));
+ register_file_progress_abort(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_FILE_PROGRESS_ABORT"));
+ register_file_init(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_init"));
+ register_file_shutdown(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_shutdown"));
+ register_file_mod_time(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_mod_time"));
+ register_file_size(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_size"));
+ register_file_exists(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_exists"));
+ register_file_is_dir(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_is_dir"));
+ register_file_mkdir(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_mkdir"));
+ register_file_mkdirs(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_mkdirs"));
+ register_file_mksubdirs(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_mksubdirs"));
+ register_file_rmdir(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_rmdir"));
+ register_file_unlink(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_unlink"));
+ register_file_remove(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_remove"));
+ register_file_recursive_rm(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_file_recursive_rm"));
+ register_file_mkpath(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_mkpath"));
+ register_file_mkpaths(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_mkpaths"));
+ register_file_cp(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_cp"));
+ register_file_mv(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_mv"));
+ register_file_symlink(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_symlink"));
+ register_file_realpath(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_realpath"));
+ register_file_file_get(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_file_get"));
+ register_file_dir_get(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_dir_get"));
+ register_file_can_read(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_can_read"));
+ register_file_can_write(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_can_write"));
+ register_file_can_exec(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_can_exec"));
+ register_file_readlink(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_readlink"));
+ register_file_ls(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_file_ls"));
+ register_file_app_exe_get(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_file_app_exe_get"));
+ register_file_escape_name(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_file_escape_name"));
+ register_file_strip_ext(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_strip_ext"));
+ register_file_dir_is_empty(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_file_dir_is_empty"));
+ register_file_monitor_add(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_file_monitor_add"));
+ register_file_path_dir_exists(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_file_path_dir_exists"));
+ register_file_app_installed(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_file_app_installed"));
+ register_file_app_list(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_app_list"));
+ register_file_download(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_file_download"));
+ register_file_download_abort_all(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_file_download_abort_all"));
+ register_file_download_protocol_available(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate,
+ "ecore_file_download_protocol"
+ "_available"));
+ register_file_mkstemp(isolate, exports,
+ compatibility_new<v8::String>(isolate, "mkstemp"));
+ register_file_environment_tmp(isolate, exports,
+ compatibility_new<v8::String>(isolate, "environment_tmp"));
+}
+
+} } } // namespace efl { namespace ecore { namespace js {
diff --git a/src/bindings/ecore_js/ecore_js_idle.cc b/src/bindings/ecore_js/ecore_js_idle.cc
new file mode 100644
index 0000000000..293cef2f45
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_idle.cc
@@ -0,0 +1,294 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Ecore_Js.hh>
+
+namespace efl { namespace ecore { namespace js {
+
+static Ecore_Idler* extract_idler(v8::Local<v8::Object> object)
+{
+ auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
+ return reinterpret_cast<Ecore_Idler*>(ptr);
+}
+
+static
+v8::Local<v8::Object> wrap_idler(Ecore_Idler *idler, v8::Isolate *isolate)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_idler_del(extract_idler(info.This()));
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+
+ ret->SetInternalField(0, compatibility_new<v8::External>(isolate, idler));
+
+ return ret;
+}
+
+static Ecore_Idle_Enterer* extract_idle_enterer(v8::Local<v8::Object> object)
+{
+ auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
+ return reinterpret_cast<Ecore_Idle_Enterer*>(ptr);
+}
+
+static v8::Local<v8::Object> wrap_idle_enterer(Ecore_Idle_Enterer *idle_enterer,
+ v8::Isolate *isolate)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+ using v8::External;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_idle_enterer_del(extract_idle_enterer(info.This()));
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+
+ ret->SetInternalField(0,
+ compatibility_new<External>(isolate, idle_enterer));
+
+ return ret;
+}
+
+static Ecore_Idle_Exiter* extract_idle_exiter(v8::Local<v8::Object> object)
+{
+ auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
+ return reinterpret_cast<Ecore_Idle_Exiter*>(ptr);
+}
+
+static v8::Local<v8::Object> wrap_idle_exiter(Ecore_Idle_Exiter *idle_exiter,
+ v8::Isolate *isolate)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+ using v8::External;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_idle_exiter_del(extract_idle_exiter(info.This()));
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+
+ ret->SetInternalField(0, compatibility_new<External>(isolate, idle_exiter));
+
+ return ret;
+}
+
+void register_idler_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Local;
+ using v8::Value;
+ using v8::Undefined;
+ using v8::Function;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[0]);
+ auto ret = ecore_idler_add([](void *data) -> Eina_Bool {
+ auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
+ auto o = persistent->handle();
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ if (!bret)
+ {
+ persistent->dispose();
+ delete persistent;
+ }
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ }, f);
+
+ return compatibility_return(wrap_idler(ret, args.GetIsolate()), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_idle_enterer_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Local;
+ using v8::Value;
+ using v8::Undefined;
+ using v8::Function;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[0]);
+ auto ret = ecore_idle_enterer_add([](void *data) -> Eina_Bool {
+ auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
+ auto o = persistent->handle();
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ if (!bret)
+ {
+ persistent->dispose();
+ delete persistent;
+ }
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ }, f);
+
+ return compatibility_return(wrap_idle_enterer(ret, args.GetIsolate()),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_idle_enterer_before_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Local;
+ using v8::Value;
+ using v8::Undefined;
+ using v8::Function;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[0]);
+ auto ret = ecore_idle_enterer_before_add([](void *data) -> Eina_Bool {
+ auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
+ auto o = persistent->handle();
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ if (!bret)
+ {
+ persistent->dispose();
+ delete persistent;
+ }
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ }, f);
+
+ return compatibility_return(wrap_idle_enterer(ret, args.GetIsolate()),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_idle_exiter_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Local;
+ using v8::Value;
+ using v8::Undefined;
+ using v8::Function;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[0]);
+ auto ret = ecore_idle_exiter_add([](void *data) -> Eina_Bool {
+ auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
+ auto o = persistent->handle();
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ if (!bret)
+ {
+ persistent->dispose();
+ delete persistent;
+ }
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ }, f);
+
+ return compatibility_return(wrap_idle_exiter(ret, args.GetIsolate()),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_ecore_idle(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
+{
+ register_idler_add(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_idler_add"));
+ register_idle_enterer_add(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_idle_enterer"
+ "_add"));
+ register_idle_enterer_before_add(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_idle"
+ "_enterer_before"
+ "_add"));
+ register_idle_exiter_add(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_idle_exiter_add"));
+}
+
+} } } // namespace efl { namespace js {
diff --git a/src/bindings/ecore_js/ecore_js_init.cc b/src/bindings/ecore_js/ecore_js_init.cc
new file mode 100644
index 0000000000..724d16ae17
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_init.cc
@@ -0,0 +1,77 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Ecore_Js.hh>
+
+namespace efl { namespace ecore { namespace js {
+
+namespace {
+
+void register_init(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto init = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ::ecore_init();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, init)
+ ->GetFunction());
+}
+
+void register_shutdown(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto shutdown = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_shutdown();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, shutdown)
+ ->GetFunction());
+}
+
+}
+
+EAPI
+void register_ecore(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
+{
+ efl::ecore::js::register_init(isolate, exports,
+ efl::eina::js::compatibility_new<v8::String>
+ (isolate, "ecore_init"));
+ efl::ecore::js::register_shutdown(isolate, exports,
+ efl::eina::js::compatibility_new<v8::String>
+ (isolate, "ecore_shutdown"));
+ register_ecore_animator(isolate, exports);
+ register_ecore_event(isolate, exports);
+ register_ecore_file(isolate, exports);
+ register_ecore_idle(isolate, exports);
+ register_ecore_job(isolate, exports);
+ register_ecore_mainloop(isolate, exports);
+ register_ecore_poller(isolate, exports);
+ register_ecore_throttle(isolate, exports);
+ register_ecore_timer(isolate, exports);
+}
+
+} } } // namespace efl { namespace js {
diff --git a/src/bindings/ecore_js/ecore_js_job.cc b/src/bindings/ecore_js/ecore_js_job.cc
new file mode 100644
index 0000000000..4ec438aaaf
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_job.cc
@@ -0,0 +1,83 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Ecore_Js.hh>
+
+namespace efl { namespace ecore { namespace js {
+
+static Ecore_Job* extract_job(v8::Local<v8::Object> object)
+{
+ auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
+ return reinterpret_cast<Ecore_Job*>(ptr);
+}
+
+static v8::Local<v8::Object> wrap_job(Ecore_Job *job, v8::Isolate *isolate)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_job_del(extract_job(info.This()));
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+
+ ret->SetInternalField(0, compatibility_new<v8::External>(isolate, job));
+
+ return ret;
+}
+
+EAPI
+void register_job_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Local;
+ using v8::Value;
+ using v8::Undefined;
+ using v8::Function;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[0]);
+ auto ret = ecore_job_add([](void *data) {
+ auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
+ auto o = persistent->handle();
+
+ Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
+
+ persistent->dispose();
+ delete persistent;
+ }, f);
+
+ return compatibility_return(wrap_job(ret, args.GetIsolate()), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_ecore_job(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
+{
+ register_job_add(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_job_add"));
+}
+
+} } } // namespace efl { namespace js {
diff --git a/src/bindings/ecore_js/ecore_js_mainloop.cc b/src/bindings/ecore_js/ecore_js_mainloop.cc
new file mode 100644
index 0000000000..180b35f0f6
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_mainloop.cc
@@ -0,0 +1,207 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Ecore_Js.hh>
+
+namespace efl { namespace ecore { namespace js {
+
+namespace {
+
+void register_callback_cancel(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ global->Set(name, compatibility_new<Boolean>(isolate,
+ bool{ECORE_CALLBACK_CANCEL}));
+}
+
+void register_callback_renew(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ global->Set(name, compatibility_new<Boolean>(isolate,
+ bool{ECORE_CALLBACK_RENEW}));
+}
+
+void register_callback_pass_on(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ global->Set(name, compatibility_new<Boolean>(isolate,
+ bool{ECORE_CALLBACK_PASS_ON}));
+}
+
+void register_callback_done(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ global->Set(name, compatibility_new<Boolean>(isolate,
+ bool{ECORE_CALLBACK_DONE}));
+}
+
+void register_mainloop_iterate(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ ecore_main_loop_iterate();
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_mainloop_iterate_may_block(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ auto ret = ecore_main_loop_iterate_may_block(args[0]->NumberValue());
+ return compatibility_return(compatibility_new<Integer>
+ (args.GetIsolate(), ret), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_mainloop_begin(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ ecore_main_loop_begin();
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_mainloop_quit(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ ecore_main_loop_quit();
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_mainloop_animator_ticked_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto ret = ecore_main_loop_animator_ticked_get();
+ return compatibility_return(compatibility_new<Boolean>
+ (args.GetIsolate(), ret), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_mainloop_nested_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Boolean;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto ret = ecore_main_loop_nested_get();
+ return compatibility_return(compatibility_new<Boolean>
+ (args.GetIsolate(), ret), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+}
+
+EAPI
+void register_ecore_mainloop(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
+{
+ register_callback_cancel(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_CALLBACK_CANCEL"));
+ register_callback_renew(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_CALLBACK_RENEW"));
+ register_callback_pass_on(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_CALLBACK_PASS_ON"));
+ register_callback_done(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ECORE_CALLBACK_DONE"));
+ register_mainloop_iterate(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_mainloop_iterate"));
+ register_mainloop_iterate_may_block(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate,
+ "ecore_mainloop_iterate_may_block"));
+ register_mainloop_begin(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_mainloop_begin"));
+ register_mainloop_quit(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_mainloop_quit"));
+ register_mainloop_animator_ticked_get(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate,
+ "ecore_mainlop_animator_ticked_get"));
+ register_mainloop_nested_get(isolate, exports,
+ compatibility_new<v8::String>
+ (isolate, "ecore_mainloop_nested_get"));
+}
+
+} } } // namespace efl { namespace js {
diff --git a/src/bindings/ecore_js/ecore_js_poller.cc b/src/bindings/ecore_js/ecore_js_poller.cc
new file mode 100644
index 0000000000..e3bfbc843a
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_poller.cc
@@ -0,0 +1,190 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Ecore_Js.hh>
+
+namespace efl { namespace ecore { namespace js {
+
+namespace {
+
+Ecore_Poller* extract_poller(v8::Local<v8::Object> object)
+{
+ auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
+ return reinterpret_cast<Ecore_Poller*>(ptr);
+}
+
+v8::Local<v8::Object> wrap_poller(Ecore_Poller *poller,
+ v8::Isolate *isolate)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_poller_del(extract_poller(info.This()));
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+
+ ret->SetInternalField(0, compatibility_new<v8::External>(isolate, poller));
+
+ return ret;
+}
+
+void register_poller_core(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+
+ global->Set(name, compatibility_new<Integer>(isolate, ECORE_POLLER_CORE));
+}
+
+void register_poller_poll_interval_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsNumber() || !args[1]->IsNumber())
+ return compatibility_return();
+
+ Ecore_Poller_Type type;
+
+ switch ((int)(args[0]->NumberValue())) {
+ case ECORE_POLLER_CORE:
+ type = ECORE_POLLER_CORE;
+ break;
+ default:
+ return compatibility_return();
+ }
+
+ ecore_poller_poll_interval_set(type, args[1]->NumberValue());
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_poller_poll_interval_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ Ecore_Poller_Type type;
+
+ switch ((int)(args[0]->NumberValue())) {
+ case ECORE_POLLER_CORE:
+ type = ECORE_POLLER_CORE;
+ break;
+ default:
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_poller_poll_interval_get(type);
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_poller_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::Value;
+ using v8::FunctionTemplate;
+ using v8::Isolate;
+ using v8::Function;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 3 || !args[0]->IsNumber() || !args[1]->IsNumber()
+ || !args[2]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ Ecore_Poller_Type type;
+
+ switch ((int)(args[0]->NumberValue())) {
+ case ECORE_POLLER_CORE:
+ type = ECORE_POLLER_CORE;
+ break;
+ default:
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+ auto f = new efl::eina::js::global_ref<Value>(isolate, args[2]);
+
+ auto cb = [](void *data) -> Eina_Bool {
+ auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
+ auto o = persistent->handle();
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ if (!bret)
+ {
+ persistent->dispose();
+ delete persistent;
+ }
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+
+ auto ret = ecore_poller_add(type, args[1]->NumberValue(), cb, f);
+ return compatibility_return(wrap_poller(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+}
+
+EAPI
+void register_ecore_poller(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
+{
+ register_poller_core(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ECORE_POLLER_CORE"));
+ register_poller_poll_interval_set(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_poller"
+ "_poll_interval"
+ "_set"));
+ register_poller_poll_interval_get(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_poller"
+ "_poll_interval"
+ "_get"));
+ register_poller_add(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_poller_add"));
+}
+
+} } } // namespace efl { namespace js {
diff --git a/src/bindings/ecore_js/ecore_js_throttle.cc b/src/bindings/ecore_js/ecore_js_throttle.cc
new file mode 100644
index 0000000000..830a40fec6
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_throttle.cc
@@ -0,0 +1,63 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Ecore_Js.hh>
+
+namespace efl { namespace ecore { namespace js {
+
+namespace {
+
+void register_throttle_adjust(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ ecore_throttle_adjust(args[0]->NumberValue());
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_throttle_get(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Number;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = ecore_throttle_get();
+ return compatibility_return(compatibility_new<Number>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+}
+
+EAPI
+void register_ecore_throttle(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
+{
+ register_throttle_adjust(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_throttle_adjust"));
+ register_throttle_get(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_throttle_get"));
+}
+
+} } } // namespace efl { namespace js {
diff --git a/src/bindings/ecore_js/ecore_js_timer.cc b/src/bindings/ecore_js/ecore_js_timer.cc
new file mode 100644
index 0000000000..38a3e51fac
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_timer.cc
@@ -0,0 +1,263 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Ecore_Js.hh>
+
+#include <memory>
+#include <cstdlib>
+
+namespace efl { namespace ecore { namespace js {
+
+namespace {
+
+Ecore_Timer* extract_timer(v8::Local<v8::Object> object)
+{
+ auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
+ return reinterpret_cast<Ecore_Timer*>(ptr);
+}
+
+v8::Local<v8::Object> wrap_timer(Ecore_Timer *timer,
+ v8::Isolate *isolate)
+{
+ using v8::Boolean;
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_timer_del(extract_timer(info.This()));
+ return compatibility_return();
+ };
+
+ auto freeze = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_timer_freeze(extract_timer(info.This()));
+ return compatibility_return();
+ };
+
+ auto freeze_get = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ auto ret = ecore_timer_freeze_get(extract_timer(info.This()));
+ return compatibility_return(compatibility_new<Boolean>
+ (info.GetIsolate(), bool(ret)),
+ info);
+ };
+
+ auto thaw = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_timer_thaw(extract_timer(info.This()));
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+ ret->Set(compatibility_new<String>(isolate, "freeze"),
+ compatibility_new<FunctionTemplate>(isolate, freeze)
+ ->GetFunction());
+ ret->Set(compatibility_new<String>(isolate, "freeze_get"),
+ compatibility_new<FunctionTemplate>(isolate, freeze_get)
+ ->GetFunction());
+ ret->Set(compatibility_new<String>(isolate, "thaw"),
+ compatibility_new<FunctionTemplate>(isolate, thaw)->GetFunction());
+
+ ret->SetInternalField(0, compatibility_new<v8::External>(isolate, timer));
+
+ return ret;
+}
+
+void register_timer_precision_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Number;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto ret = ecore_timer_precision_get();
+ return compatibility_return(compatibility_new<Number>
+ (args.GetIsolate(), ret), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_timer_precision_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ ecore_timer_precision_set(args[0]->NumberValue());
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_timer_dump(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+ using std::unique_ptr;
+ using std::free;
+ using std::unique_ptr;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto dump = unique_ptr<char, void(*)(char*)>(ecore_timer_dump(),
+ [](char *str) {
+ free(str);
+ });
+ auto ret = (dump
+ ? compatibility_new<String>(args.GetIsolate(), dump.get())
+ : compatibility_new<String>(args.GetIsolate(), ""));
+
+ return compatibility_return(ret, args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_timer_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Local;
+ using v8::Value;
+ using v8::Undefined;
+ using v8::Function;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsNumber()
+ || !args[1]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[1]);
+
+ auto cb = [](void *data) -> Eina_Bool {
+ auto persistent = reinterpret_cast<efl::eina::js::global_ref<Value>*>(data);
+ auto o = persistent->handle();
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ if (!bret)
+ {
+ persistent->dispose();
+ delete persistent;
+ }
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+
+ auto ret = ecore_timer_add(args[0]->NumberValue(), cb, f);
+ return compatibility_return(wrap_timer(ret, args.GetIsolate()), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_timer_loop_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Local;
+ using v8::Value;
+ using v8::Undefined;
+ using v8::Function;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsNumber()
+ || !args[1]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[1]);
+
+ auto cb = [](void *d) -> Eina_Bool {
+ auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(d);
+ auto o = persistent->handle();
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ if (!bret)
+ {
+ persistent->dispose();
+ delete persistent;
+ }
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+
+ auto ret = ecore_timer_loop_add(args[0]->NumberValue(), cb, f);
+
+ return compatibility_return(wrap_timer(ret, args.GetIsolate()), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+}
+
+EAPI
+void register_ecore_timer(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
+{
+ register_timer_precision_get(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_timer_precision"
+ "_get"));
+ register_timer_precision_set(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_timer_precision"
+ "_set"));
+ register_timer_dump(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_timer_dump"));
+ register_timer_add(isolate, exports,
+ compatibility_new<v8::String>(isolate, "ecore_timer_add"));
+ register_timer_loop_add(isolate, exports,
+ compatibility_new<v8::String>(isolate,
+ "ecore_timer_loop_add"));
+}
+
+} } } // namespace efl { namespace ecore { namespace js {
diff --git a/src/bindings/ecore_js/ecore_js_timer.hh b/src/bindings/ecore_js/ecore_js_timer.hh
new file mode 100644
index 0000000000..e002587ee4
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_timer.hh
@@ -0,0 +1,38 @@
+#ifndef ECORE_JS_TIMER_HH
+#define ECORE_JS_TIMER_HH
+
+#include <Eina.hh>
+
+#include <Eina_Js.hh>
+
+namespace efl { namespace ecore { namespace js {
+
+using ::efl::eina::js::compatibility_new;
+using ::efl::eina::js::compatibility_return_type;
+using ::efl::eina::js::compatibility_callback_info_type;
+using ::efl::eina::js::compatibility_return;
+using ::efl::eina::js::compatibility_get_pointer_internal_field;
+using ::efl::eina::js::compatibility_set_pointer_internal_field;
+using ::efl::eina::js::compatibility_persistent;
+
+void register_timer_precision_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_timer_precision_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_timer_dump(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_timer_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_timer_loop_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+} } } // namespace efl::js
+
+#endif /* ECORE_JS_TIMER_HH */
diff --git a/src/bindings/eina_cxx/Eina.hh b/src/bindings/eina_cxx/Eina.hh
index d12b0c930f..8f5462892e 100644
--- a/src/bindings/eina_cxx/Eina.hh
+++ b/src/bindings/eina_cxx/Eina.hh
@@ -22,6 +22,7 @@
#include <eina_log.hh>
#include <eina_optional.hh>
#include <eina_integer_sequence.hh>
+#include <eina_pp.hh>
/**
* @page eina_cxx_main Eina C++ (BETA)
diff --git a/src/bindings/eina_cxx/eina_accessor.hh b/src/bindings/eina_cxx/eina_accessor.hh
index b867f14248..d084918ca8 100644
--- a/src/bindings/eina_cxx/eina_accessor.hh
+++ b/src/bindings/eina_cxx/eina_accessor.hh
@@ -114,7 +114,10 @@ struct accessor_common_base
* @warning It is important to take care when using it, since the
* handle will be automatically release upon object destruction.
*/
- Eina_Accessor* native_handle() const;
+ Eina_Accessor* native_handle() const
+ {
+ return _impl;
+ }
/**
* @brief Swap content between both objects.
diff --git a/src/bindings/eina_cxx/eina_array.hh b/src/bindings/eina_cxx/eina_array.hh
index eb9e5578aa..d352de5ab7 100644
--- a/src/bindings/eina_cxx/eina_array.hh
+++ b/src/bindings/eina_cxx/eina_array.hh
@@ -32,6 +32,8 @@ public:
typedef typename _base_type::reverse_iterator reverse_iterator; /**< Type for reverse iterator for this container. */
typedef typename _base_type::const_reverse_iterator const_reverse_iterator; /**< Type for reverse iterator for this container. */
+ typedef typename _base_type::native_handle_type native_handle_type;
+
using _base_type::_base_type;
using _base_type::clear;
using _base_type::size;
@@ -59,6 +61,7 @@ public:
using _base_type::ciend;
using _base_type::swap;
using _base_type::max_size;
+ using _base_type::release_native_handle;
using _base_type::native_handle;
friend bool operator==(array<T, CloneAllocator> const& lhs, array<T, CloneAllocator> const& rhs)
@@ -131,6 +134,101 @@ struct _ptr_eo_array_iterator : _ptr_array_iterator<Eo>
using _base_type::native_handle;
};
+/**
+ * @internal
+ */
+struct _eo_array_access_traits : _ptr_array_access_traits
+{
+ template <typename T>
+ struct iterator
+ {
+ typedef _ptr_eo_array_iterator<T> type;
+ };
+ template <typename T>
+ struct const_iterator : iterator<T const> {};
+
+ template <typename T>
+ static T& back(Eina_Array* array)
+ {
+ return *static_cast<T*>(static_cast<void*>(array->data[size<T>(array)-1]));
+ }
+ template <typename T>
+ static T const& back(Eina_Array const* array)
+ {
+ return _eo_array_access_traits::back<T>(const_cast<Eina_Array*>(array));
+ }
+ template <typename T>
+ static T& front(Eina_Array* array)
+ {
+ return *static_cast<T*>(static_cast<void*>(array->data[0]));
+ }
+ template <typename T>
+ static T const& front(Eina_Array const* array)
+ {
+ return _eo_array_access_traits::front<T>(const_cast<Eina_Array*>(array));
+ }
+ template <typename T>
+ static typename iterator<T>::type begin(Eina_Array* array)
+ {
+ return _ptr_eo_array_iterator<T>(array->data);
+ }
+ template <typename T>
+ static typename iterator<T>::type end(Eina_Array* array)
+ {
+ return _ptr_eo_array_iterator<T>(array->data + size<T>(array));
+ }
+ template <typename T>
+ static typename const_iterator<T>::type begin(Eina_Array const* array)
+ {
+ return _eo_array_access_traits::begin<T>(const_cast<Eina_Array*>(array));
+ }
+ template <typename T>
+ static typename const_iterator<T>::type end(Eina_Array const* array)
+ {
+ return _eo_array_access_traits::end<T>(const_cast<Eina_Array*>(array));
+ }
+ template <typename T>
+ static std::reverse_iterator<typename iterator<T>::type> rbegin(Eina_Array* array)
+ {
+ return std::reverse_iterator<_ptr_eo_array_iterator<T> >(_eo_array_access_traits::end<T>(array));
+ }
+ template <typename T>
+ static std::reverse_iterator<typename iterator<T>::type> rend(Eina_Array* array)
+ {
+ return std::reverse_iterator<_ptr_eo_array_iterator<T> >(_eo_array_access_traits::begin<T>(array));
+ }
+ template <typename T>
+ static std::reverse_iterator<typename const_iterator<T>::type> rbegin(Eina_Array const* array)
+ {
+ return std::reverse_iterator<_ptr_eo_array_iterator<T>const>(_eo_array_access_traits::end<T>(array));
+ }
+ template <typename T>
+ static std::reverse_iterator<typename const_iterator<T>::type> rend(Eina_Array const* array)
+ {
+ return std::reverse_iterator<_ptr_eo_array_iterator<T>const>(_eo_array_access_traits::begin<T>(array));
+ }
+ template <typename T>
+ static typename const_iterator<T>::type cbegin(Eina_Array const* array)
+ {
+ return _eo_array_access_traits::begin<T>(array);
+ }
+ template <typename T>
+ static typename const_iterator<T>::type cend(Eina_Array const* array)
+ {
+ return _eo_array_access_traits::end<T>(array);
+ }
+ template <typename T>
+ static std::reverse_iterator<typename const_iterator<T>::type> crbegin(Eina_Array const* array)
+ {
+ return _eo_array_access_traits::rbegin<T>(array);
+ }
+ template <typename T>
+ static std::reverse_iterator<typename const_iterator<T>::type> crend(Eina_Array const* array)
+ {
+ return _eo_array_access_traits::rend<T>(array);
+ }
+};
+
template <typename T, typename CloneAllocator>
class array<T, CloneAllocator, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type>
: ptr_array<Eo, typename std::conditional
@@ -156,7 +254,9 @@ public:
typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this container. */
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for reverse iterator for this container. */
- explicit array(Eina_Array* handle)
+ typedef typename _base_type::native_handle_type native_handle_type; /**< Type for the native handle of the container. */
+
+ explicit array(native_handle_type handle)
: _base_type(handle) {}
array(clone_allocator_type alloc) : _base_type(alloc) {}
array() {}
@@ -318,6 +418,7 @@ public:
using _base_type::swap;
using _base_type::max_size;
+ using _base_type::release_native_handle;
using _base_type::native_handle;
friend bool operator==(array<T, CloneAllocator> const& lhs, array<T, CloneAllocator> const& rhs)
@@ -331,7 +432,154 @@ bool operator!=(array<T, CloneAllocator> const& lhs, array<T, CloneAllocator> co
{
return !(lhs == rhs);
}
+
+template <typename T, typename Enable = void>
+class range_array : range_ptr_array<T>
+{
+ typedef range_ptr_array<T> _base_type;
+public:
+ typedef typename _base_type::value_type value_type;
+ typedef typename _base_type::reference reference;
+ typedef typename _base_type::const_reference const_reference;
+ typedef typename _base_type::const_iterator const_iterator;
+ typedef typename _base_type::iterator iterator;
+ typedef typename _base_type::pointer pointer;
+ typedef typename _base_type::const_pointer const_pointer;
+ typedef typename _base_type::size_type size_type;
+ typedef typename _base_type::difference_type difference_type;
+
+ typedef typename _base_type::reverse_iterator reverse_iterator;
+ typedef typename _base_type::const_reverse_iterator const_reverse_iterator;
+
+ typedef typename _base_type::native_handle_type native_handle_type;
+
+ range_array& operator=(range_array&& other) = default;
+
+ using _base_type::_base_type;
+ using _base_type::size;
+ using _base_type::empty;
+ using _base_type::back;
+ using _base_type::front;
+ using _base_type::begin;
+ using _base_type::end;
+ using _base_type::rbegin;
+ using _base_type::rend;
+ using _base_type::cbegin;
+ using _base_type::cend;
+ using _base_type::crbegin;
+ using _base_type::crend;
+ using _base_type::release_native_handle;
+ using _base_type::native_handle;
+};
+
+template <typename T>
+class range_array<T, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type>
+ : range_ptr_array<Eo>
+{
+ typedef range_ptr_array<Eo> _base_type;
+ typedef range_array<T> _self_type;
+public:
+ typedef T value_type;
+ typedef value_type& reference;
+ typedef value_type const& const_reference;
+ typedef _ptr_eo_array_iterator<value_type const> const_iterator;
+ typedef _ptr_eo_array_iterator<value_type> iterator;
+ typedef value_type* pointer;
+ typedef value_type const* const_pointer;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ typedef typename _base_type::native_handle_type native_handle_type;
+
+ explicit range_array(native_handle_type handle)
+ : _base_type(handle) {}
+ range_array() {}
+ range_array(range_array<T> const& other)
+ : _base_type(other.native_handle())
+ {
+ }
+ range_array<T>& operator=(range_array<T>const& other)
+ {
+ _base_type::_handle = other._handle;
+ return *this;
+ }
+ range_array& operator=(range_array&& other) = default;
+ range_array(range_array&& other) = default;
+ using _base_type::size;
+ using _base_type::empty;
+
+ reference front()
+ {
+ return _eo_array_access_traits::front<value_type>(native_handle());
+ }
+ reference back()
+ {
+ return _eo_array_access_traits::back<value_type>(native_handle());
+ }
+ const_reference front() const { return const_cast<_self_type*>(this)->front(); }
+ const_reference back() const { return const_cast<_self_type*>(this)->back(); }
+ iterator begin()
+ {
+ return _eo_array_access_traits::begin<value_type>(native_handle());
+ }
+ iterator end()
+ {
+ return _eo_array_access_traits::end<value_type>(native_handle());
+ }
+ const_iterator begin() const
+ {
+ return const_cast<_self_type*>(this)->begin();
+ }
+ const_iterator end() const
+ {
+ return const_cast<_self_type*>(this)->end();
+ }
+ const_iterator cbegin() const
+ {
+ return begin();
+ }
+ const_iterator cend() const
+ {
+ return end();
+ }
+ reverse_iterator rbegin()
+ {
+ return _eo_array_access_traits::rbegin<value_type>(native_handle());
+ }
+ reverse_iterator rend()
+ {
+ return _eo_array_access_traits::rend<value_type>(native_handle());
+ }
+ const_reverse_iterator rbegin() const
+ {
+ return const_cast<_self_type*>(this)->rbegin();
+ }
+ const_reverse_iterator rend() const
+ {
+ return const_cast<_self_type*>(this)->rend();
+ }
+ const_reverse_iterator crbegin() const
+ {
+ return rbegin();
+ }
+ const_reverse_iterator crend() const
+ {
+ return rend();
+ }
+ using _base_type::swap;
+ using _base_type::release_native_handle;
+ using _base_type::native_handle;
+
+ friend bool operator==(range_array<T> const& rhs, range_array<T> const& lhs)
+ {
+ return rhs.size() == lhs.size() && std::equal(rhs.begin(), rhs.end(), lhs.begin());
+ }
+};
+
} }
#endif
diff --git a/src/bindings/eina_cxx/eina_clone_allocators.hh b/src/bindings/eina_cxx/eina_clone_allocators.hh
index 824d6d6ce9..76ff620f98 100644
--- a/src/bindings/eina_cxx/eina_clone_allocators.hh
+++ b/src/bindings/eina_cxx/eina_clone_allocators.hh
@@ -154,7 +154,8 @@ struct malloc_clone_allocator
template <typename T>
static void deallocate_clone(T const* p)
{
- static_assert(std::is_pod<T>::value, "malloc_clone_allocator can only be used with POD types");
+ static_assert(std::is_pod<T>::value || std::is_void<T>::value
+ , "malloc_clone_allocator can only be used with POD types");
std::free(const_cast<T*>(p));
}
};
diff --git a/src/bindings/eina_cxx/eina_function.hh b/src/bindings/eina_cxx/eina_function.hh
new file mode 100644
index 0000000000..cef6da5a43
--- /dev/null
+++ b/src/bindings/eina_cxx/eina_function.hh
@@ -0,0 +1,26 @@
+#ifndef EFL_EINA_FUNCTION_HH
+#define EFL_EINA_FUNCTION_HH
+
+namespace efl { namespace eina { namespace _mpl {
+
+template <typename T>
+struct function_params;
+
+template <typename R, typename... P>
+struct function_params<R(*)(P...)>
+{
+ typedef std::tuple<P...> type;
+};
+
+template <typename T>
+struct function_return;
+
+template <typename R, typename... P>
+struct function_return<R(*)(P...)>
+{
+ typedef R type;
+};
+
+} } }
+
+#endif
diff --git a/src/bindings/eina_cxx/eina_integer_sequence.hh b/src/bindings/eina_cxx/eina_integer_sequence.hh
index 854bb8f3d0..f99c871c34 100644
--- a/src/bindings/eina_cxx/eina_integer_sequence.hh
+++ b/src/bindings/eina_cxx/eina_integer_sequence.hh
@@ -1,6 +1,8 @@
#ifndef EINA_CXX_EINA_INTEGER_SEQUENCE_HH
#define EINA_CXX_EINA_INTEGER_SEQUENCE_HH
+#include <cstdlib>
+
/**
* @addtogroup Eina_Cxx_Data_Types_Group
*
diff --git a/src/bindings/eina_cxx/eina_list.hh b/src/bindings/eina_cxx/eina_list.hh
index 760ada3963..1221867c7b 100644
--- a/src/bindings/eina_cxx/eina_list.hh
+++ b/src/bindings/eina_cxx/eina_list.hh
@@ -190,6 +190,8 @@ public:
typedef typename _base_type::reverse_iterator reverse_iterator;
typedef typename _base_type::const_reverse_iterator const_reverse_iterator;
+ using _base_type::native_handle_type;
+
list& operator=(list&& other) = default;
list(list&& other) = default;
list() = default;
@@ -224,6 +226,7 @@ public:
using _base_type::max_size;
using _base_type::native_handle;
using _base_type::accessor;
+ using _base_type::release_native_handle;
};
template <typename T, typename CloneAllocator>
@@ -251,7 +254,9 @@ public:
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- explicit list(Eina_List* handle)
+ using _base_type::native_handle_type;
+
+ explicit list(typename _self_type::native_handle_type handle)
: _base_type(handle) {}
list(clone_allocator_type alloc) : _base_type(alloc) {}
list() {}
@@ -295,6 +300,7 @@ public:
using _base_type::get_clone_allocator;
using _base_type::pop_back;
using _base_type::pop_front;
+ using _base_type::release_native_handle;
void push_back(const_reference w)
{
@@ -464,6 +470,8 @@ public:
typedef typename _base_type::reverse_iterator reverse_iterator;
typedef typename _base_type::const_reverse_iterator const_reverse_iterator;
+ using _base_type::native_handle_type;
+
using _base_type::_base_type;
using _base_type::size;
using _base_type::empty;
@@ -501,9 +509,9 @@ public:
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef typename _base_type::native_handle_type native_handle_type;
+ using _base_type::native_handle_type;
- explicit range_list(native_handle_type handle)
+ explicit range_list(typename _self_type::native_handle_type handle)
: _base_type(handle) {}
range_list() {}
range_list(range_list<T> const& other)
diff --git a/src/bindings/eina_cxx/eina_logical.hh b/src/bindings/eina_cxx/eina_logical.hh
new file mode 100644
index 0000000000..d53d3541ad
--- /dev/null
+++ b/src/bindings/eina_cxx/eina_logical.hh
@@ -0,0 +1,34 @@
+#ifndef EFL_EINA_LOGICAL_HH
+#define EFL_EINA_LOGICAL_HH
+
+#include <type_traits>
+
+namespace efl { namespace eina { namespace _mpl {
+
+template <bool... N>
+struct or_;
+
+template <>
+struct or_<> : std::integral_constant<bool, false> {};
+
+template <bool B>
+struct or_<B> : std::integral_constant<bool, B> {};
+
+template <bool B1, bool B2, bool... Bs>
+struct or_<B1, B2, Bs...> : std::integral_constant<bool, B1 || B2 || or_<Bs...>::value> {};
+
+template <bool... N>
+struct and_;
+
+template <>
+struct and_<> : std::integral_constant<bool, true> {};
+
+template <bool B>
+struct and_<B> : std::integral_constant<bool, B> {};
+
+template <bool B1, bool B2, bool... Bs>
+struct and_<B1, B2, Bs...> : std::integral_constant<bool, B1 && B2 && and_<Bs...>::value> {};
+
+} } }
+
+#endif
diff --git a/src/bindings/eina_cxx/eina_pp.hh b/src/bindings/eina_cxx/eina_pp.hh
new file mode 100644
index 0000000000..22a6a22ef7
--- /dev/null
+++ b/src/bindings/eina_cxx/eina_pp.hh
@@ -0,0 +1,8 @@
+
+#ifndef EINA_PP_HH
+#define EINA_PP_HH
+
+#define EINA_STRINGIZE_IMPL(x) #x
+#define EINA_STRINGIZE(x) EINA_STRINGIZE_IMPL(x)
+
+#endif
diff --git a/src/bindings/eina_cxx/eina_ptrarray.hh b/src/bindings/eina_cxx/eina_ptrarray.hh
index 2f40627ce9..f47202ebb5 100644
--- a/src/bindings/eina_cxx/eina_ptrarray.hh
+++ b/src/bindings/eina_cxx/eina_ptrarray.hh
@@ -295,10 +295,12 @@ struct range_ptr_array : _range_template<T, _ptr_array_access_traits>
typedef _range_template<T, _ptr_array_access_traits> _base_type; /**< Type for the base class. */
typedef typename _base_type::value_type value_type; /**< The type of each element. */
+ typedef typename _base_type::native_handle_type native_handle_type;
+
/**
* @brief Creates a range from a native Eina array handle.
*/
- range_ptr_array(Eina_Array* array)
+ range_ptr_array(native_handle_type array)
: _base_type(array)
{}
@@ -391,7 +393,7 @@ struct _ptr_array_common_base
/**
* @internal
*/
- T* _new_clone(T const& a)
+ T* _new_clone(typename container_value_type<T>::type const& a)
{
return _get_clone_allocator().allocate_clone(a);
}
@@ -402,6 +404,7 @@ struct _ptr_array_common_base
struct _ptr_array_impl : CloneAllocator
{
_ptr_array_impl() : _array( ::eina_array_new(32u) ) {}
+ _ptr_array_impl(Eina_Array* array) : _array(array) {}
_ptr_array_impl(CloneAllocator allocator)
: clone_allocator_type(allocator), _array( ::eina_array_new(32u)) {}
@@ -449,6 +452,8 @@ public:
typedef std::unique_ptr<value_type, clone_allocator_deleter<clone_allocator_type> > _unique_ptr;
+ typedef Eina_Array* native_handle_type;
+
/**
* @brief Default constructor. Create an empty array.
*
@@ -1210,6 +1215,13 @@ public:
*/
size_type max_size() const { return -1; }
+ Eina_Array* release_native_handle()
+ {
+ Eina_Array* tmp = this->_impl._array;
+ this->_impl._array = ::eina_array_new(32u);
+ return tmp;
+ }
+
/**
* @brief Get a handle for the wrapped Eina_Array.
* @return Handle for the native Eina array.
diff --git a/src/bindings/eina_cxx/eina_ptrlist.hh b/src/bindings/eina_cxx/eina_ptrlist.hh
index 2f18d10ffb..f7254b1ef2 100644
--- a/src/bindings/eina_cxx/eina_ptrlist.hh
+++ b/src/bindings/eina_cxx/eina_ptrlist.hh
@@ -9,6 +9,7 @@
#include <eina_eo_concrete_fwd.hh>
#include <eina_iterator.hh>
#include <eina_throw.hh>
+#include <eina_range_types.hh>
#include <memory>
#include <iterator>
@@ -370,7 +371,7 @@ struct _ptr_list_common_base
/**
* @internal
*/
- T* _new_clone(T const& a)
+ T* _new_clone(typename container_value_type<T>::type const& a)
{
return _get_clone_allocator().allocate_clone(a);
}
@@ -413,11 +414,12 @@ class ptr_list : protected _ptr_list_common_base<T, CloneAllocator>
{
typedef _ptr_list_common_base<T, CloneAllocator> _base_type; /**< Type for the base class. */
public:
- typedef T value_type; /**< The type of each element. */
- typedef T& reference; /**< Type for a reference to an element. */
- typedef T const& const_reference; /**< Type for a constant reference to an element. */
- typedef _ptr_list_iterator<T const> const_iterator; /**< Type for a iterator for this container. */
- typedef _ptr_list_iterator<T> iterator; /**< Type for a constant iterator for this container. */
+ typedef typename container_value_type<T>::type
+ value_type; /**< The type of each element. */
+ typedef value_type& reference; /**< Type for a reference to an element. */
+ typedef value_type const& const_reference; /**< Type for a constant reference to an element. */
+ typedef _ptr_list_iterator<value_type const> const_iterator; /**< Type for a iterator for this container. */
+ typedef _ptr_list_iterator<value_type> iterator; /**< Type for a constant iterator for this container. */
typedef T* pointer; /**< Type for a pointer to an element. */
typedef T const* const_pointer; /**< Type for a constant pointer for an element. */
typedef std::size_t size_type; /**< Type for size information. */
@@ -427,6 +429,8 @@ public:
typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this container. */
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for reverse iterator for this container. */
+ typedef Eina_List* native_handle_type;
+
typedef std::unique_ptr<value_type, clone_allocator_deleter<clone_allocator_type> > _unique_ptr;
/**
@@ -554,7 +558,7 @@ public:
*/
std::size_t size() const
{
- return _ptr_list_access_traits::size<T>(this->_impl._list);
+ return _ptr_list_access_traits::size<value_type>(this->_impl._list);
}
/**
@@ -566,7 +570,7 @@ public:
*/
bool empty() const
{
- return _ptr_list_access_traits::empty<T>(this->_impl._list);
+ return _ptr_list_access_traits::empty<value_type>(this->_impl._list);
}
/**
@@ -940,7 +944,7 @@ public:
*/
value_type& back()
{
- return _ptr_list_access_traits::back<T>(this->_impl._list);
+ return _ptr_list_access_traits::back<value_type>(this->_impl._list);
}
/**
@@ -952,7 +956,7 @@ public:
*/
value_type const& back() const
{
- return _ptr_list_access_traits::back<T>(this->_impl._list);
+ return _ptr_list_access_traits::back<value_type>(this->_impl._list);
}
/**
@@ -961,7 +965,7 @@ public:
*/
value_type& front()
{
- return _ptr_list_access_traits::front<T>(this->_impl._list);
+ return _ptr_list_access_traits::front<value_type>(this->_impl._list);
}
/**
@@ -973,7 +977,7 @@ public:
*/
value_type const& front() const
{
- return _ptr_list_access_traits::front<T>(this->_impl._list);
+ return _ptr_list_access_traits::front<value_type>(this->_impl._list);
}
/**
@@ -985,7 +989,7 @@ public:
*/
const_iterator begin() const
{
- return _ptr_list_access_traits::cbegin<T>(this->_impl._list);
+ return _ptr_list_access_traits::cbegin<value_type>(this->_impl._list);
}
/**
@@ -997,7 +1001,7 @@ public:
*/
const_iterator end() const
{
- return _ptr_list_access_traits::cend<T>(this->_impl._list);
+ return _ptr_list_access_traits::cend<value_type>(this->_impl._list);
}
/**
@@ -1010,7 +1014,7 @@ public:
*/
iterator begin()
{
- return _ptr_list_access_traits::begin<T>(this->_impl._list);
+ return _ptr_list_access_traits::begin<value_type>(this->_impl._list);
}
/**
@@ -1026,7 +1030,7 @@ public:
*/
iterator end()
{
- return _ptr_list_access_traits::end<T>(this->_impl._list);
+ return _ptr_list_access_traits::end<value_type>(this->_impl._list);
}
/**
@@ -1038,7 +1042,7 @@ public:
*/
const_reverse_iterator rbegin() const
{
- return _ptr_list_access_traits::rbegin<T>(this->_impl._list);
+ return _ptr_list_access_traits::rbegin<value_type>(this->_impl._list);
}
/**
@@ -1050,7 +1054,7 @@ public:
*/
const_reverse_iterator rend() const
{
- return _ptr_list_access_traits::rend<T>(this->_impl._list);
+ return _ptr_list_access_traits::rend<value_type>(this->_impl._list);
}
/**
@@ -1063,7 +1067,7 @@ public:
*/
reverse_iterator rbegin()
{
- return _ptr_list_access_traits::rbegin<T>(this->_impl._list);
+ return _ptr_list_access_traits::rbegin<value_type>(this->_impl._list);
}
/**
@@ -1080,7 +1084,7 @@ public:
*/
reverse_iterator rend()
{
- return _ptr_list_access_traits::rend<T>(this->_impl._list);
+ return _ptr_list_access_traits::rend<value_type>(this->_impl._list);
}
/**
@@ -1093,7 +1097,7 @@ public:
*/
const_iterator cbegin() const
{
- return _ptr_list_access_traits::cbegin<T>(this->_impl._list);
+ return _ptr_list_access_traits::cbegin<value_type>(this->_impl._list);
}
/**
@@ -1106,7 +1110,7 @@ public:
*/
const_iterator cend() const
{
- return _ptr_list_access_traits::cend<T>(this->_impl._list);
+ return _ptr_list_access_traits::cend<value_type>(this->_impl._list);
}
/**
@@ -1119,7 +1123,7 @@ public:
*/
const_reverse_iterator crbegin() const
{
- return _ptr_list_access_traits::crbegin<T>(this->_impl._list);
+ return _ptr_list_access_traits::crbegin<value_type>(this->_impl._list);
}
/**
@@ -1132,7 +1136,7 @@ public:
*/
const_reverse_iterator crend() const
{
- return _ptr_list_access_traits::crend<T>(this->_impl._list);
+ return _ptr_list_access_traits::crend<value_type>(this->_impl._list);
}
/**
@@ -1143,9 +1147,9 @@ public:
* the first element of the list. If the list is empty the returned
* iterator is the same as the one returned by @ref iend().
*/
- eina::iterator<T> ibegin()
+ eina::iterator<value_type> ibegin()
{
- return _ptr_list_access_traits::ibegin<T>(this->_impl._list);
+ return _ptr_list_access_traits::ibegin<value_type>(this->_impl._list);
}
/**
@@ -1160,9 +1164,9 @@ public:
* @note Note that attempting to access this position causes undefined
* behavior.
*/
- eina::iterator<T> iend()
+ eina::iterator<value_type> iend()
{
- return _ptr_list_access_traits::iend<T>(this->_impl._list);
+ return _ptr_list_access_traits::iend<value_type>(this->_impl._list);
}
/**
@@ -1174,7 +1178,7 @@ public:
*/
eina::iterator<T const> ibegin() const
{
- return _ptr_list_access_traits::ibegin<T>(this->_impl._list);
+ return _ptr_list_access_traits::ibegin<value_type>(this->_impl._list);
}
/**
@@ -1186,7 +1190,7 @@ public:
*/
eina::iterator<T const> iend() const
{
- return _ptr_list_access_traits::iend<T>(this->_impl._list);
+ return _ptr_list_access_traits::iend<value_type>(this->_impl._list);
}
/**
@@ -1199,7 +1203,7 @@ public:
*/
eina::iterator<T const> cibegin() const
{
- return _ptr_list_access_traits::cibegin<T>(this->_impl._list);
+ return _ptr_list_access_traits::cibegin<value_type>(this->_impl._list);
}
/**
@@ -1212,7 +1216,7 @@ public:
*/
eina::iterator<T const> ciend() const
{
- return _ptr_list_access_traits::ciend<T>(this->_impl._list);
+ return _ptr_list_access_traits::ciend<value_type>(this->_impl._list);
}
/**
@@ -1230,6 +1234,13 @@ public:
*/
size_type max_size() const { return -1; }
+ Eina_List* release_native_handle()
+ {
+ Eina_List* tmp = this->_impl._list;
+ this->_impl._list = 0;
+ return tmp;
+ }
+
/**
* @brief Get a handle for the wrapped @c Eina_List.
* @return Handle for the native Eina list.
@@ -1275,9 +1286,9 @@ public:
* @brief Get a @ref eina::accessor for the list.
* @return <tt>eina::accessor</tt> to the list.
*/
- eina::accessor<T> accessor()
+ eina::accessor<value_type> accessor()
{
- return eina::accessor<T>(eina_list_accessor_new(this->_impl._list));
+ return eina::accessor<value_type>(eina_list_accessor_new(this->_impl._list));
}
};
diff --git a/src/bindings/eina_cxx/eina_range_types.hh b/src/bindings/eina_cxx/eina_range_types.hh
index 844e2ef4cc..313ca05cd9 100644
--- a/src/bindings/eina_cxx/eina_range_types.hh
+++ b/src/bindings/eina_cxx/eina_range_types.hh
@@ -22,11 +22,12 @@ namespace efl { namespace eina {
template <typename T, typename Traits>
struct _const_range_template
{
- typedef typename Traits::template const_iterator<T>::type const_iterator; /**< Type for constant iterator to the range. */
- typedef typename Traits::template iterator<T>::type iterator; /**< Type for iterator to the range. */
- typedef T value_type; /**< The type of each element. */
- typedef T& reference; /**< Type for a reference to an element. */
- typedef T const& const_reference; /**< Type for a constant reference to an element. */
+ typedef typename container_value_type<T>::type
+ value_type; /**< The type of each element. */
+ typedef typename Traits::template const_iterator<value_type>::type const_iterator; /**< Type for constant iterator to the range. */
+ typedef typename Traits::template iterator<value_type>::type iterator; /**< Type for iterator to the range. */
+ typedef value_type& reference; /**< Type for a reference to an element. */
+ typedef value_type const& const_reference; /**< Type for a constant reference to an element. */
typedef T* pointer; /**< Type for a pointer to an element. */
typedef T const* const_pointer; /**< Type for a constant pointer to an element. */
typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator to the range. */
@@ -50,6 +51,17 @@ struct _const_range_template
: _handle(handle) {}
/**
+ * @brief Release the handle of the native Eina container.
+ * @return Handle for the native Eina container.
+ */
+ native_handle_type release_native_handle()
+ {
+ auto h = _handle;
+ _handle = nullptr;
+ return h;
+ }
+
+ /**
* @brief Get a constant handle for the native Eina container.
* @return Constant handle for the native Eina container.
*/
@@ -241,10 +253,13 @@ void swap(_const_range_template<T, Traits>& lhs, _const_range_template<T, Traits
template <typename T, typename Traits>
struct _mutable_range_template : _const_range_template<T, Traits>
{
- typedef T value_type; /**< The type of each element. */
- typedef typename Traits::template iterator<T>::type iterator; /**< Type for a iterator to the range. */
+ typedef typename container_value_type<T>::type
+ value_type; /**< The type of each element. */
+ typedef value_type& reference_type;
+ typedef value_type const& const_reference_type;
+ typedef typename Traits::template iterator<value_type>::type iterator; /**< Type for a iterator to the range. */
typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for constant reverse iterator to the range. */
- typedef typename Traits::template native_handle<T>::type native_handle_type; /**< Type for the native handle of the container. */
+ typedef typename Traits::template native_handle<value_type>::type native_handle_type; /**< Type for the native handle of the container. */
typedef _const_range_template<T, Traits> _base_type; /**< Type for the base class. */
/**
@@ -254,6 +269,17 @@ struct _mutable_range_template : _const_range_template<T, Traits>
: _base_type(handle) {}
/**
+ * @brief Release the handle of the native Eina container.
+ * @return Handle for the native Eina container.
+ */
+ native_handle_type release_native_handle()
+ {
+ auto h = _handle;
+ _handle = nullptr;
+ return h;
+ }
+
+ /**
* @brief Get a constant handle for the native Eina container.
* @return Constant handle for the native Eina container.
*/
@@ -266,7 +292,7 @@ struct _mutable_range_template : _const_range_template<T, Traits>
* @brief Get a reference to the last element.
* @return Reference to the last element of the range.
*/
- value_type& back() const
+ reference_type back() const
{
return Traits::template back<value_type>(native_handle());
}
@@ -275,7 +301,7 @@ struct _mutable_range_template : _const_range_template<T, Traits>
* @brief Get a reference to the first element.
* @return Reference to the first element of the range.
*/
- value_type& front() const
+ reference_type front() const
{
return Traits::template front<value_type>(native_handle());
}
@@ -355,11 +381,12 @@ protected:
template <typename T, typename Traits>
struct _range_template : private std::conditional
<std::is_const<T>::value
- , _const_range_template<typename std::remove_const<T>::type, Traits>
- , _mutable_range_template<T, Traits> >::type
+ , _const_range_template<typename nonconst_container_value_type<T>::type, Traits>
+ , _mutable_range_template<typename nonconst_container_value_type<T>::type, Traits>
+ >::type
{
typedef std::integral_constant<bool, !std::is_const<T>::value> is_mutable; /**< Type that specifies if the elements can be modified. */
- typedef typename std::remove_const<T>::type value_type; /**< The type of each element. */
+ typedef typename nonconst_container_value_type<T>::type value_type; /**< The type of each element. */
typedef typename std::conditional<is_mutable::value, _mutable_range_template<value_type, Traits>
, _const_range_template<value_type, Traits> >::type _base_type; /**< Type for the base class. */
typedef typename _base_type::native_handle_type native_handle_type; /**< Type for the native handle of the container. */
@@ -368,9 +395,9 @@ struct _range_template : private std::conditional
typedef value_type const& const_reference; /**< Type for a constant reference to an element. */
typedef value_type* pointer; /**< Type for a pointer to an element. */
typedef value_type const* const_pointer; /**< Type for a constant pointer to an element. */
- typedef typename Traits::template const_iterator<T>::type const_iterator; /**< Type for constant iterator to the range. */
+ typedef typename Traits::template const_iterator<value_type>::type const_iterator; /**< Type for constant iterator to the range. */
typedef typename _base_type::const_reverse_iterator const_reverse_iterator; /**< Type for constant reverse iterator to the range. */
- typedef typename Traits::template iterator<T>::type iterator; /**< Type for iterator to the range. */
+ typedef typename Traits::template iterator<value_type>::type iterator; /**< Type for iterator to the range. */
typedef typename _base_type::reverse_iterator reverse_iterator; /**< Type for reverse iterator to the range. */
typedef typename _base_type::size_type size_type; /**< Type for size information. */
typedef typename _base_type::difference_type difference_type; /**< Type to represent the distance between two iterators. */
@@ -388,6 +415,7 @@ struct _range_template : private std::conditional
: _base_type(handle)
{}
+ using _base_type::release_native_handle;
using _base_type::native_handle;
using _base_type::back;
using _base_type::front;
diff --git a/src/bindings/eina_cxx/eina_tuple.hh b/src/bindings/eina_cxx/eina_tuple.hh
index f0f22d9cae..45545c3702 100644
--- a/src/bindings/eina_cxx/eina_tuple.hh
+++ b/src/bindings/eina_cxx/eina_tuple.hh
@@ -1,6 +1,11 @@
#ifndef EFL_EINA_EINA_TUPLE_HH_
#define EFL_EINA_EINA_TUPLE_HH_
+#include <eina_integer_sequence.hh>
+#include <eina_logical.hh>
+
+#include <tuple>
+
namespace efl { namespace eina { namespace _mpl {
template <typename A, typename... Args>
@@ -21,15 +26,64 @@ struct push_front<C<Args...>, AArgs...>
typedef C<Args..., AArgs...> type;
};
-template <typename A>
+template <typename A, std::size_t N = 1>
struct pop_front;
-
+
template <template <typename...> class C, typename T, typename... Args>
-struct pop_front<C<T, Args...> >
+struct pop_front<C<T, Args...>, 1>
{
typedef C<Args...> type;
};
+template <typename A, std::size_t N>
+struct pop_front : pop_front<typename pop_front<A, 1>::type, N-1>
+{
+};
+
+template <typename T, typename F, std::size_t... I>
+void for_each_impl(T&& t, F&& f, eina::index_sequence<I...>)
+{
+ std::initializer_list<int> l = { (f(std::get<I>(t)), 0)...};
+ static_cast<void>(l);
+}
+
+template <typename T, typename F>
+void for_each(T&& t, F&& f)
+{
+ _mpl::for_each_impl(t, f, eina::make_index_sequence
+ <std::tuple_size<typename std::remove_reference<T>::type>::value>());
+}
+
+template <typename T, typename Transform>
+struct tuple_transform;
+
+template <typename...T, typename Transform>
+struct tuple_transform<std::tuple<T...>, Transform>
+{
+ typedef std::tuple<typename Transform::template apply<T>::type...> type;
+};
+
+template <typename T, typename Tuple>
+struct tuple_contains;
+
+
+
+template <typename T, typename...Ts>
+struct tuple_contains<T, std::tuple<Ts...> >
+ : _mpl::or_<std::is_same<T, Ts>::value...>
+{
+};
+
+template <typename T, typename Tuple>
+struct tuple_find : std::integral_constant<int, -1> {};
+
+template <typename T, typename... Ts>
+struct tuple_find<T, std::tuple<T, Ts...> > : std::integral_constant<std::size_t, 0> {};
+
+template <typename T, typename T1, typename... Ts>
+struct tuple_find<T, std::tuple<T1, Ts...> > : std::integral_constant
+ <std::size_t, 1 + tuple_find<T, std::tuple<Ts...> >::value> {};
+
} } }
#endif
diff --git a/src/bindings/eina_cxx/eina_tuple_c.hh b/src/bindings/eina_cxx/eina_tuple_c.hh
new file mode 100644
index 0000000000..64d67c49a9
--- /dev/null
+++ b/src/bindings/eina_cxx/eina_tuple_c.hh
@@ -0,0 +1,24 @@
+#ifndef EFL_EINA_EINA_TUPLE_C_HH_
+#define EFL_EINA_EINA_TUPLE_C_HH_
+
+#include <tuple>
+
+namespace efl { namespace eina { namespace _mpl {
+
+template <typename T, T... Ts>
+using tuple_c = std::tuple<std::integral_constant<T, Ts>...>;
+
+template <typename T, T... Ts>
+constexpr std::size_t tuple_c_size(tuple_c<T, Ts...> const&)
+{
+ return sizeof...(Ts);
+}
+
+constexpr std::size_t tuple_c_size(std::tuple<> const&)
+{
+ return 0;
+}
+
+} } }
+
+#endif
diff --git a/src/bindings/eina_cxx/eina_type_traits.hh b/src/bindings/eina_cxx/eina_type_traits.hh
index 9e8628ad90..ff8bfbbff9 100644
--- a/src/bindings/eina_cxx/eina_type_traits.hh
+++ b/src/bindings/eina_cxx/eina_type_traits.hh
@@ -64,6 +64,22 @@ struct if_ : if_c<U::value, T, F>
{
};
+template <typename T>
+struct container_value_type
+{
+ typedef typename std::conditional<
+ std::is_void<T>::value
+ , T*, T>::type type;
+};
+
+template <typename T>
+struct nonconst_container_value_type
+{
+ typedef typename std::conditional<
+ std::is_void<T>::value
+ , T*, typename std::remove_const<T>::type>::type type;
+};
+
/**
* @}
*/
diff --git a/src/bindings/eina_js/Eina_Js.hh b/src/bindings/eina_js/Eina_Js.hh
new file mode 100644
index 0000000000..b193b5461c
--- /dev/null
+++ b/src/bindings/eina_js/Eina_Js.hh
@@ -0,0 +1,50 @@
+
+#ifndef EFL_EINA_JS_HH
+#define EFL_EINA_JS_HH
+
+#include <Eina.hh>
+#include <eo_concrete.hh>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_EINA_JS_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+#include <eina_js_container.hh>
+#include <eina_js_accessor.hh>
+#include <eina_js_array.hh>
+#include <eina_js_compatibility.hh>
+#include <eina_js_error.hh>
+#include <eina_js_get_value_from_c.hh>
+#include <eina_js_get_value.hh>
+#include <eina_js_iterator.hh>
+#include <eina_js_list.hh>
+#include <eina_js_log.hh>
+#include <eina_js_value.hh>
+#include <eina_js_log.hh>
+
+#undef EAPI
+#define EAPI
+
+#endif
diff --git a/src/bindings/eina_js/eina_js_accessor.cc b/src/bindings/eina_js/eina_js_accessor.cc
new file mode 100644
index 0000000000..d6891547ed
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_accessor.cc
@@ -0,0 +1,34 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Eina.hh>
+
+#include <Eina_Js.hh>
+
+#include <iostream>
+
+namespace efl { namespace eina { namespace js {
+
+EAPI void register_destroy_accessor(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ typedef void (*deleter_t)(void*);
+
+ auto f = [](compatibility_callback_info_type info) -> compatibility_return_type
+ {
+ if (info.Length() != 1 || !info[0]->IsObject())
+ return compatibility_return();
+
+ v8::Handle<v8::Object> o = info[0]->ToObject();
+
+ deleter_t deleter = compatibility_get_pointer_internal_field<deleter_t>(o, 1);
+ deleter(compatibility_get_pointer_internal_field<>(o, 0));
+ return compatibility_return();
+ };
+
+ global->Set(name, compatibility_new<v8::FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+} } } // namespace efl { namespace js {
diff --git a/src/bindings/eina_js/eina_js_accessor.hh b/src/bindings/eina_js/eina_js_accessor.hh
new file mode 100644
index 0000000000..abf3090fed
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_accessor.hh
@@ -0,0 +1,87 @@
+#ifndef EINA_JS_ACCESSOR_HH
+#define EINA_JS_ACCESSOR_HH
+
+#include <memory>
+
+#include <eina_js_value.hh>
+#include <eina_js_compatibility.hh>
+#include <eina_js_get_value.hh>
+#include <eina_js_get_value_from_c.hh>
+
+#include <iostream>
+
+namespace efl { namespace eina { namespace js {
+
+template <typename T, typename A>
+js::compatibility_return_type accessor_get(js::compatibility_callback_info_type info)
+{
+ v8::Isolate* isolate = info.GetIsolate();
+ if (info.Length() != 1 || !info[0]->IsNumber())
+ return js::compatibility_return();
+
+ auto idx = js::get_value_from_javascript
+ (info[0], isolate, "", js::value_tag<std::size_t>());
+
+ std::string class_name;
+ if (info.Data()->IsString())
+ {
+ v8::String::Utf8Value str(info.Data());
+ class_name = *str;
+ }
+
+ void *ptr = compatibility_get_pointer_internal_field(info.Holder(), 0);
+
+ return compatibility_return
+ (::efl::eina::js::get_value_from_c
+ (js::wrap_value<T>(container_unwrap((*static_cast<A*>(ptr))[idx]), js::value_tag<T>{})
+ , isolate, class_name.c_str()), info);
+};
+
+/* Creates a copy from \p a accessor and exports it to be manipulated by the JS
+ code */
+template <typename T, typename W>
+inline v8::Local<v8::Object> export_accessor(::efl::eina::accessor<W> &a, v8::Isolate *isolate, const char* class_name)
+{
+ typedef ::efl::eina::accessor<W> accessor_type;
+
+ static efl::eina::js::global_ref<v8::ObjectTemplate> obj_tpl
+ (isolate,
+ [&]()
+ {
+ auto obj_tpl = compatibility_new<v8::ObjectTemplate>(isolate);
+ (*obj_tpl)->SetInternalFieldCount(1);
+
+ // TODO: (*obj_tpl)->SetIndexedPropertyHandler(&accessor_get<accessor_type>);
+
+ (*obj_tpl)->Set(js::compatibility_new<v8::String>(isolate, "get")
+ , js::compatibility_new<v8::FunctionTemplate>(isolate
+ , &accessor_get<T, accessor_type>
+ , js::compatibility_new<v8::String>(isolate, class_name)));
+ return obj_tpl;
+ }());
+
+ auto instance = obj_tpl.handle()->NewInstance();
+ compatibility_set_pointer_internal_field(instance, 0, &a);
+ return instance;
+}
+
+/* Extracts and returns a copy from the internal accessor object from the JS
+ object */
+template <typename T>
+::efl::eina::accessor<T>& import_accessor(v8::Handle<v8::Object> o)
+{
+ typedef ::efl::eina::accessor<T> accessor_type;
+
+ void* ptr = compatibility_get_pointer_internal_field(o, 0);
+
+ return *static_cast<accessor_type*>(ptr);
+}
+
+/* Registers the function to destroy the accessor objects to the JS code */
+void register_destroy_accessor(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+} } } // namespace efl::js
+
+#endif /* EINA_JS_ACCESSOR_HH */
diff --git a/src/bindings/eina_js/eina_js_array.hh b/src/bindings/eina_js/eina_js_array.hh
new file mode 100644
index 0000000000..9cdd142e7c
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_array.hh
@@ -0,0 +1,119 @@
+#ifndef EINA_JS_ARRAY_HH
+#define EINA_JS_ARRAY_HH
+
+#include <iostream>
+
+#include <iterator>
+
+#include <eina_js_container.hh>
+
+namespace efl { namespace eina { namespace js {
+
+template <typename T, typename K, typename W>
+struct eina_array : eina_container_common<efl::eina::array
+ <W
+ , typename std::conditional
+ <std::is_base_of<efl::eo::concrete, W>::value
+ , efl::eina::eo_clone_allocator
+ , efl::eina::malloc_clone_allocator
+ >::type>, T, K>
+{
+ typedef eina_container_common<efl::eina::array<W
+ , typename std::conditional
+ <std::is_base_of<efl::eo::concrete, W>::value
+ , efl::eina::eo_clone_allocator
+ , efl::eina::malloc_clone_allocator
+ >::type>, T, K> base_type;
+ using base_type::base_type;
+ typedef typename base_type::container_type container_type;
+
+ eina_container_base* concat(eina_container_base const& other) const
+ {
+ return detail::concat(*this, other);
+ }
+ eina_container_base* slice(std::int64_t i, std::int64_t j) const
+ {
+ return detail::slice(*this, i, j);
+ }
+ v8::Local<v8::Value> set(v8::Isolate* isolate, std::size_t index, v8::Local<v8::Value> v)
+ {
+ return detail::set<T,W>(isolate, *this, index, v);
+ }
+ int push(v8::Isolate* isolate, v8::Local<v8::Value> v)
+ {
+ return detail::push<T,W>(isolate, *this, v);
+ }
+ v8::Local<v8::Value> pop(v8::Isolate* isolate)
+ {
+ return detail::pop<T,W,K>(isolate, *this);
+ }
+ js::container_type get_container_type() const { return array_container_type; }
+};
+
+template <typename T, typename K, typename W>
+struct range_eina_array : eina_container_common<efl::eina::range_array<W>, T, K>
+{
+ typedef eina_container_common<efl::eina::range_array<W>, T, K> base_type;
+ using base_type::base_type;
+ typedef typename base_type::container_type container_type;
+ typedef typename std::conditional
+ <std::is_base_of<efl::eo::concrete, W>::value
+ , efl::eina::eo_clone_allocator
+ , efl::eina::malloc_clone_allocator
+ >::type clone_allocator_type;
+
+ eina_container_base* concat(eina_container_base const& other) const
+ {
+ range_eina_array<T, K, W> const& rhs = static_cast<range_eina_array<T, K, W>const&>(other);
+ efl::eina::array<W, clone_allocator_type>
+ array(this->_container.begin(), this->_container.end());
+ array.insert(array.end(), rhs._container.begin(), rhs._container.end());
+ return new eina_array<T, K, W>(array.release_native_handle());
+ }
+ eina_container_base* slice(std::int64_t i, std::int64_t j) const
+ {
+ efl::eina::array<W, clone_allocator_type>
+ array(std::next(this->_container.begin(), i), std::next(this->_container.begin(), j));
+ return new eina_array<T, K, W>(array.release_native_handle());
+ }
+ js::container_type get_container_type() const { return array_container_type; }
+};
+
+// Problematic types.
+template <>
+struct eina_array<_Elm_Calendar_Mark*, js::nonclass_cls_name_getter, _Elm_Calendar_Mark>
+ : empty_container_base
+{ eina_array(Eina_Array const*){} };
+template <>
+struct eina_array<Elm_Gen_Item*, js::nonclass_cls_name_getter, Elm_Gen_Item>
+ : empty_container_base
+{ eina_array(Eina_Array const*){} };
+template <>
+struct eina_array<_Evas_Textblock_Rectangle*, js::nonclass_cls_name_getter, _Evas_Textblock_Rectangle>
+ : empty_container_base
+{ eina_array(Eina_Array const*){} };
+template <>
+struct eina_array<_Elm_Map_Overlay*, js::nonclass_cls_name_getter, _Elm_Map_Overlay>
+ : empty_container_base
+{ eina_array(Eina_Array const*){} };
+
+template <>
+struct range_eina_array<_Elm_Calendar_Mark*, js::nonclass_cls_name_getter, _Elm_Calendar_Mark>
+ : empty_container_base
+{ range_eina_array(Eina_Array const*){} };
+template <>
+struct range_eina_array<Elm_Gen_Item*, js::nonclass_cls_name_getter, Elm_Gen_Item>
+ : empty_container_base
+{ range_eina_array(Eina_Array const*){} };
+template <>
+struct range_eina_array<_Evas_Textblock_Rectangle*, js::nonclass_cls_name_getter, _Evas_Textblock_Rectangle>
+ : empty_container_base
+{ range_eina_array(Eina_Array const*){} };
+template <>
+struct range_eina_array<_Elm_Map_Overlay*, js::nonclass_cls_name_getter, _Elm_Map_Overlay>
+ : empty_container_base
+{ range_eina_array(Eina_Array const*){} };
+
+} } }
+
+#endif
diff --git a/src/bindings/eina_js/eina_js_compatibility.cc b/src/bindings/eina_js/eina_js_compatibility.cc
new file mode 100644
index 0000000000..a1d992f59e
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_compatibility.cc
@@ -0,0 +1,12 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Eina.hh>
+#include <Eina_Js.hh>
+
+namespace efl { namespace eina { namespace js {
+
+std::map<std::string, v8::Local<v8::Function>> constructors_map_;
+
+} } }
diff --git a/src/bindings/eina_js/eina_js_compatibility.hh b/src/bindings/eina_js/eina_js_compatibility.hh
new file mode 100644
index 0000000000..9ef0cb814e
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_compatibility.hh
@@ -0,0 +1,918 @@
+#ifndef EFL_EINA_JS_COMPATIBILITY_HH
+#define EFL_EINA_JS_COMPATIBILITY_HH
+
+#include <type_traits>
+#include <utility>
+#include <map>
+#include <string>
+#include <cstdlib>
+
+
+#ifdef HAVE_NODE_V8_H
+#include <node/v8.h>
+#elif defined(HAVE_NODEJS_DEPS_V8_V8_H)
+#include <nodejs/deps/v8/v8.h>
+#elif defined(HAVE_NODEJS_DEPS_V8_INCLUDE_V8_H)
+#include <nodejs/deps/v8/include/v8.h>
+#elif defined(HAVE_NODEJS_SRC_V8_H)
+#include <nodejs/src/v8.h>
+#elif defined(HAVE_V8_H)
+#include <v8.h>
+#else
+#error We must have at least one v8 header to include
+#endif
+
+namespace v8 {
+
+template <typename T>
+struct FunctionCallbackInfo;
+template <typename T>
+struct PropertyCallbackInfo;
+template <typename T>
+#ifdef HAVE_V8_GLOBAL
+struct Global;
+#else
+struct UniquePersistent;
+#endif
+
+class AccessorInfo;
+
+class Arguments;
+
+}
+
+namespace efl { namespace eina { namespace js {
+
+template <typename T>
+struct value_tag
+{
+ typedef T type;
+};
+
+template <typename T, typename... U>
+struct complex_tag
+{
+ T value;
+ typedef std::tuple<U...> inner_types;
+};
+
+template <typename T>
+struct make_tag_traits
+{
+ typedef typename std::remove_reference<T>::type a1;
+ typedef typename std::conditional
+ <std::is_pointer<T>::value
+ , typename std::remove_cv<T>::type
+ , T>::type type;
+};
+
+template <typename T, typename... U>
+using make_complex_tag = complex_tag<typename make_tag_traits<T>::type
+ , typename make_tag_traits<U>::type...>;
+
+template <typename T>
+struct struct_tag
+{
+ T value;
+};
+
+template <typename T>
+using make_struct_tag = struct_tag<typename make_tag_traits<T>::type>;
+
+template <typename T>
+struct struct_ptr_tag
+{
+ T value;
+};
+
+template <typename T>
+using make_struct_ptr_tag = struct_ptr_tag<typename make_tag_traits<T>::type>;
+
+template <typename T, typename... Ts>
+struct remove_tag
+{
+ typedef T type;
+};
+
+template <typename T, typename... U>
+struct remove_tag<complex_tag<T, U...>>
+{
+ typedef typename eina::js::remove_tag<T, U...>::type type;
+};
+
+template <typename T>
+struct remove_tag<struct_tag<T>>
+{
+ typedef typename eina::js::remove_tag<T>::type type;
+};
+
+template <typename T>
+struct remove_tag<struct_ptr_tag<T>>
+{
+ typedef typename eina::js::remove_tag<T>::type type;
+};
+
+template <typename T>
+struct is_handable_by_value
+{
+ static constexpr bool value = !std::is_class<T>::value || std::is_same<T, ::efl::eo::concrete>::value;
+};
+
+template <typename... T>
+struct container_wrapper
+{
+ typedef typename eina::js::remove_tag<T...>::type _notag_type;
+ typedef typename std::conditional<
+ std::is_convertible<_notag_type, Eo const* const>::value
+ , typename std::conditional<
+ std::is_const<typename std::remove_pointer<_notag_type>::type>::value
+ , ::efl::eo::concrete const
+ , ::efl::eo::concrete
+ >::type
+ , _notag_type
+ >::type type;
+};
+
+template <typename T>
+T container_wrap(T&& v)
+{
+ return std::forward<T>(v);
+}
+
+inline ::efl::eo::concrete container_wrap(Eo* v)
+{
+ if(v)
+ eo_ref(v);
+ return ::efl::eo::concrete{v};
+}
+
+inline ::efl::eo::concrete container_wrap(Eo const* v)
+{
+ if (v)
+ eo_ref(v);
+ return ::efl::eo::concrete{const_cast<Eo*>(v)};
+}
+
+template <typename T>
+T& container_unwrap(T& v)
+{
+ return v;
+}
+
+inline Eo* container_unwrap(::efl::eo::concrete& v)
+{
+ return v._eo_ptr();
+}
+
+inline Eo* container_unwrap(::efl::eo::concrete const& v)
+{
+ return v._eo_ptr();
+}
+
+template <typename T>
+struct is_complex_tag : std::false_type {};
+
+template <typename... T>
+struct is_complex_tag<complex_tag<T...>> : std::true_type {};
+
+template <typename T>
+struct is_struct_tag : std::false_type {};
+
+template <typename T>
+struct is_struct_tag<struct_tag<T>> : std::true_type {};
+
+template <typename T>
+struct is_struct_ptr_tag : std::false_type {};
+
+template <typename T>
+struct is_struct_ptr_tag<struct_ptr_tag<T>> : std::true_type {};
+
+template <typename T>
+struct is_type_tag
+{
+ static constexpr bool value =
+ is_complex_tag<T>::value
+ || is_struct_tag<T>::value
+ || is_struct_ptr_tag<T>::value;
+};
+
+
+// Class name getters
+struct cls_name_getter_base {};
+struct cls_name_getter_generated_base : cls_name_getter_base {};
+/// Name getter for types that are not classes
+struct nonclass_cls_name_getter : cls_name_getter_base
+{
+ static char const* class_name() { return ""; }
+};
+
+// JS container base
+enum container_type
+{
+ list_container_type
+ , array_container_type
+ , container_type_size
+};
+
+struct eina_container_base
+{
+ virtual ~eina_container_base() {}
+
+ virtual std::size_t size() const = 0;
+ virtual eina_container_base* concat(eina_container_base const& rhs) const = 0;
+ virtual eina_container_base* slice(std::int64_t i, std::int64_t j) const = 0;
+ virtual int index_of(v8::Isolate* isolate, v8::Local<v8::Value> v) const = 0;
+ virtual int last_index_of(v8::Isolate* isolate, v8::Local<v8::Value> v) const = 0;
+ virtual v8::Local<v8::Value> get(v8::Isolate*, std::size_t) const = 0;
+ virtual v8::Local<v8::Value> set(v8::Isolate* isolate, std::size_t index, v8::Local<v8::Value> v) = 0;
+ virtual int push(v8::Isolate* isolate, v8::Local<v8::Value> v) = 0;
+ virtual v8::Local<v8::Value> pop(v8::Isolate* isolate) = 0;
+ virtual v8::Local<v8::String> to_string(v8::Isolate*) const = 0;
+ virtual v8::Local<v8::String> join(v8::Isolate*, v8::Local<v8::Value> separator) const = 0;
+ virtual container_type get_container_type() const = 0;
+ virtual void* get_container_native_handle() = 0;
+ virtual void const* get_container_native_handle() const = 0;
+};
+
+// Containers forward declarations
+
+// Array
+template <typename T, typename K = nonclass_cls_name_getter, typename W = typename container_wrapper<T>::type>
+struct eina_array;
+template <typename T, typename K = nonclass_cls_name_getter, typename W = typename container_wrapper<T>::type>
+struct range_eina_array;
+
+EAPI v8::Handle<v8::Function> get_array_instance_template();
+
+// List
+template <typename T, typename K = nonclass_cls_name_getter, typename W = typename container_wrapper<T>::type>
+struct eina_list;
+template <typename T, typename K = nonclass_cls_name_getter, typename W = typename container_wrapper<T>::type>
+struct range_eina_list;
+
+EAPI v8::Handle<v8::Function> get_list_instance_template();
+
+// Accessor
+template <typename T, typename W>
+v8::Local<v8::Object> export_accessor(::efl::eina::accessor<W>&, v8::Isolate*, const char*);
+
+template <typename T>
+::efl::eina::accessor<T>& import_accessor(v8::Handle<v8::Object>);
+
+// Wrap value functions
+template <typename R, typename T>
+typename std::remove_cv<typename std::remove_reference<R>::type>::type
+wrap_value(T v, value_tag<R>
+ , typename std::enable_if<!is_type_tag<typename std::remove_cv<R>::type>::value>::type* = 0)
+{
+ return v;
+}
+
+template <typename R, typename T>
+R wrap_value(T const& v, value_tag<eina::js::struct_tag<T>>)
+{
+ return R {v};
+}
+
+template <typename R, typename T>
+R wrap_value(T v, value_tag<eina::js::struct_ptr_tag<T>>)
+{
+ return R {v};
+}
+
+template <typename R, typename T, typename... U>
+R wrap_value(T v, value_tag<eina::js::complex_tag<T, U...>>)
+{
+ return R {v};
+}
+
+template <typename T = v8::External>
+struct _libv8_isolate_test
+{
+ using new_signature = v8::Local<T>(*)(v8::Isolate*, void*);
+ static const bool value = std::is_same<decltype(static_cast<new_signature>(&T::New)), new_signature>::value;
+};
+
+template <typename T = v8::FunctionTemplate, typename Enable = void>
+struct _libv8_callback_info_test;
+
+typedef v8::Handle<v8::Value>(*_libv8_invocation_callback)(v8::Arguments const&);
+
+template <typename T>
+struct _libv8_callback_info_test
+<T, typename std::enable_if
+ <!std::is_same<decltype( & T::SetCallHandler)
+ , void (T::*)(_libv8_invocation_callback, v8::Handle<v8::Value>)>::value>::type>
+ : std::true_type
+{
+};
+
+template <typename T>
+struct _libv8_callback_info_test
+<T, typename std::enable_if
+ <std::is_same<decltype( & T::SetCallHandler)
+ , void (T::*)(_libv8_invocation_callback, v8::Handle<v8::Value>)>::value>::type>
+ : std::false_type
+{
+};
+
+template <typename T = v8::ObjectTemplate, typename Enable = void>
+struct _libv8_property_callback_info_test
+ : std::true_type {};
+
+typedef v8::Handle<v8::Value>(*_libv8_getter_callback)(v8::Local<v8::String>, v8::AccessorInfo const&);
+typedef void(*_libv8_setter_callback)(v8::Local<v8::String>, v8::Local<v8::Value>, v8::AccessorInfo const&);
+
+template <typename T>
+struct _libv8_property_callback_info_test
+<T, typename std::enable_if
+ <std::is_same<decltype( & T::SetAccessor)
+ , void (T::*)
+ (v8::Handle<v8::String>
+ , _libv8_getter_callback
+ , _libv8_setter_callback
+ , v8::Handle<v8::Value>
+ , v8::AccessControl
+ , v8::PropertyAttribute
+ , v8::Handle<v8::AccessorSignature>
+ )>::value>::type>
+ : std::false_type
+{
+};
+
+static constexpr bool const v8_uses_isolate = _libv8_isolate_test<>::value;
+static constexpr bool const v8_uses_callback_info = _libv8_callback_info_test<>::value;
+static constexpr bool const v8_uses_property_callback_info = _libv8_property_callback_info_test<>::value;
+
+using compatibility_return_type = std::conditional<v8_uses_callback_info, void, v8::Handle<v8::Value> >::type;
+using compatibility_callback_info_type
+ = std::conditional<v8_uses_callback_info, v8::FunctionCallbackInfo<v8::Value> const&, v8::Arguments const&>
+ ::type;
+using compatibility_callback_info_pointer
+ = std::conditional<v8_uses_callback_info, v8::FunctionCallbackInfo<v8::Value> const*, v8::Arguments const*>
+ ::type;
+
+typedef compatibility_return_type(*compatibility_function_callback)(compatibility_callback_info_type);
+
+using compatibility_accessor_getter_return_type
+ = std::conditional<v8_uses_property_callback_info, void, v8::Handle<v8::Value> >::type;
+using compatibility_accessor_getter_callback_info_type
+ = std::conditional<v8_uses_property_callback_info
+ , v8::PropertyCallbackInfo<v8::Value> const&, v8::AccessorInfo const&>
+ ::type;
+
+using compatibility_accessor_setter_return_type
+ = void;
+using compatibility_accessor_setter_callback_info_type
+ = std::conditional<v8_uses_property_callback_info
+ , v8::PropertyCallbackInfo<void> const&, v8::AccessorInfo const&>
+ ::type;
+
+using compatibility_indexed_property_getset_return_type
+ = std::conditional<v8_uses_property_callback_info, void, v8::Handle<v8::Value> >::type;
+using compatibility_indexed_property_callback_info_type
+ = std::conditional<v8_uses_property_callback_info
+ , v8::PropertyCallbackInfo<v8::Value> const&, v8::AccessorInfo const&>
+ ::type;
+
+static_assert(v8_uses_property_callback_info == v8_uses_callback_info
+ && v8_uses_callback_info == v8_uses_isolate, "");
+
+template <typename T>
+struct compatibility_type_tag {};
+
+template <bool = v8_uses_isolate>
+struct compatibility_string;
+
+template <>
+struct compatibility_string<true> : v8::String
+{
+ template <typename... Args>
+ static v8::Local<v8::String> New(Args...args)
+ {
+ return NewFromUtf8(v8::Isolate::GetCurrent(), args...);
+ }
+};
+
+template <>
+struct compatibility_string<false> : v8::String
+{
+};
+
+template <typename...Args>
+auto compatibility_new_impl(v8::Isolate*, std::true_type, compatibility_type_tag<v8::String>
+ , Args...args) ->
+ decltype(compatibility_string<>::New(args...))
+{
+ return compatibility_string<>::New(args...);
+}
+
+template <typename...Args>
+auto compatibility_new_impl(v8::Isolate*, std::false_type, compatibility_type_tag<v8::String>
+ , Args...args) ->
+ decltype(compatibility_string<>::New(args...))
+{
+ return compatibility_string<>::New(args...);
+}
+
+template <typename...Args>
+auto compatibility_new_impl(std::nullptr_t, std::true_type, compatibility_type_tag<v8::String>
+ , Args...args) ->
+ decltype(compatibility_string<>::New(args...))
+{
+ return compatibility_string<>::New(args...);
+}
+
+template <typename...Args>
+auto compatibility_new_impl(std::nullptr_t, std::false_type, compatibility_type_tag<v8::String>
+ , Args...args) ->
+ decltype(compatibility_string<>::New(args...))
+{
+ return compatibility_string<>::New(args...);
+}
+
+template <typename T, typename...Args>
+auto compatibility_new_impl(v8::Isolate* isolate, std::true_type, compatibility_type_tag<T>
+ , Args...args) ->
+ decltype(T::New(isolate, args...))
+{
+ return T::New(isolate, args...);
+}
+
+template <typename T, typename...Args>
+auto compatibility_new_impl(v8::Isolate*, std::false_type, compatibility_type_tag<T>
+ , Args...args) ->
+ decltype(T::New(args...))
+{
+ return T::New(args...);
+}
+
+template <typename T, typename...Args>
+auto compatibility_new_impl(std::nullptr_t, std::true_type, compatibility_type_tag<T>
+ , Args...args) ->
+ decltype(T::New(v8::Isolate::GetCurrent(), args...))
+{
+ return T::New(v8::Isolate::GetCurrent(), args...);
+}
+
+template <typename T, typename...Args>
+auto compatibility_new_impl(std::nullptr_t, std::false_type, compatibility_type_tag<T>
+ , Args...args) ->
+ decltype(T::New(args...))
+{
+ return T::New(args...);
+}
+
+template <typename T, typename...Args>
+auto compatibility_new(v8::Isolate* isolate, Args...args) ->
+ decltype(js::compatibility_new_impl<>
+ (isolate, std::integral_constant<bool, v8_uses_isolate>()
+ , compatibility_type_tag<T>()
+ , args...))
+{
+ return js::compatibility_new_impl(isolate, std::integral_constant<bool, v8_uses_isolate>()
+ , compatibility_type_tag<T>()
+ , args...);
+}
+
+template <typename T, typename...Args>
+auto compatibility_new(std::nullptr_t, Args...args) ->
+ decltype(js::compatibility_new_impl<>(nullptr, std::integral_constant<bool, v8_uses_isolate>()
+ , compatibility_type_tag<T>()
+ , args...))
+{
+ return js::compatibility_new_impl<>(nullptr, std::integral_constant<bool, v8_uses_isolate>()
+ , compatibility_type_tag<T>()
+ , args...);
+}
+
+#ifdef HAVE_V8_CREATE_PARAMS
+namespace detail {
+class array_buffer_allocator : public v8::ArrayBuffer::Allocator
+{
+ public:
+ virtual void* Allocate(std::size_t length)
+ {
+ void* data = AllocateUninitialized(length);
+ return data ? std::memset(data, 0, length) : data;
+ }
+ virtual void* AllocateUninitialized(std::size_t length) { return std::malloc(length); }
+ virtual void Free(void* data, std::size_t) { std::free(data); }
+};
+}
+
+inline v8::Isolate* compatibility_isolate_new()
+{
+ static detail::array_buffer_allocator allocator;
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = &allocator;
+ return v8::Isolate::New(create_params);
+}
+
+#else
+
+inline v8::Isolate* compatibility_isolate_new()
+{
+ return v8::Isolate::New();
+}
+
+#endif
+
+template <typename T, typename U>
+inline void compatibility_return_impl(T object, U const& info, std::true_type)
+{
+ info.GetReturnValue().Set(object);
+}
+
+template <typename T>
+inline v8::Handle<v8::Value>
+compatibility_return_impl(T object, compatibility_callback_info_type, std::false_type)
+{
+ return object;
+}
+
+template <typename T>
+inline v8::Handle<v8::Value>
+compatibility_return_impl(T object, compatibility_accessor_getter_callback_info_type, std::false_type)
+{
+ return object;
+}
+
+template <typename T>
+compatibility_return_type
+compatibility_return(T object, compatibility_callback_info_type args)
+{
+ return compatibility_return_impl(object, args, std::integral_constant<bool, v8_uses_callback_info>());
+}
+
+template <typename T>
+compatibility_return_type
+compatibility_return(T object, compatibility_accessor_getter_callback_info_type args)
+{
+ return compatibility_return_impl(object, args, std::integral_constant<bool, v8_uses_property_callback_info>());
+}
+
+inline void compatibility_return_nil_impl(std::true_type) {}
+
+inline v8::Handle<v8::Value>
+compatibility_return_nil_impl(std::false_type)
+{
+ return v8::Handle<v8::Value>();
+}
+
+inline
+compatibility_return_type
+compatibility_return()
+{
+ return compatibility_return_nil_impl(std::integral_constant<bool, v8_uses_callback_info>());
+}
+
+struct _v8_isolate_throw_exception : v8::Isolate
+{
+ v8::Handle<v8::Value> ThrowException_impl(v8::Handle<v8::Value> v)
+ {
+ using namespace v8;
+ return ThrowException(v);
+ }
+};
+
+inline void
+compatibility_throw_impl(v8::Isolate* isolate, v8::Local<v8::Value> exception, std::true_type)
+{
+ static_cast<_v8_isolate_throw_exception*>(isolate)->ThrowException_impl(exception);
+}
+
+inline v8::Handle<v8::Value>
+compatibility_throw_impl(v8::Isolate* isolate, v8::Local<v8::Value> exception, std::false_type)
+{
+ return static_cast<_v8_isolate_throw_exception*>(isolate)->ThrowException_impl(exception);
+}
+
+inline std::conditional<v8_uses_isolate, void, v8::Handle<v8::Value> >::type
+compatibility_throw(v8::Isolate* isolate, v8::Local<v8::Value> exception)
+{
+ return compatibility_throw_impl(isolate, exception, std::integral_constant<bool, v8_uses_isolate>());
+}
+
+inline void
+compatibility_throw_impl(v8::Local<v8::Value> exception, std::true_type)
+{
+ static_cast<_v8_isolate_throw_exception*>(v8::Isolate::GetCurrent())->ThrowException_impl(exception);
+}
+
+inline v8::Handle<v8::Value>
+compatibility_throw_impl(v8::Local<v8::Value> exception, std::false_type)
+{
+ return static_cast<_v8_isolate_throw_exception*>(v8::Isolate::GetCurrent())->ThrowException_impl(exception);
+}
+
+inline std::conditional<v8_uses_isolate, void, v8::Handle<v8::Value> >::type
+compatibility_throw(v8::Local<v8::Value> exception)
+{
+ return compatibility_throw_impl(exception, std::integral_constant<bool, v8_uses_isolate>());
+}
+
+template <typename T, typename U>
+v8::Local<T> compatibility_cast(v8::Local<U> v);
+template <typename T, typename U>
+v8::Local<T> compatibility_cast(U* v);
+
+template <typename Tag>
+struct hack_private_member {
+ /* export it ... */
+ typedef typename Tag::type type;
+ static type ptr;
+};
+
+template <typename Tag>
+typename hack_private_member<Tag>::type hack_private_member<Tag>::ptr;
+
+template <typename Tag, typename Tag::type p>
+struct rob_private_member : hack_private_member<Tag> {
+ /* fill it ... */
+ struct filler {
+ filler() { hack_private_member<Tag>::ptr = p; }
+ };
+ static filler filler_obj;
+};
+
+template<typename Tag, typename Tag::type p>
+typename rob_private_member<Tag, p>::filler rob_private_member<Tag, p>::filler_obj;
+
+template <typename T>
+struct persistent_base_new { typedef T*(*type)(v8::Isolate*, T*); };
+
+template class rob_private_member<persistent_base_new<v8::Value>, &v8::PersistentBase<v8::Value>::New>;
+
+template <typename T>
+v8::Local<T> make_persistent(v8::Isolate* isolate, v8::Handle<T> v)
+{
+ v8::Value* p = hack_private_member<persistent_base_new<v8::Value>>::ptr
+ (isolate, *compatibility_cast<v8::Value>(v));
+ return compatibility_cast<T>(compatibility_cast<v8::Value>(p));
+}
+
+template <typename T, typename F>
+v8::Local<T> make_weak(v8::Isolate* isolate, v8::Handle<T> v, F&& f)
+{
+ v8::Value* p = hack_private_member<persistent_base_new<v8::Value>>::ptr
+ (isolate, *compatibility_cast<v8::Value>(v));
+ v8::PersistentBase<v8::Value>* persistent = static_cast<v8::PersistentBase<v8::Value>*>
+ (static_cast<void*>(&p));
+
+ auto callback = [](const v8::WeakCallbackInfo<typename std::remove_reference<F>::type>& data) -> void
+ {
+ typename std::remove_reference<F>::type* f = data.GetParameter();
+ (*f)();
+ delete f;
+ };
+
+ persistent->SetWeak(new typename std::remove_reference<F>::type(std::forward<F>(f)),
+ callback, v8::WeakCallbackType::kParameter);
+ return compatibility_cast<T>(compatibility_cast<v8::Value>(p));
+}
+
+template <typename T>
+struct global_ref
+{
+ global_ref() {}
+ global_ref(v8::Local<T> v)
+ : _value(make_persistent(nullptr, v))
+ {
+ }
+ global_ref(v8::Isolate* isolate, v8::Local<T> v)
+ : _value(make_persistent(isolate, v))
+ {
+ }
+
+ void dispose() const
+ {
+ v8::PersistentBase<T>* p = static_cast<v8::PersistentBase<T>*>(static_cast<void*>(&_value));
+ p->Reset();
+ }
+
+ v8::Handle<T> handle() const { return _value; }
+private:
+ mutable v8::Local<T> _value;
+};
+
+template <typename T = std::integral_constant<bool, v8_uses_isolate> >
+struct _v8_object_internal_field;
+
+template <>
+struct _v8_object_internal_field<std::true_type> : v8::Object
+{
+};
+
+inline void* GetPointerFromInternalField(int) { return nullptr; }
+inline void SetPointerInInternalField(int, void*) {}
+
+template <>
+struct _v8_object_internal_field<std::false_type> : v8::Object
+{
+ void* GetAlignedPointerFromInternalField(int index)
+ {
+ return GetPointerFromInternalField(index);
+ }
+ void SetAlignedPointerInInternalField(int index, void* p)
+ {
+ SetPointerInInternalField(index, p);
+ }
+};
+
+template <typename T = void*>
+inline T compatibility_get_pointer_internal_field(v8::Handle<v8::Object> object, std::size_t index)
+{
+ return reinterpret_cast<T>
+ (static_cast<_v8_object_internal_field<>*>(*object)->GetAlignedPointerFromInternalField(index));
+}
+
+template <typename T>
+inline void compatibility_set_pointer_internal_field(v8::Handle<v8::Object> object, std::size_t index
+ , T* pointer)
+{
+ static_cast<_v8_object_internal_field<>*>(*object)->SetAlignedPointerInInternalField(index, pointer);
+}
+
+template <typename T = void, bool = v8_uses_isolate>
+struct compatibility_handle_scope_impl;
+
+template <typename T>
+struct compatibility_handle_scope_impl<T, true> : v8::HandleScope
+{
+ compatibility_handle_scope_impl()
+ : HandleScope(v8::Isolate::GetCurrent())
+ {}
+ compatibility_handle_scope_impl(v8::Isolate* isolate)
+ : HandleScope((assert(isolate != nullptr), isolate))
+ {}
+};
+
+template <typename T>
+struct compatibility_handle_scope_impl<T, false> : v8::HandleScope
+{
+ compatibility_handle_scope_impl()
+ {}
+ compatibility_handle_scope_impl(v8::Isolate*)
+ {}
+};
+
+using compatibility_handle_scope = compatibility_handle_scope_impl<>;
+
+template <bool = v8_uses_isolate>
+struct _v8_initialize_icu;
+
+template <>
+struct _v8_initialize_icu<true> : v8::V8
+{
+};
+
+template <>
+struct _v8_initialize_icu<false> : v8::V8
+{
+ static bool InitializeICU(const char* = NULL)
+ {
+ return true;
+ }
+};
+
+inline void compatibility_initialize()
+{
+#ifdef HAVE_V8_CREATE_PARAMS
+ constexpr const char* argv[] = {""};
+ static_cast<_v8_initialize_icu<>*>(nullptr)->InitializeICU();
+ v8::V8::InitializeExternalStartupData(argv[0]);
+ v8::V8::Initialize();
+#else
+ v8::V8::Initialize();
+ static_cast<_v8_initialize_icu<>*>(nullptr)->InitializeICU();
+#endif
+}
+
+template <typename T, typename U>
+v8::Local<T> compatibility_cast(v8::Local<U> v)
+{
+ static_assert(sizeof(v8::Local<T>) == sizeof(v8::Local<U>), "");
+ v8::Local<T> l;
+ std::memcpy(&l, &v, sizeof(v8::Local<T>));
+ return l;
+}
+
+template <typename T, typename U>
+v8::Local<T> compatibility_cast(U* v)
+{
+ static_assert(sizeof(v8::Local<T>) == sizeof(U*), "");
+ v8::Local<T> l;
+ std::memcpy(&l, &v, sizeof(v8::Local<T>));
+ return l;
+}
+
+template <typename T = v8::Isolate, bool = v8_uses_isolate>
+struct _v8_get_current_context;
+
+template <typename T>
+struct _v8_get_current_context<T, false> : v8::Context
+{
+};
+
+template <typename T>
+struct _v8_get_current_context<T, true> : T
+{
+ static v8::Local<v8::Context> GetCurrent()
+ {
+ return T::GetCurrent()->GetCurrentContext();
+ }
+};
+
+template <typename T>
+inline v8::Local<v8::Value>
+new_v8_external_instance(v8::Handle<v8::Function>& ctor, T v, v8::Isolate* isolate)
+{
+ // TODO: ensure v8::External ownership ??? (memory leak in case NewInstance throws)
+ v8::Handle<v8::Value> a[] = {efl::eina::js::compatibility_new<v8::External>(isolate, v)};
+ return ctor->NewInstance(1, a);
+}
+
+inline
+compatibility_return_type cast_function(compatibility_callback_info_type args);
+
+inline v8::Local<v8::Value>
+new_v8_external_instance(v8::Handle<v8::Function>& ctor, Eo* v, v8::Isolate* isolate)
+{
+ // TODO: ensure v8::External ownership ??? (memory leak in case NewInstance throws)
+ v8::Handle<v8::Value> a[] = {efl::eina::js::compatibility_new<v8::External>(isolate, v)};
+ auto obj = ctor->NewInstance(1, a);
+ obj->Set(compatibility_new<v8::String>(isolate, "cast"),
+ compatibility_new<v8::FunctionTemplate>(isolate, &cast_function)->GetFunction());
+ return obj;
+}
+
+inline v8::Local<v8::Object> compatibility_global()
+{
+ return _v8_get_current_context<>::GetCurrent()->Global();
+}
+
+EAPI extern std::map<std::string, v8::Local<v8::Function>> constructors_map_;
+
+inline v8::Handle<v8::Function> get_class_constructor(std::string const& class_name)
+{
+ auto it = constructors_map_.find(class_name);
+ if (it == constructors_map_.end())
+ throw std::runtime_error("Class not found");
+ return it->second;
+}
+
+inline void register_class_constructor(std::string const& class_name,
+ v8::Handle<v8::Function> constructor_ptr)
+{
+ // TODO: check if already exist?
+ constructors_map_[class_name] = constructor_ptr;
+}
+
+template<class T = v8::StackTrace>
+typename std::enable_if<!v8_uses_isolate, v8::Local<T>>::type
+compatibility_current_stack_trace(v8::Isolate*, int frame_limit,
+ v8::StackTrace::StackTraceOptions options)
+{
+ return T::CurrentStackTrace(frame_limit, options);
+}
+
+template<class T = v8::StackTrace>
+typename std::enable_if<v8_uses_isolate, v8::Local<T>>::type
+compatibility_current_stack_trace(v8::Isolate *isolate, int frame_limit,
+ v8::StackTrace::StackTraceOptions options)
+{
+ return T::CurrentStackTrace(isolate, frame_limit, options);
+}
+
+inline
+compatibility_return_type cast_function(compatibility_callback_info_type args)
+{
+ auto isolate = args.GetIsolate();
+ compatibility_handle_scope scope(isolate);
+ v8::Local<v8::Value> type;
+ if(args.Length() == 1 && (type = args[0])->IsString())
+ {
+ v8::Local<v8::Object> self = args.This();
+ v8::Local<v8::Value> external = self->GetInternalField(0);
+ Eo* eo = static_cast<Eo*>(v8::External::Cast(*external)->Value());
+
+ v8::String::Utf8Value str(type->ToString());
+ char* class_name = *str;
+
+ auto ctor = ::efl::eina::js::get_class_constructor(class_name);
+ return compatibility_return
+ (new_v8_external_instance(ctor, ::eo_ref(eo), isolate), args);
+ }
+ else
+ {
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected String type")));
+ return compatibility_return();
+ }
+}
+
+} } }
+
+#endif
diff --git a/src/bindings/eina_js/eina_js_container.cc b/src/bindings/eina_js/eina_js_container.cc
new file mode 100644
index 0000000000..60c53e0e74
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_container.cc
@@ -0,0 +1,495 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Eina.hh>
+#include <Eina.h>
+#include <cstdlib>
+
+#include <Eo.h>
+
+#include <eina_integer_sequence.hh>
+#include <eina_tuple.hh>
+#include <eina_ptrlist.hh>
+
+#include <Eina_Js.hh>
+
+#include <tuple>
+
+#include <iostream>
+
+namespace efl { namespace eina { namespace js {
+
+template <typename T>
+struct tag { typedef T type; };
+
+namespace {
+
+global_ref<v8::ObjectTemplate> instance_persistents[container_type_size];
+global_ref<v8::Function> instance_templates[container_type_size];
+
+v8::Local<v8::Value> push(eina_container_base& self, v8::Isolate* isolate, v8::Local<v8::Value> value)
+{
+ return v8::Integer::New(isolate, self.push(isolate, value));
+}
+
+v8::Local<v8::Value> pop(eina_container_base& self, v8::Isolate* isolate, v8::Local<v8::Value>)
+{
+ return self.pop(isolate);
+}
+
+v8::Local<v8::Value> concat(eina_container_base& lhs, v8::Isolate* isolate, v8::Local<v8::Value> other)
+{
+ const char* error_message = 0;
+ if(other->IsObject())
+ {
+ v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(other);
+ v8::String::Utf8Value constructor_name (obj->GetConstructorName());
+ if(obj->GetConstructorName()->Equals(efl::eina::js::compatibility_new<v8::String>(isolate, "eina_list"))
+ || obj->GetConstructorName()->Equals(efl::eina::js::compatibility_new<v8::String>(isolate, "eina_array")))
+ {
+ eina_container_base& rhs = *static_cast<eina_container_base*>
+ (efl::eina::js::compatibility_get_pointer_internal_field(obj, 0));
+ std::type_info const& typeinfo_lhs = typeid(lhs)
+ , &typeinfo_rhs = typeid(rhs);
+ if(!typeinfo_lhs.before(typeinfo_rhs) && !typeinfo_rhs.before(typeinfo_lhs))
+ {
+ v8::Handle<v8::Value> a[] =
+ {efl::eina::js::compatibility_new<v8::External>(isolate, rhs.concat(lhs))};
+ assert(!!*instance_templates[lhs.get_container_type()].handle());
+ v8::Local<v8::Object> result =
+ instance_templates[lhs.get_container_type()].handle()->NewInstance(1, a);
+ return result;
+ }
+ else
+ error_message = "Containers are not of the same type.";
+ }
+ else
+ error_message = "Object to be concatenated is not a container.";
+ }
+ else
+ error_message = "Concatenation argument is not an container";
+
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError(eina::js::compatibility_new<v8::String>(isolate, error_message)));
+
+ return v8::Undefined(isolate);
+}
+
+v8::Local<v8::Value> slice(eina_container_base& self, v8::Isolate* isolate, v8::Local<v8::Value> begin
+ , v8::Local<v8::Value> end)
+{
+ std::size_t i, j;
+
+ if(begin->IsUint32() || begin->IsInt32())
+ i = begin->IntegerValue();
+ else if (begin->IsUndefined())
+ i = 0;
+ else
+ return v8::Undefined(isolate);
+
+ if(end->IsUint32() || end->IsInt32())
+ j = end->IntegerValue();
+ else if (end->IsUndefined())
+ j = self.size();
+ else
+ return v8::Undefined(isolate);
+
+ v8::Handle<v8::Value> a[] = {efl::eina::js::compatibility_new<v8::External>(isolate, self.slice(i, j))};
+ v8::Local<v8::Object> result = instance_templates[self.get_container_type()].handle()
+ ->NewInstance(1, a);
+ return result;
+}
+
+compatibility_accessor_getter_return_type length
+ (v8::Local<v8::String>, compatibility_accessor_getter_callback_info_type info)
+{
+ v8::Local<v8::Object> self_obj = compatibility_cast<v8::Object>(info.This());
+ eina_container_base* self = static_cast<eina_container_base*>
+ (compatibility_get_pointer_internal_field(self_obj, 0));
+ return compatibility_return(js::get_value_from_c(self->size(), info.GetIsolate(), ""), info);
+}
+
+compatibility_indexed_property_getset_return_type index_get
+ (uint32_t index, compatibility_indexed_property_callback_info_type info)
+{
+ v8::Local<v8::Object> self_obj = v8::Local<v8::Object>::Cast(info.This());
+ eina_container_base* self = static_cast<eina_container_base*>
+ (compatibility_get_pointer_internal_field(self_obj, 0));
+ return compatibility_return(self->get(info.GetIsolate(), index), info);
+}
+
+compatibility_indexed_property_getset_return_type index_set
+ (uint32_t index, v8::Local<v8::Value> value, compatibility_indexed_property_callback_info_type info)
+{
+ v8::Local<v8::Object> self_obj = v8::Local<v8::Object>::Cast(info.This());
+ eina_container_base* self = static_cast<eina_container_base*>
+ (compatibility_get_pointer_internal_field(self_obj, 0));
+
+ return compatibility_return(self->set(info.GetIsolate(), index, value), info);
+}
+
+
+#define GENERATE_CONTAINER_CONSTRUCT_TYPE_IF(x) GENERATE_CONTAINER_CONSTRUCT_TYPE2_IF(x, x)
+#define GENERATE_CONTAINER_CONSTRUCT_TYPE2_IF(x, y) if (!strcmp(class_name, #x)) \
+ return new Container<y, nonclass_cls_name_getter, typename container_wrapper<y>::type>();
+
+template< template<typename, typename, typename> class Container>
+eina_container_base* construct_container(const char* class_name)
+{
+ GENERATE_CONTAINER_CONSTRUCT_TYPE_IF(int);
+ GENERATE_CONTAINER_CONSTRUCT_TYPE_IF(float);
+ GENERATE_CONTAINER_CONSTRUCT_TYPE2_IF(bool, Eina_Bool);
+ GENERATE_CONTAINER_CONSTRUCT_TYPE2_IF(string, char*);
+
+ return 0;
+}
+
+compatibility_return_type new_eina_list_internal(compatibility_callback_info_type args)
+{
+ if(args.IsConstructCall())
+ {
+ if(args.Length() == 0)
+ {
+ eina_container_base* p = new eina_list<int>;
+ compatibility_set_pointer_internal_field
+ (args.This(), 0, dynamic_cast<void*>(p));
+ }
+ else
+ {
+ if(args[0]->IsExternal())
+ {
+ eina_container_base* base = reinterpret_cast<eina_container_base*>
+ (v8::External::Cast(*args[0])->Value());
+ compatibility_set_pointer_internal_field
+ (args.This(), 0, dynamic_cast<void*>(base));
+ }
+ else
+ std::abort();
+ }
+ }
+ else
+ std::abort();
+ return compatibility_return();
+}
+
+compatibility_return_type new_eina_list(compatibility_callback_info_type args)
+{
+ if(args.IsConstructCall())
+ {
+ if(args.Length() == 0) // Default constructor, list of ints. Or should be list of Eo's?
+ {
+ eina_container_base* p = new eina_list<int>;
+ compatibility_set_pointer_internal_field
+ (args.This(), 0, dynamic_cast<void*>(p));
+ return compatibility_return();
+ }
+ else if (args.Length() == 1 && args[0]->IsString())
+ {
+ v8::String::Utf8Value string(args[0]);
+ eina_container_base* p = construct_container<efl::eina::js::eina_list>(*string);
+ if (!p) {
+ return eina::js::compatibility_throw
+ (args.GetIsolate(), v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Invalid type for container.")));
+ }
+ compatibility_set_pointer_internal_field
+ (args.This(), 0, dynamic_cast<void*>(p));
+ return compatibility_return();
+ }
+ }
+ return eina::js::compatibility_throw
+ (args.GetIsolate(), v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Wrong number of arguments for constructor call")));
+}
+
+compatibility_return_type new_eina_array_internal(compatibility_callback_info_type args)
+{
+ if(args.IsConstructCall())
+ {
+ if(args.Length() == 0)
+ {
+ eina_container_base* p = new eina_array<int>;
+ compatibility_set_pointer_internal_field
+ (args.This(), 0, dynamic_cast<void*>(p));
+ }
+ else
+ {
+ if(args[0]->IsExternal())
+ {
+ eina_container_base* base = reinterpret_cast<eina_container_base*>
+ (v8::External::Cast(*args[0])->Value());
+ compatibility_set_pointer_internal_field
+ (args.This(), 0, dynamic_cast<void*>(base));
+ }
+ else
+ std::abort();
+ }
+ }
+ else
+ std::abort();
+ return compatibility_return();
+}
+
+compatibility_return_type new_eina_array(compatibility_callback_info_type args)
+{
+ if(args.IsConstructCall())
+ {
+ if(args.Length() == 0)
+ {
+ eina_container_base* p = new eina_array<int>;
+ compatibility_set_pointer_internal_field
+ (args.This(), 0, dynamic_cast<void*>(p));
+ return compatibility_return();
+ }
+ else if (args.Length() == 1 && args[0]->IsString())
+ {
+ v8::String::Utf8Value string(args[0]);
+ eina_container_base* p = construct_container<efl::eina::js::eina_array>(*string);
+ if (!p) {
+ return eina::js::compatibility_throw
+ (args.GetIsolate(), v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Invalid type for container.")));
+ }
+ compatibility_set_pointer_internal_field
+ (args.This(), 0, dynamic_cast<void*>(p));
+ return compatibility_return();
+ }
+ }
+ return eina::js::compatibility_throw
+ (args.GetIsolate(), v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Wrong number of arguments for constructor call")));
+}
+
+template <typename F>
+struct function_params;
+
+template <typename R, typename... Sig>
+struct function_params<R(*)(Sig...)>
+{
+ typedef std::tuple<Sig...> type;
+};
+
+template <typename F>
+struct function_result;
+
+template <typename R, typename... Sig>
+struct function_result<R(*)(Sig...)>
+{
+ typedef R type;
+};
+
+template <typename T>
+struct is_persistent : std::false_type {};
+
+template <typename...A>
+struct is_persistent<v8::Persistent<A...> > : std::true_type {};
+
+template <std::size_t I, typename Sig>
+typename std::tuple_element<I, Sig>::type
+get_element(v8::Isolate* isolate
+ , compatibility_callback_info_type args
+ , typename std::enable_if
+ <is_persistent<typename std::tuple_element<I, Sig>::type>::value>::type* = 0)
+{
+ return typename std::tuple_element<I, Sig>::type(isolate, args[I]);
+}
+
+template <std::size_t I, typename Sig>
+typename std::tuple_element<I, Sig>::type
+get_element(v8::Isolate* /*isolate*/
+ , compatibility_callback_info_type args
+ , typename std::enable_if
+ <!is_persistent<typename std::tuple_element<I, Sig>::type>::value>::type* = 0)
+{
+ return args[I];
+}
+
+template <typename Sig, typename R, typename T, typename F, std::size_t... N>
+R call_impl(v8::Isolate* isolate
+ , compatibility_callback_info_type args
+ , T* self, F* f
+ , eina::index_sequence<N...>)
+{
+ assert(self != 0);
+ return (*f)(*self, isolate, js::get_element<N, Sig>(isolate, args)...);
+}
+
+template <typename Sig, typename T, typename F, typename R>
+compatibility_return_type call_generic_impl(compatibility_callback_info_type args, tag<R>)
+{
+ T* self = static_cast<T*>
+ (compatibility_get_pointer_internal_field<>(args.This(), 0));
+ F* f = reinterpret_cast<F*>(v8::External::Cast(*args.Data())->Value());
+ return compatibility_return
+ (js::get_value_from_c
+ (js::call_impl<Sig, R>(args.GetIsolate(), args, self, f
+ , eina::make_index_sequence<std::tuple_size<Sig>::value>())
+ , args.GetIsolate(), "")
+ , args);
+}
+
+template <typename Sig, typename T, typename F>
+compatibility_return_type call_generic_impl(compatibility_callback_info_type args, tag<void>)
+{
+ T* self = static_cast<T*>
+ (compatibility_get_pointer_internal_field(args.This(), 0));
+ F* f = reinterpret_cast<F*>(v8::External::Cast(*args.Data())->Value());
+ js::call_impl<Sig, void>(args.GetIsolate(), args, self, f
+ , eina::make_index_sequence<std::tuple_size<Sig>::value>());
+ return compatibility_return();
+}
+
+template <typename Sig, typename R, typename T, typename F>
+compatibility_return_type call_generic(compatibility_callback_info_type args)
+{
+ return efl::eina::js::call_generic_impl<Sig, T, F>(args, tag<R>());
+}
+
+template <typename Sig, typename T, typename F, typename R>
+compatibility_return_type call_function_impl(compatibility_callback_info_type args, tag<R>)
+{
+ T* self = static_cast<T*>
+ (compatibility_get_pointer_internal_field(args.This(), 0));
+ F f = reinterpret_cast<F>(v8::External::Cast(*args.Data())->Value());
+ return compatibility_return
+ (/*js::get_value_from_c*/
+ (js::call_impl<Sig, R>(args.GetIsolate(), args, self, f
+ , eina::make_index_sequence<std::tuple_size<Sig>::value>())
+ /*, args.GetIsolate(), ""*/)
+ , args);
+}
+
+template <typename Sig, typename T, typename F>
+compatibility_return_type call_function_impl(compatibility_callback_info_type args, tag<void>)
+{
+ T* self = static_cast<T*>
+ (compatibility_get_pointer_internal_field(args.This(), 0));
+ F f = reinterpret_cast<F>(v8::External::Cast(*args.Data())->Value());
+ js::call_impl<Sig, void>(args.GetIsolate(), args, self, f
+ , eina::make_index_sequence<std::tuple_size<Sig>::value>());
+ return compatibility_return();
+}
+
+template <typename Sig, typename R, typename T, typename F>
+compatibility_return_type call_function(compatibility_callback_info_type args)
+{
+ return efl::eina::js::call_function_impl<Sig, T, F>(args, tag<R>());
+}
+
+template <typename T, typename F>
+void register_(v8::Isolate* isolate, const char* name, F f, v8::Handle<v8::ObjectTemplate> template_
+ , typename std::enable_if<std::is_function<typename std::remove_pointer<F>::type>::value>::type* = 0)
+{
+ template_->Set(compatibility_new<v8::String>(isolate, name)
+ , compatibility_new<v8::FunctionTemplate>
+ (isolate, &efl::eina::js::call_function
+ <typename eina::_mpl::pop_front<typename function_params<F>::type, 2u>::type
+ , typename function_result<F>::type, T, F>
+ , compatibility_new<v8::External>
+ (isolate, reinterpret_cast<void*>(f))));
+}
+
+template <typename T, typename...Sig, typename F>
+void register_(v8::Isolate* isolate, const char* name, F&& f, v8::Handle<v8::ObjectTemplate> template_
+ , typename std::enable_if<!std::is_function<typename std::remove_pointer<F>::type>::value>::type* = 0)
+{
+ using result_type = decltype
+ (std::declval<F>()
+ (std::declval<T&>(), std::declval<v8::Isolate*>()
+ , std::declval<Sig>()...)
+ );
+ template_->Set(compatibility_new<v8::String>(isolate, name)
+ , compatibility_new<v8::FunctionTemplate>
+ (isolate
+ , &efl::eina::js::call_generic<std::tuple<Sig...>, result_type, T, F>
+ , compatibility_new<v8::External>
+ (isolate, new F(std::forward<F>(f)))));
+}
+
+v8::Local<v8::ObjectTemplate> register_template(v8::Isolate* isolate, v8::Handle<v8::FunctionTemplate> constructor)
+{
+ v8::Local<v8::ObjectTemplate> instance_t = constructor->InstanceTemplate();
+ instance_t->SetInternalFieldCount(1);
+
+ instance_t->SetIndexedPropertyHandler(& efl::eina::js::index_get, & efl::eina::js::index_set);
+
+ v8::Local<v8::ObjectTemplate> prototype = constructor->PrototypeTemplate();
+ prototype->SetAccessor(compatibility_new<v8::String>(isolate, "length"), &efl::eina::js::length);
+
+ using namespace std::placeholders;
+ js::register_<js::eina_container_base>
+ (isolate, "push", &js::push, prototype);
+ js::register_<js::eina_container_base>
+ (isolate, "pop", &js::pop, prototype);
+ js::register_<js::eina_container_base>
+ (isolate, "concat", &js::concat, prototype);
+ js::register_<js::eina_container_base>
+ (isolate, "slice", &js::slice, prototype);
+ js::register_<js::eina_container_base>
+ (isolate, "toString", std::bind(&js::eina_container_base::to_string, _1, _2), prototype);
+ js::register_<js::eina_container_base, v8::Local<v8::Value> >
+ (isolate, "join", std::bind(&js::eina_container_base::join, _1, _2, _3), prototype);
+ js::register_<js::eina_container_base, v8::Local<v8::Value> >
+ (isolate, "indexOf", std::bind(&js::eina_container_base::index_of, _1, _2, _3), prototype);
+ js::register_<js::eina_container_base, v8::Local<v8::Value> >
+ (isolate, "lastIndexOf", std::bind(&js::eina_container_base::last_index_of, _1, _2, _3), prototype);
+
+ return instance_t;
+}
+
+void register_class(v8::Isolate* isolate, container_type type, const char* class_name
+ , compatibility_function_callback callback)
+{
+ v8::Handle<v8::FunctionTemplate> constructor
+ = compatibility_new<v8::FunctionTemplate>(isolate, callback);
+ constructor->SetClassName(compatibility_new<v8::String>(isolate, class_name));
+
+ v8::Local<v8::ObjectTemplate> instance_t = efl::eina::js::register_template(isolate, constructor);
+
+ efl::eina::js::instance_persistents[type] = global_ref<v8::ObjectTemplate>{isolate, instance_t};
+ efl::eina::js::instance_templates[type] = global_ref<v8::Function>{isolate, constructor->GetFunction()};
+}
+void register_class(v8::Isolate* isolate, container_type, const char* class_name_
+ , const char* constructor_name_
+ , compatibility_function_callback callback
+ , v8::Handle<v8::Object> exports)
+{
+ v8::Handle<v8::FunctionTemplate> constructor
+ = compatibility_new<v8::FunctionTemplate>(isolate, callback);
+ auto class_name = compatibility_new<v8::String>(isolate, class_name_);
+ auto constructor_name = compatibility_new<v8::String>(isolate, constructor_name_);
+ constructor->SetClassName(class_name);
+
+ v8::Local<v8::ObjectTemplate> instance_t = efl::eina::js::register_template(isolate, constructor);
+ (void)instance_t;
+
+ exports->Set(constructor_name, constructor->GetFunction());
+}
+
+}
+
+EAPI v8::Handle<v8::Function> get_list_instance_template()
+{
+ return efl::eina::js::instance_templates[efl::eina::js::list_container_type].handle();
+}
+
+EAPI v8::Handle<v8::Function> get_array_instance_template()
+{
+ return efl::eina::js::instance_templates[efl::eina::js::array_container_type].handle();
+}
+
+} } }
+
+EAPI void eina_container_register(v8::Handle<v8::Object> exports, v8::Isolate* isolate)
+{
+ efl::eina::js::register_class(isolate, efl::eina::js::list_container_type
+ , "eina_list", &efl::eina::js::new_eina_list_internal);
+ efl::eina::js::register_class(isolate, efl::eina::js::list_container_type
+ , "eina_list", "List", &efl::eina::js::new_eina_list, exports);
+ efl::eina::js::register_class(isolate, efl::eina::js::array_container_type
+ , "eina_array", &efl::eina::js::new_eina_array_internal);
+ efl::eina::js::register_class(isolate, efl::eina::js::array_container_type
+ , "eina_array", "Array", &efl::eina::js::new_eina_array, exports);
+}
+
diff --git a/src/bindings/eina_js/eina_js_container.hh b/src/bindings/eina_js/eina_js_container.hh
new file mode 100644
index 0000000000..21343fd6da
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_container.hh
@@ -0,0 +1,351 @@
+#ifndef EINA_JS_CONTAINER_HH
+#define EINA_JS_CONTAINER_HH
+
+#include <algorithm>
+
+#include <eina_js_compatibility.hh>
+#include <eina_js_get_value.hh>
+#include <eina_js_get_value_from_c.hh>
+
+struct _Elm_Calendar_Mark;
+struct Elm_Gen_Item;
+struct _Eina_Rectangle;
+struct _Evas_Textblock_Rectangle;
+struct _Elm_Map_Overlay;
+
+namespace efl { namespace eina { namespace js {
+
+namespace detail {
+
+template <typename T>
+eina_container_base* concat(T const& self, eina_container_base const& other)
+{
+ T const& rhs = static_cast<T const&>(other);
+ typedef typename T::container_type container_type;
+ container_type container(self._container.begin(), self._container.end());
+ container.insert(container.end(), rhs._container.begin(), rhs._container.end());
+ return new T(container.release_native_handle());
+}
+
+template <typename T>
+eina_container_base* slice(T const& self, std::int64_t i, std::int64_t j)
+{
+ typedef typename T::container_type container_type;
+ container_type container(std::next(self._container.begin(), i), std::next(self._container.begin(), j));
+ return new T(container.release_native_handle());
+}
+
+// T, W from the container instantiation
+template<typename T, typename W, typename C>
+int push(v8::Isolate* isolate, C& self, v8::Local<v8::Value> v)
+{
+ try
+ {
+ W value = container_wrap(get_value_from_javascript(v, isolate, "", value_tag<T>()));
+ self._container.push_back(value);
+ }
+ catch (std::logic_error const&)
+ {
+ return -1;
+ }
+ return self.size();
+}
+
+template<typename T, typename W, typename K, typename C>
+v8::Local<v8::Value> pop(v8::Isolate* isolate, C& self)
+{
+
+ if (self._container.empty())
+ return v8::Undefined(isolate);
+
+ auto value = eina::js::get_value_from_c(
+ eina::js::wrap_value<T>(eina::js::container_unwrap(self._container.back()), eina::js::value_tag<T>{})
+ , isolate
+ , K::class_name());
+ self._container.pop_back();
+ return value;
+}
+template<typename T, typename W, typename C>
+v8::Local<v8::Value> set(v8::Isolate* isolate, C& self, std::size_t index, v8::Local<v8::Value> v)
+ {
+ using notag_type = typename remove_tag<T>::type;
+ try
+ {
+ W value = container_wrap(get_value_from_javascript(v, isolate, "", value_tag<T>()));
+
+ if (index >= self.size())
+ {
+ std::size_t items_to_add = index - self.size() + 1;
+ for (int i = items_to_add; i; i--)
+ {
+ self._container.push_back(container_wrap(notag_type{}));
+ }
+ }
+
+ auto v2 = std::next(self._container.begin(), index);
+ *v2 = value;
+ }
+ catch (std::logic_error const&)
+ {
+ return v8::Undefined(isolate);
+ }
+
+ return v;
+ }
+
+}
+
+template <typename InputIterator, typename T>
+inline InputIterator find_element(InputIterator first, InputIterator last, T const& value, typename std::enable_if<is_handable_by_value<T>::value>::type* = 0)
+{
+ return std::find(first, last, value);
+}
+
+template <typename InputIterator, typename T>
+inline InputIterator find_element(InputIterator first, InputIterator last, T const& value, typename std::enable_if<!is_handable_by_value<T>::value>::type* = 0)
+{
+ return std::find_if(first, last, [&](T const& e){ return &e == &value; });
+}
+
+template <typename InputIterator>
+inline InputIterator find_element(InputIterator first, InputIterator last, char * value)
+{
+ return std::find_if(first, last, [=](char* e){ return strcmp(e, value) == 0; });
+}
+
+template <typename CharT, typename T>
+inline void stream_element(std::basic_ostream<CharT>& s, T const& value, typename std::enable_if<is_handable_by_value<T>::value>::type* = 0)
+{
+ s << value;
+}
+
+template <typename CharT, typename T>
+inline void stream_element(std::basic_ostream<CharT>& s, T const& value, typename std::enable_if<!is_handable_by_value<T>::value>::type* = 0)
+{
+ s << &value;
+}
+
+template <typename CharT>
+inline void stream_element(std::basic_ostream<CharT>& s, Eina_Bool value)
+{
+ s << (value ? "true" : "false");
+}
+
+template <typename C, typename T, typename K>
+struct eina_container_common;
+
+
+template <typename C, typename V, typename T, typename K, typename Enable = void>
+struct eina_container_type_specific
+ : eina_container_base
+{
+ v8::Local<v8::Value> get(v8::Isolate* isolate, std::size_t index) const
+ {
+ if(index >= this->size())
+ return v8::Undefined(isolate);
+ return eina::js::get_value_from_c(
+ eina::js::wrap_value<T>(eina::js::container_unwrap(*std::next(container_get().begin(), index)), eina::js::value_tag<T>{})
+ , isolate
+ , K::class_name());
+ }
+ int index_of(v8::Isolate* isolate, v8::Local<v8::Value> v) const
+ {
+ try
+ {
+ V value = container_wrap(get_value_from_javascript(
+ v, isolate, K::class_name(), eina::js::value_tag<T>{}, false));
+ typedef typename C::const_iterator iterator;
+ iterator first = container_get().cbegin()
+ , last = container_get().cend()
+ , found = find_element(first, last, value);
+ if(found == last)
+ return -1;
+ else
+ return std::distance(first, found);
+ }
+ catch (std::logic_error const&)
+ {
+ return -1;
+ }
+ }
+ int last_index_of(v8::Isolate* isolate, v8::Local<v8::Value> v) const
+ {
+ try
+ {
+ V value = container_wrap(get_value_from_javascript(
+ v, isolate, K::class_name(), eina::js::value_tag<T>{}, false));
+ auto last = container_get().crend()
+ , found = find_element(container_get().crbegin(), last, value);
+ if(found == last)
+ return -1;
+ else
+ return std::distance(container_get().cbegin(), found.base()) -1;
+ }
+ catch (std::logic_error const&)
+ {
+ return -1;
+ }
+ }
+ void* get_container_native_handle()
+ {
+ void const* h = container_get().native_handle();
+ return const_cast<void*>(h);
+ }
+ void const* get_container_native_handle() const
+ {
+ return container_get().native_handle();
+ }
+ C& container_get() { return static_cast<eina_container_common<C, T, K>&>(*this)._container; }
+ C const& container_get() const { return static_cast<eina_container_common<C, T, K>const&>(*this)._container; }
+};
+
+template <typename C, typename T, typename K>
+struct eina_container_common : eina_container_type_specific<C, typename C::value_type, T, K>
+{
+ eina_container_common() : _container() {}
+ eina_container_common(typename C::native_handle_type raw) : _container(raw) {}
+
+ std::size_t size() const { return _container.size(); }
+ v8::Local<v8::String> to_string(v8::Isolate* isolate) const
+ {
+ return join(isolate, compatibility_new<v8::String>(isolate, ","));
+ }
+
+ v8::Local<v8::String> join(v8::Isolate* isolate, v8::Local<v8::Value> separator_js) const
+ {
+ std::string separator = ",";
+ typedef typename container_type::const_iterator iterator;
+ std::stringstream s;
+
+ if (separator_js->IsString())
+ {
+ v8::String::Utf8Value str(separator_js);
+ if (*str)
+ {
+ separator = *str;
+ }
+ else
+ {
+ eina::js::compatibility_throw(
+ isolate, v8::Exception::TypeError(
+ eina::js::compatibility_new<v8::String>(isolate, "Invalid separator.")));
+ return compatibility_new<v8::String>(isolate, "");
+ }
+ }
+ else if (!separator_js->IsUndefined()) // Called join without arguments.
+ {
+ eina::js::compatibility_throw(
+ isolate, v8::Exception::TypeError(
+ eina::js::compatibility_new<v8::String>(isolate, "Separator must be a string.")));
+ return compatibility_new<v8::String>(isolate, "");
+ }
+
+ for(iterator first = _container.begin()
+ , last = _container.end()
+ , last_elem = std::next(last, -1); first != last; ++first)
+ {
+ stream_element(s, *first);
+ if(first != last_elem)
+ s << separator;
+ }
+ return compatibility_new<v8::String>(isolate, s.str().c_str());
+ }
+
+ // Default implementation of some methods
+ int push(v8::Isolate* isolate, v8::Local<v8::Value>)
+ {
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Push method was not implemented.")));
+ return -1;
+ }
+ v8::Local<v8::Value> pop(v8::Isolate* isolate)
+ {
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Pop method was not implemented.")));
+ return v8::Undefined(isolate);
+ }
+ v8::Local<v8::Value> set(v8::Isolate* isolate, std::size_t, v8::Local<v8::Value>)
+ {
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Indexed attribution was not implemented.")));
+ return v8::Undefined(isolate);
+ }
+ C _container;
+ typedef C container_type;
+};
+
+
+// Specialization for problematic types
+struct empty_container_base
+ : eina_container_base
+{
+ empty_container_base() {}
+ virtual ~empty_container_base() {}
+
+ std::size_t size() const
+ {
+ return 0;
+ }
+ eina_container_base* concat(eina_container_base const& ) const
+ {
+ return new empty_container_base;
+ }
+ eina_container_base* slice(std::int64_t , std::int64_t ) const
+ {
+ return new empty_container_base;
+ }
+ int index_of(v8::Isolate*, v8::Local<v8::Value>) const
+ {
+ return -1;
+ }
+ int last_index_of(v8::Isolate*, v8::Local<v8::Value>) const
+ {
+ return -1;
+ }
+ v8::Local<v8::Value> get(v8::Isolate* isolate, std::size_t) const
+ {
+ return v8::Undefined(isolate);
+ }
+ v8::Local<v8::Value> set(v8::Isolate* isolate, std::size_t, v8::Local<v8::Value>)
+ {
+ return v8::Undefined(isolate);
+ }
+ int push(v8::Isolate*, v8::Local<v8::Value>)
+ {
+ return -1;
+ }
+ v8::Local<v8::Value> pop(v8::Isolate* isolate)
+ {
+ return v8::Undefined(isolate);
+ }
+ v8::Local<v8::String> to_string(v8::Isolate* isolate) const
+ {
+ return compatibility_new<v8::String>(isolate, "");
+ }
+ v8::Local<v8::String> join(v8::Isolate* isolate, v8::Local<v8::Value>) const
+ {
+ return compatibility_new<v8::String>(isolate, "");
+ }
+ container_type get_container_type() const
+ {
+ throw std::runtime_error("get_container_type of container with unmanagable type");
+ return container_type_size;
+ }
+ void* get_container_native_handle()
+ {
+ return nullptr;
+ }
+ void const* get_container_native_handle() const
+ {
+ return nullptr;
+ }
+};
+
+} } }
+
+EAPI void eina_container_register(v8::Handle<v8::Object> exports, v8::Isolate* isolate);
+
+#endif
diff --git a/src/bindings/eina_js/eina_js_error.cc b/src/bindings/eina_js/eina_js_error.cc
new file mode 100644
index 0000000000..89d69a1895
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_error.cc
@@ -0,0 +1,24 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Eina_Js.hh>
+
+namespace efl { namespace eina {namespace js {
+
+EAPI
+js::compatibility_return_type convert_error_to_javascript_exception(v8::Isolate *isolate)
+{
+ Eina_Error err = eina_error_get();
+ if (!err)
+ return compatibility_return();
+
+ v8::Local<v8::Object> je = eina::js::compatibility_new<v8::Object>(isolate);
+ je->Set(compatibility_new<v8::String>(isolate, "code"),
+ compatibility_new<v8::String>(isolate, "Eina_Error"));
+ je->Set(compatibility_new<v8::String>(isolate, "value"),
+ compatibility_new<v8::String>(isolate, eina_error_msg_get(err)));
+ return compatibility_throw(isolate, je);
+}
+
+} } } // namespace efl { namespace js {
diff --git a/src/bindings/eina_js/eina_js_error.hh b/src/bindings/eina_js/eina_js_error.hh
new file mode 100644
index 0000000000..49cef35161
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_error.hh
@@ -0,0 +1,25 @@
+#ifndef EINA_JS_ERROR_HH
+#define EINA_JS_ERROR_HH
+
+#include <eina_js_compatibility.hh>
+
+namespace efl { namespace eina { namespace js {
+
+/**
+ * Converts the error value set through Eina's error tool to a JavaScript
+ * exception.
+ *
+ * The exception object will have a `code` string field with the `"Eina_Error"`
+ * string value and a `value` string field with the value extracted from
+ * `eina_error_msg_get`.
+ *
+ * It won't reset the error to NULL, so you can still access the error object,
+ * but if you keep calling this function without clearing the error, a new
+ * exception will be generated for each call after some error is reached. We,
+ * therefore, suggest you to call `eina_error_set(0)` afterwards.
+ */
+js::compatibility_return_type convert_error_to_javascript_exception(v8::Isolate *isolate);
+
+} } } // namespace efl::eina::js
+
+#endif /* EINA_JS_ERROR_HH */
diff --git a/src/bindings/eina_js/eina_js_get_value.hh b/src/bindings/eina_js/eina_js_get_value.hh
new file mode 100644
index 0000000000..637b48a9c8
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_get_value.hh
@@ -0,0 +1,449 @@
+#ifndef EFL_EINA_JS_GET_VALUE_HH
+#define EFL_EINA_JS_GET_VALUE_HH
+
+#include <eina_js_compatibility.hh>
+
+#include <type_traits>
+#include <cstdlib>
+#include <iostream>
+#include <typeinfo>
+
+namespace efl { namespace eina { namespace js {
+
+template <typename T>
+inline int get_value_from_javascript
+ (v8::Local<v8::Value> v
+ , v8::Isolate* isolate
+ , const char*
+ , value_tag<T>
+ , bool throw_js_exception = true
+ , typename std::enable_if<(std::is_integral<T>::value && !std::is_same<T, Eina_Bool>::value)>::type* = 0)
+{
+ if(v->IsInt32())
+ return v->Int32Value();
+ else if(v->IsUint32())
+ return v->Uint32Value();
+ else
+ {
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Integral type")));
+
+ throw std::logic_error("");
+ }
+ return 0;
+}
+
+inline char* get_value_from_javascript
+ (v8::Local<v8::Value> v
+ , v8::Isolate* isolate
+ , const char*
+ , value_tag<char*>
+ , bool throw_js_exception = true)
+{
+ if(v->IsNull())
+ return nullptr;
+ else if(v->IsString())
+ {
+ v8::String::Utf8Value str(v->ToString());
+ char* string = strdup(*str); // TODO: leaks
+ return string;
+ }
+ else
+ {
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected String type")));
+
+ throw std::logic_error("");
+ }
+ return 0;
+}
+
+inline const char* get_value_from_javascript
+ (v8::Local<v8::Value> v
+ , v8::Isolate* isolate
+ , const char* class_name
+ , value_tag<const char*>
+ , bool throw_js_exception = true)
+{
+ return get_value_from_javascript(v, isolate, class_name, value_tag<char*>(), throw_js_exception);
+}
+
+inline Eo* get_value_from_javascript
+ (v8::Local<v8::Value> v
+ , v8::Isolate* isolate
+ , const char*
+ , value_tag<Eo*>
+ , bool throw_js_exception = true)
+{
+ if(v->IsNull())
+ return nullptr;
+ else if(v->IsObject())
+ {
+ v8::Local<v8::Object> object = v->ToObject();
+ if(object->InternalFieldCount() == 1)
+ {
+ v8::Local<v8::Value> r = object->GetInternalField(0);
+ if(v8::External* external = v8::External::Cast(*r))
+ {
+ return static_cast<Eo*>(external->Value());
+ }
+ }
+ }
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Eolian object type")));
+ throw std::logic_error("");
+ return nullptr;
+}
+
+inline Eo* get_value_from_javascript
+ (v8::Local<v8::Value> v
+ , v8::Isolate* isolate
+ , const char* class_name
+ , value_tag<Eo* const>
+ , bool throw_js_exception = true)
+{
+ return get_value_from_javascript(v, isolate, class_name, value_tag<Eo*>(), throw_js_exception);
+}
+
+template <typename T>
+inline T get_value_from_javascript
+ (v8::Local<v8::Value> v
+ , v8::Isolate* isolate
+ , const char*
+ , value_tag<struct_ptr_tag<T>>
+ , bool throw_js_exception = true)
+{
+ if(v->IsNull())
+ return nullptr;
+ else if(v->IsObject())
+ {
+ v8::Local<v8::Object> object = v->ToObject();
+ if(object->InternalFieldCount() == 1)
+ {
+ return compatibility_get_pointer_internal_field<T>(object, 0);
+ }
+ }
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Eolian struct type")));
+ throw std::logic_error("");
+ return nullptr;
+}
+
+template <typename T>
+inline T get_value_from_javascript
+ (v8::Local<v8::Value> v
+ , v8::Isolate* isolate
+ , const char* class_name
+ , value_tag<struct_tag<T>>
+ , bool throw_js_exception = true)
+{
+ T* ptr = get_value_from_javascript(v, isolate, class_name, value_tag<struct_ptr_tag<T*>>(), throw_js_exception);
+ if (ptr)
+ return *ptr;
+
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Conversion of null pointer to by-value struct.")));
+ throw std::logic_error("");
+ return T{};
+}
+
+template <typename T>
+inline T get_value_from_javascript
+ (v8::Local<v8::Value> v
+ , v8::Isolate* isolate
+ , const char*
+ , value_tag<T>
+ , bool throw_js_exception = true
+ , typename std::enable_if<std::is_enum<T>::value>::type* = 0)
+{
+ if(v->IsInt32())
+ return static_cast<T>(v->Int32Value());
+ else if(v->IsUint32())
+ return static_cast<T>(v->Uint32Value());
+ else
+ {
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected enumeration type")));
+
+ throw std::logic_error("");
+ }
+ return T();
+}
+
+inline Eina_Bool get_value_from_javascript
+ (v8::Local<v8::Value> v
+ , v8::Isolate* isolate
+ , const char*
+ , value_tag<Eina_Bool>
+ , bool throw_js_exception = true)
+{
+ if(v->IsBoolean() || v->IsBooleanObject())
+ {
+ return v->BooleanValue() ? EINA_TRUE : EINA_FALSE;
+ }
+ else
+ {
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Boolean type")));
+
+ throw std::logic_error("");
+ }
+ return 0;
+}
+
+template <typename T>
+inline double get_value_from_javascript
+ (v8::Local<v8::Value> v
+ , v8::Isolate* isolate
+ , const char*
+ , value_tag<T>
+ , bool throw_js_exception = true
+ , typename std::enable_if<std::is_floating_point<T>::value>::type* = 0)
+{
+ if(v->IsNumber())
+ {
+ return v->NumberValue();
+ }
+ else
+ {
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected floating point type")));
+ throw std::logic_error("");
+ }
+ return 0.0;
+}
+
+template <typename T>
+inline T get_value_from_javascript
+ (v8::Local<v8::Value>, v8::Isolate* isolate, const char*, value_tag<T>
+ , bool throw_js_exception = true
+ , typename std::enable_if<
+ !std::is_floating_point<T>::value &&
+ !std::is_integral<T>::value &&
+ !std::is_enum<T>::value &&
+ !js::is_struct_tag<T>::value &&
+ !js::is_struct_ptr_tag<T>::value &&
+ !js::is_complex_tag<T>::value &&
+ !std::is_same<T, Eina_Accessor*>::value &&
+ !std::is_same<T, Eina_Array*>::value &&
+ !std::is_same<T, Eina_Iterator*>::value &&
+ !std::is_same<T, Eina_Hash*>::value &&
+ !std::is_same<T, Eina_List*>::value &&
+ !std::is_same<T, const Eina_Accessor*>::value &&
+ !std::is_same<T, const Eina_Array*>::value &&
+ !std::is_same<T, const Eina_Iterator*>::value &&
+ !std::is_same<T, const Eina_Hash*>::value &&
+ !std::is_same<T, const Eina_List*>::value
+ >::type* = 0)
+{
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Not implemented yet")));
+ throw std::logic_error("");
+}
+
+// TODO: Fix for const types
+template <typename T, typename K>
+inline Eina_Accessor* get_value_from_javascript(
+ v8::Local<v8::Value> v,
+ v8::Isolate* isolate,
+ const char*,
+ value_tag<complex_tag<Eina_Accessor *, T, K>>,
+ bool throw_js_exception = true)
+{
+ if(v->IsNull())
+ return nullptr;
+ else if(v->IsObject())
+ {
+ using wrapped_type = typename container_wrapper<T>::type;
+ v8::Local<v8::Object> object = v->ToObject();
+ auto& acc = import_accessor<wrapped_type>(object);
+ return acc.native_handle();
+ }
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Eolian accessor type")));
+ throw std::logic_error("");
+}
+
+template <typename...I>
+inline const Eina_Accessor* get_value_from_javascript(
+ v8::Local<v8::Value> v,
+ v8::Isolate* isolate,
+ const char* class_name,
+ value_tag<complex_tag<const Eina_Accessor *, I...>>,
+ bool throw_js_exception = true)
+{
+ return get_value_from_javascript(v, isolate, class_name, value_tag<complex_tag<Eina_Accessor *, I...>>{}, throw_js_exception);
+}
+
+template <typename...I>
+inline Eina_Array* get_value_from_javascript(
+ v8::Local<v8::Value> v,
+ v8::Isolate* isolate,
+ const char*,
+ value_tag<complex_tag<Eina_Array *, I...>>,
+ bool throw_js_exception = true)
+{
+ if(v->IsNull())
+ return nullptr;
+ else if(v->IsObject())
+ {
+ v8::Local<v8::Object> object = v->ToObject();
+ if(object->InternalFieldCount() == 1)
+ {
+ eina_container_base* cbase = compatibility_get_pointer_internal_field<eina_container_base*>(object, 0);
+ return static_cast<Eina_Array*>(cbase->get_container_native_handle());
+ }
+ }
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Eolian list type")));
+ throw std::logic_error("");
+ return nullptr;
+}
+
+template <typename...I>
+inline const Eina_Array* get_value_from_javascript(
+ v8::Local<v8::Value> v,
+ v8::Isolate* isolate,
+ const char* class_name,
+ value_tag<complex_tag<const Eina_Array *, I...>>,
+ bool throw_js_exception = true)
+{
+ return get_value_from_javascript(v, isolate, class_name, value_tag<complex_tag<Eina_Array *, I...>>{}, throw_js_exception);
+}
+
+template <typename...I>
+inline Eina_Iterator* get_value_from_javascript(
+ v8::Local<v8::Value>,
+ v8::Isolate* isolate,
+ const char*,
+ value_tag<complex_tag<Eina_Iterator *, I...>> tag,
+ bool throw_js_exception = true)
+{
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Not implemented yet")));
+ throw std::logic_error("");
+}
+
+template <typename...I>
+inline const Eina_Iterator* get_value_from_javascript(
+ v8::Local<v8::Value> v,
+ v8::Isolate* isolate,
+ const char* class_name,
+ value_tag<complex_tag<const Eina_Iterator *, I...>>,
+ bool throw_js_exception = true)
+{
+ return get_value_from_javascript(v, isolate, class_name, value_tag<complex_tag<Eina_Iterator *, I...>>{}, throw_js_exception);
+}
+
+template <typename T, typename...U>
+inline Eina_Hash* get_value_from_javascript(
+ v8::Local<v8::Value>,
+ v8::Isolate* isolate,
+ const char*,
+ value_tag<complex_tag<Eina_Hash *, T, U...>> tag,
+ bool throw_js_exception = true)
+{
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Not implemented yet")));
+ throw std::logic_error("");
+}
+
+template <typename T, typename...U>
+inline const Eina_Hash* get_value_from_javascript(
+ v8::Local<v8::Value> v,
+ v8::Isolate* isolate,
+ const char* class_name,
+ value_tag<complex_tag<const Eina_Hash *, T, U...>>,
+ bool throw_js_exception = true)
+{
+ return get_value_from_javascript(v, isolate, class_name, value_tag<complex_tag<Eina_Hash *, T, U...>>{}, throw_js_exception);
+}
+
+template <typename...I>
+inline Eina_List* get_value_from_javascript(
+ v8::Local<v8::Value> v,
+ v8::Isolate* isolate,
+ const char*,
+ value_tag<complex_tag<Eina_List *, I...>> /*tag*/,
+ bool throw_js_exception = true)
+{
+ if(v->IsNull())
+ return nullptr;
+ else if(v->IsObject())
+ {
+ v8::Local<v8::Object> object = v->ToObject();
+ if(object->InternalFieldCount() == 1)
+ {
+ eina_container_base* cbase = compatibility_get_pointer_internal_field<eina_container_base*>(object, 0);
+ return static_cast<Eina_List*>(cbase->get_container_native_handle());
+ }
+ }
+ if (throw_js_exception)
+ eina::js::compatibility_throw
+ (isolate, v8::Exception::TypeError
+ (eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Eolian list type")));
+ throw std::logic_error("");
+ return nullptr;
+}
+
+template <typename...I>
+inline const Eina_List* get_value_from_javascript(
+ v8::Local<v8::Value> v,
+ v8::Isolate* isolate,
+ const char* class_name,
+ value_tag<complex_tag<const Eina_List *, I...>>,
+ bool throw_js_exception = true)
+{
+ return get_value_from_javascript(v, isolate, class_name, value_tag<complex_tag<Eina_List *, I...>>{}, throw_js_exception);
+}
+
+inline const void* get_value_from_javascript
+ (v8::Local<v8::Value>,
+ v8::Isolate*,
+ const char*,
+ value_tag<const void *>)
+{
+ return nullptr;
+}
+
+
+typedef void (*Evas_Smart_Cb)(void*, _Eo_Opaque*, void*);
+
+inline Evas_Smart_Cb get_value_from_javascript (
+ v8::Local<v8::Value>,
+ v8::Isolate*,
+ const char*,
+ value_tag<Evas_Smart_Cb>)
+{
+ return nullptr;
+}
+
+} } }
+
+#endif
diff --git a/src/bindings/eina_js/eina_js_get_value_from_c.hh b/src/bindings/eina_js/eina_js_get_value_from_c.hh
new file mode 100644
index 0000000000..655b1b1974
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_get_value_from_c.hh
@@ -0,0 +1,261 @@
+#ifndef EFL_EINA_JS_GET_VALUE_FROM_C_HH
+#define EFL_EINA_JS_GET_VALUE_FROM_C_HH
+
+#include <eina_js_compatibility.hh>
+
+#include <type_traits>
+#include <cstdlib>
+#include <typeinfo>
+#include <memory>
+
+namespace efl { namespace eina { namespace js {
+
+template <typename T> struct print_tag {};
+
+template <typename T>
+inline v8::Local<v8::Value>
+get_value_from_c(T v, v8::Isolate* isolate, const char*
+ , typename std::enable_if<std::is_integral<typename std::remove_reference<T>::type>::value && !std::is_same<T, Eina_Bool>::value>::type* = 0)
+{
+ return eina::js::compatibility_new<v8::Integer>(isolate, v);
+}
+
+template <typename T>
+inline v8::Local<v8::Value>
+get_value_from_c(T v, v8::Isolate* isolate, const char*
+ , typename std::enable_if<std::is_enum<typename std::remove_reference<T>::type>::value>::type* = 0)
+{
+ return eina::js::compatibility_new<v8::Integer>(isolate, v);
+}
+
+template <typename T>
+inline v8::Local<v8::Value>
+get_value_from_c(T v, v8::Isolate* isolate, const char*
+ , typename std::enable_if<std::is_same<typename std::remove_reference<T>::type, Eina_Bool>::value>::type* = 0)
+{
+ return eina::js::compatibility_new<v8::Boolean>(isolate, v);
+}
+
+template <typename T>
+inline v8::Local<T>
+get_value_from_c(v8::Local<T> v, v8::Isolate*, const char*)
+{
+ return v;
+}
+
+template <typename T>
+inline v8::Local<v8::Value>
+get_value_from_c(T v, v8::Isolate* isolate, const char*
+ , typename std::enable_if<std::is_floating_point<typename std::remove_reference<T>::type>::value>::type* = 0)
+{
+ return eina::js::compatibility_new<v8::Number>(isolate, v);
+}
+
+inline v8::Local<v8::Value>
+get_value_from_c(const char* v, v8::Isolate* isolate, const char*)
+{
+ if (!v)
+ return v8::Null(isolate);
+
+ return eina::js::compatibility_new<v8::String>(isolate, v);
+}
+
+inline v8::Local<v8::Value>
+get_value_from_c(char* v, v8::Isolate* isolate, const char* class_name)
+{
+ return js::get_value_from_c(const_cast<const char*>(v), isolate, class_name);
+}
+
+inline v8::Local<v8::Value>
+get_value_from_c(void*, v8::Isolate*, const char*)
+{
+ // TODO: create Extern?
+ std::cerr << "aborting because we don't know the type void*" << std::endl;
+ std::abort();
+}
+
+inline v8::Local<v8::Value>
+get_value_from_c(const void*, v8::Isolate*, const char*)
+{
+ // TODO: create Extern?
+ std::cerr << "aborting because we don't know the type void*" << std::endl;
+ std::abort();
+}
+
+// For function pointer types
+template <typename T>
+inline v8::Local<v8::Value>
+get_value_from_c(T, v8::Isolate*, const char*
+ , typename std::enable_if
+ <std::is_pointer<typename std::remove_reference<T>::type>::value
+ && std::is_function<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value
+ >::type* = 0)
+{
+ // TODO: create Extern?
+ std::cerr << "aborting because we don't know the type " << typeid(print_tag<T>).name() << std::endl;
+ std::abort();
+}
+
+// For all non-pointer types that are not handled
+template <typename T>
+inline v8::Local<v8::Value>
+get_value_from_c(T, v8::Isolate*, const char*
+ , typename std::enable_if
+ <!std::is_pointer<typename std::remove_reference<T>::type>::value
+ && !std::is_integral<typename std::remove_reference<T>::type>::value
+ && !std::is_floating_point<typename std::remove_reference<T>::type>::value
+ && !std::is_enum<typename std::remove_reference<T>::type>::value
+ && !std::is_same<typename std::remove_reference<T>::type, Eina_Bool>::value
+ && !js::is_struct_tag<typename std::remove_reference<T>::type>::value
+ && !js::is_struct_ptr_tag<typename std::remove_reference<T>::type>::value
+ && !js::is_complex_tag<typename std::remove_reference<T>::type>::value
+ >::type* = 0)
+{
+ std::cerr << "aborting because we don't know the type " << typeid(print_tag<T>).name() << std::endl;
+ std::abort();
+}
+
+// For all non-handled pointer types (which are not function pointers):
+// - we try to dereference it in the SFINAE
+// - if it matches we call get_value_from_c for the dereferenced type
+// - if it fails (probably because it is opaque) the void* or const void*
+// overload will take place (implicit conversion)
+template <typename T>
+inline auto
+get_value_from_c(T object, v8::Isolate* isolate, const char* class_name
+ , typename std::enable_if<
+ (std::is_pointer<typename std::remove_reference<T>::type>::value
+ && !std::is_function<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value
+ )
+ && !(std::is_same<typename std::remove_reference<T>::type, char*>::value ||
+ std::is_same<typename std::remove_reference<T>::type, const char*>::value ||
+ std::is_same<typename std::remove_reference<T>::type, void*>::value ||
+ std::is_same<typename std::remove_reference<T>::type, const void*>::value ||
+ std::is_same<typename std::remove_reference<T>::type, Eo*>::value ||
+ std::is_same<typename std::remove_reference<T>::type, const Eo*>::value
+ )>::type* = 0) -> decltype(get_value_from_c(*object, isolate, class_name))
+{
+ std::cerr << "dereferencing " << typeid(print_tag<T>).name() << std::endl;
+ return get_value_from_c(*object, isolate, class_name);
+}
+
+inline v8::Local<v8::Value>
+get_value_from_c(Eo* v, v8::Isolate* isolate, const char* class_name)
+{
+ auto ctor = ::efl::eina::js::get_class_constructor(class_name);
+ return new_v8_external_instance(ctor, v, isolate);
+}
+
+inline v8::Local<v8::Value>
+get_value_from_c(const Eo* v, v8::Isolate* isolate, const char* class_name)
+{
+ // TODO: implement const objects?
+ auto ctor = ::efl::eina::js::get_class_constructor(class_name);
+ return new_v8_external_instance(ctor, const_cast<Eo*>(v), isolate);
+}
+
+template <typename T>
+inline v8::Local<v8::Value>
+get_value_from_c(struct_ptr_tag<T> v, v8::Isolate* isolate, const char* class_name)
+{
+ // TODO: implement const structs?
+ auto ctor = ::efl::eina::js::get_class_constructor(class_name);
+ return new_v8_external_instance(ctor, const_cast<typename std::remove_const<T>::type>(v.value), isolate);
+}
+
+template <typename T>
+inline v8::Local<v8::Value>
+get_value_from_c(struct_tag<T> v, v8::Isolate* isolate, const char* class_name)
+{
+ return get_value_from_c(struct_ptr_tag<T*>{new T(v.value)}, isolate, class_name);
+}
+
+template <typename T, typename K>
+inline v8::Local<v8::Value>
+get_value_from_c(efl::eina::js::complex_tag<Eina_Accessor *, T, K> v, v8::Isolate* isolate, const char*)
+{
+ using wrapped_type = typename container_wrapper<T>::type;
+ auto a = new ::efl::eina::accessor<wrapped_type>{v.value};
+ return export_accessor<T>(*a , isolate, K::class_name());
+}
+
+template <typename T, typename K>
+inline v8::Local<v8::Value>
+get_value_from_c(efl::eina::js::complex_tag<const Eina_Accessor *, T, K> v, v8::Isolate* isolate, const char* class_name)
+{
+ // TODO implement const accessor?
+ return get_value_from_c(efl::eina::js::complex_tag<Eina_Accessor*, T, K>{const_cast<Eina_Accessor*>(v.value)}, isolate, class_name);
+}
+
+template <typename T, typename K>
+inline v8::Local<v8::Value>
+get_value_from_c(efl::eina::js::complex_tag<Eina_Array *, T, K> v, v8::Isolate* isolate, const char*)
+{
+ // TODO: use unique_ptr for eina_array to avoid leak ?
+ auto o = new ::efl::eina::js::range_eina_array<T, K>(v.value);
+ auto ctor = get_array_instance_template();
+ return new_v8_external_instance(ctor, o, isolate);
+}
+
+template <typename T, typename K>
+inline v8::Local<v8::Value>
+get_value_from_c(efl::eina::js::complex_tag<const Eina_Array *, T, K> v, v8::Isolate* isolate, const char* class_name)
+{
+ // TODO: implement const array?
+ return get_value_from_c(efl::eina::js::complex_tag<Eina_Array *, T, K>{const_cast<Eina_Array*>(v.value)}, isolate, class_name);
+}
+
+template <typename T, typename K>
+inline v8::Local<v8::Value>
+get_value_from_c(efl::eina::js::complex_tag<Eina_Iterator *, T, K>, v8::Isolate*, const char*)
+{
+ std::cerr << "get_value_from_c for Eina_Iterator not implemented. Aborting..." << std::endl;
+ std::abort();
+}
+
+template <typename T, typename K>
+inline v8::Local<v8::Value>
+get_value_from_c(efl::eina::js::complex_tag<const Eina_Iterator *, T, K>, v8::Isolate*, const char*)
+{
+ std::cerr << "get_value_from_c for Eina_Iterator not implemented. Aborting..." << std::endl;
+ std::abort();
+}
+
+template <typename T, typename U, typename K>
+inline v8::Local<v8::Value>
+get_value_from_c(efl::eina::js::complex_tag<Eina_Hash *, T, U, K>, v8::Isolate*, const char*)
+{
+ std::cerr << "get_value_from_c for Eina_Hash not implemented. Aborting..." << std::endl;
+ std::abort();
+}
+
+template <typename T, typename U, typename K>
+inline v8::Local<v8::Value>
+get_value_from_c(efl::eina::js::complex_tag<const Eina_Hash *, T, U, K>, v8::Isolate*, const char*)
+{
+ std::cerr << "get_value_from_c for Eina_Hash not implemented. Aborting..." << std::endl;
+ std::abort();
+}
+
+template <typename T, typename K>
+inline v8::Local<v8::Value>
+get_value_from_c(efl::eina::js::complex_tag<Eina_List *, T, K> v, v8::Isolate* isolate, const char*)
+{
+ // TODO: ensure eina_list ownership ???
+ auto o = new ::efl::eina::js::range_eina_list<T, K>(v.value);
+ auto ctor = get_list_instance_template();
+ return new_v8_external_instance(ctor, o, isolate);
+}
+
+template <typename T, typename K>
+inline v8::Local<v8::Value>
+get_value_from_c(efl::eina::js::complex_tag<const Eina_List *, T, K> v, v8::Isolate* isolate, const char* class_name)
+{
+ // TODO: implement const list?
+ return get_value_from_c(efl::eina::js::complex_tag<Eina_List *, T, K>{const_cast<Eina_List*>(v.value)}, isolate, class_name);
+}
+
+
+} } }
+
+#endif
diff --git a/src/bindings/eina_js/eina_js_iterator.cc b/src/bindings/eina_js/eina_js_iterator.cc
new file mode 100644
index 0000000000..d2480b8be2
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_iterator.cc
@@ -0,0 +1,32 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Eina.hh>
+#include <Eina_Js.hh>
+
+namespace efl { namespace eina { namespace js {
+
+EAPI
+void register_destroy_iterator(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ typedef void (*deleter_t)(void*);
+
+ auto f = [](compatibility_callback_info_type info) -> compatibility_return_type
+ {
+ if (info.Length() != 1 || !info[0]->IsObject())
+ return compatibility_return();
+
+ v8::Handle<v8::Object> o = info[0]->ToObject();
+
+ deleter_t deleter = compatibility_get_pointer_internal_field<deleter_t>(o, 1);
+ deleter(compatibility_get_pointer_internal_field<>(o, 0));
+ return compatibility_return();
+ };
+
+ global->Set(name, compatibility_new<v8::FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+} } } // namespace efl { namespace js {
diff --git a/src/bindings/eina_js/eina_js_iterator.hh b/src/bindings/eina_js/eina_js_iterator.hh
new file mode 100644
index 0000000000..ed0066bf0b
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_iterator.hh
@@ -0,0 +1,81 @@
+#ifndef EINA_JS_ITERATOR_HH
+#define EINA_JS_ITERATOR_HH
+
+#include <type_traits>
+
+#include <eina_js_value.hh>
+
+namespace efl { namespace eina { namespace js {
+
+/* Exports the \p iterator to be manipulated by the JS code. The iterator should
+ remain alive as long as there is JS code referencing it. The JS code is able
+ to destroy the iterator by itself if you register the appropriate function
+ through `register_destroy_iterator`.
+
+ The exported JS object models part the [iterator concept from ECMAScript
+ 6](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol).
+
+ The iterator will have the `next` function, but the returned object won't
+ have a `done` attribute, because the eina_iterator itself doesn't expose this
+ information.*/
+template<class T>
+v8::Local<v8::Object> export_iterator(::efl::eina::iterator<T> *i,
+ v8::Isolate *isolate)
+{
+ typedef ::efl::eina::iterator<T> value_type;
+ typedef value_type *ptr_type;
+ typedef void (*deleter_t)(void*);
+
+ auto obj_tpl = compatibility_new<v8::ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(2);
+
+ auto ret = obj_tpl->NewInstance();
+
+ auto next = [](js::compatibility_callback_info_type info) -> compatibility_return_type
+ {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ void *ptr = compatibility_get_pointer_internal_field(info.This(), 0);
+ auto &value = *static_cast<ptr_type>(ptr);
+ v8::Local<v8::Object> o = compatibility_new<v8::Object>(info.GetIsolate());
+ o->Set(compatibility_new<v8::String>(info.GetIsolate(), "value"),
+ value_cast<v8::Local<v8::Value>>(*value, info.GetIsolate()));
+ ++value;
+ return compatibility_return(o, info);
+ };
+
+ ret->Set(compatibility_new<v8::String>(isolate, "next"),
+ compatibility_new<v8::FunctionTemplate>(isolate, next)->GetFunction());
+
+ {
+ deleter_t deleter = [](void *i) {
+ delete static_cast<ptr_type>(i);
+ };
+ compatibility_set_pointer_internal_field(ret, 0, i);
+ compatibility_set_pointer_internal_field
+ (ret, 1, reinterpret_cast<void*>(deleter));
+ }
+
+ return ret;
+}
+
+/* Extracts and returns a copy from the internal iterator object from the JS
+ object. */
+template<class T>
+::efl::eina::iterator<T> *import_iterator(v8::Handle<v8::Object> o)
+ ;
+// {
+// typedef ::efl::eina::iterator<T> value_type;
+// typedef value_type *ptr_type;
+
+// return reinterpret_cast<ptr_type>(o->GetAlignedPointerFromInternalField(0));
+// }
+
+void register_destroy_iterator(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+} } } // namespace efl::js
+
+#endif /* EINA_JS_ITERATOR_HH */
diff --git a/src/bindings/eina_js/eina_js_list.hh b/src/bindings/eina_js/eina_js_list.hh
new file mode 100644
index 0000000000..6ab0521847
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_list.hh
@@ -0,0 +1,132 @@
+#ifndef EINA_JS_LIST_HH
+#define EINA_JS_LIST_HH
+
+#include <iostream>
+
+#include <eina_js_container.hh>
+#include <eina_js_compatibility.hh>
+
+#include <iterator>
+
+namespace efl { namespace eina { namespace js {
+
+template <typename T, typename K, typename W>
+struct eina_list : eina_container_common<efl::eina::list
+ <W
+ , typename std::conditional
+ <std::is_base_of<efl::eo::concrete, W>::value
+ , efl::eina::eo_clone_allocator
+ , efl::eina::malloc_clone_allocator
+ >::type>, T, K>
+{
+ typedef eina_container_common<efl::eina::list<W
+ , typename std::conditional
+ <std::is_base_of<efl::eo::concrete, W>::value
+ , efl::eina::eo_clone_allocator
+ , efl::eina::malloc_clone_allocator
+ >::type>, T, K> base_type;
+ using base_type::base_type;
+ typedef typename base_type::container_type container_type;
+
+ eina_container_base* concat(eina_container_base const& other) const
+ {
+ return detail::concat(*this, other);
+ }
+ eina_container_base* slice(std::int64_t i, std::int64_t j) const
+ {
+ return detail::slice(*this, i, j);
+ }
+ v8::Local<v8::Value> set(v8::Isolate* isolate, std::size_t index, v8::Local<v8::Value> v)
+ {
+ return detail::set<T,W>(isolate, *this, index, v);
+ }
+ int push(v8::Isolate* isolate, v8::Local<v8::Value> v)
+ {
+ return detail::push<T,W>(isolate, *this, v);
+ }
+ v8::Local<v8::Value> pop(v8::Isolate* isolate)
+ {
+ return detail::pop<T,W,K>(isolate, *this);
+ }
+ js::container_type get_container_type() const { return list_container_type; }
+};
+
+template <typename T, typename K, typename W>
+struct range_eina_list : eina_container_common<typename efl::eina::range_list<W>, T, K>
+{
+ typedef eina_container_common<efl::eina::range_list<W>, T, K> base_type;
+ using base_type::base_type;
+ typedef typename base_type::container_type container_type;
+ typedef typename std::conditional
+ <std::is_base_of<efl::eo::concrete, W>::value
+ , efl::eina::eo_clone_allocator
+ , efl::eina::malloc_clone_allocator
+ >::type clone_allocator_type;
+
+ eina_container_base* concat(eina_container_base const& other) const
+ {
+ range_eina_list<T, K, W>const& rhs = static_cast<range_eina_list<T, K, W>const&>(other);
+ efl::eina::list<W, clone_allocator_type>
+ list(this->_container.begin(), this->_container.end());
+ list.insert(list.end(), rhs._container.begin(), rhs._container.end());
+ return new eina::js::eina_list<T, K, W>(list.release_native_handle());
+ }
+ eina_container_base* slice(std::int64_t i, std::int64_t j) const
+ {
+ efl::eina::list<W, clone_allocator_type>
+ list(std::next(this->_container.begin(), i), std::next(this->_container.begin(), j));
+ return new eina::js::eina_list<T, K, W>(list.release_native_handle());
+ }
+ v8::Local<v8::Value> set(v8::Isolate* isolate, std::size_t, v8::Local<v8::Value>)
+ {
+ return v8::Undefined(isolate);
+ }
+ int push(v8::Isolate*, v8::Local<v8::Value>)
+ {
+ return this->size();
+ }
+ v8::Local<v8::Value> pop(v8::Isolate* isolate)
+ {
+ return v8::Undefined(isolate);
+ }
+ js::container_type get_container_type() const { return list_container_type; }
+};
+
+// Problematic types.
+template <>
+struct eina_list<_Elm_Calendar_Mark*, js::nonclass_cls_name_getter, _Elm_Calendar_Mark>
+ : empty_container_base
+{ eina_list(Eina_List const*){} };
+template <>
+struct eina_list<Elm_Gen_Item*, js::nonclass_cls_name_getter, Elm_Gen_Item>
+ : empty_container_base
+{ eina_list(Eina_List const*){} };
+template <>
+struct eina_list<_Evas_Textblock_Rectangle*, js::nonclass_cls_name_getter, _Evas_Textblock_Rectangle>
+ : empty_container_base
+{ eina_list(Eina_List const*){} };
+template <>
+struct eina_list<_Elm_Map_Overlay*, js::nonclass_cls_name_getter, _Elm_Map_Overlay>
+ : empty_container_base
+{ eina_list(Eina_List const*){} };
+
+template <>
+struct range_eina_list<_Elm_Calendar_Mark*, js::nonclass_cls_name_getter, _Elm_Calendar_Mark>
+ : empty_container_base
+{ range_eina_list(Eina_List const*){} };
+template <>
+struct range_eina_list<Elm_Gen_Item*, js::nonclass_cls_name_getter, Elm_Gen_Item>
+ : empty_container_base
+{ range_eina_list(Eina_List const*){} };
+template <>
+struct range_eina_list<_Evas_Textblock_Rectangle*, js::nonclass_cls_name_getter, _Evas_Textblock_Rectangle>
+ : empty_container_base
+{ range_eina_list(Eina_List const*){} };
+template <>
+struct range_eina_list<_Elm_Map_Overlay*, js::nonclass_cls_name_getter, _Elm_Map_Overlay>
+ : empty_container_base
+{ range_eina_list(Eina_List const*){} };
+
+} } }
+
+#endif
diff --git a/src/bindings/eina_js/eina_js_log.cc b/src/bindings/eina_js/eina_js_log.cc
new file mode 100644
index 0000000000..415a827d1f
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_log.cc
@@ -0,0 +1,742 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+#include <map>
+#include <Eina_Js.hh>
+
+namespace efl { namespace eina { namespace js {
+
+v8::Local<v8::String> to_v8_string(v8::Isolate *isolate, const char *fmt,
+ va_list args)
+{
+ using v8::String;
+#if 0
+ /* TODO: unfortunately, the elegant and exception-safe version isn't
+ compiling (yet!) */
+ efl::eina::stringshare s(eina_stringshare_vprintf(fmt, args),
+ efl::eina::steal_stringshare_ref);
+ return compatibility_new<String>(isolate, s.data(), String::kNormalString,
+ s.size());
+#else
+ auto s = eina_stringshare_vprintf(fmt, args);
+ auto ret = compatibility_new<String>(isolate, s);
+ eina_stringshare_del(s);
+ return ret;
+#endif
+}
+
+static global_ref<v8::Value> js_eina_log_print_cb_data;
+static std::map<int, std::string> js_eina_log_color_map;
+
+static void js_eina_log_print_cb(const Eina_Log_Domain *d, Eina_Log_Level level,
+ const char *file, const char *fnc, int line,
+ const char *fmt, void */*data*/, va_list args)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::Isolate;
+
+ Isolate *const isolate = Isolate::GetCurrent();
+ constexpr unsigned argc = 7;
+
+ v8::Handle<v8::Value> argv[argc] = {
+ compatibility_new<String>(isolate, d->name ? d->name : ""),
+ compatibility_new<String>(isolate, d->color ? d->color : ""),
+ compatibility_new<Integer>(isolate, static_cast<int>(level)),
+ compatibility_new<String>(isolate, file),
+ compatibility_new<String>(isolate, fnc),
+ compatibility_new<Integer>(isolate, line),
+ to_v8_string(isolate, fmt, args)
+ };
+
+ auto o = js_eina_log_print_cb_data.handle();
+ v8::Function::Cast(*o)->Call(o->ToObject(), argc, argv);
+}
+
+static bool valid_level_conversion(int src, Eina_Log_Level &dst)
+{
+ if (src != EINA_LOG_LEVEL_CRITICAL && src != EINA_LOG_LEVEL_ERR
+ && src != EINA_LOG_LEVEL_WARN && src != EINA_LOG_LEVEL_INFO
+ && src != EINA_LOG_LEVEL_DBG)
+ return false;
+
+ dst = static_cast<Eina_Log_Level>(src);
+ return true;
+}
+
+EAPI
+void register_log_print(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::String;
+ using v8::StackTrace;
+ using v8::FunctionTemplate;
+
+ auto print = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 3 || !args[0]->IsNumber() || !args[1]->IsNumber()
+ || !args[2]->IsString())
+ return compatibility_return();
+
+ Eina_Log_Level level;
+ if (!valid_level_conversion(args[1]->NumberValue(), level))
+ return compatibility_return();
+
+ auto frame = compatibility_current_stack_trace<>(args.GetIsolate(), 1,
+ StackTrace::kDetailed)->GetFrame(0);
+
+ eina_log_print(args[0]->NumberValue(), level,
+ *String::Utf8Value(frame->GetScriptNameOrSourceURL()),
+ *String::Utf8Value(frame->GetFunctionName()),
+ frame->GetLineNumber(), "%s",
+ *String::Utf8Value(args[2]));
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, print)
+ ->GetFunction());
+}
+
+EAPI
+void register_log_domain_register(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::Local;
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString())
+ return compatibility_return();
+
+ // We duplicate the color string as eina takes a const char* but does take care of
+ // its lifetime, assuming a ever lasting string.
+ std::string color = *String::Utf8Value(args[1]);
+ int d = eina_log_domain_register(*String::Utf8Value(args[0]),
+ color.c_str());
+ js_eina_log_color_map[d] = color;
+
+ auto isolate = args.GetIsolate();
+ return compatibility_return(value_cast<Local<Value>>(d, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_domain_unregister(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ int domain = args[0]->NumberValue();
+ eina_log_domain_unregister(domain);
+ js_eina_log_color_map.erase(domain);
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_domain_registered_level_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::Local;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ int l = eina_log_domain_registered_level_get(args[0]->NumberValue());
+ auto isolate = args.GetIsolate();
+ return compatibility_return(value_cast<Local<Value>>(l, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_domain_registered_level_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsNumber() || !args[1]->IsNumber())
+ return compatibility_return();
+
+ eina_log_domain_registered_level_set(args[0]->NumberValue(),
+ args[1]->NumberValue());
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_print_cb_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ js_eina_log_print_cb_data
+ = global_ref<v8::Value>(args.GetIsolate(), args[0]);
+ eina_log_print_cb_set(js_eina_log_print_cb, NULL);
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_level_set(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ eina_log_level_set(args[0]->NumberValue());
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_level_get(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+ using v8::Integer;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ int l = eina_log_level_get();
+ auto ret = compatibility_new<Integer>(args.GetIsolate(), l);
+ return compatibility_return(ret, args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_level_check(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+ using v8::Boolean;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ bool b = eina_log_level_check(args[0]->NumberValue());
+ auto ret = compatibility_new<Boolean>(args.GetIsolate(), b);
+ return compatibility_return(ret, args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_color_disable_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsBoolean())
+ return compatibility_return();
+
+ eina_log_color_disable_set(args[0]->BooleanValue());
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_color_disable_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::Boolean;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ bool b = eina_log_color_disable_get();
+ auto ret = compatibility_new<Boolean>(args.GetIsolate(), b);
+ return compatibility_return(ret, args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_file_disable_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsBoolean())
+ return compatibility_return();
+
+ eina_log_file_disable_set(args[0]->BooleanValue());
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_file_disable_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::Boolean;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ bool b = eina_log_file_disable_get();
+ auto ret = compatibility_new<Boolean>(args.GetIsolate(), b);
+ return compatibility_return(ret, args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_function_disable_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsBoolean())
+ return compatibility_return();
+
+ eina_log_function_disable_set(args[0]->BooleanValue());
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_function_disable_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::Boolean;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ bool b = eina_log_function_disable_get();
+ auto ret = compatibility_new<Boolean>(args.GetIsolate(), b);
+ return compatibility_return(ret, args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_abort_on_critical_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsBoolean())
+ return compatibility_return();
+
+ eina_log_abort_on_critical_set(args[0]->BooleanValue());
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_abort_on_critical_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::Boolean;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ bool b = eina_log_abort_on_critical_get();
+ auto ret = compatibility_new<Boolean>(args.GetIsolate(), b);
+ return compatibility_return(ret, args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_abort_on_critical_level_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ eina_log_abort_on_critical_level_set(args[0]->NumberValue());
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_abort_on_critical_level_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+ using v8::Integer;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ int l = eina_log_abort_on_critical_level_get();
+ auto ret = compatibility_new<Integer>(args.GetIsolate(), l);
+ return compatibility_return(ret, args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_domain_level_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+ using v8::String;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsNumber())
+ return compatibility_return();
+
+ eina_log_domain_level_set(*String::Utf8Value(args[0]),
+ args[1]->NumberValue());
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_domain_level_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+ using v8::String;
+ using v8::Integer;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ int l = eina_log_domain_level_get(*String::Utf8Value(args[0]));
+ auto ret = compatibility_new<Integer>(args.GetIsolate(), l);
+ return compatibility_return(ret, args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_log_timing(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Value;
+ using v8::FunctionTemplate;
+ using v8::String;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 3 || !args[0]->IsNumber() || !args[1]->IsNumber()
+ || !args[2]->IsString()) {
+ return compatibility_return();
+ }
+
+ eina_log_timing(args[0]->NumberValue(),
+ static_cast<Eina_Log_State>(args[1]->NumberValue()),
+ *String::Utf8Value(args[2]));
+ return compatibility_return();
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+static void register_constant(v8::Isolate *isolate, v8::Handle<v8::Object> global, int value, const char* name)
+{
+ global->Set(compatibility_new<v8::String>(isolate, name), compatibility_new<v8::Integer>(isolate, value));
+}
+
+static void register_constant(v8::Isolate *isolate, v8::Handle<v8::Object> global, const char* value, const char* name)
+{
+ global->Set(compatibility_new<v8::String>(isolate, name), compatibility_new<v8::String>(isolate, value));
+}
+
+EAPI void register_log_constants(v8::Isolate *isolate, v8::Handle<v8::Object> global)
+{
+ register_constant(isolate, global, EINA_LOG_STATE_START, "LOG_STATE_START");
+ register_constant(isolate, global, EINA_LOG_STATE_START, "LOG_STATE_STOP");
+
+ register_constant(isolate, global, EINA_LOG_LEVEL_CRITICAL, "LOG_LEVEL_CRITICAL");
+ register_constant(isolate, global, EINA_LOG_LEVEL_ERR, "LOG_LEVEL_ERR");
+ register_constant(isolate, global, EINA_LOG_LEVEL_WARN, "LOG_LEVEL_WARN");
+ register_constant(isolate, global, EINA_LOG_LEVEL_INFO, "LOG_LEVEL_INFO");
+ register_constant(isolate, global, EINA_LOG_LEVEL_DBG, "LOG_LEVEL_DBG");
+ register_constant(isolate, global, EINA_LOG_LEVELS, "LOG_LEVELS");
+ register_constant(isolate, global, EINA_LOG_LEVEL_UNKNOWN, "LOG_LEVEL_UNKNOWN");
+
+ register_constant(isolate, global, EINA_LOG_DOMAIN_GLOBAL, "LOG_DOMAIN_GLOBAL");
+
+ register_constant(isolate, global, EINA_COLOR_LIGHTRED, "COLOR_LIGHTRED");
+ register_constant(isolate, global, EINA_COLOR_RED, "COLOR_RED");
+ register_constant(isolate, global, EINA_COLOR_LIGHTBLUE, "COLOR_LIGHTBLUE");
+ register_constant(isolate, global, EINA_COLOR_BLUE, "COLOR_BLUE");
+ register_constant(isolate, global, EINA_COLOR_GREEN, "COLOR_GREEN");
+ register_constant(isolate, global, EINA_COLOR_YELLOW, "COLOR_YELLOW");
+ register_constant(isolate, global, EINA_COLOR_ORANGE, "COLOR_ORANGE");
+ register_constant(isolate, global, EINA_COLOR_WHITE, "COLOR_WHITE");
+ register_constant(isolate, global, EINA_COLOR_LIGHTCYAN, "COLOR_LIGHTCYAN");
+ register_constant(isolate, global, EINA_COLOR_CYAN, "COLOR_CYAN");
+ register_constant(isolate, global, EINA_COLOR_RESET, "COLOR_RESET");
+ register_constant(isolate, global, EINA_COLOR_HIGH, "COLOR_HIGH");
+}
+
+
+#define REGISTER_LOG_HELPER(isolate, global, level, name) \
+{ \
+ using v8::String; \
+ using v8::FunctionTemplate;\
+ using v8::StackTrace;\
+\
+ auto wrapper = [](compatibility_callback_info_type args)\
+ -> compatibility_return_type {\
+ if (args.Length() != 1 || !args[0]->IsString()) {\
+ eina::js::compatibility_throw \
+ (args.GetIsolate(), v8::Exception::TypeError(\
+ eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Message must be a string."))); \
+ return compatibility_return();\
+ } \
+\
+ auto frame = compatibility_current_stack_trace<>(args.GetIsolate(), 1,\
+ StackTrace::kDetailed)->GetFrame(0);\
+\
+ eina_log_print(EINA_LOG_DOMAIN_GLOBAL, level,\
+ *String::Utf8Value(frame->GetScriptNameOrSourceURL()),\
+ *String::Utf8Value(frame->GetFunctionName()),\
+ frame->GetLineNumber(), "%s",\
+ *String::Utf8Value(args[0]));\
+\
+ return compatibility_return();\
+ };\
+\
+ global->Set(compatibility_new<String>(isolate, name),\
+ compatibility_new<FunctionTemplate>(isolate, wrapper)->GetFunction());\
+}
+
+EAPI void register_log_helpers(v8::Isolate *isolate, v8::Handle<v8::Object> global)
+{
+ REGISTER_LOG_HELPER(isolate, global, EINA_LOG_LEVEL_CRITICAL, "logCritical");
+ REGISTER_LOG_HELPER(isolate, global, EINA_LOG_LEVEL_ERR, "logError");
+ REGISTER_LOG_HELPER(isolate, global, EINA_LOG_LEVEL_WARN, "logWarning");
+ REGISTER_LOG_HELPER(isolate, global, EINA_LOG_LEVEL_INFO, "logInfo");
+ REGISTER_LOG_HELPER(isolate, global, EINA_LOG_LEVEL_DBG, "logDebug");
+}
+
+} } } // namespace efl { namespace js {
+
+EAPI
+void eina_log_register(v8::Handle<v8::Object> exports, v8::Isolate* isolate)
+{
+ using efl::eina::js::compatibility_new;
+
+ efl::eina::js::register_log_domain_register(isolate, exports
+ , compatibility_new<v8::String>(isolate, "registerLogDomain"));
+ efl::eina::js::register_log_domain_unregister(isolate, exports
+ , compatibility_new<v8::String>(isolate, "unregisterLogDomain"));
+ efl::eina::js::register_log_domain_registered_level_set(isolate, exports
+ , compatibility_new<v8::String>(isolate, "setLogDomainRegisteredLevel"));
+ efl::eina::js::register_log_domain_registered_level_get(isolate, exports
+ , compatibility_new<v8::String>(isolate, "getLogDomainRegisteredLevel"));
+
+ efl::eina::js::register_log_print(isolate, exports
+ , compatibility_new<v8::String>(isolate, "logPrint"
+));
+ efl::eina::js::register_log_print_cb_set(isolate, exports
+ , compatibility_new<v8::String>(isolate, "setLogPrintCb"
+));
+
+ efl::eina::js::register_log_level_set(isolate, exports
+ , compatibility_new<v8::String>(isolate, "setLogLevel"
+));
+ efl::eina::js::register_log_level_get(isolate, exports
+ , compatibility_new<v8::String>(isolate, "getLogLevel"
+));
+ efl::eina::js::register_log_level_check(isolate, exports
+ , compatibility_new<v8::String>(isolate, "checkLogLevel"
+));
+
+ efl::eina::js::register_log_color_disable_set(isolate, exports
+ , compatibility_new<v8::String>(isolate, "setLogColorDisable"
+));
+ efl::eina::js::register_log_color_disable_get(isolate, exports
+ , compatibility_new<v8::String>(isolate, "getLogColorDisable"
+));
+
+ efl::eina::js::register_log_file_disable_set(isolate, exports
+ , compatibility_new<v8::String>(isolate, "setLogFileDisable"
+));
+ efl::eina::js::register_log_file_disable_get(isolate, exports
+ , compatibility_new<v8::String>(isolate, "getLogFileDisable"
+));
+
+ efl::eina::js::register_log_function_disable_set(isolate, exports
+ , compatibility_new<v8::String>(isolate, "setLogFunctionDisable"
+));
+ efl::eina::js::register_log_function_disable_get(isolate, exports
+ , compatibility_new<v8::String>(isolate, "getLogFunctionDisable"
+));
+
+ efl::eina::js::register_log_abort_on_critical_set(isolate, exports
+ , compatibility_new<v8::String>(isolate, "setLogAbortOnCritical"
+));
+ efl::eina::js::register_log_abort_on_critical_get(isolate, exports
+ , compatibility_new<v8::String>(isolate, "getLogAbortOnCritical"
+));
+ efl::eina::js::register_log_abort_on_critical_level_set(isolate, exports
+ , compatibility_new<v8::String>(isolate, "setLogAbortOnCriticalLevel"
+));
+ efl::eina::js::register_log_abort_on_critical_level_get(isolate, exports
+ , compatibility_new<v8::String>(isolate, "getLogAbortOnCriticalLevel"
+));
+
+ efl::eina::js::register_log_domain_level_set(isolate, exports
+ , compatibility_new<v8::String>(isolate, "setLogDomainLevel"
+));
+ efl::eina::js::register_log_domain_level_get(isolate, exports
+ , compatibility_new<v8::String>(isolate, "getLogDomainLevel"
+));
+
+ efl::eina::js::register_log_timing(isolate, exports
+ , compatibility_new<v8::String>(isolate, "logTiming"));
+
+ efl::eina::js::register_log_constants(isolate, exports);
+
+ efl::eina::js::register_log_helpers(isolate, exports);
+}
diff --git a/src/bindings/eina_js/eina_js_log.hh b/src/bindings/eina_js/eina_js_log.hh
new file mode 100644
index 0000000000..bed5a1bf9d
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_log.hh
@@ -0,0 +1,133 @@
+#ifndef EINA_JS_LOG_HH
+#define EINA_JS_LOG_HH
+
+#include <type_traits>
+
+namespace efl { namespace eina { namespace js {
+
+using ::efl::eina::js::compatibility_new;
+using ::efl::eina::js::compatibility_return_type;
+using ::efl::eina::js::compatibility_callback_info_type;
+using ::efl::eina::js::compatibility_return;
+using ::efl::eina::js::compatibility_get_pointer_internal_field;
+using ::efl::eina::js::compatibility_set_pointer_internal_field;
+
+void register_log_level_critical(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_level_err(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_level_warn(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_level_info(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_level_dbg(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_domain_global(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_print(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_domain_register(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_domain_unregister(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_domain_registered_level_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_domain_registered_level_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_print_cb_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_level_set(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_level_get(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_level_check(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_color_disable_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_color_disable_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_file_disable_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_file_disable_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_function_disable_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_function_disable_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_abort_on_critical_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_abort_on_critical_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_abort_on_critical_level_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_abort_on_critical_level_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_domain_level_set(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_domain_level_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_state_start(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_state_stop(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+void register_log_timing(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+} } } // namespace efl::js
+
+EAPI void eina_log_register(v8::Handle<v8::Object> exports, v8::Isolate* isolate);
+
+#endif /* EINA_JS_LOG_HH */
diff --git a/src/bindings/eina_js/eina_js_node.hh b/src/bindings/eina_js/eina_js_node.hh
new file mode 100644
index 0000000000..cfa4169d82
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_node.hh
@@ -0,0 +1,14 @@
+
+#ifdef HAVE_NODE_NODE_H
+#include <node/node.h>
+#elif defined(HAVE_NODEJS_DEPS_NODE_NODE_H)
+#include <nodejs/deps/node/node.h>
+#elif defined(HAVE_NODEJS_DEPS_NODE_INCLUDE_NODE_H)
+#include <nodejs/deps/node/include/node.h>
+#elif defined(HAVE_NODEJS_SRC_NODE_H)
+#include <nodejs/src/node.h>
+#elif defined(HAVE_NODE_H)
+#include <node.h>
+#else
+#error We must have at least one node header to include
+#endif
diff --git a/src/bindings/eina_js/eina_js_value.cc b/src/bindings/eina_js/eina_js_value.cc
new file mode 100644
index 0000000000..5b5b822160
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_value.cc
@@ -0,0 +1,132 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Eina_Js.hh>
+
+namespace efl { namespace eina { namespace js {
+
+namespace {
+
+compatibility_return_type eina_value_set(compatibility_callback_info_type args)
+{
+ if (args.Length() != 1)
+ return compatibility_return();
+
+ void *ptr = js::compatibility_get_pointer_internal_field(args.Holder(), 0);
+ v8::Isolate *isolate = args.GetIsolate();
+ try {
+ *static_cast<value*>(ptr) = value_cast<value>(args[0]);
+ } catch(const std::bad_cast &e) {
+ v8::Local<v8::Object> je = compatibility_new<v8::Object>(isolate);
+ je->Set(compatibility_new<v8::String>(isolate, "code"),
+ compatibility_new<v8::String>(isolate, "std::bad_cast"));
+ return compatibility_throw(isolate, je);
+ } catch(const ::efl::eina::system_error &e) {
+ v8::Local<v8::Object> je = compatibility_new<v8::Object>(isolate);
+ je->Set(compatibility_new<v8::String>(isolate, "code"),
+ compatibility_new<v8::String>(isolate, "std::error_code"));
+ je->Set(compatibility_new<v8::String>(isolate, "category"),
+ compatibility_new<v8::String>(isolate, e.code().category().name()));
+ je->Set(compatibility_new<v8::String>(isolate, "value"),
+ compatibility_new<v8::Integer>(isolate, e.code().value()));
+ return compatibility_throw(isolate, je);
+ }
+ return compatibility_return();
+}
+
+compatibility_return_type eina_value_get(compatibility_callback_info_type args)
+{
+ void *ptr = compatibility_get_pointer_internal_field(args.Holder(), 0);
+ auto &value = *static_cast<eina::value*>(ptr);
+ return compatibility_return
+ (value_cast<v8::Local<v8::Value>>(value, args.GetIsolate()), args);
+}
+
+compatibility_return_type eina_value_constructor(compatibility_callback_info_type args)
+{
+ if (args.Length() != 1)
+ return compatibility_return();
+
+ v8::Isolate* isolate = args.GetIsolate();
+
+ try {
+ std::unique_ptr<value>
+ ptr(new value(value_cast<value>(args[0])));
+ compatibility_set_pointer_internal_field(args.This(), 0, ptr.get());
+ ptr.release();
+ } catch(const std::bad_cast &e) {
+ v8::Local<v8::Object> je = compatibility_new<v8::Object>(isolate);
+ je->Set(compatibility_new<v8::String>(isolate, "code"),
+ compatibility_new<v8::String>(isolate, "std::bad_cast"));
+ return compatibility_throw(isolate,je);
+ } catch(const ::efl::eina::system_error &e) {
+ v8::Local<v8::Object> je = compatibility_new<v8::Object>(isolate);
+ je->Set(compatibility_new<v8::String>(isolate, "code"),
+ compatibility_new<v8::String>(isolate, "std::error_code"));
+ je->Set(compatibility_new<v8::String>(isolate, "category"),
+ compatibility_new<v8::String>(isolate, e.code().category().name()));
+ je->Set(compatibility_new<v8::String>(isolate, "value"),
+ compatibility_new<v8::Integer>(isolate, e.code().value()));
+ return compatibility_throw(isolate, je);
+ }
+ // makeweak
+ // {
+ // typedef global_ref<v8::Object> persistent_t;
+ // typedef v8::WeakCallbackData<v8::Object, persistent_t> cb_type;
+
+ // auto on_gc = [](const cb_type &data) {
+ // typedef ::efl::eina::value value_type;
+ // typedef value_type *ptr_type;
+
+ // auto o = data.GetValue();
+ // delete static_cast<ptr_type>
+ // (compatibility_get_pointer_internal_field(o, 0));
+ // compatibility_set_pointer_internal_field<void*>(o, 0, nullptr);
+
+ // delete data.GetParameter();
+ // };
+
+ // auto persistent = new persistent_t(isolate, args.This());
+ // persistent->SetWeak<v8::Object>(persistent, on_gc);
+ // }
+}
+
+}
+
+EAPI
+void register_value(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Isolate;
+ using v8::Local;
+ using v8::Value;
+ using v8::Integer;
+ using v8::String;
+ using v8::Object;
+ using v8::FunctionTemplate;
+ using v8::FunctionCallbackInfo;
+
+ v8::Local<v8::FunctionTemplate> constructor = compatibility_new<v8::FunctionTemplate>(isolate, &eina_value_constructor);
+
+ v8::Local<v8::ObjectTemplate> instance = constructor->InstanceTemplate();
+ instance->SetInternalFieldCount(1);
+
+ auto prototype = constructor->PrototypeTemplate();
+
+ prototype->Set(compatibility_new<v8::String>(isolate, "set")
+ , compatibility_new<FunctionTemplate>(isolate, &eina_value_set));
+ prototype->Set(compatibility_new<v8::String>(isolate, "get")
+ , compatibility_new<FunctionTemplate>(isolate, &eina_value_get));
+
+ global->Set(name, constructor->GetFunction());
+}
+
+} } } // namespace efl { namespace js {
+
+EAPI
+void eina_value_register(v8::Handle<v8::Object> global, v8::Isolate* isolate)
+{
+ efl::eina::js::register_value(isolate, global
+ , efl::eina::js::compatibility_new<v8::String>(isolate, "value"));
+}
diff --git a/src/bindings/eina_js/eina_js_value.hh b/src/bindings/eina_js/eina_js_value.hh
new file mode 100644
index 0000000000..e6ebd30ca7
--- /dev/null
+++ b/src/bindings/eina_js/eina_js_value.hh
@@ -0,0 +1,142 @@
+#ifndef EINA_JS_VALUE_HH
+#define EINA_JS_VALUE_HH
+
+#include <type_traits>
+
+#include <eina_js_compatibility.hh>
+
+namespace efl { namespace eina { namespace js {
+
+namespace detail {
+
+template<class T, class = void>
+struct is_representable_as_v8_integer: std::false_type {};
+
+template<class T>
+struct is_representable_as_v8_integer
+<T,
+ typename std::enable_if<std::is_integral<T>::value
+ /* v8::Integer only stores 32-bit signed and unsigned
+ numbers. */
+ && (sizeof(T) <= sizeof(int32_t))>::type>
+: std::true_type {};
+
+template<class T>
+typename std::enable_if<is_representable_as_v8_integer<T>::value
+ && std::is_signed<T>::value,
+ v8::Local<v8::Value>>::type
+to_v8_number(const T &v, v8::Isolate *isolate)
+{
+ return compatibility_new<v8::Integer>(isolate, v);
+}
+
+template<class T>
+typename std::enable_if<is_representable_as_v8_integer<T>::value
+ && std::is_unsigned<T>::value,
+ v8::Local<v8::Value>>::type
+to_v8_number(const T &v, v8::Isolate *isolate)
+{
+ return compatibility_new<v8::Integer>(isolate, v);
+}
+
+template<class T>
+typename std::enable_if<(std::is_integral<T>::value
+ && !is_representable_as_v8_integer<T>::value)
+ || std::is_floating_point<T>::value,
+ v8::Local<v8::Value>>::type
+to_v8_number(const T &v, v8::Isolate *isolate)
+{
+ return compatibility_new<v8::Number>(isolate, v);
+}
+
+template<class T>
+typename std::enable_if<std::is_same<T, ::efl::eina::stringshare>::value
+ || std::is_same<T, std::string>::value,
+ v8::Local<v8::Value>>::type
+to_v8_string(const T &v, v8::Isolate *isolate)
+{
+ return compatibility_new<v8::String>(isolate, v.c_str());
+}
+
+} // namespace detail
+
+template<class T>
+typename std::enable_if<std::is_same<T, v8::Local<v8::Value>>::value, T>::type
+value_cast(const ::efl::eina::value &v, v8::Isolate *isolate)
+{
+ using detail::to_v8_number;
+ using detail::to_v8_string;
+ using ::efl::eina::get;
+
+ const auto &t = v.type_info();
+ if (t == EINA_VALUE_TYPE_UINT64) {
+ return to_v8_number(get<uint64_t>(v), isolate);
+ } else if (t == EINA_VALUE_TYPE_UCHAR) {
+ return to_v8_number(get<unsigned char>(v), isolate);
+ } else if (t == EINA_VALUE_TYPE_USHORT) {
+ return to_v8_number(get<unsigned short>(v), isolate);
+ } else if (t == EINA_VALUE_TYPE_UINT) {
+ return to_v8_number(get<unsigned int>(v), isolate);
+ } else if (t == EINA_VALUE_TYPE_ULONG) {
+ return to_v8_number(get<unsigned long>(v), isolate);
+ } else if (t == EINA_VALUE_TYPE_CHAR) {
+ return to_v8_number(get<char>(v), isolate);
+ } else if (t == EINA_VALUE_TYPE_SHORT) {
+ return to_v8_number(get<short>(v), isolate);
+ } else if (t == EINA_VALUE_TYPE_INT) {
+ return to_v8_number(get<int>(v), isolate);
+ } else if (t == EINA_VALUE_TYPE_LONG) {
+ return to_v8_number(get<long>(v), isolate);
+ } else if (t == EINA_VALUE_TYPE_FLOAT) {
+ return to_v8_number(get<float>(v), isolate);
+ } else if (t == EINA_VALUE_TYPE_DOUBLE) {
+ return to_v8_number(get<double>(v), isolate);
+ } else if (t == EINA_VALUE_TYPE_STRINGSHARE) {
+ return to_v8_string(get<::efl::eina::stringshare>(v), isolate);
+ } else if (t == EINA_VALUE_TYPE_STRING) {
+ return to_v8_string(get<std::string>(v), isolate);
+ }
+
+ throw std::bad_cast{};
+}
+
+template<class T>
+typename std::enable_if<std::is_same<T, ::efl::eina::value>::value, T>::type
+value_cast(const v8::Handle<v8::Value> &v)
+{
+ using ::efl::eina::value;
+
+ if (v->IsBoolean()) {
+ return value(int{v->BooleanValue()});
+ } else if (v->IsInt32()) {
+ return value(v->Int32Value());
+ } else if (v->IsUint32()) {
+ return value(v->Uint32Value());
+ } else if (v->IsNumber()) {
+ return value(v->NumberValue());
+ } else if (v->IsString()) {
+ v8::String::Utf8Value data(v);
+ return value(std::string(*data, data.length()));
+ }
+
+ throw std::bad_cast{};
+}
+
+/*
+ # JS binding
+
+ - There is the `value()` constructor, which accepts a primitive value as input
+ argument and might throw.
+ - The returned object has a `get()` method, which can be used to get the
+ wrapped value as a JavaScript value.
+ - The returned object has a `set()` method, which can be used to change the
+ wrapped value.
+ */
+void register_value(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name);
+
+} } } // namespace efl::js
+
+EAPI void eina_value_register(v8::Handle<v8::Object> global, v8::Isolate* isolate);
+
+#endif /* EINA_JS_VALUE_HH */
diff --git a/src/bindings/eio_js/Eio_Js.hh b/src/bindings/eio_js/Eio_Js.hh
new file mode 100644
index 0000000000..e379229870
--- /dev/null
+++ b/src/bindings/eio_js/Eio_Js.hh
@@ -0,0 +1,44 @@
+#ifndef EIO_JS_INIT_HH
+#define EIO_JS_INIT_HH
+
+#include <Eio.h>
+#include <Ecore.h>
+
+#include <Eina.hh>
+
+#include <Eina_Js.hh>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_EIO_JS_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_EIO_JS_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+namespace efl { namespace eio { namespace js {
+
+EAPI
+void register_eio(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
+
+} } } // namespace efl { namespace eio { namespace js {
+
+#endif /* EIO_JS_INIT_HH */
diff --git a/src/bindings/eio_js/eio_js.cc b/src/bindings/eio_js/eio_js.cc
new file mode 100644
index 0000000000..8441247e63
--- /dev/null
+++ b/src/bindings/eio_js/eio_js.cc
@@ -0,0 +1,1756 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Eio_Js.hh>
+
+namespace efl { namespace eio { namespace js {
+
+using ::efl::eina::js::compatibility_new;
+using ::efl::eina::js::compatibility_return_type;
+using ::efl::eina::js::compatibility_callback_info_type;
+using ::efl::eina::js::compatibility_return;
+using ::efl::eina::js::compatibility_get_pointer_internal_field;
+using ::efl::eina::js::compatibility_set_pointer_internal_field;
+
+namespace {
+
+Eio_File* extract_eio_file(v8::Local<v8::Object> object)
+{
+ return compatibility_get_pointer_internal_field<Eio_File*>(object, 0);
+}
+
+v8::Local<v8::Object> wrap_eio_file(Eio_File *file, v8::Isolate *isolate)
+{
+ using v8::String;
+ using v8::Boolean;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto cancel = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = info.GetIsolate();
+
+ auto ret = eio_file_cancel(extract_eio_file(info.This()));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ info);
+ };
+
+ auto check = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = info.GetIsolate();
+
+ auto ret = eio_file_check(extract_eio_file(info.This()));
+ return compatibility_return(compatibility_new<Boolean>(isolate, ret),
+ info);
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "cancel"),
+ compatibility_new<FunctionTemplate>(isolate, cancel)
+ ->GetFunction());
+ ret->Set(compatibility_new<String>(isolate, "check"),
+ compatibility_new<FunctionTemplate>(isolate, check)
+ ->GetFunction());
+
+ compatibility_set_pointer_internal_field(ret, 0, file);
+
+ return ret;
+}
+
+static Eina_File* extract_eina_file(v8::Local<v8::Object> object)
+{
+ return compatibility_get_pointer_internal_field<Eina_File*>(object, 0);
+}
+
+static v8::Local<v8::Object> wrap_eina_file(Eina_File *file,
+ v8::Isolate *isolate)
+{
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::Object;
+ using v8::FunctionTemplate;
+ using v8::WeakCallbackData;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ /* TODO:
+
+ Eina_File only handle files open in read-only mode. Althought there
+ aren't many useful functions exposed to a JavaScript binding, the exposed
+ `file->fd` can be used to expose a few read operations found in
+ `<cstdio>`.
+ */
+
+ auto close = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ auto o = info.This();
+
+ auto file = extract_eina_file(o);
+ if (!file)
+ return compatibility_return();
+
+ eina_file_close(file);
+ compatibility_set_pointer_internal_field<void*>(o, 0, nullptr);
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "close"),
+ compatibility_new<FunctionTemplate>(isolate, close)
+ ->GetFunction());
+
+ compatibility_set_pointer_internal_field(ret, 0, file);
+
+ auto on_gc = [ret]() {
+ auto file = extract_eina_file(ret);
+
+ if (file) {
+ eina_file_close(file);
+ compatibility_set_pointer_internal_field<void*>(ret, 0, nullptr);
+ }
+ };
+
+ efl::eina::js::make_weak(isolate, ret, on_gc);
+
+ return ret;
+}
+
+static Eio_Monitor* extract_monitor(v8::Local<v8::Object> object)
+{
+ return compatibility_get_pointer_internal_field<Eio_Monitor*>(object, 0);
+}
+
+static v8::Local<v8::Object> wrap_monitor(Eio_Monitor *monitor,
+ v8::Isolate *isolate)
+{
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ eio_monitor_del(extract_monitor(info.This()));
+ return compatibility_return();
+ };
+
+ auto path_get = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ auto ret = eio_monitor_path_get(extract_monitor(info.This()));
+ return compatibility_return(compatibility_new<String>(info.GetIsolate(),
+ ret),
+ info);
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+ ret->Set(compatibility_new<String>(isolate, "path_get"),
+ compatibility_new<FunctionTemplate>(isolate, path_get)
+ ->GetFunction());
+
+ compatibility_set_pointer_internal_field(ret, 0, monitor);
+
+ return ret;
+}
+
+static Ecore_Event_Handler *extract_event_handler(v8::Local<v8::Object> object)
+{
+ return compatibility_get_pointer_internal_field<Ecore_Event_Handler*>
+ (object, 0);
+}
+
+static v8::Local<v8::Object> wrap_event_handler(Ecore_Event_Handler *handler,
+ v8::Isolate *isolate)
+{
+ using v8::String;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+ using v8::Value;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ auto p = ecore_event_handler_del(extract_event_handler(info.This()));
+
+ auto per = static_cast<efl::eina::js::global_ref<Value>*>(p);
+ per->dispose();
+ delete per;
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+
+ compatibility_set_pointer_internal_field(ret, 0, handler);
+
+ return ret;
+}
+
+static
+v8::Local<v8::Object> wrap_eina_file_direct_info(const Eina_File_Direct_Info*
+ info,
+ v8::Isolate *isolate)
+{
+ using v8::Object;
+ using v8::String;
+ using v8::Integer;
+
+ auto wrapped_info = compatibility_new<Object>(isolate);
+
+ wrapped_info->Set(compatibility_new<String>(isolate, "path_length"),
+ compatibility_new<Integer>(isolate, info->path_length));
+ wrapped_info->Set(compatibility_new<String>(isolate, "mame_length"),
+ compatibility_new<Integer>(isolate, info->name_length));
+ wrapped_info->Set(compatibility_new<String>(isolate, "name_start"),
+ compatibility_new<Integer>(isolate, info->name_start));
+ wrapped_info->Set(compatibility_new<String>(isolate, "type"),
+ compatibility_new<Integer>(isolate, info->type));
+ wrapped_info->Set(compatibility_new<String>(isolate, "path"),
+ compatibility_new<String>(isolate, info->path));
+
+ return wrapped_info;
+}
+
+EAPI
+void register_init(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto init = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = eio_init();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, init)
+ ->GetFunction());
+}
+
+EAPI
+void register_shutdown(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto shutdown = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = eio_shutdown();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, shutdown)
+ ->GetFunction());
+}
+
+EAPI
+void register_op_file_copy(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name, compatibility_new<Integer>(isolate, EIO_FILE_COPY));
+}
+
+EAPI
+void register_op_file_move(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name, compatibility_new<Integer>(isolate, EIO_FILE_MOVE));
+}
+
+EAPI
+void register_op_dir_copy(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name, compatibility_new<Integer>(isolate, EIO_DIR_COPY));
+}
+
+EAPI
+void register_op_dir_move(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name, compatibility_new<Integer>(isolate, EIO_DIR_MOVE));
+}
+
+EAPI
+void register_op_unlink(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name, compatibility_new<Integer>(isolate, EIO_UNLINK));
+}
+
+EAPI
+void register_op_file_getpwnam(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name, compatibility_new<Integer>(isolate, EIO_FILE_GETPWNAM));
+}
+
+EAPI
+void register_op_file_getgrnam(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name, compatibility_new<Integer>(isolate, EIO_FILE_GETGRNAM));
+}
+
+EAPI
+void register_file_open(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::Value;
+ using v8::String;
+ using v8::FunctionTemplate;
+ using v8::Function;
+ using v8::Handle;
+ using std::unique_ptr;
+
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 4 || !args[0]->IsString() || !args[1]->IsBoolean()
+ || !args[2]->IsFunction() || !args[3]->IsFunction())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+
+ auto cb_data = unique_ptr<persistent_t[]>(new persistent_t[2]);
+ cb_data[0] = persistent_t(isolate, args[2]);
+ cb_data[1] = persistent_t(isolate, args[3]);
+
+ auto open_cb = [](void *data, Eio_File *handler, Eina_File *file) {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ wrap_eina_file(file, isolate)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] persistent;
+ };
+ auto error_cb = [](void *data, Eio_File *handler, int error) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 1;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<Integer>(isolate, error)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] (persistent - 1);
+ };
+
+ auto ret = eio_file_open(*String::Utf8Value(args[0]),
+ args[1]->BooleanValue(), open_cb, error_cb,
+ cb_data.release());
+
+ return compatibility_return(wrap_eio_file(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_monitor_file_created(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, EIO_MONITOR_FILE_CREATED));
+}
+
+EAPI
+void register_monitor_file_deleted(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, EIO_MONITOR_FILE_DELETED));
+}
+
+EAPI
+void register_monitor_file_modified(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, EIO_MONITOR_FILE_MODIFIED));
+}
+
+EAPI
+void register_monitor_file_closed(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, EIO_MONITOR_FILE_CLOSED));
+}
+
+EAPI
+void register_monitor_directory_created(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ EIO_MONITOR_DIRECTORY_CREATED));
+}
+
+EAPI
+void register_monitor_directory_deleted(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ EIO_MONITOR_DIRECTORY_DELETED));
+}
+
+EAPI
+void register_monitor_directory_modified(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ EIO_MONITOR_DIRECTORY_MODIFIED));
+}
+
+EAPI
+void register_monitor_directory_closed(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ EIO_MONITOR_DIRECTORY_CLOSED));
+}
+
+EAPI
+void register_monitor_self_rename(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, EIO_MONITOR_SELF_RENAME));
+}
+
+EAPI
+void register_monitor_self_deleted(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, EIO_MONITOR_SELF_DELETED));
+}
+
+EAPI
+void register_monitor_error(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, EIO_MONITOR_ERROR));
+}
+
+EAPI
+void register_monitor_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::FunctionTemplate;
+ using v8::Handle;
+ using v8::Value;
+ using v8::Function;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = eio_monitor_add(*String::Utf8Value(args[0]));
+ return compatibility_return(wrap_monitor(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+template<int &wanted_event>
+static
+void register_monitor_event_handler_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::String;
+ using v8::Value;
+ using v8::Object;
+ using v8::Function;
+ using v8::Handle;
+ using v8::Local;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsFunction())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+
+ auto p = new efl::eina::js::global_ref<Value>(isolate, args[0]);
+
+ auto cb = [](void *d, int type, void *event) -> Eina_Bool {
+ auto p = reinterpret_cast<efl::eina::js::global_ref<Value>*>(d);
+ auto e = reinterpret_cast<Eio_Monitor_Event*>(event);
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ auto o = p->handle();
+ auto wrapped_event = compatibility_new<Object>(isolate);
+
+ wrapped_event->Set(compatibility_new<String>(isolate, "monitor"),
+ wrap_monitor(e->monitor, isolate));
+ wrapped_event->Set(compatibility_new<String>(isolate, "filename"),
+ compatibility_new<String>(isolate, e->filename));
+
+ Handle<Value> args[2]{
+ compatibility_new<Integer>(isolate, type),
+ wrapped_event
+ };
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+
+ auto ret = ecore_event_handler_add(wanted_event, cb, p);
+ return compatibility_return(wrap_event_handler(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void
+register_event_monitor_file_created_handler_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ return register_monitor_event_handler_add<EIO_MONITOR_FILE_CREATED>
+ (isolate, global, name);
+}
+
+EAPI
+void
+register_event_monitor_file_deleted_handler_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ return register_monitor_event_handler_add<EIO_MONITOR_FILE_DELETED>
+ (isolate, global, name);
+}
+
+EAPI
+void
+register_event_monitor_file_modified_handler_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ return register_monitor_event_handler_add<EIO_MONITOR_FILE_MODIFIED>
+ (isolate, global, name);
+}
+
+EAPI
+void
+register_event_monitor_file_closed_handler_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ return register_monitor_event_handler_add<EIO_MONITOR_FILE_CLOSED>
+ (isolate, global, name);
+}
+
+EAPI
+void register_event_monitor_directory_created_handler_add
+(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ return register_monitor_event_handler_add<EIO_MONITOR_DIRECTORY_CREATED>
+ (isolate, global, name);
+}
+
+EAPI
+void register_event_monitor_directory_deleted_handler_add
+(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ return register_monitor_event_handler_add<EIO_MONITOR_DIRECTORY_DELETED>
+ (isolate, global, name);
+}
+
+EAPI
+void register_event_monitor_directory_modified_handler_add
+(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ return register_monitor_event_handler_add<EIO_MONITOR_DIRECTORY_MODIFIED>
+ (isolate, global, name);
+}
+
+EAPI
+void register_event_monitor_directory_closed_handler_add
+(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ return register_monitor_event_handler_add<EIO_MONITOR_DIRECTORY_CLOSED>
+ (isolate, global, name);
+}
+
+EAPI
+void
+register_event_monitor_self_rename_handler_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ return register_monitor_event_handler_add<EIO_MONITOR_SELF_RENAME>
+ (isolate, global, name);
+}
+
+EAPI
+void
+register_event_monitor_self_deleted_handler_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ return register_monitor_event_handler_add<EIO_MONITOR_SELF_DELETED>
+ (isolate, global, name);
+}
+
+EAPI
+void
+register_event_monitor_error_handler_add(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ return register_monitor_event_handler_add<EIO_MONITOR_ERROR>
+ (isolate, global, name);
+}
+
+EAPI
+void register_file_ls(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::FunctionTemplate;
+ using v8::Handle;
+ using v8::Value;
+ using v8::Function;
+ using std::unique_ptr;
+
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 5 || !args[0]->IsString() || !args[1]->IsFunction()
+ || !args[2]->IsFunction() || !args[3]->IsFunction()
+ || !args[4]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+
+ auto cb_data = unique_ptr<persistent_t[]>(new persistent_t[4]);
+ cb_data[0] = persistent_t(isolate, args[1]);
+ cb_data[1] = persistent_t(isolate, args[2]);
+ cb_data[2] = persistent_t(isolate, args[3]);
+ cb_data[3] = persistent_t(isolate, args[4]);
+
+ auto filter_cb = [](void *data, Eio_File *handler, const char *file)
+ -> Eina_Bool {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<String>(isolate, file)
+ };
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+ auto main_cb = [](void *data, Eio_File *handler, const char *file) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 1;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<String>(isolate, file)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ };
+ auto done_cb = [](void *data, Eio_File *handler) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 2;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args = wrap_eio_file(handler, isolate);
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+
+ delete[] (persistent - 2);
+ };
+ auto error_cb = [](void *data, Eio_File *handler, int error) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 3;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<Integer>(isolate, error)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] (persistent - 3);
+ };
+
+ auto ret = eio_file_ls(*String::Utf8Value(args[0]), filter_cb, main_cb,
+ done_cb, error_cb, cb_data.release());
+ return compatibility_return(wrap_eio_file(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_file_chmod(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::FunctionTemplate;
+ using v8::Handle;
+ using v8::Value;
+ using v8::Function;
+ using std::unique_ptr;
+
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 4 || !args[0]->IsString() || !args[1]->IsNumber()
+ || !args[2]->IsFunction() || !args[3]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+
+ auto cb_data = unique_ptr<persistent_t[]>(new persistent_t[2]);
+ cb_data[0] = persistent_t(isolate, args[2]);
+ cb_data[1] = persistent_t(isolate, args[3]);
+ auto done_cb = [](void *data, Eio_File *handler) {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args = wrap_eio_file(handler, isolate);
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+
+ delete[] persistent;
+ };
+ auto error_cb = [](void *data, Eio_File *handler, int error) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 1;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<Integer>(isolate, error)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] (persistent - 1);
+ };
+
+ auto ret = eio_file_chmod(*String::Utf8Value(args[0]),
+ args[1]->IntegerValue(), done_cb, error_cb,
+ cb_data.release());
+ return compatibility_return(wrap_eio_file(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_file_chown(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::FunctionTemplate;
+ using v8::Handle;
+ using v8::Value;
+ using v8::Function;
+ using std::unique_ptr;
+
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 5 || !args[0]->IsString() || !args[1]->IsString()
+ || !args[2]->IsString() || !args[3]->IsFunction()
+ || !args[4]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+
+ auto cb_data = unique_ptr<persistent_t[]>(new persistent_t[2]);
+ cb_data[0] = persistent_t(isolate, args[3]);
+ cb_data[1] = persistent_t(isolate, args[4]);
+ auto done_cb = [](void *data, Eio_File *handler) {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args = wrap_eio_file(handler, isolate);
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+
+ delete[] persistent;
+ };
+ auto error_cb = [](void *data, Eio_File *handler, int error) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 1;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<Integer>(isolate, error)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] (persistent - 1);
+ };
+
+ auto ret = eio_file_chown(*String::Utf8Value(args[0]),
+ *String::Utf8Value(args[1]),
+ *String::Utf8Value(args[2]), done_cb,
+ error_cb,
+ cb_data.release());
+ return compatibility_return(wrap_eio_file(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_file_unlink(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::FunctionTemplate;
+ using v8::Handle;
+ using v8::Value;
+ using v8::Function;
+ using std::unique_ptr;
+
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 3 || !args[0]->IsString() || !args[1]->IsFunction()
+ || !args[2]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+
+ auto cb_data = unique_ptr<persistent_t[]>(new persistent_t[2]);
+ cb_data[0] = persistent_t(isolate, args[1]);
+ cb_data[1] = persistent_t(isolate, args[2]);
+ auto done_cb = [](void *data, Eio_File *handler) {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args = wrap_eio_file(handler, isolate);
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+
+ delete[] persistent;
+ };
+ auto error_cb = [](void *data, Eio_File *handler, int error) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 1;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<Integer>(isolate, error)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] (persistent - 1);
+ };
+
+ auto ret = eio_file_unlink(*String::Utf8Value(args[0]), done_cb,
+ error_cb, cb_data.release());
+ return compatibility_return(wrap_eio_file(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_file_mkdir(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::FunctionTemplate;
+ using v8::Handle;
+ using v8::Value;
+ using v8::Function;
+ using std::unique_ptr;
+
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 4 || !args[0]->IsString() || !args[1]->IsNumber()
+ || !args[2]->IsString() || !args[3]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+
+ auto cb_data = unique_ptr<persistent_t[]>(new persistent_t[2]);
+ cb_data[0] = persistent_t(isolate, args[2]);
+ cb_data[1] = persistent_t(isolate, args[3]);
+ auto done_cb = [](void *data, Eio_File *handler) {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args = wrap_eio_file(handler, isolate);
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+
+ delete[] persistent;
+ };
+ auto error_cb = [](void *data, Eio_File *handler, int error) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 1;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<Integer>(isolate, error)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] (persistent - 1);
+ };
+
+ auto ret = eio_file_mkdir(*String::Utf8Value(args[0]),
+ args[1]->IntegerValue(), done_cb, error_cb,
+ cb_data.release());
+ return compatibility_return(wrap_eio_file(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_file_move(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::Number;
+ using v8::Object;
+ using v8::FunctionTemplate;
+ using v8::Handle;
+ using v8::Value;
+ using v8::Function;
+ using std::unique_ptr;
+
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 5 || !args[0]->IsString() || !args[1]->IsString()
+ || !args[2]->IsFunction() || !args[3]->IsFunction()
+ || !args[4]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+
+ auto cb_data = unique_ptr<persistent_t[]>(new persistent_t[3]);
+ cb_data[0] = persistent_t(isolate, args[2]);
+ cb_data[1] = persistent_t(isolate, args[3]);
+ cb_data[2] = persistent_t(isolate, args[4]);
+ auto progress_cb = [](void *data, Eio_File *handler,
+ const Eio_Progress *info) {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ auto wrapped_info = compatibility_new<Object>(isolate);
+
+ wrapped_info->Set(compatibility_new<String>(isolate, "op"),
+ compatibility_new<Integer>(isolate, info->op));
+ wrapped_info->Set(compatibility_new<String>(isolate, "current"),
+ compatibility_new<Integer>(isolate,
+ info->current));
+ wrapped_info->Set(compatibility_new<String>(isolate, "max"),
+ compatibility_new<Integer>(isolate, info->max));
+ wrapped_info->Set(compatibility_new<String>(isolate, "percent"),
+ compatibility_new<Number>(isolate,
+ info->percent));
+ wrapped_info->Set(compatibility_new<String>(isolate, "source"),
+ compatibility_new<String>(isolate, info->source));
+ wrapped_info->Set(compatibility_new<String>(isolate, "dest"),
+ compatibility_new<String>(isolate, info->dest));
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ wrapped_info
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ };
+ auto done_cb = [](void *data, Eio_File *handler) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 1;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args = wrap_eio_file(handler, isolate);
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+
+ delete[] (persistent - 1);
+ };
+ auto error_cb = [](void *data, Eio_File *handler, int error) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 2;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<Integer>(isolate, error)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] (persistent - 2);
+ };
+
+ auto ret = eio_file_move(*String::Utf8Value(args[0]),
+ *String::Utf8Value(args[1]),
+ progress_cb, done_cb, error_cb,
+ cb_data.release());
+ return compatibility_return(wrap_eio_file(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_file_copy(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::Number;
+ using v8::Object;
+ using v8::FunctionTemplate;
+ using v8::Handle;
+ using v8::Value;
+ using v8::Function;
+ using std::unique_ptr;
+
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 5 || !args[0]->IsString() || !args[1]->IsString()
+ || !args[2]->IsFunction() || !args[3]->IsFunction()
+ || !args[4]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+
+ auto cb_data = unique_ptr<persistent_t[]>(new persistent_t[3]);
+ cb_data[0] = persistent_t(isolate, args[2]);
+ cb_data[1] = persistent_t(isolate, args[3]);
+ cb_data[2] = persistent_t(isolate, args[4]);
+ auto progress_cb = [](void *data, Eio_File *handler,
+ const Eio_Progress *info) {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ auto wrapped_info = compatibility_new<Object>(isolate);
+
+ wrapped_info->Set(compatibility_new<String>(isolate, "op"),
+ compatibility_new<Integer>(isolate, info->op));
+ wrapped_info->Set(compatibility_new<String>(isolate, "current"),
+ compatibility_new<Integer>(isolate,
+ info->current));
+ wrapped_info->Set(compatibility_new<String>(isolate, "max"),
+ compatibility_new<Integer>(isolate, info->max));
+ wrapped_info->Set(compatibility_new<String>(isolate, "percent"),
+ compatibility_new<Number>(isolate,
+ info->percent));
+ wrapped_info->Set(compatibility_new<String>(isolate, "source"),
+ compatibility_new<String>(isolate, info->source));
+ wrapped_info->Set(compatibility_new<String>(isolate, "dest"),
+ compatibility_new<String>(isolate, info->dest));
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ wrapped_info
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ };
+ auto done_cb = [](void *data, Eio_File *handler) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 1;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args = wrap_eio_file(handler, isolate);
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+
+ delete[] (persistent - 1);
+ };
+ auto error_cb = [](void *data, Eio_File *handler, int error) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 2;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<Integer>(isolate, error)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] (persistent - 2);
+ };
+
+ auto ret = eio_file_copy(*String::Utf8Value(args[0]),
+ *String::Utf8Value(args[1]),
+ progress_cb, done_cb, error_cb,
+ cb_data.release());
+ return compatibility_return(wrap_eio_file(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_dir_move(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::Number;
+ using v8::Object;
+ using v8::FunctionTemplate;
+ using v8::Handle;
+ using v8::Value;
+ using v8::Function;
+ using std::unique_ptr;
+
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 6 || !args[0]->IsString() || !args[1]->IsString()
+ || !args[2]->IsFunction() || !args[3]->IsFunction()
+ || !args[4]->IsFunction() || !args[5]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+
+ auto cb_data = unique_ptr<persistent_t[]>(new persistent_t[4]);
+ cb_data[0] = persistent_t(isolate, args[2]);
+ cb_data[1] = persistent_t(isolate, args[3]);
+ cb_data[2] = persistent_t(isolate, args[4]);
+ cb_data[3] = persistent_t(isolate, args[5]);
+ auto filter_cb = [](void *data, Eio_File *handler,
+ const Eina_File_Direct_Info *info) -> Eina_Bool {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ wrap_eina_file_direct_info(info, isolate)
+ };
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+ auto progress_cb = [](void *data, Eio_File *handler,
+ const Eio_Progress *info) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 1;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ auto wrapped_info = compatibility_new<Object>(isolate);
+
+ wrapped_info->Set(compatibility_new<String>(isolate, "op"),
+ compatibility_new<Integer>(isolate, info->op));
+ wrapped_info->Set(compatibility_new<String>(isolate, "current"),
+ compatibility_new<Integer>(isolate,
+ info->current));
+ wrapped_info->Set(compatibility_new<String>(isolate, "max"),
+ compatibility_new<Integer>(isolate, info->max));
+ wrapped_info->Set(compatibility_new<String>(isolate, "percent"),
+ compatibility_new<Number>(isolate,
+ info->percent));
+ wrapped_info->Set(compatibility_new<String>(isolate, "source"),
+ compatibility_new<String>(isolate, info->source));
+ wrapped_info->Set(compatibility_new<String>(isolate, "dest"),
+ compatibility_new<String>(isolate, info->dest));
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ wrapped_info
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ };
+ auto done_cb = [](void *data, Eio_File *handler) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 2;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args = wrap_eio_file(handler, isolate);
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+
+ delete[] (persistent - 2);
+ };
+ auto error_cb = [](void *data, Eio_File *handler, int error) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 3;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<Integer>(isolate, error)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] (persistent - 3);
+ };
+
+ auto ret = eio_dir_move(*String::Utf8Value(args[0]),
+ *String::Utf8Value(args[1]), filter_cb,
+ progress_cb, done_cb, error_cb,
+ cb_data.release());
+ return compatibility_return(wrap_eio_file(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_dir_copy(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::Number;
+ using v8::Object;
+ using v8::FunctionTemplate;
+ using v8::Handle;
+ using v8::Value;
+ using v8::Function;
+ using std::unique_ptr;
+
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 6 || !args[0]->IsString() || !args[1]->IsString()
+ || !args[2]->IsFunction() || !args[3]->IsFunction()
+ || !args[4]->IsFunction() || !args[5]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+
+ auto cb_data = unique_ptr<persistent_t[]>(new persistent_t[4]);
+ cb_data[0] = persistent_t(isolate, args[2]);
+ cb_data[1] = persistent_t(isolate, args[3]);
+ cb_data[2] = persistent_t(isolate, args[4]);
+ cb_data[3] = persistent_t(isolate, args[5]);
+ auto filter_cb = [](void *data, Eio_File *handler,
+ const Eina_File_Direct_Info *info) -> Eina_Bool {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ wrap_eina_file_direct_info(info, isolate)
+ };
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+ auto progress_cb = [](void *data, Eio_File *handler,
+ const Eio_Progress *info) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 1;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ auto wrapped_info = compatibility_new<Object>(isolate);
+
+ wrapped_info->Set(compatibility_new<String>(isolate, "op"),
+ compatibility_new<Integer>(isolate, info->op));
+ wrapped_info->Set(compatibility_new<String>(isolate, "current"),
+ compatibility_new<Integer>(isolate,
+ info->current));
+ wrapped_info->Set(compatibility_new<String>(isolate, "max"),
+ compatibility_new<Integer>(isolate, info->max));
+ wrapped_info->Set(compatibility_new<String>(isolate, "percent"),
+ compatibility_new<Number>(isolate,
+ info->percent));
+ wrapped_info->Set(compatibility_new<String>(isolate, "source"),
+ compatibility_new<String>(isolate, info->source));
+ wrapped_info->Set(compatibility_new<String>(isolate, "dest"),
+ compatibility_new<String>(isolate, info->dest));
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ wrapped_info
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ };
+ auto done_cb = [](void *data, Eio_File *handler) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 2;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args = wrap_eio_file(handler, isolate);
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+
+ delete[] (persistent - 2);
+ };
+ auto error_cb = [](void *data, Eio_File *handler, int error) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 3;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<Integer>(isolate, error)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] (persistent - 3);
+ };
+
+ auto ret = eio_dir_copy(*String::Utf8Value(args[0]),
+ *String::Utf8Value(args[1]), filter_cb,
+ progress_cb, done_cb, error_cb,
+ cb_data.release());
+ return compatibility_return(wrap_eio_file(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+void register_dir_unlink(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::Number;
+ using v8::Object;
+ using v8::FunctionTemplate;
+ using v8::Handle;
+ using v8::Value;
+ using v8::Function;
+ using std::unique_ptr;
+
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 5 || !args[0]->IsString() || !args[1]->IsFunction()
+ || !args[2]->IsFunction() || !args[3]->IsFunction()
+ || !args[4]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+
+ auto cb_data = unique_ptr<persistent_t[]>(new persistent_t[4]);
+ cb_data[0] = persistent_t(isolate, args[1]);
+ cb_data[1] = persistent_t(isolate, args[2]);
+ cb_data[2] = persistent_t(isolate, args[3]);
+ cb_data[3] = persistent_t(isolate, args[4]);
+ auto filter_cb = [](void *data, Eio_File *handler,
+ const Eina_File_Direct_Info *info) -> Eina_Bool {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ wrap_eina_file_direct_info(info, isolate)
+ };
+
+ auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+ return bret ? EINA_TRUE : EINA_FALSE;
+ };
+ auto progress_cb = [](void *data, Eio_File *handler,
+ const Eio_Progress *info) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 1;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ auto wrapped_info = compatibility_new<Object>(isolate);
+
+ wrapped_info->Set(compatibility_new<String>(isolate, "op"),
+ compatibility_new<Integer>(isolate, info->op));
+ wrapped_info->Set(compatibility_new<String>(isolate, "current"),
+ compatibility_new<Integer>(isolate,
+ info->current));
+ wrapped_info->Set(compatibility_new<String>(isolate, "max"),
+ compatibility_new<Integer>(isolate, info->max));
+ wrapped_info->Set(compatibility_new<String>(isolate, "percent"),
+ compatibility_new<Number>(isolate,
+ info->percent));
+ wrapped_info->Set(compatibility_new<String>(isolate, "source"),
+ compatibility_new<String>(isolate, info->source));
+ wrapped_info->Set(compatibility_new<String>(isolate, "dest"),
+ compatibility_new<String>(isolate, info->dest));
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ wrapped_info
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+ };
+ auto done_cb = [](void *data, Eio_File *handler) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 2;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args = wrap_eio_file(handler, isolate);
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+
+ delete[] (persistent - 2);
+ };
+ auto error_cb = [](void *data, Eio_File *handler, int error) {
+ auto persistent = reinterpret_cast<persistent_t*>(data) + 3;
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_eio_file(handler, isolate),
+ compatibility_new<Integer>(isolate, error)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete[] (persistent - 3);
+ };
+
+ auto ret = eio_dir_unlink(*String::Utf8Value(args[0]), filter_cb,
+ progress_cb, done_cb, error_cb,
+ cb_data.release());
+ return compatibility_return(wrap_eio_file(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+}
+
+EAPI
+void register_eio(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
+{
+ using v8::String;
+ register_init(isolate, exports,
+ compatibility_new<String>(isolate, "eio_init"));
+ register_shutdown(isolate, exports,
+ compatibility_new<String>(isolate, "eio_shutdown"));
+ register_op_file_copy(isolate, exports,
+ compatibility_new<String>(isolate, "EIO_FILE_COPY"));
+ register_op_file_move(isolate, exports,
+ compatibility_new<String>(isolate, "EIO_FILE_MOVE"));
+ register_op_dir_copy(isolate, exports,
+ compatibility_new<String>(isolate, "EIO_DIR_COPY"));
+ register_op_dir_move(isolate, exports,
+ compatibility_new<String>(isolate, "EIO_DIR_MOVE"));
+ register_op_unlink(isolate, exports,
+ compatibility_new<String>(isolate, "EIO_LINK"));
+ register_op_file_getpwnam(isolate, exports,
+ compatibility_new<String>(isolate,
+ "EIO_FILE_GETPWNAM"));
+ register_op_file_getgrnam(isolate, exports,
+ compatibility_new<String>(isolate,
+ "EIO_FILE_GETGRNAM"));
+ register_file_open(isolate, exports,
+ compatibility_new<String>(isolate, "eio_file_open"));
+ register_monitor_file_created(isolate, exports,
+ compatibility_new<String>(isolate,
+ "EIO_MONITOR_FILE"
+ "_CREATED"));
+ register_monitor_file_deleted(isolate, exports,
+ compatibility_new<String>(isolate,
+ "EIO_MONITOR_FILE"
+ "_DELETED"));
+ register_monitor_file_modified(isolate, exports,
+ compatibility_new<String>(isolate,
+ "EIO_MONITOR_FILE"
+ "_MODIFIED"));
+ register_monitor_file_closed(isolate, exports,
+ compatibility_new<String>(isolate,
+ "EIO_MONITOR_FILE"
+ "_CLOSED"));
+ register_monitor_directory_created(isolate, exports,
+ compatibility_new<String>
+ (isolate,
+ "EIO_MONITOR_DIRECTORY_CREATED"));
+ register_monitor_directory_deleted(isolate, exports,
+ compatibility_new<String>
+ (isolate,
+ "EIO_MONITOR_DIRECTORY_DELETED"));
+ register_monitor_directory_modified(isolate, exports,
+ compatibility_new<String>
+ (isolate,
+ "EIO_MONITOR_DIRECTORY_MODIFIED"));
+ register_monitor_directory_closed(isolate, exports,
+ compatibility_new<String>
+ (isolate, "EIO_MONITOR_DIRECTORY_CLOSED"));
+ register_monitor_self_rename(isolate, exports,
+ compatibility_new<String>
+ (isolate, "EIO_MONITOR_SELF_RENAME"));
+ register_monitor_self_deleted(isolate, exports,
+ compatibility_new<String>
+ (isolate, "EIO_MONITOR_SELF_DELETED"));
+ register_monitor_error(isolate, exports,
+ compatibility_new<String>(isolate,
+ "EIO_MONITOR_ERROR"));
+ register_monitor_add(isolate, exports,
+ compatibility_new<String>(isolate, "eio_monitor_add"));
+ register_event_monitor_file_created_handler_add
+ (isolate, exports,
+ compatibility_new<String>(isolate,
+ "eio_event_monitor_file_created_handler_add"));
+ register_event_monitor_file_deleted_handler_add
+ (isolate, exports,
+ compatibility_new<String>(isolate,
+ "eio_event_monitor_file_deleted_handler_add"));
+ register_event_monitor_file_modified_handler_add
+ (isolate, exports,
+ compatibility_new<String>
+ (isolate, "eio_event_monitor_file_modified_handler_add"));
+ register_event_monitor_file_closed_handler_add
+ (isolate, exports,
+ compatibility_new<String>(isolate,
+ "eio_event_monitor_file_closed_handler_add"));
+ register_event_monitor_directory_created_handler_add
+ (isolate, exports,
+ compatibility_new<String>
+ (isolate, "eio_event_monitor_directory_created_handler_add"));
+ register_event_monitor_directory_deleted_handler_add
+ (isolate, exports,
+ compatibility_new<String>
+ (isolate, "eio_event_monitor_directory_deleted_handler_add"));
+ register_event_monitor_directory_modified_handler_add
+ (isolate, exports,
+ compatibility_new<String>
+ (isolate, "eio_event_monitor_directory_modified_handler_add"));
+ register_event_monitor_directory_closed_handler_add
+ (isolate, exports,
+ compatibility_new<String>
+ (isolate, "eio_event_monitor_directory_closed_handler_add"));
+ register_event_monitor_self_rename_handler_add
+ (isolate, exports,
+ compatibility_new<String>(isolate,
+ "eio_event_monitor_self_rename_handler_add"));
+ register_event_monitor_self_deleted_handler_add
+ (isolate, exports,
+ compatibility_new<String>(isolate,
+ "eio_event_monitor_self_deleted_handler_add"));
+ register_event_monitor_error_handler_add
+ (isolate, exports,
+ compatibility_new<String>(isolate,
+ "eio_event_monitor_error_handler_add"));
+ register_file_ls(isolate, exports,
+ compatibility_new<String>(isolate, "eio_file_ls"));
+ register_file_chmod(isolate, exports,
+ compatibility_new<String>(isolate, "eio_file_chmod"));
+ register_file_chown(isolate, exports,
+ compatibility_new<String>(isolate, "eio_file_chown"));
+ register_file_unlink(isolate, exports,
+ compatibility_new<String>(isolate, "eio_file_unlink"));
+ register_file_mkdir(isolate, exports,
+ compatibility_new<String>(isolate, "eio_file_mkdir"));
+ register_file_move(isolate, exports,
+ compatibility_new<String>(isolate, "eio_file_move"));
+ register_file_copy(isolate, exports,
+ compatibility_new<String>(isolate, "eio_file_copy"));
+ register_dir_move(isolate, exports,
+ compatibility_new<String>(isolate, "eio_dir_move"));
+ register_dir_copy(isolate, exports,
+ compatibility_new<String>(isolate, "eio_dir_copy"));
+ register_dir_unlink(isolate, exports,
+ compatibility_new<String>(isolate, "eio_dir_unlink"));
+}
+
+} } } // namespace efl { namespace eio { namespace js {
diff --git a/src/bindings/eldbus_cxx/eldbus_freedesktop.hh b/src/bindings/eldbus_cxx/eldbus_freedesktop.hh
index e44b9b228d..4af8c58e30 100644
--- a/src/bindings/eldbus_cxx/eldbus_freedesktop.hh
+++ b/src/bindings/eldbus_cxx/eldbus_freedesktop.hh
@@ -11,7 +11,6 @@ namespace efl { namespace eldbus { namespace _detail {
template <typename Callback, typename... Ins>
void _callback_wrapper(void* data, Eldbus_Message const* message, Eldbus_Pending* pending)
{
- std::cout << "_callback_wrapper" << std::endl;
Callback* callback(static_cast<Callback*>(data));
const char* errname, *errmsg;
diff --git a/src/bindings/eldbus_js/Eldbus_Js.hh b/src/bindings/eldbus_js/Eldbus_Js.hh
new file mode 100644
index 0000000000..00da9ca924
--- /dev/null
+++ b/src/bindings/eldbus_js/Eldbus_Js.hh
@@ -0,0 +1,48 @@
+
+#ifndef EFL_ELDBUS_JS_HH
+#define EFL_ELDBUS_JS_HH
+
+#include <Eina.hh>
+#include <Eina_Js.hh>
+
+#include <Eldbus.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_EINA_JS_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+namespace efl { namespace eldbus { namespace js {
+
+EAPI void register_eldbus_connection(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
+EAPI void register_eldbus_core(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
+EAPI void register_eldbus_message(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
+EAPI void register_eldbus_object_mapper(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
+EAPI void register_eldbus(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
+
+} } }
+
+#include <eldbus_js_util.hh>
+
+#endif
diff --git a/src/bindings/eldbus_js/eldbus_js_connection.cc b/src/bindings/eldbus_js/eldbus_js_connection.cc
new file mode 100644
index 0000000000..c02dc8c600
--- /dev/null
+++ b/src/bindings/eldbus_js/eldbus_js_connection.cc
@@ -0,0 +1,543 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Eldbus_Js.hh>
+
+namespace efl { namespace eldbus { namespace js {
+
+namespace {
+
+v8::Local<v8::Object> wrap_event_callback(Eldbus_Connection *conn,
+ Eldbus_Connection_Event_Type type,
+ Eldbus_Connection_Event_Cb cb,
+ void *cb_data, v8::Isolate *isolate)
+{
+ using v8::String;
+ using v8::Integer;
+ using v8::Value;
+ using v8::Object;
+ using v8::ObjectTemplate;
+ using v8::FunctionTemplate;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(3);
+ auto ret = obj_tpl->NewInstance();
+
+ ret->Set(compatibility_new<String>(isolate, "_type"),
+ compatibility_new<Integer>(isolate, type));
+
+ compatibility_set_pointer_internal_field(ret, 0, conn);
+ compatibility_set_pointer_internal_field(ret, 1, (void*)(cb));
+ compatibility_set_pointer_internal_field(ret, 2, cb_data);
+
+ auto del = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ auto o = info.This();
+ auto isolate = info.GetIsolate();
+
+ auto conn
+ = (compatibility_get_pointer_internal_field<Eldbus_Connection*>
+ (o, 0));
+ auto cb
+ = (compatibility_get_pointer_internal_field
+ <Eldbus_Connection_Event_Cb>(o, 1));
+ auto cb_data
+ = (compatibility_get_pointer_internal_field
+ <efl::eina::js::global_ref<Value>*>(o, 2));
+ auto type
+ = (static_cast<Eldbus_Connection_Event_Type>
+ (o->Get(compatibility_new<String>(isolate, "_type"))
+ ->IntegerValue()));
+
+ eldbus_connection_event_callback_del(conn, type, cb, cb_data);
+
+ delete cb_data;
+ return compatibility_return();
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "del"),
+ compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
+
+ return ret;
+}
+
+Eldbus_Connection* extract_eldbus_connection(v8::Local<v8::Object> o)
+{
+ return compatibility_get_pointer_internal_field<Eldbus_Connection*>(o, 0);
+}
+
+void register_timeout_infinite(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name, compatibility_new<Integer>(isolate,
+ ELDBUS_TIMEOUT_INFINITE));
+}
+
+void register_connection_type_unknown(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ELDBUS_CONNECTION_TYPE_UNKNOWN));
+}
+
+void register_connection_type_session(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ELDBUS_CONNECTION_TYPE_SESSION));
+}
+
+void register_connection_type_system(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ELDBUS_CONNECTION_TYPE_SYSTEM));
+}
+
+void register_connection_type_starter(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ELDBUS_CONNECTION_TYPE_STARTER));
+}
+
+void register_connection_type_address(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ELDBUS_CONNECTION_TYPE_ADDRESS));
+}
+
+void register_connection_type_last(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ELDBUS_CONNECTION_TYPE_LAST));
+}
+
+void register_connection_event_del(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name, compatibility_new<Integer>(isolate,
+ ELDBUS_CONNECTION_EVENT_DEL));
+}
+
+void register_connection_event_disconnected(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>
+ (isolate, ELDBUS_CONNECTION_EVENT_DISCONNECTED));
+}
+
+void register_connection_event_last(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name, compatibility_new<Integer>(isolate,
+ ELDBUS_CONNECTION_EVENT_LAST));
+}
+
+void register_connection_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ Eldbus_Connection_Type type;
+
+ switch (args[0]->IntegerValue()) {
+ case ELDBUS_CONNECTION_TYPE_UNKNOWN:
+ type = ELDBUS_CONNECTION_TYPE_UNKNOWN;
+ break;
+ case ELDBUS_CONNECTION_TYPE_SESSION:
+ type = ELDBUS_CONNECTION_TYPE_SESSION;
+ break;
+ case ELDBUS_CONNECTION_TYPE_SYSTEM:
+ type = ELDBUS_CONNECTION_TYPE_SYSTEM;
+ break;
+ case ELDBUS_CONNECTION_TYPE_STARTER:
+ type = ELDBUS_CONNECTION_TYPE_STARTER;
+ break;
+ case ELDBUS_CONNECTION_TYPE_ADDRESS:
+ type = ELDBUS_CONNECTION_TYPE_ADDRESS;
+ break;
+ case ELDBUS_CONNECTION_TYPE_LAST:
+ type = ELDBUS_CONNECTION_TYPE_LAST;
+ break;
+ default:
+ return compatibility_return();
+ }
+ auto ret = eldbus_connection_get(type);
+ return compatibility_return(wrap_eldbus_connection(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_private_connection_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsNumber())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ Eldbus_Connection_Type type;
+
+ switch (args[0]->IntegerValue()) {
+ case ELDBUS_CONNECTION_TYPE_UNKNOWN:
+ type = ELDBUS_CONNECTION_TYPE_UNKNOWN;
+ break;
+ case ELDBUS_CONNECTION_TYPE_SESSION:
+ type = ELDBUS_CONNECTION_TYPE_SESSION;
+ break;
+ case ELDBUS_CONNECTION_TYPE_SYSTEM:
+ type = ELDBUS_CONNECTION_TYPE_SYSTEM;
+ break;
+ case ELDBUS_CONNECTION_TYPE_STARTER:
+ type = ELDBUS_CONNECTION_TYPE_STARTER;
+ break;
+ case ELDBUS_CONNECTION_TYPE_ADDRESS:
+ type = ELDBUS_CONNECTION_TYPE_ADDRESS;
+ break;
+ case ELDBUS_CONNECTION_TYPE_LAST:
+ type = ELDBUS_CONNECTION_TYPE_LAST;
+ break;
+ default:
+ return compatibility_return();
+ }
+ auto ret = eldbus_private_connection_get(type);
+ return compatibility_return(wrap_eldbus_connection(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_address_connection_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+
+ auto ret = eldbus_address_connection_get(*String::Utf8Value(args[0]));
+ return compatibility_return(wrap_eldbus_connection(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_private_address_connection_get(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsString())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+
+ String::Utf8Value address(args[0]);
+
+ auto ret = eldbus_private_address_connection_get(*address);
+ return compatibility_return(wrap_eldbus_connection(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+}
+
+v8::Local<v8::Object> wrap_eldbus_connection(Eldbus_Connection *conn,
+ v8::Isolate *isolate)
+{
+ using v8::String;
+ using v8::Boolean;
+ using v8::Value;
+ using v8::Handle;
+ using v8::ObjectTemplate;
+ using v8::Function;
+ using v8::FunctionTemplate;
+ using std::unique_ptr;
+
+ typedef efl::eina::js::global_ref<Value> persistent_t;
+
+ auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
+ obj_tpl->SetInternalFieldCount(1);
+ auto ret = obj_tpl->NewInstance();
+
+ auto event_callback_add = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 2 || !info[0]->IsNumber()
+ || !info[1]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = info.GetIsolate();
+ auto conn = extract_eldbus_connection(info.This());
+ Eldbus_Connection_Event_Type type;
+
+ switch (info[0]->IntegerValue()) {
+ case ELDBUS_CONNECTION_EVENT_DEL:
+ type = ELDBUS_CONNECTION_EVENT_DEL;
+ break;
+ case ELDBUS_CONNECTION_EVENT_DISCONNECTED:
+ type = ELDBUS_CONNECTION_EVENT_DISCONNECTED;
+ break;
+ case ELDBUS_CONNECTION_EVENT_LAST:
+ type = ELDBUS_CONNECTION_EVENT_LAST;
+ break;
+ default:
+ return compatibility_return();
+ }
+
+ unique_ptr<persistent_t> cb_data{new persistent_t{isolate, info[1]}};
+
+ auto cb = [](void *data, Eldbus_Connection *conn,
+ void */*event_info*/) {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args{wrap_eldbus_connection(conn, isolate)};
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+ };
+
+ eldbus_connection_event_callback_add(conn, type, cb, cb_data.get());
+ auto ret = wrap_event_callback(conn, type, cb, cb_data.release(),
+ isolate);
+ return compatibility_return(ret, info);
+ };
+
+ auto send = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 3 || !info[0]->IsObject() || !info[1]->IsFunction()
+ || !info[2]->IsNumber()) {
+ return compatibility_return();
+ }
+
+ auto isolate = info.GetIsolate();
+ auto conn = extract_eldbus_connection(info.This());
+ auto msg
+ = (compatibility_get_pointer_internal_field<Eldbus_Message*>
+ (info[0]->ToObject(), 0));
+
+ unique_ptr<persistent_t> cb_data{new persistent_t{isolate, info[1]}};
+
+ auto cb = [](void *data, const Eldbus_Message *msg,
+ Eldbus_Pending *pending) {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args[2] = {
+ wrap_const_eldbus_msg(msg, isolate),
+ wrap_eldbus_pending(pending, persistent, isolate)
+ };
+
+ Function::Cast(*o)->Call(o->ToObject(), 2, args);
+
+ delete persistent;
+ };
+
+ auto ret = eldbus_connection_send(conn, msg, cb, cb_data.get(),
+ info[2]->NumberValue());
+ return compatibility_return(wrap_eldbus_pending(ret, cb_data.release(),
+ isolate),
+ info);
+ };
+
+ auto unique_name_get = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = info.GetIsolate();
+ auto conn = extract_eldbus_connection(info.This());
+
+ auto ret = eldbus_connection_unique_name_get(conn);
+ return compatibility_return(compatibility_new<String>(isolate, ret),
+ info);
+ };
+
+ auto object_get = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 2 || !info[0]->IsString() || !info[1]->IsString())
+ return compatibility_return();
+
+ auto isolate = info.GetIsolate();
+ auto conn = extract_eldbus_connection(info.This());
+
+ auto ret = eldbus_object_get(conn, *String::Utf8Value(info[0]),
+ *String::Utf8Value(info[1]));
+ return compatibility_return(wrap_eldbus_object(ret, isolate), info);
+ };
+
+ auto signal_handler_add = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 5 || !info[0]->IsString() || !info[1]->IsString()
+ || !info[2]->IsString() || !info[3]->IsString()
+ || !info[4]->IsFunction()) {
+ return compatibility_return();
+ }
+
+ auto isolate = info.GetIsolate();
+ auto conn = extract_eldbus_connection(info.This());
+
+ unique_ptr<persistent_t> cb_data{new persistent_t{isolate, info[4]}};
+
+ auto cb = [](void *data, const Eldbus_Message *msg) {
+ auto persistent = reinterpret_cast<persistent_t*>(data);
+ auto o = persistent->handle();
+
+ auto isolate = v8::Isolate::GetCurrent();
+
+ Handle<Value> args{wrap_const_eldbus_msg(msg, isolate)};
+
+ Function::Cast(*o)->Call(o->ToObject(), 1, &args);
+ };
+
+ auto ret = eldbus_signal_handler_add(conn, *String::Utf8Value(info[0]),
+ *String::Utf8Value(info[1]),
+ *String::Utf8Value(info[2]),
+ *String::Utf8Value(info[3]),
+ cb, cb_data.get());
+ auto wrapped_ret = wrap_eldbus_signal_handler(ret, cb_data.release(),
+ isolate);
+ return compatibility_return(wrapped_ret, info);
+ };
+
+ ret->Set(compatibility_new<String>(isolate, "event_callback_add"),
+ compatibility_new<FunctionTemplate>(isolate, event_callback_add)
+ ->GetFunction());
+ ret->Set(compatibility_new<String>(isolate, "send"),
+ compatibility_new<FunctionTemplate>(isolate, send)->GetFunction());
+ ret->Set(compatibility_new<String>(isolate, "unique_name_get"),
+ compatibility_new<FunctionTemplate>(isolate, unique_name_get)
+ ->GetFunction());
+ ret->Set(compatibility_new<String>(isolate, "object_get"),
+ compatibility_new<FunctionTemplate>(isolate, object_get)
+ ->GetFunction());
+ ret->Set(compatibility_new<String>(isolate, "signal_handler_add"),
+ compatibility_new<FunctionTemplate>(isolate, signal_handler_add)
+ ->GetFunction());
+
+ compatibility_set_pointer_internal_field(ret, 0, conn);
+
+ return ret;
+}
+
+EAPI
+void register_eldbus_connection(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
+{
+ using v8::String;
+ register_timeout_infinite(isolate, exports,
+ compatibility_new<String>
+ (isolate, "ELDBUS_TIMEOUT_INFINITE"));
+ register_connection_type_unknown(isolate, exports,
+ compatibility_new<String>
+ (isolate, "ELDBUS_CONNECTION_TYPE_UNKNOWN"));
+ register_connection_type_session(isolate, exports,
+ compatibility_new<String>
+ (isolate, "ELDBUS_CONNECTION_TYPE_SESSION"));
+ register_connection_type_system(isolate, exports,
+ compatibility_new<String>
+ (isolate, "ELDBUS_CONNECTION_TYPE_SYSTEM"));
+ register_connection_type_starter(isolate, exports,
+ compatibility_new<String>
+ (isolate, "ELDBUS_CONNECTION_TYPE_STARTER"));
+ register_connection_type_address(isolate, exports,
+ compatibility_new<String>
+ (isolate, "ELDBUS_CONNECTION_TYPE_ADDRESS"));
+ register_connection_type_last(isolate, exports,
+ compatibility_new<String>
+ (isolate, "ELDBUS_CONNECTION_TYPE_LAST"));
+ register_connection_event_del(isolate, exports,
+ compatibility_new<String>
+ (isolate, "ELDBUS_CONNECTION_EVENT_DEL"));
+ register_connection_event_disconnected(isolate, exports,
+ compatibility_new<String>
+ (isolate,
+ "ELDBUS_CONNECTION_EVENT"
+ "_DISCONNECTED"));
+ register_connection_event_last(isolate, exports,
+ compatibility_new<String>
+ (isolate, "ELDBUS_CONNECTION_EVENT_LAST"));
+
+ register_connection_get(isolate, exports,
+ compatibility_new<String>
+ (isolate, "connection_get"));
+
+ register_private_connection_get(isolate, exports,
+ compatibility_new<String>
+ (isolate, "private_connection_get"));
+
+ register_address_connection_get(isolate, exports,
+ compatibility_new<String>
+ (isolate, "address_connection_get"));
+
+ register_private_address_connection_get(isolate, exports,
+ compatibility_new<String>
+ (isolate, "private_address_connection_get"));
+}
+
+} } } // namespace efl { namespace eldbus { namespace js {
diff --git a/src/bindings/eldbus_js/eldbus_js_core.cc b/src/bindings/eldbus_js/eldbus_js_core.cc
new file mode 100644
index 0000000000..e9a8c3344d
--- /dev/null
+++ b/src/bindings/eldbus_js/eldbus_js_core.cc
@@ -0,0 +1,183 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Eldbus_Js.hh>
+
+namespace efl { namespace eldbus { namespace js {
+
+namespace {
+
+void register_init(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto init = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = eldbus_init();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, init)
+ ->GetFunction());
+}
+
+void register_shutdown(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ using v8::FunctionTemplate;
+
+ auto shutdown = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto ret = eldbus_shutdown();
+ return compatibility_return(compatibility_new<Integer>(isolate, ret),
+ args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, shutdown)
+ ->GetFunction());
+}
+
+void register_fdo_bus(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ global->Set(name, compatibility_new<String>(isolate, ELDBUS_FDO_BUS));
+}
+
+void register_fdo_path(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ global->Set(name, compatibility_new<String>(isolate, ELDBUS_FDO_PATH));
+}
+
+void register_fdo_interface(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ global->Set(name, compatibility_new<String>(isolate, ELDBUS_FDO_INTERFACE));
+}
+
+void register_fdo_interface_properties(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ global->Set(name,
+ compatibility_new<String>(isolate,
+ ELDBUS_FDO_INTERFACE_PROPERTIES));
+}
+
+void register_fdo_interface_object_manager(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ global->Set(name,
+ compatibility_new<String>(isolate,
+ ELDBUS_FDO_INTERFACE_OBJECT_MANAGER));
+}
+
+void register_fdo_interface_introspectable(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ global->Set(name,
+ compatibility_new<String>(isolate,
+ ELDBUS_FDO_INTERFACE_INTROSPECTABLE));
+}
+
+void register_fdo_inteface_peer(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ global->Set(name,
+ compatibility_new<String>(isolate, ELDBUS_FDO_INTEFACE_PEER));
+}
+
+void register_error_pending_canceled(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ global->Set(name,
+ compatibility_new<String>(isolate,
+ ELDBUS_ERROR_PENDING_CANCELED));
+}
+
+void register_error_pending_timeout(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ global->Set(name,
+ compatibility_new<String>(isolate,
+ ELDBUS_ERROR_PENDING_TIMEOUT));
+}
+
+}
+
+EAPI
+void register_eldbus_core(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
+{
+ using v8::String;
+ register_init(isolate, exports,
+ compatibility_new<String>(isolate, "eldbus_init"));
+ register_shutdown(isolate, exports,
+ compatibility_new<String>(isolate, "eldbus_shutdown"));
+ register_fdo_bus(isolate, exports,
+ compatibility_new<String>(isolate, "ELDBUS_FDO_BUS"));
+ register_fdo_path(isolate, exports,
+ compatibility_new<String>(isolate, "ELDBUS_FDO_PATH"));
+ register_fdo_interface(isolate, exports,
+ compatibility_new<String>(isolate,
+ "ELDBUS_FDO_INTERFACE"));
+ register_fdo_interface_properties(isolate, exports,
+ compatibility_new<String>
+ (isolate,
+ "ELDBUS_FDO_INTERFACE_PROPERTIES"));
+ register_fdo_interface_object_manager(isolate, exports,
+ compatibility_new<String>
+ (isolate, "ELDBUS_FDO_INTERFACE_OBJECT_MANAGER"));
+
+ register_fdo_interface_introspectable
+ (isolate, exports,
+ compatibility_new<String>(isolate,
+ "ELDBUS_FDO_INTERFACE_INTROSPECTABLE"));
+ register_fdo_inteface_peer(isolate, exports,
+ compatibility_new<String>
+ (isolate, "ELDBUS_FDO_INTEFACE_PEER"));
+ register_error_pending_canceled
+ (isolate, exports,
+ compatibility_new<String>(isolate, "ELDBUS_ERROR_PENDING_CANCELED"));
+ register_error_pending_timeout
+ (isolate, exports,
+ compatibility_new<String>(isolate, "ELDBUS_ERROR_PENDING_TIMEOUT"));
+}
+
+EAPI void register_eldbus(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
+{
+ register_eldbus_connection(isolate, exports);
+ register_eldbus_core(isolate, exports);
+ register_eldbus_message(isolate, exports);
+ register_eldbus_object_mapper(isolate, exports);
+}
+
+} } } // namespace efl { namespace eldbus { namespace js {
diff --git a/src/bindings/eldbus_js/eldbus_js_message.cc b/src/bindings/eldbus_js/eldbus_js_message.cc
new file mode 100644
index 0000000000..f9cfa40b76
--- /dev/null
+++ b/src/bindings/eldbus_js/eldbus_js_message.cc
@@ -0,0 +1,103 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Eldbus_Js.hh>
+
+namespace efl { namespace eldbus { namespace js {
+
+namespace {
+
+void register_message_method_call_new(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 4 || !args[0]->IsString() || !args[1]->IsString()
+ || !args[2]->IsString() || !args[3]->IsString()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+ auto ret = eldbus_message_method_call_new(*String::Utf8Value(args[0]),
+ *String::Utf8Value(args[1]),
+ *String::Utf8Value(args[2]),
+ *String::Utf8Value(args[3]));
+ return compatibility_return(wrap_eldbus_msg(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_message_error_new(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 3 || !args[0]->IsObject() || !args[1]->IsString()
+ || !args[2]->IsString()) {
+ return compatibility_return();
+ }
+
+ auto isolate = args.GetIsolate();
+ auto ret = eldbus_message_error_new(extract_eldbus_msg(args[0]
+ ->ToObject()),
+ *String::Utf8Value(args[1]),
+ *String::Utf8Value(args[2]));
+ return compatibility_return(wrap_eldbus_msg(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+void register_message_method_return_new(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 1 || !args[0]->IsObject())
+ return compatibility_return();
+
+ auto isolate = args.GetIsolate();
+ auto eldbus_msg = extract_eldbus_msg(args[0]->ToObject());
+ auto ret = eldbus_message_method_return_new(eldbus_msg);
+ return compatibility_return(wrap_eldbus_msg(ret, isolate), args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+}
+
+EAPI
+void register_eldbus_message(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
+{
+ register_message_method_call_new
+ (isolate, exports, compatibility_new<v8::String>
+ (isolate, "message_method_call_new"));
+
+ register_message_error_new
+ (isolate, exports, compatibility_new<v8::String>
+ (isolate, "message_error_new"));
+
+ register_message_method_return_new
+ (isolate, exports, compatibility_new<v8::String>
+ (isolate, "message_method_return_new"));
+}
+
+} } } // namespace efl { namespace eldbus { namespace js {
diff --git a/src/bindings/eldbus_js/eldbus_js_object_mapper.cc b/src/bindings/eldbus_js/eldbus_js_object_mapper.cc
new file mode 100644
index 0000000000..955ce80948
--- /dev/null
+++ b/src/bindings/eldbus_js/eldbus_js_object_mapper.cc
@@ -0,0 +1,100 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Eldbus_Js.hh>
+
+namespace efl { namespace eldbus { namespace js {
+
+namespace {
+
+void register_object_event_iface_added(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ELDBUS_OBJECT_EVENT_IFACE_ADDED));
+}
+
+void register_object_event_iface_removed(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate,
+ ELDBUS_OBJECT_EVENT_IFACE_REMOVED));
+}
+
+void register_object_event_property_changed(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>
+ (isolate, ELDBUS_OBJECT_EVENT_PROPERTY_CHANGED));
+}
+
+void register_object_event_property_removed(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>
+ (isolate, ELDBUS_OBJECT_EVENT_PROPERTY_REMOVED));
+}
+
+void register_object_event_del(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ELDBUS_OBJECT_EVENT_DEL));
+}
+
+void register_object_event_last(v8::Isolate *isolate,
+ v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::Integer;
+ global->Set(name,
+ compatibility_new<Integer>(isolate, ELDBUS_OBJECT_EVENT_LAST));
+}
+
+}
+
+EAPI
+void register_eldbus_object_mapper(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
+{
+ register_object_event_iface_added
+ (isolate, exports, compatibility_new<v8::String>
+ (isolate, "object_event_iface_added"));
+
+ register_object_event_iface_removed
+ (isolate, exports, compatibility_new<v8::String>
+ (isolate, "object_event_iface_removed"));
+
+ register_object_event_property_changed
+ (isolate, exports, compatibility_new<v8::String>
+ (isolate, "object_event_propert