[evolution] Fix various problems with deleting the selection that ends or starts in the quoted content
- From: Tomas Popela <tpopela src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] Fix various problems with deleting the selection that ends or starts in the quoted content
- Date: Wed, 28 Jan 2015 10:16:17 +0000 (UTC)
commit 80405083300384a2c63566e95cc27f61bfc488ec
Author: Tomas Popela <tpopela redhat com>
Date: Wed Jan 28 11:13:30 2015 +0100
Fix various problems with deleting the selection that ends or starts in the quoted content
e-util/e-html-editor-selection.c | 13 ++--
e-util/e-html-editor-selection.h | 3 +-
e-util/e-html-editor-view.c | 164 +++++++++++++++++++++++++++++++++++--
3 files changed, 164 insertions(+), 16 deletions(-)
---
diff --git a/e-util/e-html-editor-selection.c b/e-util/e-html-editor-selection.c
index b755072..5684e5e 100644
--- a/e-util/e-html-editor-selection.c
+++ b/e-util/e-html-editor-selection.c
@@ -3771,7 +3771,7 @@ e_html_editor_selection_set_monospaced (EHTMLEditorSelection *selection,
range, WEBKIT_DOM_NODE (monospace), NULL);
e_html_editor_selection_move_caret_into_element (
- document, monospace);
+ document, monospace, FALSE);
}
} else {
gboolean is_bold, is_italic, is_underline, is_strikethrough;
@@ -4857,7 +4857,8 @@ e_html_editor_selection_replace_image_src (EHTMLEditorSelection *selection,
void
e_html_editor_selection_move_caret_into_element (WebKitDOMDocument *document,
- WebKitDOMElement *element)
+ WebKitDOMElement *element,
+ gboolean to_start)
{
WebKitDOMDOMWindow *window;
WebKitDOMDOMSelection *window_selection;
@@ -4871,8 +4872,8 @@ e_html_editor_selection_move_caret_into_element (WebKitDOMDocument *document,
new_range = webkit_dom_document_create_range (document);
webkit_dom_range_select_node_contents (
- new_range, WEBKIT_DOM_NODE (element), NULL);
- webkit_dom_range_collapse (new_range, FALSE, NULL);
+ new_range, WEBKIT_DOM_NODE (element), NULL);
+ webkit_dom_range_collapse (new_range, to_start, NULL);
webkit_dom_dom_selection_remove_all_ranges (window_selection);
webkit_dom_dom_selection_add_range (window_selection, new_range);
}
@@ -5071,13 +5072,13 @@ e_html_editor_selection_restore_caret_position (EHTMLEditorSelection *selection)
remove_node (WEBKIT_DOM_NODE (element));
e_html_editor_selection_move_caret_into_element (
- document, WEBKIT_DOM_ELEMENT (next_sibling));
+ document, WEBKIT_DOM_ELEMENT (next_sibling), FALSE);
goto out;
}
}
- e_html_editor_selection_move_caret_into_element (document, element);
+ e_html_editor_selection_move_caret_into_element (document, element, FALSE);
if (fix_after_quoting) {
prev_sibling = webkit_dom_node_get_previous_sibling (
diff --git a/e-util/e-html-editor-selection.h b/e-util/e-html-editor-selection.h
index 3290dfe..5ae9492 100644
--- a/e-util/e-html-editor-selection.h
+++ b/e-util/e-html-editor-selection.h
@@ -185,7 +185,8 @@ void e_html_editor_selection_insert_image
const gchar *image_uri);
void e_html_editor_selection_move_caret_into_element
(WebKitDOMDocument *document,
- WebKitDOMElement *element);
+ WebKitDOMElement *element,
+ gboolean to_start);
void e_html_editor_selection_clear_caret_position_marker
(EHTMLEditorSelection *selection);
WebKitDOMNode *
diff --git a/e-util/e-html-editor-view.c b/e-util/e-html-editor-view.c
index 77a1df7..76a767a 100644
--- a/e-util/e-html-editor-view.c
+++ b/e-util/e-html-editor-view.c
@@ -2179,10 +2179,13 @@ body_keyup_event_cb (WebKitDOMElement *element,
* BackSpace or Delete. */
gint level;
WebKitDOMElement *selection_start_marker, *selection_end_marker;
- WebKitDOMElement *br_element;
+ WebKitDOMElement *tmp_element;
WebKitDOMDocument *document;
WebKitDOMNode *node, *parent;
+ if (e_html_editor_view_get_html_mode (view))
+ return;
+
document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
e_html_editor_selection_save (selection);
@@ -2191,6 +2194,33 @@ body_keyup_event_cb (WebKitDOMElement *element,
selection_end_marker = webkit_dom_document_get_element_by_id (
document, "-x-evo-selection-end-marker");
+ /* Situation where the end of the selection was in the
+ * middle of quoted content and the start in the beginning of
+ * the non quoted content before the citation. WebKit took out
+ * the block from citation and inserted the block before the citation.
+ * We made a clone of the original block so we have to move the
+ * content there and reinsert the quote marks.
+ *
+ * |xxx
+ * > x|xx
+ * */
+ tmp_element = webkit_dom_document_get_element_by_id (document, "-x-evo-repair-block");
+ if (tmp_element) {
+ parent = get_parent_block_node_from_child (
+ WEBKIT_DOM_NODE (selection_start_marker));
+
+ while ((node = webkit_dom_node_get_first_child (parent)))
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (tmp_element), node, NULL);
+
+ level = get_citation_level (WEBKIT_DOM_NODE (tmp_element), FALSE);
+ quote_plain_text_element_after_wrapping (
+ document, tmp_element, level);
+ webkit_dom_element_remove_attribute (tmp_element, "id");
+ remove_node (parent);
+ goto restore;
+ }
+
level = get_citation_level (
WEBKIT_DOM_NODE (selection_start_marker), FALSE);
@@ -2212,10 +2242,29 @@ body_keyup_event_cb (WebKitDOMElement *element,
parent = get_parent_block_node_from_child (
WEBKIT_DOM_NODE (selection_start_marker));
+ if (!node) {
+ /* Situation where the end of the selection was in the
+ * beginning of the block inside the quoted content and
+ * the start in non quoted content before the citation.
+ * In this situation WebKit will do the things right, but
+ * it will remove the quote marks so we have to restore them.
+ *
+ * xx|x
+ * > |xxx
+ * */
+ tmp_element = webkit_dom_element_query_selector (
+ WEBKIT_DOM_ELEMENT (parent), "span.-x-evo-quoted", NULL);
+ if (!tmp_element) {
+ quote_plain_text_element_after_wrapping (
+ document, WEBKIT_DOM_ELEMENT (parent), level);
+ goto restore;
+ }
+ }
+
node = webkit_dom_node_get_previous_sibling (parent);
if (!node) {
- /* Situation where the start of the selection was in the
- * multiple quoted content and that start on the beginning
+ /* Situation where the end of the selection was in the
+ * multiple quoted content and the start on the beginning
* of the citation.
*
* >
@@ -2232,9 +2281,9 @@ body_keyup_event_cb (WebKitDOMElement *element,
goto restore;
}
- br_element = webkit_dom_element_query_selector (
+ tmp_element = webkit_dom_element_query_selector (
WEBKIT_DOM_ELEMENT (node), "span.-x-evo-quote-character > br", NULL);
- if (br_element) {
+ if (tmp_element) {
WebKitDOMNode *tmp;
if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node)) {
@@ -2247,7 +2296,7 @@ body_keyup_event_cb (WebKitDOMElement *element,
*/
/* <span class="-x-evo-quote-character"> */
node = webkit_dom_node_get_parent_node (
- WEBKIT_DOM_NODE (br_element));
+ WEBKIT_DOM_NODE (tmp_element));
/* <span class="-x-evo-quoted"> */
node = webkit_dom_node_get_parent_node (node);
/* right block */
@@ -2269,9 +2318,9 @@ body_keyup_event_cb (WebKitDOMElement *element,
if (!WEBKIT_DOM_IS_HTMLBR_ELEMENT (webkit_dom_node_get_last_child (node)))
webkit_dom_node_append_child (
- node, WEBKIT_DOM_NODE (br_element), NULL);
+ node, WEBKIT_DOM_NODE (tmp_element), NULL);
else
- remove_node (WEBKIT_DOM_NODE (br_element));
+ remove_node (WEBKIT_DOM_NODE (tmp_element));
remove_node (parent);
}
@@ -2859,6 +2908,99 @@ change_quoted_block_to_normal (EHTMLEditorView *view)
}
static gboolean
+fix_structure_after_delete_before_quoted_content (EHTMLEditorView *view)
+{
+ EHTMLEditorSelection *selection;
+ gboolean collapsed = FALSE;
+ WebKitDOMDocument *document;
+ WebKitDOMElement *selection_start_marker, *selection_end_marker;
+ WebKitDOMNode *block, *next_sibling, *node;
+
+ selection = e_html_editor_view_get_selection (view);
+
+ collapsed = e_html_editor_selection_is_collapsed (selection);
+
+ e_html_editor_selection_save (selection);
+
+ document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
+ selection_start_marker = webkit_dom_document_query_selector (
+ document, "span#-x-evo-selection-start-marker", NULL);
+ selection_end_marker = webkit_dom_document_query_selector (
+ document, "span#-x-evo-selection-end-marker", NULL);
+
+ if (!selection_start_marker || !selection_end_marker)
+ return FALSE;
+
+ if (collapsed) {
+ block = get_parent_block_node_from_child (
+ WEBKIT_DOM_NODE (selection_start_marker));
+
+ next_sibling = webkit_dom_node_get_next_sibling (block);
+
+ /* Next block is quoted content */
+ if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (next_sibling))
+ goto restore;
+
+ /* Delete was pressed in block without any content */
+ if (webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (selection_start_marker)))
+ goto restore;
+
+ /* If there is just BR element go ahead */
+ node = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (selection_end_marker));
+ if (node && !WEBKIT_DOM_IS_HTMLBR_ELEMENT (node))
+ goto restore;
+ else {
+ /* Remove the empty block and move caret into the beginning of the citation */
+ remove_node (block);
+
+ e_html_editor_selection_move_caret_into_element (
+ document, WEBKIT_DOM_ELEMENT (next_sibling), TRUE);
+
+ return TRUE;
+ }
+ } else {
+ gint level_start, level_end;
+
+ printf ("%s\n", webkit_dom_html_element_get_outer_html (WEBKIT_DOM_HTML_ELEMENT
(webkit_dom_document_get_body (document))));
+ /* Delete was pressed in block without any content */
+ if (webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (selection_start_marker)))
+ goto restore;
+
+ /* Situation where the end of the selection is in the
+ * middle of quoted content and the start in the beginning of
+ * the non quoted content before the citation. WebKit will take
+ * the block out from citation and insert the block before the citation.
+ * We have to make a clone of the block to restore it correctly later.
+ *
+ * |xxx
+ * > x|xx
+ * */
+ level_start = get_citation_level (WEBKIT_DOM_NODE (selection_start_marker), FALSE);
+ level_end = get_citation_level (WEBKIT_DOM_NODE (selection_end_marker), FALSE);
+
+ if (level_start == 0 && level_end > 0) {
+ WebKitDOMNode *clone;
+
+ block = get_parent_block_node_from_child (
+ WEBKIT_DOM_NODE (selection_end_marker));
+
+ clone = webkit_dom_node_clone_node (block, FALSE);
+ webkit_dom_element_set_id (WEBKIT_DOM_ELEMENT (clone), "-x-evo-repair-block");
+
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (block),
+ clone,
+ webkit_dom_node_get_next_sibling (block),
+ NULL);
+ }
+ }
+ restore:
+ e_html_editor_selection_restore (selection);
+
+ return FALSE;
+}
+
+static gboolean
html_editor_view_key_press_event (GtkWidget *widget,
GdkEventKey *event)
{
@@ -2950,6 +3092,10 @@ html_editor_view_key_press_event (GtkWidget *widget,
return TRUE;
}
+ if (event->keyval == GDK_KEY_Delete || event->keyval == GDK_KEY_BackSpace)
+ if (fix_structure_after_delete_before_quoted_content (view))
+ return TRUE;
+
/* Chain up to parent's key_press_event() method. */
return GTK_WIDGET_CLASS (e_html_editor_view_parent_class)->
key_press_event (widget, event);
@@ -7091,7 +7237,7 @@ html_editor_view_load_status_changed (EHTMLEditorView *view)
if (webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (body), "data-evo-draft")) {
/* Restore the selection how it was when the draft was saved */
e_html_editor_selection_move_caret_into_element (
- document, WEBKIT_DOM_ELEMENT (body));
+ document, WEBKIT_DOM_ELEMENT (body), FALSE);
e_html_editor_selection_restore (
e_html_editor_view_get_selection (view));
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]