[evolution/wip/tpopela/freeze-fixes: 5/7] Bug 746277 - Typing text in composer destroys primary clipboard content
- From: Tomas Popela <tpopela src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/tpopela/freeze-fixes: 5/7] Bug 746277 - Typing text in composer destroys primary clipboard content
- Date: Wed, 18 Mar 2015 14:11:07 +0000 (UTC)
commit 7b4f64c182b5181d1d6f03e090ad6f69b0fe9cec
Author: Tomas Popela <tpopela redhat com>
Date: Wed Mar 18 14:04:59 2015 +0100
Bug 746277 - Typing text in composer destroys primary clipboard content
Rework how the history is saved for input and delete to avoid
introducing a selection in composer that led to overwriting the primary
clipboard content.
e-util/e-html-editor-view.c | 134 ++++++++++++++++++++++++++++++++-----------
1 files changed, 100 insertions(+), 34 deletions(-)
---
diff --git a/e-util/e-html-editor-view.c b/e-util/e-html-editor-view.c
index 92faea3..4822a8f 100644
--- a/e-util/e-html-editor-view.c
+++ b/e-util/e-html-editor-view.c
@@ -421,6 +421,20 @@ html_editor_view_selection_changed_cb (EHTMLEditorView *view,
}
}
+static void
+block_selection_changed_callbacks (EHTMLEditorView *view)
+{
+ e_html_editor_selection_block_selection_changed (view->priv->selection);
+ g_signal_handlers_block_by_func (view, html_editor_view_selection_changed_cb, NULL);
+}
+
+static void
+unblock_selection_changed_callbacks (EHTMLEditorView *view)
+{
+ e_html_editor_selection_unblock_selection_changed (view->priv->selection);
+ g_signal_handlers_unblock_by_func (view, html_editor_view_selection_changed_cb, NULL);
+}
+
static gboolean
html_editor_view_should_show_delete_interface_for_element (EHTMLEditorView *view,
WebKitDOMHTMLElement *element)
@@ -494,9 +508,7 @@ e_html_editor_view_force_spell_check_for_current_paragraph (EHTMLEditorView *vie
/* Block callbacks of selection-changed signal as we don't want to
* recount all the block format things in EHTMLEditorSelection and here as well
* when we are moving with caret */
- g_signal_handlers_block_by_func (
- view, html_editor_view_selection_changed_cb, NULL);
- e_html_editor_selection_block_selection_changed (selection);
+ block_selection_changed_callbacks (view);
parent = get_parent_block_element (WEBKIT_DOM_NODE (selection_end_marker));
@@ -539,9 +551,7 @@ e_html_editor_view_force_spell_check_for_current_paragraph (EHTMLEditorView *vie
remove_node (WEBKIT_DOM_NODE (text));
/* Unblock the callbacks */
- g_signal_handlers_unblock_by_func (
- view, html_editor_view_selection_changed_cb, NULL);
- e_html_editor_selection_unblock_selection_changed (selection);
+ unblock_selection_changed_callbacks (view);
e_html_editor_selection_restore (selection);
}
@@ -682,9 +692,7 @@ refresh_spell_check (EHTMLEditorView *view,
/* Block callbacks of selection-changed signal as we don't want to
* recount all the block format things in EHTMLEditorSelection and here as well
* when we are moving with caret */
- g_signal_handlers_block_by_func (
- view, html_editor_view_selection_changed_cb, NULL);
- e_html_editor_selection_block_selection_changed (selection);
+ block_selection_changed_callbacks (view);
/* Append some text on the end of the body */
text = webkit_dom_document_create_text_node (document, "-x-evo-end");
@@ -717,9 +725,7 @@ refresh_spell_check (EHTMLEditorView *view,
remove_node (WEBKIT_DOM_NODE (text));
/* Unblock the callbacks */
- g_signal_handlers_unblock_by_func (
- view, html_editor_view_selection_changed_cb, NULL);
- e_html_editor_selection_unblock_selection_changed (selection);
+ unblock_selection_changed_callbacks (view);
e_html_editor_selection_restore (selection);
}
@@ -2417,11 +2423,13 @@ static void
save_history_for_input (EHTMLEditorView *view)
{
EHTMLEditorViewHistoryEvent *ev;
+ glong offset;
WebKitDOMDocument *document;
WebKitDOMDocumentFragment *fragment;
WebKitDOMDOMWindow *dom_window;
WebKitDOMDOMSelection *dom_selection;
- WebKitDOMRange *range;
+ WebKitDOMRange *range, *range_clone;
+ WebKitDOMNode *start_container;
document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
dom_window = webkit_dom_document_get_default_view (document);
@@ -2433,20 +2441,67 @@ save_history_for_input (EHTMLEditorView *view)
ev = g_new0 (EHTMLEditorViewHistoryEvent, 1);
ev->type = HISTORY_INPUT;
+ block_selection_changed_callbacks (view);
+
e_html_editor_selection_get_selection_coordinates (
view->priv->selection,
&ev->after.start.x,
&ev->after.start.y,
&ev->after.end.x,
&ev->after.end.y);
- webkit_dom_dom_selection_modify (dom_selection, "extend", "left", "character");
+
range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
- fragment = webkit_dom_range_clone_contents (range, NULL);
+ range_clone = webkit_dom_range_clone_range (range, NULL);
+ offset = webkit_dom_range_get_start_offset (range_clone, NULL);
+ start_container = webkit_dom_range_get_start_container (range_clone, NULL);
+ if (offset > 0)
+ webkit_dom_range_set_start (
+ range_clone,
+ start_container,
+ offset - 1,
+ NULL);
+ fragment = webkit_dom_range_clone_contents (range_clone, NULL);
/* We have to specialy handle Return key press */
if (view->priv->return_key_pressed) {
- WebKitDOMNode *node;
+ WebKitDOMElement *element_start, *element_end;
+ WebKitDOMNode *parent_start, *parent_end, *node;
+
+ element_start = webkit_dom_document_create_element (document, "span", NULL);
+ webkit_dom_range_surround_contents (range, WEBKIT_DOM_NODE (element_start), NULL);
+ webkit_dom_dom_selection_modify (dom_selection, "move", "left", "character");
+ range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
+ element_end = webkit_dom_document_create_element (document, "span", NULL);
+ webkit_dom_range_surround_contents (range, WEBKIT_DOM_NODE (element_end), NULL);
+
+ parent_start = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element_start));
+ parent_end = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element_end));
+
+ while (!webkit_dom_node_is_same_node (parent_start, parent_end)) {
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (fragment),
+ webkit_dom_node_clone_node (parent_start, FALSE),
+ webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment)),
+ NULL);
+ parent_start = webkit_dom_node_get_parent_node (parent_start);
+ parent_end = webkit_dom_node_get_parent_node (parent_end);
+ }
node = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment));
+ while (webkit_dom_node_get_next_sibling (node)) {
+ WebKitDOMNode *last_child;
+
+ last_child = webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (fragment));
+ webkit_dom_node_append_child (
+ webkit_dom_node_get_previous_sibling (last_child),
+ last_child,
+ NULL);
+ }
+
+ node = webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (fragment));
+ while (webkit_dom_node_get_last_child (node)) {
+ node = webkit_dom_node_get_last_child (node);
+ }
+
webkit_dom_node_append_child (
node,
WEBKIT_DOM_NODE (
@@ -2463,7 +2518,10 @@ save_history_for_input (EHTMLEditorView *view)
create_selection_marker (document, FALSE)),
NULL);
- remove_node (webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (fragment)));
+ remove_node (WEBKIT_DOM_NODE (element_start));
+ remove_node (WEBKIT_DOM_NODE (element_end));
+
+ webkit_dom_dom_selection_modify (dom_selection, "move", "right", "character");
} else {
webkit_dom_node_append_child (
WEBKIT_DOM_NODE (fragment),
@@ -2477,7 +2535,8 @@ save_history_for_input (EHTMLEditorView *view)
NULL);
}
- webkit_dom_dom_selection_modify (dom_selection, "move", "right", "character");
+
+ unblock_selection_changed_callbacks (view);
ev->data.fragment = fragment;
e_html_editor_view_insert_new_history_event (view, ev);
@@ -3874,36 +3933,41 @@ save_history_for_delete_or_backspace (EHTMLEditorView *view,
range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
if (webkit_dom_range_get_collapsed (range, NULL)) {
- WebKitDOMNode *node = webkit_dom_range_get_end_container (range, NULL);
+ WebKitDOMRange *range_clone;
- if (delete_key && !webkit_dom_node_get_next_sibling (node)) {
- g_free (ev);
- return;
- }
+ block_selection_changed_callbacks (view);
- if (delete_key)
- webkit_dom_dom_selection_modify (dom_selection, "extend", "right", "character");
- else
- webkit_dom_dom_selection_modify (dom_selection, "extend", "left", "character");
-
- range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
- fragment = webkit_dom_range_clone_contents (range, NULL);
+ range_clone = webkit_dom_range_clone_range (range, NULL);
+ if (delete_key) {
+ glong offset = webkit_dom_range_get_start_offset (range_clone, NULL);
+ webkit_dom_range_set_end (
+ range_clone,
+ webkit_dom_range_get_end_container (range_clone, NULL),
+ offset + 1,
+ NULL);
+ } else {
+ webkit_dom_range_set_start (
+ range_clone,
+ webkit_dom_range_get_start_container (range_clone, NULL),
+ webkit_dom_range_get_start_offset (range_clone, NULL) - 1,
+ NULL);
+ }
+ fragment = webkit_dom_range_clone_contents (range_clone, NULL);
if (!webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment))) {
g_free (ev);
+ unblock_selection_changed_callbacks (view);
return;
}
if (delete_key) {
- webkit_dom_dom_selection_collapse_to_start (dom_selection, NULL);
-
e_html_editor_selection_get_selection_coordinates (
selection, &ev->after.start.x, &ev->after.start.y, &ev->after.end.x,
&ev->after.end.y);
} else {
+ webkit_dom_dom_selection_modify (dom_selection, "move", "left", "character");
e_html_editor_selection_get_selection_coordinates (
selection, &ev->after.start.x, &ev->after.start.y, &ev->after.end.x,
&ev->after.end.y);
-
- webkit_dom_dom_selection_collapse_to_end (dom_selection, NULL);
+ webkit_dom_dom_selection_modify (dom_selection, "move", "right", "character");
}
if (!delete_key) {
@@ -3936,6 +4000,8 @@ save_history_for_delete_or_backspace (EHTMLEditorView *view,
create_selection_marker (document, FALSE)),
NULL);
}
+
+ unblock_selection_changed_callbacks (view);
} else {
ev->after.start.x = ev->before.start.x;
ev->after.start.y = ev->before.start.y;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]