[evolution/wip/webkit2] Bug 756707 - calculations of lineno and offset for external editor gvim component is broken



commit 2a8a937b4dd403cb6676825857bf4b4056d69316
Author: Tomas Popela <tpopela redhat com>
Date:   Wed Mar 2 14:43:22 2016 +0100

    Bug 756707 - calculations of lineno and offset for external editor gvim component is broken

 plugins/external-editor/external-editor.c          |   34 ++++++++-
 .../composer/e-html-editor-view-dom-functions.c    |   86 ++++++++++++++------
 .../composer/e-html-editor-view-dom-functions.h    |    2 +
 .../composer/e-html-editor-web-extension.c         |   20 +++++
 4 files changed, 117 insertions(+), 25 deletions(-)
---
diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c
index f4b6632..1e8a109 100644
--- a/plugins/external-editor/external-editor.c
+++ b/plugins/external-editor/external-editor.c
@@ -255,6 +255,36 @@ numlines (const gchar *text,
 }
 
 static gint32
+get_caret_offset (EHTMLEditorView *view)
+{
+       GDBusProxy *web_extension;
+       gint position = 0;
+       GVariant *result;
+
+       web_extension = e_html_editor_view_get_web_extension_proxy (view);
+       if (!web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               web_extension,
+               "DOMGetCaretOffset",
+               g_variant_new (
+                       "(t)",
+                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               position = g_variant_get_int32 (result);
+               g_variant_unref (result);
+       }
+
+       return position;
+}
+
+static gint32
 get_caret_position (EHTMLEditorView *view)
 {
        GDBusProxy *web_extension;
@@ -370,7 +400,9 @@ external_editor_thread (gpointer user_data)
                gboolean set_nofork;
 
                set_nofork = g_strrstr (editor_cmd, "gvim") != NULL;
-               /* Increment 1 so that entering vim insert mode places you
+
+               offset = get_caret_offset (view);
+               /* Increment by 1 so that entering vim insert mode places you
                 * in the same entry position you were at in the html. */
                offset++;
 
diff --git a/web-extensions/composer/e-html-editor-view-dom-functions.c 
b/web-extensions/composer/e-html-editor-view-dom-functions.c
index e3d8f3c..d84955b 100644
--- a/web-extensions/composer/e-html-editor-view-dom-functions.c
+++ b/web-extensions/composer/e-html-editor-view-dom-functions.c
@@ -9214,14 +9214,15 @@ dom_process_content_after_mode_change (WebKitDOMDocument *document,
 }
 
 gint
-dom_get_caret_position (WebKitDOMDocument *document)
+dom_get_caret_offset (WebKitDOMDocument *document,
+                     EHTMLEditorWebExtension *extension)
 {
+       gint ret_val;
+       gchar *text;
        WebKitDOMDOMWindow *dom_window;
        WebKitDOMDOMSelection *dom_selection;
+       WebKitDOMNode *anchor;
        WebKitDOMRange *range;
-       gint range_count, ret_val;
-       WebKitDOMNodeList *nodes;
-       gulong ii, length;
 
        dom_window = webkit_dom_document_get_default_view (document);
        dom_selection = webkit_dom_dom_window_get_selection (dom_window);
@@ -9232,34 +9233,71 @@ dom_get_caret_position (WebKitDOMDocument *document)
                return 0;
        }
 
+       webkit_dom_dom_selection_collapse_to_start (dom_selection, NULL);
+       /* Select the text from the current caret position to the beginning of the line. */
+       webkit_dom_dom_selection_modify (dom_selection, "extend", "left", "lineBoundary");
+
        range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
-       range_count = 0;
-       nodes = webkit_dom_node_get_child_nodes (
-               webkit_dom_node_get_parent_node (
-                       webkit_dom_dom_selection_get_anchor_node (
-                               dom_selection)));
-       length = webkit_dom_node_list_get_length (nodes);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *node;
+       anchor = webkit_dom_dom_selection_get_anchor_node (dom_selection);
+       text = webkit_dom_range_to_string (range, NULL);
+       ret_val = strlen (text);
+       g_free (text);
 
-               node = webkit_dom_node_list_item (nodes, ii);
-               if (webkit_dom_node_is_same_node (
-                       node, webkit_dom_dom_selection_get_anchor_node (dom_selection))) {
+       webkit_dom_dom_selection_collapse_to_end (dom_selection, NULL);
 
-                       g_object_unref (node);
-                       break;
-               } else if (WEBKIT_DOM_IS_TEXT (node)) {
-                       gchar *text = webkit_dom_node_get_text_content (node);
-                       range_count += strlen (text);
-                       g_free (text);
+       /* In the plain text mode we need to increase the return value by 2 per
+        * citation level because of "> ". */
+       if (!e_html_editor_web_extension_get_html_mode (extension)) {
+               WebKitDOMNode *parent = anchor;
+
+               while (parent && !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
+                       if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
+                           element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-plaintext-quoted"))
+                               ret_val += 2;
+
+                       parent = webkit_dom_node_get_parent_node (parent);
                }
-               g_object_unref (node);
        }
 
-       g_object_unref (nodes);
+       g_object_unref (range);
+       g_object_unref (dom_selection);
 
-       ret_val = webkit_dom_range_get_start_offset (range, NULL) + range_count;
+       return ret_val;
+}
 
+gint
+dom_get_caret_position (WebKitDOMDocument *document)
+{
+       gint ret_val;
+       gchar *text;
+       WebKitDOMHTMLElement *body;
+       WebKitDOMDOMWindow *dom_window;
+       WebKitDOMDOMSelection *dom_selection;
+       WebKitDOMRange *range, *range_clone;
+
+       dom_window = webkit_dom_document_get_default_view (document);
+       dom_selection = webkit_dom_dom_window_get_selection (dom_window);
+       g_object_unref (dom_window);
+
+       if (webkit_dom_dom_selection_get_range_count (dom_selection) < 1) {
+               g_object_unref (dom_selection);
+               return 0;
+       }
+
+       range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
+       range_clone = webkit_dom_range_clone_range (range, NULL);
+
+       body = webkit_dom_document_get_body (document);
+       /* Select the text from the beginning of the body to the current caret. */
+       webkit_dom_range_set_start_before (
+               range_clone, webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)), NULL);
+
+       /* This is returning a text without new lines! */
+       text = webkit_dom_range_to_string (range_clone, NULL);
+       ret_val = strlen (text);
+       g_free (text);
+
+       g_object_unref (range_clone);
        g_object_unref (range);
        g_object_unref (dom_selection);
 
diff --git a/web-extensions/composer/e-html-editor-view-dom-functions.h 
b/web-extensions/composer/e-html-editor-view-dom-functions.h
index 8fc6691..faa73e5 100644
--- a/web-extensions/composer/e-html-editor-view-dom-functions.h
+++ b/web-extensions/composer/e-html-editor-view-dom-functions.h
@@ -146,6 +146,8 @@ void                dom_process_content_after_mode_change
                                                (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension);
 
+gint           dom_get_caret_offset            (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 gint           dom_get_caret_position          (WebKitDOMDocument *document);
 
 void           dom_drag_and_drop_end           (WebKitDOMDocument *document,
diff --git a/web-extensions/composer/e-html-editor-web-extension.c 
b/web-extensions/composer/e-html-editor-web-extension.c
index 35f06e8..ff19560 100644
--- a/web-extensions/composer/e-html-editor-web-extension.c
+++ b/web-extensions/composer/e-html-editor-web-extension.c
@@ -641,6 +641,10 @@ static const char introspection_xml[] =
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='i' name='position' direction='out'/>"
 "    </method>"
+"    <method name='DOMGetCaretOffset'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='i' name='offset' direction='out'/>"
+"    </method>"
 "    <method name='DOMClearUndoRedoHistory'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "    </method>"
@@ -2408,6 +2412,22 @@ handle_method_call (GDBusConnection *connection,
                g_dbus_method_invocation_return_value (
                        invocation,
                        value ? g_variant_new_int32 (value) : NULL);
+       } else if (g_strcmp0 (method_name, "DOMGetCaretOffset") == 0) {
+               gint32 value;
+
+               g_variant_get (parameters, "(t)", &page_id);
+
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
+               if (!web_page)
+                       goto error;
+
+               document = webkit_web_page_get_dom_document (web_page);
+               value = dom_get_caret_offset (document, extension);
+
+               g_dbus_method_invocation_return_value (
+                       invocation,
+                       value ? g_variant_new_int32 (value) : NULL);
        } else if (g_strcmp0 (method_name, "DOMClearUndoRedoHistory") == 0) {
                g_variant_get (parameters, "(t)", &page_id);
 


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