[evolution-patches] [gtkhtml] cursor movement fix (fixes reversed typing in some cases)



Hi,

attached patch fixes reversed typing in case of html mail with anchors. It also fixes DIV blocks parsing. Empty DIV blocks were parsed to illegal object hierarchy which caused wrong cursor movement as well.

There's also test added for cursor movement around anchors.

Cheers
Radek

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/ChangeLog,v
retrieving revision 1.2110
diff -u -p -r1.2110 ChangeLog
--- ChangeLog	23 Mar 2005 21:21:50 -0000	1.2110
+++ ChangeLog	29 Mar 2005 15:42:32 -0000
@@ -1,3 +1,19 @@
+2005-03-29  Radek Doulik  <rodo novell com>
+
+	* test-suite.c (test_cursor_around_anchors): added test for cursor
+	movement around anchors (they do not accpet cursor).
+
+	* htmlobject.c (html_cursor_allow_zero_offset): new helper
+	function, decides whether we can move cursor to 0 offset on object
+	use html_cursor_allow_zero_offset where approriate
+
+	* htmlengine.c (block_end_display_block): add empty flow in case
+	cluev is empty
+
+	* htmlcursor.c: make it possible to control cursor debug output by
+	environment variable
+	(html_cursor_home): fix typo causing crash
+
 2005-03-23  Radek Doulik  <rodo novell com>
 
 	* htmlgdkpainter.c (draw_glyphs): maintain fg color unchanged
Index: htmlcursor.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlcursor.c,v
retrieving revision 1.73
diff -u -p -r1.73 htmlcursor.c
--- htmlcursor.c	14 Mar 2005 18:36:14 -0000	1.73
+++ htmlcursor.c	29 Mar 2005 15:42:32 -0000
@@ -40,14 +40,26 @@
 static gboolean move_right (HTMLCursor *cursor, HTMLEngine *e);
 static gboolean move_left (HTMLCursor *cursor, HTMLEngine *e);
 
-/* #define _HTML_CURSOR_DEBUG */
+#define _HTML_CURSOR_DEBUG
 
 #ifdef _HTML_CURSOR_DEBUG
+static int gtk_html_cursor_debug_flag = -1;
+
 static void
 debug_location (const HTMLCursor *cursor)
 {
 	HTMLObject *object;
 
+	if (gtk_html_cursor_debug_flag == -1) {
+		if (getenv("GTK_HTML_DEBUG_CURSOR") != NULL)
+			gtk_html_cursor_debug_flag = 1;
+		else
+			gtk_html_cursor_debug_flag = 0;
+	}
+
+	if (!gtk_html_cursor_debug_flag)
+		return;
+
 	object = cursor->object;
 	if (object == NULL) {
 		g_print ("Cursor has no position.\n");
@@ -171,7 +183,7 @@ html_cursor_home (HTMLCursor *cursor,
 	obj = engine->clue;
 	while (!html_object_accepts_cursor (obj)) {
 		HTMLObject *head = html_object_head (obj);
-		if (obj)
+		if (head)
 			obj = head;
 		else
 			break;
@@ -947,6 +959,8 @@ left_in_flow (HTMLCursor *cursor, HTMLEn
 			retval = FALSE;
 	}
 
+	debug_location (cursor);
+
 	return retval;
 }
 
@@ -1059,6 +1073,8 @@ right_in_flow (HTMLCursor *cursor, HTMLE
 		else
 			retval = FALSE;
 	}
+
+	debug_location (cursor);
 
 	return retval;
 }
Index: htmlengine.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlengine.c,v
retrieving revision 1.631
diff -u -p -r1.631 htmlengine.c
--- htmlengine.c	23 Mar 2005 12:55:28 -0000	1.631
+++ htmlengine.c	29 Mar 2005 15:42:39 -0000
@@ -1152,6 +1152,8 @@ pop_element (HTMLEngine *e, char *name)
 static void
 block_end_display_block (HTMLEngine *e, HTMLObject *clue, HTMLElement *elem)
 {
+	if (html_clue_is_empty (HTML_CLUE (clue)))
+		new_flow (e, clue, create_empty_text (e), HTML_CLEAR_NONE, HTML_DIRECTION_DERIVED);
 	close_flow (e, clue);
 	pop_clue (e);
 }
Index: htmlobject.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlobject.c,v
retrieving revision 1.190
diff -u -p -r1.190 htmlobject.c
--- htmlobject.c	23 Mar 2005 12:35:57 -0000	1.190
+++ htmlobject.c	29 Mar 2005 15:42:44 -0000
@@ -624,18 +624,36 @@ html_object_real_cursor_forward (HTMLObj
 }
 
 static gboolean
-html_object_real_cursor_backward (HTMLObject *self, HTMLCursor *cursor)
+html_cursor_allow_zero_offset (HTMLCursor *cursor, HTMLObject *o)
 {
-	HTMLObject *prev;
+	if (cursor->offset == 1) {
+		HTMLObject *prev;
+
+		prev = html_object_prev_not_slave (o);
+		if (!prev || HTML_IS_CLUEALIGNED (prev))
+			return TRUE;
+		else {
+			while (prev && !html_object_accepts_cursor (prev))
+				prev = html_object_prev_not_slave (prev);
+
+			if (!prev)
+				return TRUE;
+		}
+	}
+
+	return FALSE;
+}
 
+static gboolean
+html_object_real_cursor_backward (HTMLObject *self, HTMLCursor *cursor)
+{
 	g_assert (self);
 	g_assert (cursor->object == self);
 
 	if (html_object_is_container (self))
 		return FALSE;
 
-	if (cursor->offset > 1 || (cursor->offset > 0 && (! (prev = html_object_prev_not_slave (self))
-							  || HTML_IS_CLUEALIGNED (prev) || !html_object_accepts_cursor (prev)))) {
+	if (cursor->offset > 1 || html_cursor_allow_zero_offset (cursor, self)) {
 		cursor->offset --;
 		cursor->position --;
 		return TRUE;
@@ -666,10 +684,7 @@ html_object_real_cursor_right (HTMLObjec
 			return TRUE;
 		}
 	} else {
-		HTMLObject *prev;
-
-		if (cursor->offset > 1 || (cursor->offset > 0 && (! (prev = html_object_prev_not_slave (self))
-								  || HTML_IS_CLUEALIGNED (prev) || !html_object_accepts_cursor (prev)))) {
+		if (cursor->offset > 1 || html_cursor_allow_zero_offset (cursor, self)) {
 			cursor->offset --;
 			cursor->position --;
 			return TRUE;
@@ -691,9 +706,7 @@ html_object_real_cursor_left (HTMLObject
 		return FALSE;
 
 	if (dir != HTML_DIRECTION_RTL) {
-		HTMLObject *prev;
-		if (cursor->offset > 1 || (cursor->offset > 0 && (! (prev = html_object_prev_not_slave (self))
-								  || HTML_IS_CLUEALIGNED (prev) || !html_object_accepts_cursor (prev)))) {
+		if (cursor->offset > 1 || html_cursor_allow_zero_offset (cursor, self)) {
 			cursor->offset --;
 			cursor->position --;
 			return TRUE;
Index: test-suite.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/test-suite.c,v
retrieving revision 1.14
diff -u -p -r1.14 test-suite.c
--- test-suite.c	14 Mar 2005 18:36:14 -0000	1.14
+++ test-suite.c	29 Mar 2005 15:42:46 -0000
@@ -33,6 +33,7 @@ static int test_cursor_left_right_on_lin
 static int test_cursor_left_right_on_lines_boundaries_wo_white (GtkHTML *html);
 static int test_cursor_around_containers (GtkHTML *html);
 static int test_cursor_around_image (GtkHTML *html);
+static int test_cursor_around_anchors (GtkHTML *html);
 
 static int test_quotes_in_div_block (GtkHTML *html);
 static int test_quotes_in_table (GtkHTML *html);
@@ -54,6 +55,7 @@ static Test tests[] = {
 	{ "begin/end of line (RTL)", test_cursor_beol_rtl },
 	{ "around containers", test_cursor_around_containers },
 	{ "around image", test_cursor_around_image },
+	{ "around anchors", test_cursor_around_anchors },
 	{ "various fixed bugs", NULL },
 	{ "outer quotes inside div block", test_quotes_in_div_block },
 	{ "outer quotes inside table", test_quotes_in_table },
@@ -235,6 +237,73 @@ static int test_cursor_around_image (Gtk
 		;
 
 	if (html->engine->cursor->position != 0 || html->engine->cursor->offset != 0)
+		return FALSE;
+
+	return TRUE;
+}
+
+static int test_cursor_around_anchors (GtkHTML *html)
+{
+	load_editable (html, "<pre>a<a name=anchor>b");
+
+	html_cursor_jump_to_position (html->engine->cursor, html->engine, 0);
+	if (html->engine->cursor->offset != 0
+	    || html->engine->cursor->position != 0)
+		return FALSE;
+
+	html_cursor_down (html->engine->cursor, html->engine);
+
+	if (html->engine->cursor->offset != 1
+	    || html->engine->cursor->position != 2)
+		return FALSE;
+
+	html_cursor_up (html->engine->cursor, html->engine);
+
+	if (html->engine->cursor->offset != 0
+	    || html->engine->cursor->position != 0)
+		return FALSE;
+
+	html_cursor_end_of_line (html->engine->cursor, html->engine);
+
+	if (html->engine->cursor->offset != 1
+	    || html->engine->cursor->position != 2)
+		return FALSE;
+
+	html_cursor_beginning_of_line (html->engine->cursor, html->engine);
+
+	if (html->engine->cursor->offset != 0
+	    || html->engine->cursor->position != 0)
+		return FALSE;
+
+	load_editable (html, "<pre>a<a name=anchor1><img src=src><a name=anchor2>b");
+
+	html_cursor_jump_to_position (html->engine->cursor, html->engine, 0);
+	if (html->engine->cursor->offset != 0
+	    || html->engine->cursor->position != 0)
+		return FALSE;
+
+	html_cursor_down (html->engine->cursor, html->engine);
+
+	if (html->engine->cursor->offset != 1
+	    || html->engine->cursor->position != 3)
+		return FALSE;
+
+	html_cursor_up (html->engine->cursor, html->engine);
+
+	if (html->engine->cursor->offset != 0
+	    || html->engine->cursor->position != 0)
+		return FALSE;
+
+	html_cursor_end_of_line (html->engine->cursor, html->engine);
+
+	if (html->engine->cursor->offset != 1
+	    || html->engine->cursor->position != 3)
+		return FALSE;
+
+	html_cursor_beginning_of_line (html->engine->cursor, html->engine);
+
+	if (html->engine->cursor->offset != 0
+	    || html->engine->cursor->position != 0)
 		return FALSE;
 
 	return TRUE;


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