[evolution/wip/webkit2] Bug 756707 - calculations of lineno and offset for external editor gvim component is broken
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/webkit2] Bug 756707 - calculations of lineno and offset for external editor gvim component is broken
- Date: Wed, 2 Mar 2016 14:39:18 +0000 (UTC)
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]