[evolution/gnome-3-24] Bug 780088 - Pasted URL not recognized/rendered as such; renders all remaining email text as link af



commit 1251551ab1a5ba63cfe2b42a151dfcfd58049452
Author: Tomas Popela <tpopela redhat com>
Date:   Sat Apr 29 10:17:36 2017 +0200

    Bug 780088 - Pasted URL not recognized/rendered as such; renders all remaining email text as link after 
pressing Enter
    
    The main cause for both problems mentioned in the bug was the check for
    the non-breaking space in the regex that we are using to recognizing the
    URLs. Making it work would need a support for regexes in the negative
    lookbehind, but GRegex does not support them. In the end I decided to
    remove the check and check for the non-breaking space character in the
    code rather than in the regex itself.

 src/e-util/test-html-editor-units-bugs.c           |   31 +++++++++
 src/e-util/test-html-editor-units-utils.h          |    2 +
 .../web-extension/e-editor-dom-functions.c         |   65 ++++++++++++--------
 .../web-extension/e-editor-dom-functions.h         |    6 +-
 4 files changed, 74 insertions(+), 30 deletions(-)
---
diff --git a/src/e-util/test-html-editor-units-bugs.c b/src/e-util/test-html-editor-units-bugs.c
index 2c6bbd5..c39f4d5 100644
--- a/src/e-util/test-html-editor-units-bugs.c
+++ b/src/e-util/test-html-editor-units-bugs.c
@@ -1014,6 +1014,36 @@ test_bug_781116 (TestFixture *fixture)
                g_test_fail ();
 }
 
+static void
+test_bug_780088 (TestFixture *fixture)
+{
+       if (!test_utils_process_commands (fixture,
+               "mode:plain\n")) {
+               g_test_fail ();
+               return;
+       }
+
+       test_utils_set_clipboard_text ("Seeing @blah instead of @foo XX'ed on" UNICODE_NBSP 
"https://example.sub"; UNICODE_NBSP "domain.org/page I'd recommend to XX YY 
<https://example.subdomain.org/p/user/> , click fjwvne on the left, click skjd sjewncj on the right, and set 
wqje wjfdn Xs to something like wqjfnm www.example.com/~user wjfdncj or such.", FALSE);
+
+       if (!test_utils_run_simple_test (fixture,
+               "action:paste\n"
+               "seq:n",
+               HTML_PREFIX "<div style=\"width: 71ch;\">"
+               "Seeing @blah instead of @foo XX'ed on&nbsp;<a 
href=\"https://example.sub\";>https://example.sub</a>"
+               "&nbsp;domain.org/page I'd recommend to XX YY "
+               "&lt;<a 
href=\"https://example.subdomain.org/p/user/\";>https://example.subdomain.org/p/user/</a>&gt; , "
+               "click fjwvne on the left, click skjd sjewncj on the right, and set wqje wjfdn Xs to 
something like "
+               "wqjfnm <a href=\"www.example.com/~user\">www.example.com/~user</a> wjfdncj or such.</div>"
+               "</div><div style=\"width: 71ch;\"><br></div>"
+               HTML_SUFFIX,
+               "Seeing @blah instead of @foo XX'ed on" UNICODE_NBSP "https://example.sub"; UNICODE_NBSP 
"domain.org/pa\n"
+               "ge I'd recommend to XX YY <https://example.subdomain.org/p/user/> ,\n"
+               "click fjwvne on the left, click skjd sjewncj on the right, and set wqje\n"
+               "wjfdn Xs to something like wqjfnm www.example.com/~user wjfdncj or\n"
+               "such.\n"))
+               g_test_fail ();
+}
+
 void
 test_add_html_editor_bug_tests (void)
 {
@@ -1040,4 +1070,5 @@ test_add_html_editor_bug_tests (void)
        test_utils_add_test ("/bug/780275/plain", test_bug_780275_plain);
        test_utils_add_test ("/bug/781722", test_bug_781722);
        test_utils_add_test ("/bug/781116", test_bug_781116);
+       test_utils_add_test ("/bug/780088", test_bug_780088);
 }
diff --git a/src/e-util/test-html-editor-units-utils.h b/src/e-util/test-html-editor-units-utils.h
index 7867346..b8c40fa 100644
--- a/src/e-util/test-html-editor-units-utils.h
+++ b/src/e-util/test-html-editor-units-utils.h
@@ -37,6 +37,8 @@ typedef struct _TestFixture {
        GSList *undo_stack; /* UndoContent * */
 } TestFixture;
 
+#define UNICODE_NBSP "\xc2\xa0"
+
 typedef void (* ETestFixtureSimpleFunc) (TestFixture *fixture);
 
 void           test_utils_set_event_processing_delay_ms
diff --git a/src/modules/webkit-editor/web-extension/e-editor-dom-functions.c 
b/src/modules/webkit-editor/web-extension/e-editor-dom-functions.c
index 9a7171f..016ae3a 100644
--- a/src/modules/webkit-editor/web-extension/e-editor-dom-functions.c
+++ b/src/modules/webkit-editor/web-extension/e-editor-dom-functions.c
@@ -1537,16 +1537,16 @@ e_editor_dom_check_magic_links (EEditorPage *editor_page,
 
        if (urls) {
                const gchar *end_of_match = NULL;
-               gchar *final_url, *url_end_raw, *url_text;
+               gchar *final_url = NULL, *url_end_raw, *url_text;
                glong url_start, url_end, url_length;
                WebKitDOMNode *url_text_node;
                WebKitDOMElement *anchor;
 
                g_match_info_fetch_pos (match_info, 0, &start_pos_url, &end_pos_url);
 
-               /* Get start and end position of url in node's text because positions
+               /* Get start and end position of URL in node's text because positions
                 * that we get from g_match_info_fetch_pos are not UTF-8 aware */
-               url_end_raw = g_strndup(node_text, end_pos_url);
+               url_end_raw = g_strndup (node_text, end_pos_url);
                url_end = g_utf8_strlen (url_end_raw, -1);
                url_length = g_utf8_strlen (urls[0], -1);
 
@@ -1573,6 +1573,10 @@ e_editor_dom_check_magic_links (EEditorPage *editor_page,
                url_text = webkit_dom_character_data_get_data (
                        WEBKIT_DOM_CHARACTER_DATA (url_text_node));
 
+               /* Sanity check */
+               if (strrchr (url_text, ' '))
+                       goto skip;
+
                if (g_str_has_prefix (url_text, "www."))
                        final_url = g_strconcat ("http://"; , url_text, NULL);
                else if (is_email_address)
@@ -1596,9 +1600,11 @@ e_editor_dom_check_magic_links (EEditorPage *editor_page,
                        WEBKIT_DOM_NODE (url_text_node),
                        NULL);
 
+ skip:
                g_free (url_end_raw);
-               g_free (final_url);
                g_free (url_text);
+               if (final_url)
+                       g_free (final_url);
        } else {
                gboolean appending_to_link = FALSE;
                gchar *href, *text, *url, *text_to_append = NULL;
@@ -4927,26 +4933,19 @@ create_anchor_for_link (const GMatchInfo *info,
                         GString *res,
                         gpointer data)
 {
-       gboolean link_surrounded, with_nbsp = FALSE;
+       gboolean link_surrounded, ending_with_nbsp = FALSE;
        gint offset = 0, truncate_from_end = 0;
        gint match_start, match_end;
-       gchar *match_with_nbsp, *match_without_nbsp;
+       gchar *match;
        const gchar *end_of_match = NULL;
-       const gchar *match, *match_extra_characters;
+       const gchar *nbsp_match = NULL;
 
-       match_with_nbsp = g_match_info_fetch (info, 1);
-       /* E-mail addresses will be here. */
-       match_without_nbsp = g_match_info_fetch (info, 0);
+       match = g_match_info_fetch (info, 0);
+       g_match_info_fetch_pos (info, 0, &match_start, &match_end);
 
-       if (!match_with_nbsp || (strstr (match_with_nbsp, "&nbsp;") && !g_str_has_prefix (match_with_nbsp, 
"&nbsp;"))) {
-               match = match_without_nbsp;
-               match_extra_characters = match_with_nbsp;
-               g_match_info_fetch_pos (info, 0, &match_start, &match_end);
-               with_nbsp = TRUE;
-       } else {
-               match = match_with_nbsp;
-               match_extra_characters = match_without_nbsp;
-               g_match_info_fetch_pos (info, 1, &match_start, &match_end);
+       if (g_str_has_suffix (match, "&nbsp;")) {
+               ending_with_nbsp = TRUE;
+               truncate_from_end = 6;
        }
 
        if (g_str_has_prefix (match, "&nbsp;"))
@@ -4973,12 +4972,27 @@ create_anchor_for_link (const GMatchInfo *info,
                        link_surrounded = link_surrounded && g_str_has_suffix (match, "&gt;");
 
                if (link_surrounded) {
-                       /* ";" is already counted by code above */
-                       truncate_from_end += 3;
-                       end_of_match -= 3;
+                       truncate_from_end += 4;
+                       end_of_match -= 4;
                }
        }
 
+       /* The ending ';' was counted when looking for the invalid trailing characters, substract it. */
+       if (link_surrounded || ending_with_nbsp) {
+               truncate_from_end -= 1;
+               end_of_match += 1;
+       }
+
+       /* If there is non-breaking space in the match, remove it and everything
+        * after it from the match */
+       if (!g_str_has_prefix (match, "&nbsp;") && !g_str_has_suffix (match, "&nbsp;") && (nbsp_match = 
strstr (match, "&nbsp;"))) {
+               glong after_nbsp_length = g_utf8_strlen (nbsp_match, -1);
+               truncate_from_end = after_nbsp_length;
+               end_of_match -= after_nbsp_length;
+               if (link_surrounded)
+                       end_of_match += 4;
+       }
+
        g_string_append (res, "<a href=\"");
        if (strstr (match, "@") && !strstr (match, "://"))
                g_string_append (res, "mailto:";);
@@ -4996,11 +5010,10 @@ create_anchor_for_link (const GMatchInfo *info,
        if (truncate_from_end > 0)
                g_string_append (res, end_of_match);
 
-       if (!with_nbsp && match_extra_characters)
-               g_string_append (res, match_extra_characters + (match_end - match_start));
+       if (ending_with_nbsp)
+               g_string_append (res, "&nbsp;");
 
-       g_free (match_with_nbsp);
-       g_free (match_without_nbsp);
+       g_free (match);
 
        return FALSE;
 }
diff --git a/src/modules/webkit-editor/web-extension/e-editor-dom-functions.h 
b/src/modules/webkit-editor/web-extension/e-editor-dom-functions.h
index 04cb85f..3ac56b1 100644
--- a/src/modules/webkit-editor/web-extension/e-editor-dom-functions.h
+++ b/src/modules/webkit-editor/web-extension/e-editor-dom-functions.h
@@ -28,10 +28,8 @@
 
 /* stephenhay from https://mathiasbynens.be/demo/url-regex */
 #define URL_PROTOCOLS "news|telnet|nntp|file|https?|s?ftp|webcal|localhost|ssh"
-#define URL_PATTERN_BASE "(?=((?:(?:(?:" URL_PROTOCOLS 
")\\:\\/\\/)|(?:www\\.|ftp\\.))[^\\s\\/\\$\\.\\?#].[^\\s]*+)"
-#define URL_PATTERN_NO_NBSP ")((?:(?!&nbsp;).)*+)"
-#define URL_PATTERN URL_PATTERN_BASE URL_PATTERN_NO_NBSP
-#define URL_PATTERN_SPACE URL_PATTERN_BASE "\\s$" URL_PATTERN_NO_NBSP
+#define URL_PATTERN "((?:(?:(?:" URL_PROTOCOLS ")\\:\\/\\/)|(?:www\\.|ftp\\.))[^\\s\\/\\$\\.\\?#].[^\\s]*+)"
+#define URL_PATTERN_SPACE URL_PATTERN "\\s$"
 /* Taken from camel-url-scanner.c */
 #define URL_INVALID_TRAILING_CHARS ",.:;?!-|}])\""
 


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