static const gchar *formatter_mime_types[] = { "text/html", NULL };
typedef struct _EMailFormatterTextHTML {
GObject parent;
} EMailFormatterTextHTML;
typedef struct _EMailFormatterTextHTMLClass {
GObjectClass parent_class;
} EMailFormatterTextHTMLClass;
static void e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface);
static void e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface);
G_DEFINE_TYPE_EXTENDED (
EMailFormatterTextHTML,
e_mail_formatter_text_html,
G_TYPE_OBJECT,
0,
G_IMPLEMENT_INTERFACE (
E_TYPE_MAIL_EXTENSION,
e_mail_formatter_mail_extension_interface_init)
G_IMPLEMENT_INTERFACE (
E_TYPE_MAIL_FORMATTER_EXTENSION,
e_mail_formatter_formatter_extension_interface_init));
static gchar *
get_tag (const gchar *utf8_string,
const gchar *tag_name,
gchar *opening,
gchar *closing)
{
gchar *t;
gunichar c;
gboolean has_end;
t = g_utf8_find_prev_char (utf8_string, closing);
while (t != opening) {
c = g_utf8_get_char (t);
if (!g_unichar_isspace (c))
break;
}
/* Not a pair tag */
if (c == '/')
return g_strndup (opening, closing - opening + 1);
t = closing;
while (t) {
c = g_utf8_get_char (t);
if (c == '<')
break;
t = g_utf8_find_next_char (t, NULL);
}
do {
c = g_utf8_get_char (t);
if (c == '/') {
has_end = TRUE;
break;
}
if (c == '>') {
has_end = FALSE;
break;
}
t = g_utf8_find_next_char (t, NULL);
} while (t);
/* Broken HTML? */
if (!has_end)
return g_strndup (opening, closing - opening + 1);
do {
c = g_utf8_get_char (t);
if ((c != ' ') && (c != '/'))
break;
t = g_utf8_find_next_char (t, NULL);
} while (t);
/* tag_name is always ASCII */
if (g_ascii_strncasecmp (t, tag_name, strlen (tag_name)) == 0) {
closing = g_utf8_strchr (t, -1, '>');
return g_strndup (opening, closing - opening + 1);
}
/* Broken HTML? */
return g_strndup (opening, closing - opening + 1);
}
static gboolean
emfe_text_html_format (EMailFormatterExtension *extension,
EMailFormatter *formatter,
EMailFormatterContext *context,
EMailPart *part,
CamelStream *stream,
GCancellable *cancellable)
{
if (g_cancellable_is_cancelled (cancellable))
return FALSE;
if (context->mode == E_MAIL_FORMATTER_MODE_RAW) {
/* FORMATTER FIXME: Shouldn't we have some extra method for
* BASE64 and QP decoding?? */
e_mail_formatter_format_text (formatter, part, stream, cancellable);
} else if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) {
GString *string;
GByteArray *ba;
gchar *pos;
GList *tags, *iter;
gboolean valid;
gchar *tag;
const gchar *document_end;
gint length;
gint i;
CamelStream *decoded_stream;
decoded_stream = camel_stream_mem_new ();
/* FORMATTER FIXME: See above */
e_mail_formatter_format_text (formatter, part, decoded_stream, cancellable);
g_seekable_seek (G_SEEKABLE (decoded_stream), 0, G_SEEK_SET, cancellable, NULL);
ba = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (decoded_stream));
string = g_string_new_len ((gchar *) ba->data, ba->len);
g_object_unref (decoded_stream);
tags = NULL;
pos = string->str;
valid = FALSE;
if (!g_utf8_validate (string->str, -1, NULL)) {
/* FIXME - What do we do if the string is not UTF-8 valid? */
}
do {
gchar *tmp;
gchar *closing;
gchar *opening;
tmp = g_utf8_find_next_char (pos, NULL);
pos = g_utf8_strchr (tmp, -1, '<');
if (!pos)
break;
opening = pos;
closing = g_utf8_strchr (pos, -1, '>');
/* Find where the actual tag name begins */
tag = g_utf8_find_next_char (pos, NULL);
while ((tag = g_utf8_find_next_char (pos, NULL)) != NULL) {
gunichar c = g_utf8_get_char (tag);
if (!g_unichar_isspace (c))
break;
}
if (g_ascii_strncasecmp (tag, "style", 5) == 0) {
tags = g_list_append (
tags,
get_tag (string->str, "style", opening, closing));
} else if (g_ascii_strncasecmp (tag, "script", 6) == 0) {
tags = g_list_append (
tags,
get_tag (string->str, "script", opening, closing));
} else if (g_ascii_strncasecmp (tag, "link", 4) == 0) {
tags = g_list_append (
tags,
get_tag (string->str, "link", opening, closing));
} else if (g_ascii_strncasecmp (tag, "body", 4) == 0) {
valid = TRUE;
break;
}
} while (pos);
if (tags)
printf ("\n\n**%s**\n\n", (gchar *) tags->data);
/* Something's wrong, let's write the entire HTML and hope
* that WebKit can handle it */
if (!valid) {
EMailFormatterContext c = {
.folder = context->folder,
.message = context->message,
.message_uid = context->message_uid,
.parts = context->parts,
.flags = context->flags,
.mode = E_MAIL_FORMATTER_MODE_RAW,
};
emfe_text_html_format (
extension, formatter, &c, part, stream, cancellable);
return FALSE;
}
/* include the "body" as well -----v */
g_string_erase (string, 0, tag - string->str + 4);
g_string_prepend (string, "next) {
g_string_prepend (string, iter->data);
}
g_list_free_full (tags, g_free);
document_end = NULL;
/* We can probably use ASCII functions here */
if (g_strrstr (string->str, "