[evolution] M!48 - EWebView: Show the destination of hyperlinks as tooltip



commit 5d36289399c788ae58f4ba9cb891d68a44583b34
Author: Nour E-Din Osama Mohamed <nouredinosama gmail com>
Date:   Wed Apr 15 12:17:40 2020 +0200

    M!48 - EWebView: Show the destination of hyperlinks as tooltip
    
    Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/827
    Closes https://gitlab.gnome.org/GNOME/evolution/-/merge_requests/48

 data/webkit/e-web-view.js            | 25 +++++++++++
 src/e-util/e-misc-utils.c            | 83 ++++++++++++++++++++++++++++++++++++
 src/e-util/e-misc-utils.h            |  1 +
 src/e-util/e-web-view.c              | 56 +-----------------------
 src/web-extensions/e-web-extension.c | 29 +++++++++++++
 5 files changed, 139 insertions(+), 55 deletions(-)
---
diff --git a/data/webkit/e-web-view.js b/data/webkit/e-web-view.js
index 8b54bf429f..771d35139b 100644
--- a/data/webkit/e-web-view.js
+++ b/data/webkit/e-web-view.js
@@ -569,6 +569,29 @@ Evo.GetElementFromPoint = function(xx, yy)
        return res;
 }
 
+Evo.AddTooltipToLinks = function(iframe_id)
+{
+       var doc = Evo.findIFrameDocument(iframe_id);
+
+       if (!doc)
+               return;
+
+       var elements, ii;
+
+       elements = doc.getElementsByTagName("A");
+
+       for (ii = 0; ii < elements.length; ii++) {
+               var elem = elements[ii];
+
+               if (elem.href && !elem.title) {
+                       var tooltip = Evo.getUriTooltip(elem.href);
+
+                       if (tooltip)
+                               elem.title = tooltip;
+               }
+       }
+}
+
 Evo.initialize = function(elem)
 {
        var doc, elems, ii;
@@ -633,6 +656,8 @@ Evo.initializeAndPostContentLoaded = function(elem)
 
        if (window.webkit.messageHandlers.mailDisplayMagicSpacebarStateChanged)
                Evo.mailDisplayUpdateMagicSpacebarState();
+
+       Evo.AddTooltipToLinks(iframe_id);
 }
 
 Evo.EnsureMainDocumentInitialized = function()
diff --git a/src/e-util/e-misc-utils.c b/src/e-util/e-misc-utils.c
index 9639784dbf..fc96e4a3e4 100644
--- a/src/e-util/e-misc-utils.c
+++ b/src/e-util/e-misc-utils.c
@@ -4799,3 +4799,86 @@ e_util_get_supported_locales (void)
 {
        return e_supported_locales;
 }
+
+gchar *
+e_util_get_uri_tooltip (const gchar *uri)
+{
+       CamelInternetAddress *address;
+       CamelURL *curl;
+       const gchar *format = NULL;
+       GString *message = NULL;
+       gchar *who;
+
+       if (!uri || !*uri)
+               goto exit;
+
+       if (g_str_has_prefix (uri, "mailto:";))
+               format = _("Click to mail %s");
+       else if (g_str_has_prefix (uri, "callto:") ||
+                g_str_has_prefix (uri, "h323:") ||
+                g_str_has_prefix (uri, "sip:") ||
+                g_str_has_prefix (uri, "tel:"))
+               format = _("Click to call %s");
+       else if (g_str_has_prefix (uri, "##"))
+               message = g_string_new (_("Click to hide/unhide addresses"));
+       else if (g_str_has_prefix (uri, "mail:")) {
+               const gchar *fragment;
+               SoupURI *soup_uri;
+
+               soup_uri = soup_uri_new (uri);
+               if (!soup_uri)
+                       goto exit;
+
+               message = g_string_new (NULL);
+               fragment = soup_uri_get_fragment (soup_uri);
+
+               if (fragment && *fragment)
+                       g_string_append_printf (message, _("Go to the section %s of the message"), fragment);
+               else
+                       g_string_append (message, _("Go to the beginning of the message"));
+
+               soup_uri_free (soup_uri);
+       } else {
+               message = g_string_new (NULL);
+
+               g_string_append_printf (message, _("Click to open %s"), uri);
+       }
+
+       if (!format)
+               goto exit;
+
+       /* XXX Use something other than Camel here.  Surely
+        *     there's other APIs around that can do this. */
+       curl = camel_url_new (uri, NULL);
+       address = camel_internet_address_new ();
+       camel_address_decode (CAMEL_ADDRESS (address), curl->path);
+       who = camel_address_format (CAMEL_ADDRESS (address));
+       g_object_unref (address);
+       camel_url_free (curl);
+
+       if (!who)
+               who = g_strdup (strchr (uri, ':') + 1);
+
+       message = g_string_new (NULL);
+
+       g_string_append_printf (message, format, who);
+
+       g_free (who);
+
+ exit:
+
+       if (!message)
+               return NULL;
+
+       /* This limits the chars that appear as in some
+          links the size of chars can extend out of the screen */
+       if (g_utf8_strlen (message->str, -1) > 150) {
+               gchar *pos;
+
+               pos = g_utf8_offset_to_pointer (message->str, 150);
+               g_string_truncate (message, pos - message->str);
+               g_string_append (message , "…");
+       }
+
+       return g_string_free (message, FALSE);
+}
diff --git a/src/e-util/e-misc-utils.h b/src/e-util/e-misc-utils.h
index 9b1efc389b..27fb594426 100644
--- a/src/e-util/e-misc-utils.h
+++ b/src/e-util/e-misc-utils.h
@@ -354,6 +354,7 @@ gboolean    e_util_query_ldap_root_dse_sync (const gchar *host,
                                                 gchar ***out_root_dse,
                                                 GCancellable *cancellable,
                                                 GError **error);
+gchar *                e_util_get_uri_tooltip          (const gchar *uri);
 gchar *                e_util_get_language_name        (const gchar *language_tag);
 gboolean       e_util_get_language_info        (const gchar *language_tag,
                                                 gchar **out_language_name,
diff --git a/src/e-util/e-web-view.c b/src/e-util/e-web-view.c
index 1c8ea78dc2..cef66792de 100644
--- a/src/e-util/e-web-view.c
+++ b/src/e-util/e-web-view.c
@@ -1655,62 +1655,8 @@ web_view_hovering_over_link (EWebView *web_view,
                              const gchar *title,
                              const gchar *uri)
 {
-       CamelInternetAddress *address;
-       CamelURL *curl;
-       const gchar *format = NULL;
-       gchar *message = NULL;
-       gchar *who;
-
-       if (uri == NULL || *uri == '\0')
-               goto exit;
-
-       if (g_str_has_prefix (uri, "mailto:";))
-               format = _("Click to mail %s");
-       else if (g_str_has_prefix (uri, "callto:") ||
-                g_str_has_prefix (uri, "h323:") ||
-                g_str_has_prefix (uri, "sip:") ||
-                g_str_has_prefix (uri, "tel:"))
-               format = _("Click to call %s");
-       else if (g_str_has_prefix (uri, "##"))
-               message = g_strdup (_("Click to hide/unhide addresses"));
-       else if (g_str_has_prefix (uri, "mail:")) {
-               const gchar *fragment;
-               SoupURI *soup_uri;
-
-               soup_uri = soup_uri_new (uri);
-               if (!soup_uri)
-                       goto exit;
-
-               fragment = soup_uri_get_fragment (soup_uri);
-               if (fragment && *fragment)
-                       message = g_strdup_printf (_("Go to the section %s of the message"), fragment);
-               else
-                       message = g_strdup (_("Go to the beginning of the message"));
-
-               soup_uri_free (soup_uri);
-       } else
-               message = g_strdup_printf (_("Click to open %s"), uri);
-
-       if (format == NULL)
-               goto exit;
-
-       /* XXX Use something other than Camel here.  Surely
-        *     there's other APIs around that can do this. */
-       curl = camel_url_new (uri, NULL);
-       address = camel_internet_address_new ();
-       camel_address_decode (CAMEL_ADDRESS (address), curl->path);
-       who = camel_address_format (CAMEL_ADDRESS (address));
-       g_object_unref (address);
-       camel_url_free (curl);
-
-       if (who == NULL)
-               who = g_strdup (strchr (uri, ':') + 1);
-
-       message = g_strdup_printf (format, who);
-
-       g_free (who);
+       gchar *message = e_util_get_uri_tooltip (uri);
 
-exit:
        e_web_view_status_message (web_view, message);
 
        g_free (message);
diff --git a/src/web-extensions/e-web-extension.c b/src/web-extensions/e-web-extension.c
index 77db1f54ed..29a7c209d2 100644
--- a/src/web-extensions/e-web-extension.c
+++ b/src/web-extensions/e-web-extension.c
@@ -136,6 +136,15 @@ web_page_created_cb (WebKitWebExtension *wk_extension,
                extension, 0);
 }
 
+/* Returns 'null', when uri is empty or null, otherwise
+   returns a string with the constructed uri tooltip */
+static gchar *
+evo_jsc_get_uri_tooltip (const gchar *uri,
+                        gpointer user_data)
+{
+       return e_util_get_uri_tooltip (uri);
+}
+
 static void
 load_javascript_file (JSCContext *jsc_context,
                      const gchar *js_filename)
@@ -189,6 +198,7 @@ window_object_cleared_cb (WebKitScriptWorld *world,
                          gpointer user_data)
 {
        JSCContext *jsc_context;
+       JSCValue *jsc_evo_object;
 
        /* Load the javascript files only to the main frame, not to the subframes */
        if (!webkit_frame_is_main_frame (frame))
@@ -200,6 +210,25 @@ window_object_cleared_cb (WebKitScriptWorld *world,
        load_javascript_file (jsc_context, "e-convert.js");
        load_javascript_file (jsc_context, "e-web-view.js");
 
+       jsc_evo_object = jsc_context_get_value (jsc_context, "Evo");
+
+       if (jsc_evo_object) {
+               JSCValue *jsc_function;
+               const gchar *func_name;
+
+               /* Evo.getUriTooltip(uri) */
+               func_name = "getUriTooltip";
+               jsc_function = jsc_value_new_function (jsc_context, func_name,
+                              G_CALLBACK (evo_jsc_get_uri_tooltip),
+                              NULL, NULL,
+                              G_TYPE_STRING, 1, G_TYPE_STRING);
+
+               jsc_value_object_set_property (jsc_evo_object, func_name, jsc_function);
+
+               g_clear_object (&jsc_function);
+       }
+
+       g_clear_object (&jsc_evo_object);
        g_clear_object (&jsc_context);
 }
 


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