[evolution/wip/mcrha/webkit-jsc-api] Implement ElementClicked



commit 26db4e5e964a951e13f7ac62fb51aafc956dc8bd
Author: Milan Crha <mcrha redhat com>
Date:   Thu Sep 26 11:31:00 2019 +0200

    Implement ElementClicked

 src/e-util/e-web-view-jsc-utils.c         |  27 +++-
 src/e-util/e-web-view-jsc-utils.h         |   5 +
 src/e-util/e-web-view.c                   | 164 +++++++++--------------
 src/e-util/e-web-view.h                   |   2 +
 src/e-util/test-web-view.c                | 213 +++++++++++++++++++++++++-----
 src/em-format/e-mail-part-secure-button.c |   2 +
 src/mail/e-mail-display.c                 |   4 +
 src/modules/itip-formatter/itip-view.c    |   2 +
 src/web-extensions/ext-utils.js           |  48 ++++++-
 9 files changed, 325 insertions(+), 142 deletions(-)
---
diff --git a/src/e-util/e-web-view-jsc-utils.c b/src/e-util/e-web-view-jsc-utils.c
index 04df46ecdd..ed680679ef 100644
--- a/src/e-util/e-web-view-jsc-utils.c
+++ b/src/e-util/e-web-view-jsc-utils.c
@@ -64,15 +64,18 @@ e_web_view_jsc_strdup_call (const gchar *call_format,
                                        const gchar *ptr2;
 
                                        for (ptr2 = arg; *ptr2; ptr2++) {
-                                               if (*ptr2 == '\\' || *ptr2 == '\"')
-                                                       g_string_append_c (script, '\\');
+                                               if (*ptr2 == '\\')
+                                                       g_string_append (script, "\\\\");
+                                               else if (*ptr2 == '\"')
+                                                       g_string_append (script, "\\\"");
                                                else if (*ptr2 == '\r')
                                                        g_string_append (script, "\\r");
                                                else if (*ptr2 == '\n')
                                                        g_string_append (script, "\\n");
                                                else if (*ptr2 == '\t')
                                                        g_string_append (script, "\\t");
-                                               g_string_append_c (script, *ptr2);
+                                               else
+                                                       g_string_append_c (script, *ptr2);
                                        }
                                } else if (arg && *arg) {
                                        g_string_append (script, arg);
@@ -338,3 +341,21 @@ e_web_view_jsc_add_css_rule_into_style_sheet (WebKitWebView *web_view,
 
        webkit_web_view_run_javascript (web_view, script, cancellable, ewv_jsc_call_done_cb, script);
 }
+
+void
+e_web_view_jsc_register_element_clicked (WebKitWebView *web_view,
+                                        const gchar *iframe_id,
+                                        const gchar *elem_classes,
+                                        GCancellable *cancellable)
+{
+       gchar *script;
+
+       g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+       g_return_if_fail (elem_classes != NULL);
+
+       script = e_web_view_jsc_strdup_call ("Evo.RegisterElementClicked(%s,%s)",
+               iframe_id,
+               elem_classes);
+
+       webkit_web_view_run_javascript (web_view, script, cancellable, ewv_jsc_call_done_cb, script);
+}
diff --git a/src/e-util/e-web-view-jsc-utils.h b/src/e-util/e-web-view-jsc-utils.h
index 6cada9a51d..16a786ab21 100644
--- a/src/e-util/e-web-view-jsc-utils.h
+++ b/src/e-util/e-web-view-jsc-utils.h
@@ -80,6 +80,11 @@ void         e_web_view_jsc_add_css_rule_into_style_sheet
                                                 const gchar *selector,
                                                 const gchar *style,
                                                 GCancellable *cancellable);
+void           e_web_view_jsc_register_element_clicked
+                                               (WebKitWebView *web_view,
+                                                const gchar *iframe_id,
+                                                const gchar *elem_classes,
+                                                GCancellable *cancellable);
 
 G_END_DECLS
 
diff --git a/src/e-util/e-web-view.c b/src/e-util/e-web-view.c
index 2a22193835..d7a0e446b7 100644
--- a/src/e-util/e-web-view.c
+++ b/src/e-util/e-web-view.c
@@ -97,7 +97,6 @@ struct _EWebViewPrivate {
        GSList *content_requests; /* EContentRequest * */
 
        GHashTable *element_clicked_cbs; /* gchar *element_class ~> GPtrArray {ElementClickedData} */
-       guint web_extension_element_clicked_signal_id;
 
        guint32 clipboard_flags;
        guint web_extension_clipboard_flags_changed_signal_id;
@@ -1325,9 +1324,10 @@ e_web_view_element_clicked_cb (WebKitUserContentManager *manager,
                               gpointer user_data)
 {
        EWebView *web_view = user_data;
+       GtkAllocation elem_position;
+       GPtrArray *listeners;
        JSCValue *jsc_object;
-       gchar *frame_id, *elem_id, *elem_class_name, *elem_value;
-       guint elem_left, elem_top, elem_width, elem_height;
+       gchar *iframe_id, *elem_id, *elem_class, *elem_value;
 
        g_return_if_fail (web_view != NULL);
        g_return_if_fail (js_result != NULL);
@@ -1335,24 +1335,66 @@ e_web_view_element_clicked_cb (WebKitUserContentManager *manager,
        jsc_object = webkit_javascript_result_get_js_value (js_result);
        g_return_if_fail (jsc_value_is_object (jsc_object));
 
-       frame_id = e_web_view_jsc_get_object_property_string (jsc_object, "frame-id", NULL);
+       iframe_id = e_web_view_jsc_get_object_property_string (jsc_object, "iframe-id", NULL);
        elem_id = e_web_view_jsc_get_object_property_string (jsc_object, "elem-id", NULL);
-       elem_class_name = e_web_view_jsc_get_object_property_string (jsc_object, "elem-class-name", NULL);
+       elem_class = e_web_view_jsc_get_object_property_string (jsc_object, "elem-class", NULL);
        elem_value = e_web_view_jsc_get_object_property_string (jsc_object, "elem-value", NULL);
-       elem_left = e_web_view_jsc_get_object_property_int32 (jsc_object, "left", 0);
-       elem_top = e_web_view_jsc_get_object_property_int32 (jsc_object, "top", 0);
-       elem_width = e_web_view_jsc_get_object_property_int32 (jsc_object, "width", 0);
-       elem_height = e_web_view_jsc_get_object_property_int32 (jsc_object, "height", 0);
+       elem_position.x = e_web_view_jsc_get_object_property_int32 (jsc_object, "left", 0);
+       elem_position.y = e_web_view_jsc_get_object_property_int32 (jsc_object, "top", 0);
+       elem_position.width = e_web_view_jsc_get_object_property_int32 (jsc_object, "width", 0);
+       elem_position.height = e_web_view_jsc_get_object_property_int32 (jsc_object, "height", 0);
+
+       listeners = g_hash_table_lookup (web_view->priv->element_clicked_cbs, elem_class);
 
-       printf ("%s: received elementclicked: frm:%s elem:'%s' cls:'%s' val:'%s' at:[%d,%d,%d,%d]\n", 
__FUNCTION__,
-               frame_id, elem_id, elem_class_name, elem_value, elem_left, elem_top, elem_width, elem_height);
+       if (listeners) {
+               guint ii;
 
-       g_free (frame_id);
+               for (ii = 0; ii < listeners->len; ii++) {
+                       ElementClickedData *ecd = g_ptr_array_index (listeners, ii);
+
+                       if (ecd && ecd->callback)
+                               ecd->callback (web_view, iframe_id, elem_id, elem_class, elem_value, 
&elem_position, ecd->user_data);
+               }
+       }
+
+       g_free (iframe_id);
        g_free (elem_id);
-       g_free (elem_class_name);
+       g_free (elem_class);
        g_free (elem_value);
 }
 
+static void
+web_view_call_register_element_clicked (EWebView *web_view,
+                                       const gchar *iframe_id,
+                                       const gchar *only_elem_class)
+{
+       gchar *elem_classes = NULL;
+
+       if (!only_elem_class) {
+               GHashTableIter iter;
+               gpointer key;
+               GString *classes;
+
+               classes = g_string_sized_new (128);
+
+               g_hash_table_iter_init (&iter, web_view->priv->element_clicked_cbs);
+               while (g_hash_table_iter_next (&iter, &key, NULL)) {
+                       if (classes->len)
+                               g_string_append_c (classes, '\n');
+
+                       g_string_append (classes, key);
+               }
+
+               elem_classes = g_string_free (classes, FALSE);
+       }
+
+       e_web_view_jsc_register_element_clicked (WEBKIT_WEB_VIEW (web_view), iframe_id,
+               only_elem_class ? only_elem_class : elem_classes,
+               web_view->priv->load_cancellable);
+
+       g_free (elem_classes);
+}
+
 static void
 e_web_view_content_loaded_cb (WebKitUserContentManager *manager,
                              WebKitJavascriptResult *js_result,
@@ -1375,6 +1417,8 @@ e_web_view_content_loaded_cb (WebKitUserContentManager *manager,
                style_updated_cb (web_view);
        }
 
+       web_view_call_register_element_clicked (web_view, iframe_id, NULL);
+
        g_signal_emit (web_view, signals[CONTENT_LOADED], 0, iframe_id);
 
        g_free (iframe_id);
@@ -1697,26 +1741,6 @@ web_view_stop_loading (EWebView *web_view)
        webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (web_view));
 }
 
-static void
-web_view_register_element_clicked_hfunc (gpointer key,
-                                        gpointer value,
-                                        gpointer user_data)
-{
-       const gchar *elem_class = key;
-       EWebView *web_view = user_data;
-       guint64 page_id;
-
-       g_return_if_fail (elem_class && *elem_class);
-       g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
-       page_id = webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view));
-
-       e_web_extension_container_call_simple (web_view->priv->container,
-               page_id, web_view->priv->stamp,
-               "RegisterElementClicked",
-               g_variant_new ("(ts)", page_id, elem_class));
-}
-
 static void
 web_view_need_input_changed_signal_cb (GDBusConnection *connection,
                                       const gchar *sender_name,
@@ -1771,53 +1795,6 @@ web_view_clipboard_flags_changed_signal_cb (GDBusConnection *connection,
                e_web_view_set_clipboard_flags (web_view, clipboard_flags);
 }
 
-static void
-web_view_element_clicked_signal_cb (GDBusConnection *connection,
-                                   const gchar *sender_name,
-                                   const gchar *object_path,
-                                   const gchar *interface_name,
-                                   const gchar *signal_name,
-                                   GVariant *parameters,
-                                   gpointer user_data)
-{
-       EWebView *web_view = user_data;
-       const gchar *elem_class = NULL, *elem_value = NULL;
-       GtkAllocation elem_position;
-       guint64 page_id = 0;
-       gint position_left = 0, position_top = 0, position_width = 0, position_height = 0;
-       GPtrArray *listeners;
-
-       if (g_strcmp0 (signal_name, "ElementClicked") != 0)
-               return;
-
-       g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
-       if (!parameters)
-               return;
-
-       g_variant_get (parameters, "(t&s&siiii)", &page_id, &elem_class, &elem_value, &position_left, 
&position_top, &position_width, &position_height);
-
-       if (!elem_class || !*elem_class || page_id != webkit_web_view_get_page_id (WEBKIT_WEB_VIEW 
(web_view)))
-               return;
-
-       elem_position.x = position_left;
-       elem_position.y = position_top;
-       elem_position.width = position_width;
-       elem_position.height = position_height;
-
-       listeners = g_hash_table_lookup (web_view->priv->element_clicked_cbs, elem_class);
-       if (listeners) {
-               guint ii;
-
-               for (ii = 0; ii <listeners->len; ii++) {
-                       ElementClickedData *ecd = g_ptr_array_index (listeners, ii);
-
-                       if (ecd && ecd->callback)
-                               ecd->callback (web_view, elem_class, elem_value, &elem_position, 
ecd->user_data);
-               }
-       }
-}
-
 static void
 e_web_view_set_web_extension_proxy (EWebView *web_view,
                                    GDBusProxy *proxy)
@@ -1847,12 +1824,6 @@ e_web_view_set_web_extension_proxy (EWebView *web_view,
                        web_view->priv->web_extension_need_input_changed_signal_id = 0;
                }
 
-               if (web_view->priv->web_extension_element_clicked_signal_id) {
-                       if (connection)
-                               g_dbus_connection_signal_unsubscribe (connection, 
web_view->priv->web_extension_element_clicked_signal_id);
-                       web_view->priv->web_extension_element_clicked_signal_id = 0;
-               }
-
                g_clear_object (&web_view->priv->web_extension_proxy);
        }
 
@@ -1884,19 +1855,6 @@ e_web_view_set_web_extension_proxy (EWebView *web_view,
                                web_view_need_input_changed_signal_cb,
                                web_view,
                                NULL);
-
-               web_view->priv->web_extension_element_clicked_signal_id =
-                       g_dbus_connection_signal_subscribe (
-                               g_dbus_proxy_get_connection (proxy),
-                               g_dbus_proxy_get_name (proxy),
-                               E_WEB_EXTENSION_INTERFACE,
-                               "ElementClicked",
-                               E_WEB_EXTENSION_OBJECT_PATH,
-                               NULL,
-                               G_DBUS_SIGNAL_FLAGS_NONE,
-                               web_view_element_clicked_signal_cb,
-                               web_view,
-                               NULL);
        }
 
        g_object_notify (G_OBJECT (web_view), "web-extension-proxy");
@@ -1918,8 +1876,6 @@ e_web_view_page_proxy_changed_cb (EWebExtensionContainer *container,
                e_web_view_set_web_extension_proxy (web_view, proxy);
 
                if (proxy) {
-                       g_hash_table_foreach (web_view->priv->element_clicked_cbs, 
web_view_register_element_clicked_hfunc, web_view);
-
                        e_web_view_ensure_body_class (web_view);
                        style_updated_cb (web_view);
                }
@@ -4823,6 +4779,8 @@ e_web_view_set_document_iframe_src (EWebView *web_view,
 /**
  * EWebViewElementClickedFunc:
  * @web_view: an #EWebView
+ * @iframe_id: an iframe ID in which the click happened; empty string for the main frame
+ * @element_id: an element ID
  * @element_class: an element class, as set on the element which had been clicked
  * @element_value: a 'value' attribute content of the clicked element
  * @element_position: a #GtkAllocation with the position of the clicked element
@@ -4874,7 +4832,7 @@ e_web_view_register_element_clicked (EWebView *web_view,
                        if (ecd && ecd->callback == callback && ecd->user_data == user_data) {
                                /* Callback is already registered, but re-register it, in case the page
                                   was changed dynamically and new elements with the given call are added. */
-                               web_view_register_element_clicked_hfunc ((gpointer) element_class, cbs, 
web_view);
+                               web_view_call_register_element_clicked (web_view, "*", element_class);
                                return;
                        }
                }
@@ -4894,7 +4852,7 @@ e_web_view_register_element_clicked (EWebView *web_view,
        }
 
        /* Dynamically changing page can call this multiple times; re-register all classes */
-       g_hash_table_foreach (web_view->priv->element_clicked_cbs, web_view_register_element_clicked_hfunc, 
web_view);
+       web_view_call_register_element_clicked (web_view, "*", NULL);
 }
 
 /**
diff --git a/src/e-util/e-web-view.h b/src/e-util/e-web-view.h
index 387ca0d72c..5c479ed41f 100644
--- a/src/e-util/e-web-view.h
+++ b/src/e-util/e-web-view.h
@@ -67,6 +67,8 @@ typedef enum {
 } EURIScheme;
 
 typedef void (*EWebViewElementClickedFunc) (EWebView *web_view,
+                                           const gchar *iframe_id,
+                                           const gchar *element_id,
                                            const gchar *element_class,
                                            const gchar *element_value,
                                            const GtkAllocation *element_position,
diff --git a/src/e-util/test-web-view.c b/src/e-util/test-web-view.c
index e6c4f196d2..caf27a2ef4 100644
--- a/src/e-util/test-web-view.c
+++ b/src/e-util/test-web-view.c
@@ -460,36 +460,48 @@ test_utils_load_string (TestFixture *fixture,
 }
 
 static void
-test_utils_load_body (TestFixture *fixture)
-{
-       test_utils_load_string (fixture,
-               "<html><body>"
-               "Top<br>"
-               "<input id=\"btn1\" type=\"button\" value=\"Button1\"><br>"
-               "<iframe id=\"frm1\" src=\"empty:///\"></iframe><br>"
-               "<iframe id=\"frm2\" src=\"empty:///\"></iframe><br>"
-               "<input id=\"btn3\" type=\"button\" value=\"Button3\">"
-               "</body></html>");
-
-       test_utils_load_iframe_content (fixture, "frm1",
-               "<html><body>"
-               "frm1<br>"
-               "<iframe id=\"frm1_1\" src=\"empty:///\"></iframe><br>"
-               "<input id=\"btn1\" type=\"button\" value=\"Button1\">"
-               "</body></html>");
-
-       test_utils_load_iframe_content (fixture, "frm1_1",
-               "<html><body>"
-               "frm1_1<br>"
-               "<input id=\"btn1\" type=\"button\" value=\"Button1\">"
-               "</body></html>");
-
-       test_utils_load_iframe_content (fixture, "frm2",
-               "<html><body>"
-               "frm2<br>"
-               "<input id=\"btn1\" type=\"button\" value=\"Button1\">"
-               "<input id=\"btn2\" type=\"button\" value=\"Button2\">"
-               "</body></html>");
+test_utils_load_body (TestFixture *fixture,
+                     gint index)
+{
+       if (index == 0 || index == -1) {
+               test_utils_load_string (fixture,
+                       "<html><body>"
+                       "Top<br>"
+                       "<input id=\"btn1\" class=\"cbtn1\" type=\"button\" value=\"Button1\"><br>"
+                       "<iframe id=\"frm1\" src=\"empty:///\"></iframe><br>"
+                       "<iframe id=\"frm2\" src=\"empty:///\"></iframe><br>"
+                       "<input id=\"btn3\" class=\"cbtn3\" type=\"button\" value=\"Button3\">"
+                       "<a name=\"dots\" id=\"dots1\" class=\"cdots\">...</a>"
+                       "</body></html>");
+       }
+
+       if (index == 1 || index == -1) {
+               test_utils_load_iframe_content (fixture, "frm1",
+                       "<html><body>"
+                       "frm1<br>"
+                       "<iframe id=\"frm1_1\" src=\"empty:///\"></iframe><br>"
+                       "<input id=\"btn1\" class=\"cbtn1\" type=\"button\" value=\"Button1\">"
+                       "</body></html>");
+       }
+
+       if (index == 2 || index == -1) {
+               test_utils_load_iframe_content (fixture, "frm1_1",
+                       "<html><body>"
+                       "frm1_1<br>"
+                       "<input id=\"btn1\" class=\"cbtn1\" type=\"button\" value=\"Button1\">"
+                       "<a name=\"dots\" id=\"dots2\" class=\"cdots\">...</a>"
+                       "<input id=\"btn2\" class=\"cbtn2\" type=\"button\" value=\"Button2\">"
+                       "</body></html>");
+       }
+
+       if (index == 3 || index == -1) {
+               test_utils_load_iframe_content (fixture, "frm2",
+                       "<html><body>"
+                       "frm2<br>"
+                       "<input id=\"btn1\" class=\"cbtn1\" type=\"button\" value=\"Button1\">"
+                       "<input id=\"btn2\" class=\"cbtn2\" type=\"button\" value=\"Button2\">"
+                       "</body></html>");
+       }
 }
 
 static void
@@ -555,7 +567,7 @@ test_jsc_object_properties (TestFixture *fixture)
 static void
 test_set_element_hidden (TestFixture *fixture)
 {
-       test_utils_load_body (fixture);
+       test_utils_load_body (fixture, -1);
 
        g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").hidden"));
        g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").hidden"));
@@ -628,7 +640,7 @@ test_set_element_hidden (TestFixture *fixture)
 static void
 test_set_element_style_property (TestFixture *fixture)
 {
-       test_utils_load_body (fixture);
+       test_utils_load_body (fixture, -1);
 
        test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\", 
\"btn1\").style.getPropertyValue(\"color\")", "");
        test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\", 
\"btn3\").style.getPropertyValue(\"color\")", "");
@@ -671,7 +683,7 @@ test_set_element_style_property (TestFixture *fixture)
 static void
 test_set_element_attribute (TestFixture *fixture)
 {
-       test_utils_load_body (fixture);
+       test_utils_load_body (fixture, -1);
 
        test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\", \"btn1\").getAttributeNS(\"\", 
\"myattr\")", NULL);
        test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\", \"btn3\").getAttributeNS(\"\", 
\"myattr\")", NULL);
@@ -714,7 +726,7 @@ test_set_element_attribute (TestFixture *fixture)
 static void
 test_style_sheets (TestFixture *fixture)
 {
-       test_utils_load_body (fixture);
+       test_utils_load_body (fixture, -1);
 
        test_utils_jsc_call_sync (fixture,
                "var Test = {};\n"
@@ -796,6 +808,138 @@ test_style_sheets (TestFixture *fixture)
        test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm2\", \"sheet3\", \"body\", 
\"color\")", "orange");
 }
 
+typedef struct _ElementClickedData {
+       TestFixture *fixture;
+       const gchar *iframe_id;
+       const gchar *element_id;
+       const gchar *element_class;
+       const gchar *element_value;
+} ElementClickedData;
+
+static void
+test_verify_element_clicked_cb (EWebView *web_view,
+                               const gchar *iframe_id,
+                               const gchar *element_id,
+                               const gchar *element_class,
+                               const gchar *element_value,
+                               const GtkAllocation *element_position,
+                               gpointer user_data)
+{
+       ElementClickedData *expects = user_data;
+
+       g_assert_nonnull (expects);
+       g_assert_cmpstr (iframe_id, ==, expects->iframe_id);
+       g_assert_cmpstr (element_id, ==, expects->element_id);
+       g_assert_cmpstr (element_class, ==, expects->element_class);
+       g_assert_cmpstr (element_value, ==, expects->element_value);
+       g_assert_cmpint (element_position->x, >, 0);
+       g_assert_cmpint (element_position->y, >, 0);
+       g_assert_cmpint (element_position->width, >, 0);
+       g_assert_cmpint (element_position->height, >, 0);
+
+       test_flag_set (expects->fixture->flag);
+}
+
+static void
+test_verify_element_clicked (TestFixture *fixture,
+                            ElementClickedData *expects,
+                            const gchar *iframe_id,
+                            const gchar *element_id,
+                            const gchar *element_class,
+                            const gchar *element_value,
+                            gboolean wait_response)
+{
+       gchar *script;
+
+       expects->iframe_id = iframe_id;
+       expects->element_id = element_id;
+       expects->element_class = element_class;
+       expects->element_value = element_value;
+
+       script = e_web_view_jsc_strdup_call ("Evo.findIFrameDocument(%s).getElementById(%s).click();",
+               iframe_id, element_id);
+
+       test_utils_jsc_call (fixture, script);
+
+       g_free (script);
+
+       if (wait_response)
+               test_utils_wait (fixture);
+}
+
+static void
+test_element_clicked (TestFixture *fixture)
+{
+       ElementClickedData expects;
+
+       test_utils_load_body (fixture, 0);
+
+       expects.fixture = fixture;
+
+       e_web_view_register_element_clicked (E_WEB_VIEW (fixture->web_view), "cbtn1", 
test_verify_element_clicked_cb, &expects);
+
+       test_verify_element_clicked (fixture, &expects, "", "dots1", "cdots", NULL, FALSE);
+       test_verify_element_clicked (fixture, &expects, "", "btn1", "cbtn1", "Button1", TRUE);
+
+       test_utils_load_body (fixture, 1);
+
+       test_verify_element_clicked (fixture, &expects, "", "btn1", "cbtn1", "Button1", TRUE);
+       test_verify_element_clicked (fixture, &expects, "frm1", "btn1", "cbtn1", "Button1", TRUE);
+
+       test_utils_load_body (fixture, 2);
+
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "btn2", "cbtn2", "Button2", FALSE);
+
+       e_web_view_register_element_clicked (E_WEB_VIEW (fixture->web_view), "cbtn2", 
test_verify_element_clicked_cb, &expects);
+
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "btn1", "cbtn1", "Button1", TRUE);
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "btn2", "cbtn2", "Button2", TRUE);
+
+       test_utils_load_body (fixture, 3);
+
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "btn2", "cbtn2", "Button2", TRUE);
+       test_verify_element_clicked (fixture, &expects, "frm2", "btn2", "cbtn2", "Button2", TRUE);
+
+       e_web_view_register_element_clicked (E_WEB_VIEW (fixture->web_view), "cdots", 
test_verify_element_clicked_cb, &expects);
+
+       test_verify_element_clicked (fixture, &expects, "", "btn3", "cbtn3", "Button3", FALSE);
+       test_verify_element_clicked (fixture, &expects, "", "dots1", "cdots", NULL, TRUE);
+       test_verify_element_clicked (fixture, &expects, "", "btn1", "cbtn1", "Button1", TRUE);
+       test_verify_element_clicked (fixture, &expects, "frm1", "btn1", "cbtn1", "Button1", TRUE);
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "btn1", "cbtn1", "Button1", TRUE);
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "btn2", "cbtn2", "Button2", TRUE);
+       test_verify_element_clicked (fixture, &expects, "frm2", "btn1", "cbtn1", "Button1", TRUE);
+       test_verify_element_clicked (fixture, &expects, "frm2", "btn2", "cbtn2", "Button2", TRUE);
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "dots2", "cdots", NULL, TRUE);
+
+       e_web_view_unregister_element_clicked (E_WEB_VIEW (fixture->web_view), "cbtn1", 
test_verify_element_clicked_cb, &expects);
+
+       test_verify_element_clicked (fixture, &expects, "", "btn3", "cbtn3", "Button3", FALSE);
+       test_verify_element_clicked (fixture, &expects, "", "btn1", "cbtn1", "Button1", FALSE);
+       test_verify_element_clicked (fixture, &expects, "frm1", "btn1", "cbtn1", "Button1", FALSE);
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "btn1", "cbtn1", "Button1", FALSE);
+       test_verify_element_clicked (fixture, &expects, "frm2", "btn1", "cbtn1", "Button1", FALSE);
+       test_verify_element_clicked (fixture, &expects, "", "dots1", "cdots", NULL, TRUE);
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "btn2", "cbtn2", "Button2", TRUE);
+       test_verify_element_clicked (fixture, &expects, "frm2", "btn2", "cbtn2", "Button2", TRUE);
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "dots2", "cdots", NULL, TRUE);
+
+       e_web_view_unregister_element_clicked (E_WEB_VIEW (fixture->web_view), "cbtn2", 
test_verify_element_clicked_cb, &expects);
+       e_web_view_unregister_element_clicked (E_WEB_VIEW (fixture->web_view), "cdots", 
test_verify_element_clicked_cb, &expects);
+
+       test_verify_element_clicked (fixture, &expects, "", "btn3", "cbtn3", "Button3", FALSE);
+       test_verify_element_clicked (fixture, &expects, "", "dots1", "cdots", NULL, FALSE);
+       test_verify_element_clicked (fixture, &expects, "", "btn1", "cbtn1", "Button1", FALSE);
+       test_verify_element_clicked (fixture, &expects, "frm1", "btn1", "cbtn1", "Button1", FALSE);
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "btn1", "cbtn1", "Button1", FALSE);
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "btn2", "cbtn2", "Button2", FALSE);
+       test_verify_element_clicked (fixture, &expects, "frm2", "btn1", "cbtn1", "Button1", FALSE);
+       test_verify_element_clicked (fixture, &expects, "frm2", "btn2", "cbtn2", "Button2", FALSE);
+       test_verify_element_clicked (fixture, &expects, "frm1_1", "dots2", "cdots", NULL, FALSE);
+
+       test_utils_wait_noop (fixture);
+}
+
 gint
 main (gint argc,
       gchar *argv[])
@@ -817,6 +961,7 @@ main (gint argc,
        test_utils_add_test ("/EWebView/SetElementStyleProperty", test_set_element_style_property);
        test_utils_add_test ("/EWebView/SetElementAttribute", test_set_element_attribute);
        test_utils_add_test ("/EWebView/StyleSheets", test_style_sheets);
+       test_utils_add_test ("/EWebView/ElementClicked", test_element_clicked);
 
        res = g_test_run ();
 
diff --git a/src/em-format/e-mail-part-secure-button.c b/src/em-format/e-mail-part-secure-button.c
index 4719448e16..1ddeef0045 100644
--- a/src/em-format/e-mail-part-secure-button.c
+++ b/src/em-format/e-mail-part-secure-button.c
@@ -324,6 +324,8 @@ secure_button_show_validity_dialog (EWebView *web_view,
 
 static void
 secure_button_clicked_cb (EWebView *web_view,
+                         const gchar *iframe_id,
+                         const gchar *element_id,
                          const gchar *element_class,
                          const gchar *element_value,
                          const GtkAllocation *element_position,
diff --git a/src/mail/e-mail-display.c b/src/mail/e-mail-display.c
index 76e2c9189a..3b72657a55 100644
--- a/src/mail/e-mail-display.c
+++ b/src/mail/e-mail-display.c
@@ -916,6 +916,8 @@ call_attachment_save_handle_error (GObject *source_object,
 
 static void
 mail_display_attachment_expander_clicked_cb (EWebView *web_view,
+                                            const gchar *iframe_id,
+                                            const gchar *element_id,
                                             const gchar *element_class,
                                             const gchar *element_value,
                                             const GtkAllocation *element_position,
@@ -1099,6 +1101,8 @@ mail_display_attachment_select_path (EAttachmentView *view,
 
 static void
 mail_display_attachment_menu_clicked_cb (EWebView *web_view,
+                                        const gchar *iframe_id,
+                                        const gchar *element_id,
                                         const gchar *element_class,
                                         const gchar *element_value,
                                         const GtkAllocation *element_position,
diff --git a/src/modules/itip-formatter/itip-view.c b/src/modules/itip-formatter/itip-view.c
index 52e694c15c..3d9c32cd09 100644
--- a/src/modules/itip-formatter/itip-view.c
+++ b/src/modules/itip-formatter/itip-view.c
@@ -1004,6 +1004,8 @@ update_start_end_times (ItipView *view)
 
 static void
 itip_view_itip_button_clicked_cb (EWebView *web_view,
+                                 const gchar *iframe_id,
+                                 const gchar *element_id,
                                  const gchar *element_class,
                                  const gchar *element_value,
                                  const GtkAllocation *element_position,
diff --git a/src/web-extensions/ext-utils.js b/src/web-extensions/ext-utils.js
index d9a1572c48..1c17a2b013 100644
--- a/src/web-extensions/ext-utils.js
+++ b/src/web-extensions/ext-utils.js
@@ -236,9 +236,9 @@ Evo.ElemClicked = function(elem)
 
        var res = [];
 
-       res["frame-id"] = parent_iframe_id;
+       res["iframe-id"] = parent_iframe_id;
        res["elem-id"] = elem.id;
-       res["elem-class-name"] = elem.className;
+       res["elem-class"] = elem.className;
        res["elem-value"] = elem.getAttribute("value");
        res["left"] = with_parents_left - scroll_x;
        res["top"] = with_parents_top - scroll_y;
@@ -248,6 +248,50 @@ Evo.ElemClicked = function(elem)
        window.webkit.messageHandlers.elementClicked.postMessage(res);
 }
 
+Evo.registerElementClickedInDocument = function(doc, elem_classes)
+{
+       var ii;
+
+       for (ii = 0; ii < elem_classes.length; ii++) {
+               if (elem_classes[ii] != "") {
+                       var jj, elems;
+
+                       elems = doc.getElementsByClassName(elem_classes[ii]);
+
+                       for (jj = 0; jj < elems.length; jj++) {
+                               elems[jj].onclick = function() { Evo.ElemClicked(this); };
+                       }
+               }
+       }
+}
+
+Evo.registerElementClickedInDocumentRecursive = function(doc, elem_classes)
+{
+       Evo.registerElementClickedInDocument(doc, elem_classes);
+
+       var iframes, ii;
+
+       iframes = doc.getElementsByTagName("iframe");
+
+       for (ii = 0; ii < iframes.length; ii++) {
+               Evo.registerElementClickedInDocumentRecursive(iframes[ii].contentDocument, elem_classes);
+       }
+}
+
+Evo.RegisterElementClicked = function(iframe_id, elem_classes_str)
+{
+       var elem_classes = elem_classes_str.split("\n");
+
+       if (iframe_id == "*") {
+               Evo.registerElementClickedInDocumentRecursive(document, elem_classes);
+       } else {
+               var doc;
+
+               doc = Evo.findIFrameDocument(iframe_id);
+               Evo.registerElementClickedInDocument(doc, elem_classes);
+       }
+}
+
 Evo.Initialize = function(elem)
 {
        var doc, elems, ii;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]