[evolution/webkit: 4/154] Port EABContactDisplay to JavaScript and CSS



commit f80c409282b10395cf3c91223bef7cc19147b40b
Author: Dan VrÃtil <dvratil redhat com>
Date:   Mon Jul 11 15:39:37 2011 +0200

    Port EABContactDisplay to JavaScript and CSS
    
    - replace table layout by floating <div>s; this makes it possible to use one
      common HTML code for both vertical and horizontal contact preview
    - use JavaScript for collapsing/expanding subcontact lists instead of
      generating whole new HTML code and re-rendering the preview page
    - TODO: the maps widgets are not yet ported, this is blocked by
      WebKit bug #63451

 addressbook/gui/widgets/Makefile.am           |    1 +
 addressbook/gui/widgets/eab-contact-display.c |  653 +++++++------------------
 mail/em-format-html.c                         |  185 +++++++-
 modules/addressbook/e-book-shell-content.c    |    9 -
 widgets/misc/e-web-view.c                     |    2 +-
 5 files changed, 373 insertions(+), 477 deletions(-)
---
diff --git a/addressbook/gui/widgets/Makefile.am b/addressbook/gui/widgets/Makefile.am
index 546a218..e78d5b6 100644
--- a/addressbook/gui/widgets/Makefile.am
+++ b/addressbook/gui/widgets/Makefile.am
@@ -10,6 +10,7 @@ libeabwidgets_la_CPPFLAGS =				\
 	-DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\"	\
 	-DEVOLUTION_RULEDIR=\"$(ruledir)\"		\
 	-DEVOLUTION_IMAGESDIR=\"${imagesdir}\"		\
+	-DEVOLUTION_DATADIR=\"${datadir}\"		\
 	-I$(top_srcdir)					\
 	-I$(top_srcdir)/filter				\
 	-I$(top_srcdir)/widgets				\
diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c
index 76e9e11..95ba3f0 100644
--- a/addressbook/gui/widgets/eab-contact-display.c
+++ b/addressbook/gui/widgets/eab-contact-display.c
@@ -46,17 +46,13 @@
 struct _EABContactDisplayPrivate {
 	EContact *contact;
 	EABContactDisplayMode mode;
-	GtkOrientation orientation;
 	gboolean show_maps;
-
-	GHashTable *closed_lists; /* see render_contact_list_ * */
 };
 
 enum {
 	PROP_0,
 	PROP_CONTACT,
 	PROP_MODE,
-	PROP_ORIENTATION,
 	PROP_SHOW_MAPS
 };
 
@@ -76,9 +72,6 @@ common_location[] =
 	{ "OTHER", N_ ("Other") }
 };
 
-#define HTML_HEADER "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n"  \
-                    "<head>\n<meta name=\"generator\" content=\"Evolution Addressbook Component\">\n</head>\n"
-
 #define HEADER_COLOR      "#7f7f7f"
 #define IMAGE_COL_WIDTH   "20"
 #define CONTACT_LIST_ICON "stock_contact-list"
@@ -88,12 +81,40 @@ common_location[] =
 #define JABBER_ICON       "im-jabber"
 #define MSN_ICON          "im-msn"
 #define YAHOO_ICON        "im-yahoo"
-#define GADUGADU_ICON	    "im-gadugadu"
-#define SKYPE_ICON	    "stock_people"
+#define GADUGADU_ICON	  "im-gadugadu"
+#define SKYPE_ICON	  "stock_people"
 #define VIDEOCONF_ICON    "stock_video-conferencing"
 
 #define MAX_COMPACT_IMAGE_DIMENSION 48
 
+
+#define HTML_HEADER "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n"  \
+                    "<head>\n<meta name=\"generator\" content=\"Evolution Addressbook Component\">\n" \
+                    "<style type=\"text/css\" rel=\"Stylesheet\" ref=\"file://" EVOLUTION_DATADIR "/evo_style.css\">" \
+                    "<style type=\"text/css\">\n" \
+		    "  div#header { width:100%; clear: both; }\n" \
+		    "  div#columns { width: 100%; clear: both; }\n" \
+		    "  div#footer { width: 100%; clear: both; }\n" \
+		    "  div.column { width: auto; float: left; margin-right: 15px; }\n" \
+		    "  img#contact-photo { float: left; }\n" \
+		    "  div#contact-name { float: left; margin-left: 20px; }\n" \
+		    "  h2 { color: " HEADER_COLOR "; }\n" \
+		    "  table th { color: " HEADER_COLOR "; text-align: left; }\n" \
+		    "  .type { color: " HEADER_COLOR "; }\n" \
+		    "</style>\n" \
+		    "<script type=\"text/javascript\">\n" \
+		    "function collapse_list (obj, listId) {\n" \
+		    "	var l = document.getElementById (listId);\n" \
+		    "	if (l.style.display == \"none\") {\n" \
+		    "		l.style.display = \"block\"; obj.src = obj.src.substr (0, obj.src.lastIndexOf (\"/\")) + \"/minus.png\";\n" \
+		    "	} else {\n" \
+		    "		l.style.display = \"none\"; obj.src = obj.src.substr (0, obj.src.lastIndexOf (\"/\")) + \"/plus.png\";\n" \
+		    "   }\n" \
+		    "}\n" \
+		    "</script>\n" \
+                    "</head>\n"
+
+
 static const gchar *ui =
 "<ui>"
 "  <popup name='context'>"
@@ -109,6 +130,33 @@ static const gchar *ui =
 static gpointer parent_class;
 static guint signals[LAST_SIGNAL];
 
+static gchar*
+get_icon_uri (const gchar *icon_name)
+{
+	GtkIconTheme *icon_theme;
+	GtkIconInfo *icon_info;
+	const gchar *filename;
+	gchar *icon_uri;
+	GError *error = NULL;
+
+	icon_theme = gtk_icon_theme_get_default ();
+	icon_info = gtk_icon_theme_lookup_icon (
+		icon_theme, icon_name, GTK_ICON_SIZE_MENU, 0);
+	g_return_val_if_fail (icon_info != NULL, NULL);
+
+	filename = gtk_icon_info_get_filename (icon_info);
+	icon_uri = g_filename_to_uri (filename, NULL, &error);
+
+	if (error != NULL) {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
+
+	gtk_icon_info_free (icon_info);
+
+	return icon_uri;
+}
+
 static void
 contact_display_emit_send_message (EABContactDisplay *display,
                                    gint email_num)
@@ -277,48 +325,49 @@ accum_address (GString *buffer,
 }
 
 static void
-accum_name_value (GString *buffer,
+render_table_row (GString *buffer,
                   const gchar *label,
                   const gchar *str,
                   const gchar *icon,
                   guint html_flags)
 {
-	gchar *value = e_text_to_html (str, html_flags);
+	const gchar *icon_html;
+	gchar *value;
+
+	if (html_flags)
+		value = e_text_to_html (str, html_flags);
+	else
+		value = (gchar*)str;
+
+
+	if (icon) {
+		gchar *icon_uri = get_icon_uri (icon);
+		icon_html = g_strdup_printf ("<img src=\"%s\" width=\"16\" height=\"16\" />", icon_uri);
+		g_free (icon_uri);
+	} else {
+		icon_html = "";
+	}
 
 	if (TEXT_IS_RIGHT_TO_LEFT) {
 		g_string_append_printf (
 			buffer, "<tr>"
-			"<td valign=\"top\" align=\"right\">%s</td> "
-			"<td align=\"right\" valign=\"top\" width=\"100\" nowrap>"
-			"<font color=" HEADER_COLOR ">%s:</font></td>",
-			value, label);
-		g_string_append_printf (
-			buffer, "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">");
-		if (icon != NULL)
-			g_string_append_printf (
-				buffer,
-				"<object width=\"16\" height=\"16\" "
-				"type=\"image/x-themed-icon\" "
-				"data=\"%s\"/></td></tr>", icon);
-		else
-			g_string_append_printf (buffer, "</td></tr>");
+			"<td valign=\"top\" align=\"right\">%s</td>"
+			"<th align=\"right\" valign=\"top\" width=\"100\" nowrap>:%s</th>"
+			"<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">%s</td>"
+			"</tr>",
+			value, label, icon_html);
 	} else {
 		g_string_append_printf (
-			buffer, "<tr><td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">");
-		if (icon != NULL)
-			g_string_append_printf (
-				buffer,
-				"<object width=\"16\" height=\"16\" "
-				"type=\"image/x-themed-icon\" "
-				"data=\"%s\"/>", icon);
-		g_string_append_printf (
-			buffer, "</td><td valign=\"top\" width=\"100\" nowrap>"
-			"<font color=" HEADER_COLOR ">%s:</font>"
-			"</td> <td valign=\"top\">%s</td></tr>",
-			label, value);
+			buffer, "<tr>"
+			"<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">%s</td>"
+			"<th valign=\"top\" width=\"100\" nowrap>%s:</th>"
+			"<td valign=\"top\">%s</td>"
+			"</tr>",
+			icon_html, label, value);
 	}
 
-	g_free (value);
+	if (html_flags)
+		g_free (value);
 }
 
 static void
@@ -334,7 +383,7 @@ accum_attribute (GString *buffer,
 	str = e_contact_get_const (contact, field);
 
 	if (str != NULL && *str != '\0')
-		accum_name_value (buffer, html_label, str, icon, html_flags);
+		render_table_row (buffer, html_label, str, icon, html_flags);
 }
 
 static void
@@ -356,13 +405,13 @@ accum_time_attribute (GString *buffer,
 					 date->year );
 		g_date_strftime (sdate, 100, "%x", gdate);
 		g_date_free (gdate);
-		accum_name_value (buffer, html_label, sdate, icon, html_flags);
+		render_table_row (buffer, html_label, sdate, icon, html_flags);
 		e_contact_date_free (date);
 	}
 }
 
 static void
-accum_multival_attribute (GString *buffer,
+accum_attribute_multival (GString *buffer,
                           EContact *contact,
                           const gchar *html_label,
                           EContactField field,
@@ -370,34 +419,23 @@ accum_multival_attribute (GString *buffer,
                           guint html_flags)
 {
 	GList *val_list, *l;
-
-	/* Workaround till bug [1] is fixed.
-	 * [1] https://bugzilla.gnome.org/show_bug.cgi?id=473862 */
-	icon = NULL;
+	GString *val = g_string_new ("");
 
 	val_list = e_contact_get (contact, field);
+
 	for (l = val_list; l; l = l->next) {
-		const gchar *str = (const gchar *) l->data;
-		accum_name_value (buffer, html_label, str, icon, html_flags);
+		if (l != val_list)
+			g_string_append (val, "<br>");
+
+		g_string_append (val, l->data);
 	}
-	g_list_foreach (val_list, (GFunc) g_free, NULL);
-	g_list_free (val_list);
-}
 
-static void
-start_block (GString *buffer,
-             const gchar *label)
-{
-	g_string_append_printf (
-		buffer, "<tr><td height=\"20\" colspan=\"3\">"
-		"<font color=" HEADER_COLOR "><b>%s</b>"
-		"</font></td></tr>", label);
-}
+	if (val->str && *val->str)
+		render_table_row (buffer, html_label, val->str, icon, html_flags);
 
-static void
-end_block (GString *buffer)
-{
-	g_string_append (buffer, "<tr><td height=\"20\">&nbsp;</td></tr>");
+	g_string_free (val, TRUE);
+	g_list_foreach (val_list, (GFunc) g_free, NULL);
+	g_list_free (val_list);
 }
 
 static const gchar *
@@ -430,10 +468,10 @@ render_title_block (GString *buffer,
 		photo = e_contact_get (contact, E_CONTACT_LOGO);
 	/* Only handle inlined photos for now */
 	if (photo && photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
-		g_string_append (
-			buffer,
-			"<object border=\"1\" "
-			"type=\"image/x-contact-photo\"/>");
+		gchar *photo_data = g_base64_encode (photo->data.inlined.data, photo->data.inlined.length);
+		g_string_append_printf (buffer, "<img border=\"1\" src=\"data:%s;base64,%s\">",
+			photo->data.inlined.mime_type,
+			photo_data);
 	} else if (photo && photo->type == E_CONTACT_PHOTO_TYPE_URI && photo->data.uri && *photo->data.uri) {
 		g_string_append_printf (buffer, "<img border=\"1\" src=\"%s\">", photo->data.uri);
 	}
@@ -441,12 +479,12 @@ render_title_block (GString *buffer,
 	if (photo)
 		e_contact_photo_free (photo);
 
-	if (e_contact_get (contact, E_CONTACT_IS_LIST))
-		g_string_append (
-			buffer, 
-			"<object width=\"16\" height=\"16\" "
-			"type=\"image/x-themed-icon\" "
-			"data=\"" CONTACT_LIST_ICON "\"/>");
+	if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+		gchar *icon = get_icon_uri (CONTACT_LIST_ICON);
+		g_string_append_printf (buffer, "<img src=\"%s\">", icon);
+		g_free (icon);
+	}
+
 	g_string_append_printf (
 		buffer, "</td><td width=\"20\"></td><td %s valign=\"top\">\n",
 		TEXT_IS_RIGHT_TO_LEFT ? "align=\"right\"" : "");
@@ -475,12 +513,9 @@ render_contact_list_row (GString *buffer,
 {
 	gchar *evolution_imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL);
 	gboolean list_collapsed = FALSE;
-	const gchar *listId = e_destination_get_contact_uid (destination), *textrep;
+	const gchar *textrep;
 	gchar *name = NULL, *email_addr = NULL;
 
-	if (listId)
-		list_collapsed = GPOINTER_TO_INT (g_hash_table_lookup (display->priv->closed_lists, listId));
-
 	textrep = e_destination_get_textrep (destination, TRUE);
 	if (!eab_parse_qp_email (textrep, &name, &email_addr))
 		email_addr = g_strdup (textrep);
@@ -488,15 +523,15 @@ render_contact_list_row (GString *buffer,
 	g_string_append (buffer, "<tr>");
 	if (e_destination_is_evolution_list (destination)) {
 		g_string_append_printf (buffer,
-			"<td width=" IMAGE_COL_WIDTH " valign=\"top\"><a href=\"##%s##\"><img src=\"%s/%s.png\"></a></td><td width=\"100%%\">%s",
-			e_destination_get_contact_uid (destination),
+			"<td width=" IMAGE_COL_WIDTH " valign=\"top\"><img src=\"%s/minus.png\" onClick=\"collapse_list(this, %s);\"></td><td width=\"100%%\">%s",
 			evolution_imagesdir,
-			(list_collapsed ? "plus" : "minus"),
+			e_destination_get_contact_uid (destination),
 			name ? name : email_addr);
 
 		if (!list_collapsed) {
 			const GList *dest, *dests;
-			g_string_append (buffer, "<br><table cellspacing=\"1\">");
+			g_string_append_printf (buffer, "<br><table cellspacing=\"1\" id=\"%s\">",
+				e_destination_get_contact_uid (destination));
 
 			dests = e_destination_list_get_root_dests (destination);
 			for (dest = dests; dest; dest = dest->next) {
@@ -524,37 +559,9 @@ render_contact_list_row (GString *buffer,
 }
 
 static void
-render_contact_list_vertical (GString *buffer,
-                              EContact *contact,
-                              EABContactDisplay *display)
-{
-	EDestination *destination;
-	const GList *dest, *dests;
-
-	destination = e_destination_new ();
-	e_destination_set_contact (destination, contact, 0);
-	dests = e_destination_list_get_root_dests (destination);
-
-	render_title_block (buffer, contact);
-
-	g_string_append_printf (buffer, "<table border=\"0\"><tr><td valign=\"top\"><font color=" HEADER_COLOR ">%s</font></td><td>",
-		_("List Members:"));
-	g_string_append (buffer, "<table border=\"0\" cellspacing=\"1\">");
-
-	for (dest = dests; dest; dest = dest->next) {
-		render_contact_list_row (buffer, dest->data, display);
-	}
-
-	g_string_append (buffer, "</table>");
-	g_string_append (buffer, "</td></tr></table>");
-
-	g_object_unref (destination);
-}
-
-static void
-render_contact_list_horizontal (GString *buffer,
-                                EContact *contact,
-                                EABContactDisplay *display)
+render_contact_list (GString *buffer,
+		             EContact *contact,
+                     EABContactDisplay *display)
 {
 	EDestination *destination;
 	const GList *dest, *dests;
@@ -579,32 +586,17 @@ render_contact_list_horizontal (GString *buffer,
 }
 
 static void
-render_contact_list (GString *buffer,
-                     EContact *contact,
-                     EABContactDisplay *display)
-
-{
-	if (display->priv->orientation == GTK_ORIENTATION_VERTICAL)
-		render_contact_list_vertical (buffer, contact, display);
-	else
-		render_contact_list_horizontal (buffer, contact, display);
-}
-
-static void
-render_contact_block (GString *buffer,
-                      EContact *contact)
+render_contact_column (GString *buffer,
+                       EContact *contact)
 {
-	GString *accum;
+	GString *accum, *email;
 	GList *email_list, *l, *email_attr_list, *al;
 	gint email_num = 0;
 	const gchar *nl;
-	gchar *nick = NULL;
 
-	accum = g_string_new ("");
+	email = g_string_new ("");
 	nl = "";
 
-	start_block (buffer, "");
-
 	email_list = e_contact_get (contact, E_CONTACT_EMAIL);
 	email_attr_list = e_contact_get_attributes (contact, E_CONTACT_EMAIL);
 
@@ -615,7 +607,7 @@ render_contact_block (GString *buffer,
 		if (!eab_parse_qp_email (l->data, &name, &mail))
 			mail = e_text_to_html (l->data, 0);
 
-		g_string_append_printf (accum, "%s%s%s<a href=\"internal-mailto:%d\";>%s</a>%s <font color=" HEADER_COLOR ">(%s)</font>",
+		g_string_append_printf (email, "%s%s%s<a href=\"internal-mailto:%d\";>%s</a>%s <span class=\"type\">(%s)</span>",
 						nl,
 						name ? name : "",
 						name ? " &lt;" : "",
@@ -634,59 +626,34 @@ render_contact_block (GString *buffer,
 	g_list_free (email_list);
 	g_list_free (email_attr_list);
 
-	if (accum->len) {
-
-		if (TEXT_IS_RIGHT_TO_LEFT) {
-			g_string_append_printf (
-				buffer, "<tr>"
-				"<td valign=\"top\" align=\"right\">%s</td> "
-				"<td valign=\"top\" align=\"right\" width=\"100\" nowrap>"
-				"<font color=" HEADER_COLOR ">%s:</font>"
-				"</td><td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">"
-				"</td></tr>", accum->str, _("Email"));
-		} else {
-			g_string_append (
-				buffer, "<tr><td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">");
-			g_string_append_printf (
-				buffer, "</td><td valign=\"top\" width=\"100\" nowrap>"
-				"<font color=" HEADER_COLOR ">%s:</font></td> "
-				"<td valign=\"top\" nowrap>%s</td></tr>",
-				_("Email"), accum->str);
-		}
-	}
-
-	g_string_assign (accum, "");
-	nick = e_contact_get (contact, E_CONTACT_NICKNAME);
-	if (nick && *nick) {
-		accum_name_value (accum, _("Nickname"), nick, NULL, 0);
-		if (accum->len > 0)
-			g_string_append_printf (
-				buffer, "%s", accum->str);
-	}
+	accum = g_string_new ("");
 
-	g_string_assign (accum, "");
-	accum_multival_attribute (accum, contact, _("AIM"), E_CONTACT_IM_AIM, AIM_ICON, 0);
-	accum_multival_attribute (accum, contact, _("GroupWise"), E_CONTACT_IM_GROUPWISE, GROUPWISE_ICON, 0);
-	accum_multival_attribute (accum, contact, _("ICQ"), E_CONTACT_IM_ICQ, ICQ_ICON, 0);
-	accum_multival_attribute (accum, contact, _("Jabber"), E_CONTACT_IM_JABBER, JABBER_ICON, 0);
-	accum_multival_attribute (accum, contact, _("MSN"), E_CONTACT_IM_MSN, MSN_ICON, 0);
-	accum_multival_attribute (accum, contact, _("Yahoo"), E_CONTACT_IM_YAHOO, YAHOO_ICON, 0);
-	accum_multival_attribute (accum, contact, _("Gadu-Gadu"), E_CONTACT_IM_GADUGADU, GADUGADU_ICON, 0);
-	accum_multival_attribute (accum, contact, _("Skype"), E_CONTACT_IM_SKYPE, SKYPE_ICON, 0);
+	if (email->len)
+		render_table_row (accum, _("Email"), email->str, NULL, 0);
 
-	if (accum->len > 0)
-		g_string_append_printf (buffer, "%s", accum->str);
+	accum_attribute (accum, contact, _("Nickname"), E_CONTACT_NICKNAME, NULL, 0);
+	accum_attribute_multival (accum, contact, _("AIM"), E_CONTACT_IM_AIM, AIM_ICON, 0);
+	accum_attribute_multival (accum, contact, _("GroupWise"), E_CONTACT_IM_GROUPWISE, GROUPWISE_ICON, 0);
+	accum_attribute_multival (accum, contact, _("ICQ"), E_CONTACT_IM_ICQ, ICQ_ICON, 0);
+	accum_attribute_multival (accum, contact, _("Jabber"), E_CONTACT_IM_JABBER, JABBER_ICON, 0);
+	accum_attribute_multival (accum, contact, _("MSN"), E_CONTACT_IM_MSN, MSN_ICON, 0);
+	accum_attribute_multival (accum, contact, _("Yahoo"), E_CONTACT_IM_YAHOO, YAHOO_ICON, 0);
+	accum_attribute_multival (accum, contact, _("Gadu-Gadu"), E_CONTACT_IM_GADUGADU, GADUGADU_ICON, 0);
+	accum_attribute_multival (accum, contact, _("Skype"), E_CONTACT_IM_SKYPE, SKYPE_ICON, 0);
 
-	end_block (buffer);
+	if (accum->len)
+		g_string_append_printf (buffer,
+			"<div class=\"column\" id=\"contact-internet\">"
+			"<table border=\"0\" cellspacing=\"5\">%s</table>"
+			"</div>", accum->str);
 
 	g_string_free (accum, TRUE);
-	g_free (nick);
-
+	g_string_free (email, TRUE);
 }
 
 static void
-render_work_block (GString *buffer,
-                   EContact *contact)
+render_work_column (GString *buffer,
+                    EContact *contact)
 {
 	GString *accum = g_string_new ("");
 
@@ -704,17 +671,19 @@ render_work_block (GString *buffer,
 	accum_address   (accum, contact, _("Address"), E_CONTACT_ADDRESS_WORK, E_CONTACT_ADDRESS_LABEL_WORK);
 
 	if (accum->len > 0) {
-		start_block (buffer, _("Work"));
-		g_string_append_printf (buffer, "%s", accum->str);
-		end_block (buffer);
+		g_string_append_printf (buffer,
+			"<div class=\"column\" id=\"contact-work\">"
+			"<h2>%s</h2>"
+			"<table border=\"0\" cellspacing=\"5\">%s</table>"
+			"</div>", _("Work"), accum->str);
 	}
 
 	g_string_free (accum, TRUE);
 }
 
 static void
-render_personal_block (GString *buffer,
-                       EContact *contact)
+render_personal_column (GString *buffer,
+	                    EContact *contact)
 {
 	GString *accum = g_string_new ("");
 
@@ -727,33 +696,34 @@ render_personal_block (GString *buffer,
 	accum_time_attribute (accum, contact, _("Birthday"), E_CONTACT_BIRTH_DATE, NULL, 0);
 	accum_time_attribute (accum, contact, _("Anniversary"), E_CONTACT_ANNIVERSARY, NULL, 0);
 	accum_attribute (accum, contact, _("Spouse"), E_CONTACT_SPOUSE, NULL, 0);
+
 	if (accum->len > 0) {
-		start_block (buffer, _("Personal"));
-		g_string_append_printf (buffer, "%s", accum->str);
-		end_block (buffer);
+		g_string_append_printf (buffer,
+			"<div class=\"column\" id=\"contact-personal\">"
+			"<h2>%s</h2>"
+			"<table border=\"0\" cellspacing=\"5\">%s</table>"
+			"</div>", _("Personal"), accum->str);
 	}
 
 	g_string_free (accum, TRUE);
 }
 
 static void
-render_note_block (GString *buffer,
-                   EContact *contact)
+render_footer (GString *buffer,
+               EContact *contact)
 {
 	const gchar *str;
-	gchar *html;
 
 	str = e_contact_get_const (contact, E_CONTACT_NOTE);
 	if (!str || !*str)
 		return;
 
-	html = e_text_to_html (str,  E_TEXT_TO_HTML_CONVERT_ADDRESSES | E_TEXT_TO_HTML_CONVERT_URLS | E_TEXT_TO_HTML_CONVERT_NL);
-
-	start_block (buffer, _("Note"));
-	g_string_append_printf (buffer, "<tr><td>%s</td></tr>", html);
-	end_block (buffer);
-
-	g_free (html);
+	g_string_append (buffer, "<div id=\"footer\">"
+		"<table border=\"0\" cellspacing=\"5\">");
+	render_table_row (buffer, _("Note"),
+		e_contact_get_const (contact, E_CONTACT_NOTE),
+		NULL, E_TEXT_TO_HTML_CONVERT_ADDRESSES | E_TEXT_TO_HTML_CONVERT_URLS | E_TEXT_TO_HTML_CONVERT_NL);
+	g_string_append (buffer, "</table></div>");
 }
 
 static void
@@ -763,94 +733,27 @@ render_address_map (GString *buffer,
 {
 #ifdef WITH_CONTACT_MAPS
 	if (map_type == E_CONTACT_ADDRESS_WORK) {
-		g_string_append (buffer, "<object classid=\"address-map-work\"></object>");
+		g_string_append (buffer, "<object type=\"application/x-map-widget\" data=\"work\"></object>");
 	 } else {
- 		g_string_append (buffer, "<object classid=\"address-map-home\"></object>");
+ 		g_string_append (buffer, "<object type=\"application/x-map-widget\" data=\"home\"></object>");
 	 }
 #endif
 }
 
 static void
-render_contact_horizontal (GString *buffer,
-                           EContact *contact,
-                           gboolean show_maps)
-{
-	g_string_append (buffer, "<table border=\"0\">");
-	render_title_block (buffer, contact);
-	g_string_append (buffer, "</table>");
-
-	g_string_append (buffer, "<table border=\"0\">");
-	render_contact_block (buffer, contact);
-	render_work_block (buffer, contact);
-	g_string_append (buffer, "<tr><td></td><td colspan=\"2\">");
-	if (show_maps)
-		render_address_map (buffer, contact, E_CONTACT_ADDRESS_WORK);
-	g_string_append (buffer, "<br></td></tr>");
-	render_personal_block (buffer, contact);
-	g_string_append (buffer, "<tr><td></td><td colspan=\"2\">");
-	if (show_maps)
-		render_address_map (buffer, contact, E_CONTACT_ADDRESS_HOME);
-	g_string_append (buffer, "<br></td></tr>");
-	g_string_append (buffer, "</table>");
-
-	g_string_append (buffer, "<table border=\"0\">");
-	render_note_block (buffer, contact);
-	g_string_append (buffer, "</table>");
-}
-
-static void
-render_contact_vertical (GString *buffer,
-                         EContact *contact,
-                         gboolean show_maps)
+render_contact (GString *buffer,
+                EContact *contact,
+                EABContactDisplay *display)
 {
-	/* First row: photo & name */
-	g_string_append (buffer, "<tr><td colspan=\"3\">");
 	render_title_block (buffer, contact);
-	g_string_append (buffer, "</td></tr>");
-
-	/* Second row: addresses etc. */
-	g_string_append (buffer, "<tr>");
-
-	/* First column: email, IM */
-	g_string_append (buffer, "<td valign=\"top\">");
-	g_string_append (buffer, "<table border=\"0\">");
-	render_contact_block (buffer, contact);
-	g_string_append (buffer, "</table></td>");
-
-	/* Second column: Work */
-	g_string_append (buffer, "<td width=\"30\"></td><td valign=\"top\"><table border=\"0\">");
-	render_work_block (buffer, contact);
-	g_string_append (buffer, "</table>");
-	if (show_maps)
-		render_address_map (buffer, contact, E_CONTACT_ADDRESS_WORK);
-	g_string_append (buffer, "</td>");
-
-	/* Third column: Personal */
-	g_string_append (buffer, "<td width=\"30\"></td><td valign=\"top\"><table border=\"0\">");
-	render_personal_block (buffer, contact);
-	g_string_append (buffer, "</table>");
-	if (show_maps)
-		render_address_map (buffer, contact, E_CONTACT_ADDRESS_HOME);
-	g_string_append (buffer, "</td>");
 
-	/* Third row: note */
-	g_string_append (buffer, "<tr><td colspan=\"3\"><table border=\"0\"");
-	render_note_block (buffer, contact);
-	g_string_append (buffer, "</table></td></tr>");
+	g_string_append (buffer, "<div id=\"columns\">");
+	render_contact_column (buffer, contact);
+	render_work_column (buffer, contact);
+	render_personal_column (buffer, contact);
+	g_string_append (buffer, "</div>");
 
-	g_string_append (buffer, "</table>\n");
-}
-
-static void
-render_contact (GString *buffer,
-                EContact *contact,
-                GtkOrientation orientation,
-                gboolean show_maps)
-{
-	if (orientation == GTK_ORIENTATION_VERTICAL)
-		render_contact_vertical (buffer, contact, show_maps);
-	else
-		render_contact_horizontal (buffer, contact, show_maps);
+	render_footer (buffer, contact);
 }
 
 static void
@@ -863,22 +766,16 @@ eab_contact_display_render_normal (EABContactDisplay *display,
 
 	buffer = g_string_sized_new (4096);
 	g_string_append (buffer, HTML_HEADER);
-	g_string_append_printf (
-		buffer, "<body><table><tr>"
-		"<td %s>\n", TEXT_IS_RIGHT_TO_LEFT ? "align=\"right\"" : "");
+	g_string_append (buffer, "<body>");
 
 	if (contact) {
-		GtkOrientation orientation;
-		orientation = display->priv->orientation;
-
 		if (e_contact_get (contact, E_CONTACT_IS_LIST))
 			render_contact_list (buffer, contact, display);
 		else
-			render_contact (buffer, contact, orientation, display->priv->show_maps);
-
+			render_contact (buffer, contact, display);
 	}
 
-	g_string_append (buffer, "</td></tr></table></body></html>\n");
+	g_string_append (buffer, "</body></html>\n");
 
 	e_web_view_load_string (E_WEB_VIEW (display), buffer->str);
 
@@ -889,8 +786,11 @@ static void
 eab_contact_display_render_compact (EABContactDisplay *display,
                                     EContact *contact)
 {
+#warning FIXME: eab_contact_display_render_compact is not WebKit-ready
+
 	GString *buffer;
 
+
 	/* XXX The initial buffer size is arbitrary.  Tune it. */
 
 	buffer = g_string_sized_new (4096);
@@ -1116,12 +1016,6 @@ contact_display_set_property (GObject *object,
 				g_value_get_int (value));
 			return;
 
-		case PROP_ORIENTATION:
-			eab_contact_display_set_orientation (
-				EAB_CONTACT_DISPLAY (object),
-				g_value_get_int (value));
-			return;
-
 		case PROP_SHOW_MAPS:
 			eab_contact_display_set_show_maps (
 				EAB_CONTACT_DISPLAY (object),
@@ -1151,12 +1045,6 @@ contact_display_get_property (GObject *object,
 				EAB_CONTACT_DISPLAY (object)));
 			return;
 
-		case PROP_ORIENTATION:
-			g_value_set_int (
-				value, eab_contact_display_get_orientation (
-				EAB_CONTACT_DISPLAY (object)));
-			return;
-
 		case PROP_SHOW_MAPS:
 			g_value_set_boolean (
 				value, eab_contact_display_get_show_maps (
@@ -1179,86 +1067,10 @@ contact_display_dispose (GObject *object)
 		priv->contact = NULL;
 	}
 
-	if (priv->closed_lists != NULL) {
-		g_hash_table_unref (priv->closed_lists);
-		priv->closed_lists = NULL;
-	}
-
 	/* Chain up to parent's dispose() method. */
 	G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
-#if 0  /* WEBKIT */
-static void
-contact_display_url_requested (GtkHTML *html,
-                               const gchar *uri,
-                               GtkHTMLStream *handle)
-{
-	EABContactDisplay *display;
-	GtkHTMLClass *class;
-	gsize length;
-
-	display = EAB_CONTACT_DISPLAY (html);
-	class = GTK_HTML_CLASS (parent_class);
-
-	/* internal-contact-photo: */
-	if (strcmp (uri, "internal-contact-photo:") == 0) {
-		EContactPhoto *photo;
-		EContact *contact;
-
-		contact = eab_contact_display_get_contact (display);
-		photo = e_contact_get (contact, E_CONTACT_PHOTO);
-		if (photo == NULL)
-			photo = e_contact_get (contact, E_CONTACT_LOGO);
-
-		if (photo->type == E_CONTACT_PHOTO_TYPE_INLINED)
-			gtk_html_stream_write (
-				handle, (gchar *) photo->data.inlined.data,
-				photo->data.inlined.length);
-
-		gtk_html_end (html, handle, GTK_HTML_STREAM_OK);
-
-		e_contact_photo_free (photo);
-
-		return;
-	}
-
-	/* evo-icon:<<themed-icon-name>> */
-	length = strlen ("evo-icon:");
-	if (g_ascii_strncasecmp (uri, "evo-icon:", length) == 0) {
-		GtkIconTheme *icon_theme;
-		GtkIconInfo *icon_info;
-		const gchar *filename;
-		gchar *icon_uri;
-		GError *error = NULL;
-
-		icon_theme = gtk_icon_theme_get_default ();
-		icon_info = gtk_icon_theme_lookup_icon (
-			icon_theme, uri + length, GTK_ICON_SIZE_MENU, 0);
-		g_return_if_fail (icon_info != NULL);
-
-		filename = gtk_icon_info_get_filename (icon_info);
-		icon_uri = g_filename_to_uri (filename, NULL, &error);
-
-		if (error != NULL) {
-			g_warning ("%s", error->message);
-			g_error_free (error);
-		}
-
-		/* Chain up with the URI for the icon file. */
-		class->url_requested (html, icon_uri, handle);
-
-		gtk_icon_info_free (icon_info);
-		g_free (icon_uri);
-
-		return;
-	}
-
-	/* Chain up to parent's uri_requested() method. */
-	class->url_requested (html, uri, handle);
-}
-#endif
-
 static GtkWidget *
 contact_display_create_plugin_widget (EWebView *web_view,
                                       const gchar *mime_type,
@@ -1266,34 +1078,9 @@ contact_display_create_plugin_widget (EWebView *web_view,
                                       GHashTable *param)
 {
 	EWebViewClass *web_view_class;
-	EABContactDisplay *display;
-
-	display = EAB_CONTACT_DISPLAY (web_view);
-
-	if (g_strcmp0 (mime_type, "image/x-contact-photo") == 0) {
-		EContactPhoto *photo;
-		EContact *contact;
-		GdkPixbuf *pixbuf;
-		GdkPixbufLoader *loader;
-		GtkWidget *widget = NULL;
 
-		contact = eab_contact_display_get_contact (display);
-		photo = e_contact_get (contact, E_CONTACT_PHOTO);
-		if (photo == NULL)
-			photo = e_contact_get (contact, E_CONTACT_LOGO);
+#warning FIXME: contact_display_create_plugin_widget is not WebKit-ready
 
-		loader = gdk_pixbuf_loader_new ();
-		gdk_pixbuf_loader_write (
-			loader, photo->data.inlined.data,
-			photo->data.inlined.length, NULL);
-		gdk_pixbuf_loader_close (loader, NULL);
-		pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
-		if (pixbuf != NULL)
-			widget = gtk_image_new_from_pixbuf (pixbuf);
-		g_object_unref (loader);
-
-		return widget;
-	}
 
 	/* Chain up to parent's create_plugin_widget() method. */
 	web_view_class = E_WEB_VIEW_CLASS (parent_class);
@@ -1353,19 +1140,6 @@ contact_display_link_clicked (EWebView *web_view,
 		index = atoi (uri + length);
 		contact_display_emit_send_message (display, index);
 		return;
-	} else if (g_str_has_prefix (uri, "##") && g_str_has_suffix (uri, "##")) {
-		gchar *list_id = g_strndup (uri + 2, strlen (uri) - 4);
-
-		if (g_hash_table_lookup (display->priv->closed_lists, list_id)) {
-			g_hash_table_remove (display->priv->closed_lists, list_id);
-			g_free (list_id);
-		} else {
-			g_hash_table_insert (display->priv->closed_lists, list_id, GINT_TO_POINTER (TRUE));
-		}
-
-		eab_contact_display_render_normal (display, display->priv->contact);
-
-		return;
 	}
 
 	/* Chain up to parent's link_clicked() method. */
@@ -1384,6 +1158,7 @@ handle_map_scroll_event (GtkWidget *widget,
 	return TRUE;
 }
 
+#if 0
 static void
 contact_display_object_requested (GtkHTML *html,
                                   GtkHTMLEmbedded *eb,
@@ -1422,6 +1197,7 @@ contact_display_object_requested (GtkHTML *html,
 	e_contact_address_free (address);
 }
 #endif
+#endif
 
 static void
 contact_display_update_actions (EWebView *web_view)
@@ -1457,9 +1233,6 @@ static void
 eab_contact_display_class_init (EABContactDisplayClass *class)
 {
 	GObjectClass *object_class;
-#if 0  /* WEBKIT */
-	GtkHTMLClass *html_class;
-#endif
 	EWebViewClass *web_view_class;
 
 	parent_class = g_type_class_peek_parent (class);
@@ -1470,11 +1243,6 @@ eab_contact_display_class_init (EABContactDisplayClass *class)
 	object_class->get_property = contact_display_get_property;
 	object_class->dispose = contact_display_dispose;
 
-#if 0  /* WEBKIT */
-	html_class = GTK_HTML_CLASS (class);
-	html_class->url_requested = contact_display_url_requested;
-#endif
-
 	web_view_class = E_WEB_VIEW_CLASS (class);
 	web_view_class->create_plugin_widget = contact_display_create_plugin_widget;
 	web_view_class->hovering_over_link = contact_display_hovering_over_link;
@@ -1504,18 +1272,6 @@ eab_contact_display_class_init (EABContactDisplayClass *class)
 			EAB_CONTACT_DISPLAY_RENDER_NORMAL,
 			G_PARAM_READWRITE));
 
-	g_object_class_install_property (
-		object_class,
-		PROP_ORIENTATION,
-		g_param_spec_int (
-			"orientation",
-			NULL,
-			NULL,
-			GTK_ORIENTATION_HORIZONTAL,
-			GTK_ORIENTATION_VERTICAL,
-			GTK_ORIENTATION_HORIZONTAL,
-			G_PARAM_READWRITE));
-
 	g_object_class_install_property	(
 		object_class,
 		PROP_SHOW_MAPS,
@@ -1549,18 +1305,17 @@ eab_contact_display_init (EABContactDisplay *display)
 	display->priv = G_TYPE_INSTANCE_GET_PRIVATE (
 		display, EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayPrivate);
 	display->priv->mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
-	display->priv->orientation = GTK_ORIENTATION_HORIZONTAL;
 	display->priv->show_maps = FALSE;
-	display->priv->closed_lists = g_hash_table_new_full (g_str_hash, g_str_equal,
-					(GDestroyNotify) g_free, NULL);
 
 	web_view = E_WEB_VIEW (display);
 	ui_manager = e_web_view_get_ui_manager (web_view);
 
 #ifdef WITH_CONTACT_MAPS
+#if 0
 	g_signal_connect (web_view, "object-requested",
 	G_CALLBACK (contact_display_object_requested), display);
 #endif
+#endif
 
 	action_group = gtk_action_group_new ("internal-mailto");
 	gtk_action_group_set_translation_domain (action_group, domain);
@@ -1680,40 +1435,6 @@ eab_contact_display_set_mode (EABContactDisplay *display,
 	g_object_notify (G_OBJECT (display), "mode");
 }
 
-GtkOrientation
-eab_contact_display_get_orientation (EABContactDisplay *display)
-{
-	g_return_val_if_fail (EAB_IS_CONTACT_DISPLAY (display), 0);
-
-	return display->priv->orientation;
-}
-
-void
-eab_contact_display_set_orientation (EABContactDisplay *display,
-                                     GtkOrientation orientation)
-{
-	EABContactDisplayMode mode;
-	EContact *contact;
-
-	g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display));
-
-	display->priv->orientation = orientation;
-	contact = eab_contact_display_get_contact (display);
-	mode = eab_contact_display_get_mode (display);
-
-	switch (mode) {
-		case EAB_CONTACT_DISPLAY_RENDER_NORMAL:
-			eab_contact_display_render_normal (display, contact);
-			break;
-
-		case EAB_CONTACT_DISPLAY_RENDER_COMPACT:
-			eab_contact_display_render_compact (display, contact);
-			break;
-	}
-
-	g_object_notify (G_OBJECT (display), "orientation");
-}
-
 gboolean
 eab_contact_display_get_show_maps (EABContactDisplay *display)
 {
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index 366517f..6bf4fbe 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -1538,7 +1538,190 @@ em_format_html_job_queue (EMFormatHTML *emfh,
 
 /* ********************************************************************** */
 
-#if 0  /* WEBKIT */
+static void
+emfh_getpuri (struct _EMFormatHTMLJob *job,
+              GCancellable *cancellable)
+{
+	d(printf(" running getpuri task\n"));
+	if (!g_cancellable_is_cancelled (cancellable))
+		job->u.puri->func (
+			EM_FORMAT (job->format), job->stream,
+			job->u.puri, cancellable);
+}
+
+static void
+emfh_gethttp (struct _EMFormatHTMLJob *job,
+              GCancellable *cancellable)
+{
+	CamelStream *cistream = NULL, *costream = NULL, *instream = NULL;
+	CamelURL *url;
+	CamelContentType *content_type;
+	CamelHttpStream *tmp_stream;
+	gssize n, total = 0, pc_complete = 0, nread = 0;
+	gchar buffer[1500];
+	const gchar *length;
+
+	if (g_cancellable_is_cancelled (cancellable)
+	    || (url = camel_url_new (job->u.uri, NULL)) == NULL)
+		goto badurl;
+
+	d(printf(" running load uri task: %s\n", job->u.uri));
+
+	if (emfh_http_cache)
+		instream = cistream = camel_data_cache_get (emfh_http_cache, EMFH_HTTP_CACHE_PATH, job->u.uri, NULL);
+
+	if (instream == NULL) {
+		EMailImageLoadingPolicy policy;
+		gchar *proxy;
+
+		policy = em_format_html_get_image_loading_policy (job->format);
+
+		if (!(job->format->priv->load_images_now
+		      || policy == E_MAIL_IMAGE_LOADING_POLICY_ALWAYS
+		      || (policy == E_MAIL_IMAGE_LOADING_POLICY_SOMETIMES
+			  && em_utils_in_addressbook ((CamelInternetAddress *) camel_mime_message_get_from (job->format->parent.message), FALSE)))) {
+			/* TODO: Ideally we would put the http requests into another queue and only send them out
+			   if the user selects 'load images', when they do.  The problem is how to maintain this
+			   state with multiple renderings, and how to adjust the thread dispatch/setup routine to handle it */
+			camel_url_free (url);
+			goto done;
+		}
+
+		instream = camel_http_stream_new (CAMEL_HTTP_METHOD_GET, ((EMFormat *) job->format)->session, url);
+		camel_http_stream_set_user_agent((CamelHttpStream *)instream, "CamelHttpStream/1.0 Evolution/" VERSION);
+		proxy = em_utils_get_proxy_uri (job->u.uri);
+		if (proxy) {
+			camel_http_stream_set_proxy ((CamelHttpStream *) instream, proxy);
+			g_free (proxy);
+		}
+		camel_operation_push_message (
+			cancellable, _("Retrieving '%s'"), job->u.uri);
+		tmp_stream = (CamelHttpStream *) instream;
+		content_type = camel_http_stream_get_content_type (tmp_stream);
+		length = camel_header_raw_find(&tmp_stream->headers, "Content-Length", NULL);
+		d(printf("  Content-Length: %s\n", length));
+		if (length != NULL)
+			total = atoi (length);
+		camel_content_type_unref (content_type);
+	} else
+		camel_operation_push_message (
+			cancellable, _("Retrieving '%s'"), job->u.uri);
+
+	camel_url_free (url);
+
+	if (instream == NULL)
+		goto done;
+
+	if (emfh_http_cache != NULL && cistream == NULL)
+		costream = camel_data_cache_add (emfh_http_cache, EMFH_HTTP_CACHE_PATH, job->u.uri, NULL);
+
+	do {
+		if (camel_operation_cancel_check (CAMEL_OPERATION (cancellable))) {
+			n = -1;
+			break;
+		}
+		/* FIXME: progress reporting in percentage, can we get the length always?  do we care? */
+		n = camel_stream_read (instream, buffer, sizeof (buffer), cancellable, NULL);
+		if (n > 0) {
+			nread += n;
+			/* If we didn't get a valid Content-Length header, do not try to calculate percentage */
+			if (total != 0) {
+				pc_complete = ((nread * 100) / total);
+				camel_operation_progress (cancellable, pc_complete);
+			}
+			d(printf("  read %d bytes\n", n));
+			if (costream && camel_stream_write (costream, buffer, n, cancellable, NULL) == -1) {
+				n = -1;
+				break;
+			}
+
+			camel_stream_write (job->stream, buffer, n, cancellable, NULL);
+		}
+	} while (n>0);
+
+	/* indicates success */
+	if (n == 0)
+		camel_stream_close (job->stream, cancellable, NULL);
+
+	if (costream) {
+		/* do not store broken files in a cache */
+		if (n != 0)
+			camel_data_cache_remove (emfh_http_cache, EMFH_HTTP_CACHE_PATH, job->u.uri, NULL);
+		g_object_unref (costream);
+	}
+
+	g_object_unref (instream);
+done:
+	camel_operation_pop_message (cancellable);
+badurl:
+	g_free (job->u.uri);
+}
+
+/* ********************************************************************** */
+
+static void
+efh_url_requested (GtkHTML *html, const gchar *url, GtkHTMLStream *handle, EMFormatHTML *efh)
+{
+	EMFormatPURI *puri;
+	struct _EMFormatHTMLJob *job = NULL;
+
+	d(printf("url requested, html = %p, url '%s'\n", html, url));
+
+	puri = em_format_find_visible_puri ((EMFormat *) efh, url);
+	if (puri) {
+		CamelDataWrapper *dw = camel_medium_get_content ((CamelMedium *) puri->part);
+		CamelContentType *ct = dw?dw->mime_type:NULL;
+
+		/* GtkHTML only handles text and images.
+		   application/octet-stream parts are the only ones
+		   which are snooped for other content.  So only try
+		   to pass these to it - any other types are badly
+		   formed or intentionally malicious emails.  They
+		   will still show as attachments anyway */
+
+		if (ct && (camel_content_type_is(ct, "text", "*")
+			   || camel_content_type_is(ct, "image", "*")
+			   || camel_content_type_is(ct, "application", "octet-stream"))) {
+			puri->use_count++;
+
+			d(printf(" adding puri job\n"));
+			job = em_format_html_job_new (efh, emfh_getpuri, puri);
+		} else {
+			d(printf(" part is unknown type '%s', not using\n", ct?camel_content_type_format(ct):"<unset>"));
+			gtk_html_stream_close (handle, GTK_HTML_STREAM_ERROR);
+		}
+	} else if (g_ascii_strncasecmp(url, "http:", 5) == 0 || g_ascii_strncasecmp(url, "https:", 6) == 0) {
+		d(printf(" adding job, get %s\n", url));
+		job = em_format_html_job_new (efh, emfh_gethttp, g_strdup (url));
+	} else if  (g_str_has_prefix (url, "file://")) {
+		gchar *data = NULL;
+		gsize length = 0;
+		gboolean status;
+		gchar *path;
+
+		path = g_filename_from_uri (url, NULL, NULL);
+		g_return_if_fail (path != NULL);
+
+		status = g_file_get_contents (path, &data, &length, NULL);
+		if (status)
+			gtk_html_stream_write (handle, data, length);
+
+		gtk_html_stream_close (handle, status ? GTK_HTML_STREAM_OK : GTK_HTML_STREAM_ERROR);
+		g_free (data);
+		g_free (path);
+	} else {
+		d(printf("HTML Includes reference to unknown uri '%s'\n", url));
+		gtk_html_stream_close (handle, GTK_HTML_STREAM_ERROR);
+	}
+
+	if (job) {
+		job->stream = em_html_stream_new (html, handle);
+		em_format_html_job_queue (efh, job);
+	}
+
+	g_signal_stop_emission_by_name (html, "url-requested");
+}
+
 static gboolean
 efh_object_requested (GtkHTML *html,
                       GtkHTMLEmbedded *eb,
diff --git a/modules/addressbook/e-book-shell-content.c b/modules/addressbook/e-book-shell-content.c
index 0183512..f3457e8 100644
--- a/modules/addressbook/e-book-shell-content.c
+++ b/modules/addressbook/e-book-shell-content.c
@@ -286,20 +286,11 @@ book_shell_content_constructed (GObject *object)
 		EAB_CONTACT_DISPLAY (widget),
 		EAB_CONTACT_DISPLAY_RENDER_NORMAL);
 
-	eab_contact_display_set_orientation (
-		EAB_CONTACT_DISPLAY (widget),
-		priv->orientation);
-
 	eab_contact_display_set_show_maps (
 		EAB_CONTACT_DISPLAY (widget),
 		priv->preview_show_maps);
 
 	g_object_bind_property (
-		object, "orientation",
-		widget, "orientation",
-		G_BINDING_SYNC_CREATE);
-
-	g_object_bind_property (
 		object, "preview-show-maps",
 		widget, "show-maps",
 		G_BINDING_SYNC_CREATE);
diff --git a/widgets/misc/e-web-view.c b/widgets/misc/e-web-view.c
index 6333173..1944570 100644
--- a/widgets/misc/e-web-view.c
+++ b/widgets/misc/e-web-view.c
@@ -1063,7 +1063,7 @@ web_view_load_string (EWebView *web_view,
 
 	webkit_web_view_load_string (
 		WEBKIT_WEB_VIEW (web_view),
-		string, "text/html", "UTF-8", NULL);
+		string, "text/html", "UTF-8", "file://");
 }
 
 static gboolean



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