[evolution] EHTMLEditorSelection - Correctly wrap text nodes around selection markers
- From: Tomas Popela <tpopela src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] EHTMLEditorSelection - Correctly wrap text nodes around selection markers
- Date: Fri, 4 Sep 2015 11:47:47 +0000 (UTC)
commit b31f76d280e5ee9369bfc000a018b493e5724ad7
Author: Tomas Popela <tpopela redhat com>
Date: Fri Sep 4 12:08:41 2015 +0200
EHTMLEditorSelection - Correctly wrap text nodes around selection markers
The word could be split by selection markers and in this case we would wrap it
wrongly as the other part of the word is in another text node after the marker.
As a solution temporary append the text of a node that is after the caret to the
node that is before the caret and remove this appended text after we wrap the text
that is before the caret.
e-util/e-html-editor-selection.c | 105 ++++++++++++++++++++++++++++++++++----
1 files changed, 95 insertions(+), 10 deletions(-)
---
diff --git a/e-util/e-html-editor-selection.c b/e-util/e-html-editor-selection.c
index 1a93c15..0c5c736 100644
--- a/e-util/e-html-editor-selection.c
+++ b/e-util/e-html-editor-selection.c
@@ -6186,6 +6186,62 @@ mark_and_remove_leading_space (WebKitDOMDocument *document,
WEBKIT_DOM_CHARACTER_DATA (node), 0, 1, "", NULL);
}
+static void
+append_sibling_text_to_previous_node (WebKitDOMNode *node,
+ gboolean collapsed)
+{
+ WebKitDOMNode *next_text;
+
+ next_text = webkit_dom_node_get_next_sibling (node);
+ if (WEBKIT_DOM_IS_CHARACTER_DATA (next_text)) {
+ gchar *data;
+
+ data = webkit_dom_character_data_get_data (
+ WEBKIT_DOM_CHARACTER_DATA (next_text));
+ /* If there is a space or dash we would split anyway at that point
+ * so skip it. */
+ if (data && !(*data == ' ' || *data == '-')) {
+ WebKitDOMNode *prev_sibling;
+
+ prev_sibling = webkit_dom_node_get_previous_sibling (node);
+ if (collapsed)
+ prev_sibling = webkit_dom_node_get_previous_sibling (prev_sibling);
+ if (WEBKIT_DOM_IS_CHARACTER_DATA (prev_sibling)) {
+ glong length;
+
+ length = webkit_dom_character_data_get_length (
+ WEBKIT_DOM_CHARACTER_DATA (next_text));
+ webkit_dom_character_data_append_data (
+ WEBKIT_DOM_CHARACTER_DATA (prev_sibling), data, NULL);
+ g_object_set_data (
+ G_OBJECT (prev_sibling),
+ "-x-evo-char-count",
+ GINT_TO_POINTER (length));
+ }
+ }
+ g_free (data);
+ }
+}
+
+static void
+temporary_remove_selection_point (WebKitDOMNode *selection_start_marker,
+ WebKitDOMNode *selection_end_marker)
+{
+ WebKitDOMNode *next_sibling;
+
+ next_sibling = webkit_dom_node_get_next_sibling (selection_start_marker);
+ if (next_sibling && webkit_dom_node_is_same_node (next_sibling, selection_end_marker)) {
+ append_sibling_text_to_previous_node (selection_end_marker, TRUE);
+ } else {
+ /* Selection is not collapsed, so we have to prepare
+ * the start point as well as end point. */
+ append_sibling_text_to_previous_node (selection_start_marker, FALSE);
+
+ if (selection_end_marker)
+ append_sibling_text_to_previous_node (selection_end_marker, FALSE);
+ }
+}
+
static WebKitDOMElement *
wrap_lines (EHTMLEditorSelection *selection,
WebKitDOMNode *block,
@@ -6296,15 +6352,6 @@ wrap_lines (EHTMLEditorSelection *selection,
g_object_unref (list);
}
- webkit_dom_node_normalize (block_clone);
- node = webkit_dom_node_get_first_child (block_clone);
- if (node) {
- text_content = webkit_dom_node_get_text_content (node);
- if (g_strcmp0 ("\n", text_content) == 0)
- node = webkit_dom_node_get_next_sibling (node);
- g_free (text_content);
- }
-
/* We have to start from the end of the last wrapped line */
selection_start_marker = webkit_dom_element_query_selector (
WEBKIT_DOM_ELEMENT (block_clone),
@@ -6343,6 +6390,15 @@ wrap_lines (EHTMLEditorSelection *selection,
}
}
+ webkit_dom_node_normalize (block_clone);
+ node = webkit_dom_node_get_first_child (block_clone);
+ if (node) {
+ text_content = webkit_dom_node_get_text_content (node);
+ if (g_strcmp0 ("\n", text_content) == 0)
+ node = webkit_dom_node_get_next_sibling (node);
+ g_free (text_content);
+ }
+
if (start_point) {
if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (start_point))
node = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (start_point));
@@ -6351,6 +6407,19 @@ wrap_lines (EHTMLEditorSelection *selection,
start_node = block_clone;
} else
start_node = node;
+
+ if (selection_start_marker || selection_end_marker) {
+ /* The word could be split by selection markers and in this
+ * case we would wrap it wrongly as the other part of the
+ * word is in another text node after the marker.
+ * As a solution temporary append the text of a node that
+ * is after the caret to the node that is before the caret
+ * and remove this appended text after we wrap the text
+ * that is before the caret. */
+ temporary_remove_selection_point (
+ WEBKIT_DOM_NODE (selection_start_marker),
+ WEBKIT_DOM_NODE (selection_end_marker));
+ }
}
line_length = 0;
@@ -6518,6 +6587,7 @@ wrap_lines (EHTMLEditorSelection *selection,
/* wrap until we have something */
while (node && (length_left + line_length) > length_to_wrap) {
gint max_length;
+ gpointer object_data;
element = webkit_dom_document_create_element (document, "BR", NULL);
element_add_class (element, "-x-evo-wrap-br");
@@ -6539,7 +6609,22 @@ wrap_lines (EHTMLEditorSelection *selection,
/* Allow anchors to break on any character. */
if (g_object_steal_data (G_OBJECT (node), "-x-evo-anchor-text"))
offset = max_length;
- else {
+ else if ((object_data = g_object_steal_data (G_OBJECT (node), "-x-evo-char-count")))
{
+ glong characters_count;
+
+ offset = find_where_to_break_line (
+ WEBKIT_DOM_CHARACTER_DATA (node), max_length);
+
+ /* Truncate the temporary text that was added to
+ * the node previously and unmark the node. */
+ characters_count = GPOINTER_TO_INT (object_data);
+ webkit_dom_character_data_delete_data (
+ WEBKIT_DOM_CHARACTER_DATA (node),
+ webkit_dom_character_data_get_length (
+ WEBKIT_DOM_CHARACTER_DATA (node)) - characters_count,
+ characters_count,
+ NULL);
+ } else {
/* Find where we can line-break the node so that it
* effectively fills the rest of current row. */
offset = find_where_to_break_line (
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]