/pidgin/main: afa6d777bc7c: Smileys: avoid breaking (x)html by n...
Tomasz Wasilczyk
twasilczyk at pidgin.im
Mon Apr 7 09:52:29 EDT 2014
Changeset: afa6d777bc7cb8f20ff121acc3fd9343a7d6d1e7
Author: Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date: 2014-04-07 15:52 +0200
Branch: default
URL: https://hg.pidgin.im/pidgin/main/rev/afa6d777bc7c
Description:
Smileys: avoid breaking (x)html by not replacing smileys inside tags
diffstat:
libpurple/protocols/jabber/message.c | 83 ++++++++++++-----------------------
libpurple/smiley-parser.c | 38 ++++++++++++++-
libpurple/smiley-parser.h | 23 +++++++++-
pidgin/gtkconv.c | 4 +-
4 files changed, 87 insertions(+), 61 deletions(-)
diffs (230 lines):
diff --git a/libpurple/protocols/jabber/message.c b/libpurple/protocols/jabber/message.c
--- a/libpurple/protocols/jabber/message.c
+++ b/libpurple/protocols/jabber/message.c
@@ -849,57 +849,6 @@ jabber_message_get_mimetype_from_ext(con
}
}
-static gchar *
-jabber_message_get_smileyfied_xhtml(const gchar *xhtml, const GList *smileys)
-{
- /* create XML element for all smileys (img tags) */
- GString *result = g_string_new(NULL);
- int pos = 0;
- int length = strlen(xhtml);
-
- while (pos < length) {
- const GList *iterator;
- gboolean found_smiley = FALSE;
-
- for (iterator = smileys ; iterator ;
- iterator = g_list_next(iterator)) {
- const PurpleSmiley *smiley = (PurpleSmiley *) iterator->data;
- const gchar *shortcut = purple_smiley_get_shortcut(smiley);
- const gssize len = strlen(shortcut);
- gchar *escaped = g_markup_escape_text(shortcut, len);
-
- /* TODO: it doesn't take care of text inside a tag.
- * Use purple_smiley_parse. */
- if (g_str_has_prefix(&(xhtml[pos]), escaped)) {
- /* we found the current smiley at this position */
- const JabberData *data =
- jabber_data_find_local_by_alt(shortcut);
- PurpleXmlNode *img = jabber_data_get_xhtml_im(data, shortcut);
- int len;
- gchar *img_text = purple_xmlnode_to_str(img, &len);
-
- found_smiley = TRUE;
- result = g_string_append(result, img_text);
- g_free(img_text);
- pos += strlen(escaped);
- g_free(escaped);
- purple_xmlnode_free(img);
- break;
- } else {
- /* cleanup from the before the next round... */
- g_free(escaped);
- }
- }
- if (!found_smiley) {
- /* there was no smiley here, just copy one byte */
- result = g_string_append_c(result, xhtml[pos]);
- pos++;
- }
- }
-
- return g_string_free(result, FALSE);
-}
-
static gboolean
jabber_conv_support_custom_smileys(JabberStream *js,
PurpleConversation *conv,
@@ -931,6 +880,32 @@ jabber_conv_support_custom_smileys(Jabbe
}
}
+static gboolean
+jabber_message_smileyify_cb(GString *out, PurpleSmiley *smiley,
+ PurpleConversation *_empty, gpointer _unused)
+{
+ const gchar *shortcut;
+ const JabberData *data;
+ PurpleXmlNode *smiley_node;
+ gchar *node_xml;
+
+ shortcut = purple_smiley_get_shortcut(smiley);
+ data = jabber_data_find_local_by_alt(shortcut);
+
+ if (!data)
+ return FALSE;
+
+ smiley_node = jabber_data_get_xhtml_im(data, shortcut);
+ node_xml = purple_xmlnode_to_str(smiley_node, NULL);
+
+ g_string_append(out, node_xml);
+
+ purple_xmlnode_free(smiley_node);
+ g_free(node_xml);
+
+ return TRUE;
+}
+
static char *
jabber_message_smileyfy_xhtml(JabberMessage *jm, const char *xhtml)
{
@@ -1013,10 +988,10 @@ jabber_message_smileyfy_xhtml(JabberMess
jabber_data_associate_local(jdata, shortcut);
}
- smileyfied_xhtml = jabber_message_get_smileyfied_xhtml(xhtml,
- found_smileys);
+ g_list_free(found_smileys);
- g_list_free(found_smileys);
+ smileyfied_xhtml = purple_smiley_parse_custom(xhtml,
+ jabber_message_smileyify_cb, NULL);
return smileyfied_xhtml;
}
diff --git a/libpurple/smiley-parser.c b/libpurple/smiley-parser.c
--- a/libpurple/smiley-parser.c
+++ b/libpurple/smiley-parser.c
@@ -73,10 +73,8 @@ purple_smiley_parse_cb(GString *out, con
if (parse_data->in_html_tag)
return FALSE;
- parse_data->job.replace.cb(out, smiley, parse_data->job.replace.conv,
- parse_data->job.replace.ui_data);
-
- return TRUE;
+ return parse_data->job.replace.cb(out, smiley,
+ parse_data->job.replace.conv, parse_data->job.replace.ui_data);
}
/* XXX: this shouldn't be a conv for incoming messages - see
@@ -158,6 +156,38 @@ purple_smiley_parse(PurpleConversation *
purple_smiley_parse_cb, &parse_data);
}
+gchar *
+purple_smiley_parse_custom(const gchar *html_message, PurpleSmileyParseCb cb,
+ gpointer ui_data)
+{
+ PurpleTrie *custom_trie = NULL;
+ GSList *tries = NULL;
+ GSList tries_sentry, tries_custom;
+ PurpleSmileyParseData parse_data;
+
+ if (html_message == NULL || html_message[0] == '\0')
+ return g_strdup(html_message);
+
+ custom_trie = purple_smiley_list_get_trie(
+ purple_smiley_custom_get_list());
+ if (!custom_trie || purple_trie_get_size(custom_trie) == 0)
+ return g_strdup(html_message);
+
+ tries_sentry.data = html_sentry;
+ tries_custom.data = custom_trie;
+ tries_sentry.next = &tries_custom;
+ tries_custom.next = NULL;
+ tries = &tries_sentry;
+
+ parse_data.job.replace.conv = NULL;
+ parse_data.job.replace.cb = cb;
+ parse_data.job.replace.ui_data = ui_data;
+ parse_data.in_html_tag = FALSE;
+
+ return purple_trie_multi_replace(tries, html_message,
+ purple_smiley_parse_cb, &parse_data);
+}
+
static gboolean
smiley_find_cb(const gchar *word, gpointer _smiley, gpointer _found_smileys)
{
diff --git a/libpurple/smiley-parser.h b/libpurple/smiley-parser.h
--- a/libpurple/smiley-parser.h
+++ b/libpurple/smiley-parser.h
@@ -40,14 +40,19 @@
* PurpleSmileyParseCb:
* @out: the message buffer.
* @smiley: found smiley.
- * @conv: the conversation of a message.
+ * @conv: the conversation of a message (or %NULL, if not passed).
* @ui_data: the data being passed to #purple_smiley_parse.
*
* A replace callback for the found @smiley. It should append a HTML tag
* representing the @smiley to the @out string. It must not modify the
* @out string in other way than appending to its end.
+ *
+ * If callback decides not to replace a smiley, it must not modify
+ * @out in any way.
+ *
+ * Returns: %TRUE if the smiley was inserted.
*/
-typedef void (*PurpleSmileyParseCb)(GString *out, PurpleSmiley *smiley,
+typedef gboolean (*PurpleSmileyParseCb)(GString *out, PurpleSmiley *smiley,
PurpleConversation *conv, gpointer ui_data);
/**
@@ -72,6 +77,20 @@ purple_smiley_parse(PurpleConversation *
gboolean use_remote_smileys, PurpleSmileyParseCb cb, gpointer ui_data);
/**
+ * purple_smiley_parse_custom:
+ * @html_message:
+ * @cb:
+ * @ui_data:
+ *
+ * TODO
+ *
+ * Returns: TODO
+ */
+gchar *
+purple_smiley_parse_custom(const gchar *html_message, PurpleSmileyParseCb cb,
+ gpointer ui_data);
+
+/**
* purple_smiley_find:
* @smileys: the list of smileys to find.
* @message: the message.
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -6627,7 +6627,7 @@ pidgin_conv_remote_smiley_got(PurpleSmil
g_free(js);
}
-static void
+static gboolean
pidgin_conv_write_smiley(GString *out, PurpleSmiley *smiley,
PurpleConversation *conv, gpointer _proto_name)
{
@@ -6664,6 +6664,8 @@ pidgin_conv_write_smiley(GString *out, P
}
g_free(escaped_shortcut);
+
+ return TRUE;
}
static void
More information about the Commits
mailing list