Mercurial > pidgin
comparison libpurple/protocols/jabber/message.c @ 26838:aa29dac7924f
Only include XHTML payload in XMPP message when it's needed. Closes #8738.
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Thu, 07 May 2009 04:37:30 +0000 |
parents | f67f24008334 |
children | 92565c8e1e3a 45795fd9c0a9 |
comparison
equal
deleted
inserted
replaced
26836:a4b59d72b94b | 26838:aa29dac7924f |
---|---|
938 return FALSE; | 938 return FALSE; |
939 break; | 939 break; |
940 } | 940 } |
941 } | 941 } |
942 | 942 |
943 static char * | |
944 jabber_message_smileyfy_xhtml(JabberMessage *jm, const char *xhtml) | |
945 { | |
946 PurpleAccount *account = purple_connection_get_account(jm->js->gc); | |
947 PurpleConversation *conv = | |
948 purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, jm->to, | |
949 account); | |
950 | |
951 if (jabber_conv_support_custom_smileys(jm->js->gc, conv, jm->to)) { | |
952 GList *found_smileys = jabber_message_xhtml_find_smileys(xhtml); | |
953 | |
954 if (found_smileys) { | |
955 gchar *smileyfied_xhtml = NULL; | |
956 const GList *iterator; | |
957 | |
958 for (iterator = found_smileys; iterator ; | |
959 iterator = g_list_next(iterator)) { | |
960 const PurpleSmiley *smiley = | |
961 (PurpleSmiley *) iterator->data; | |
962 const gchar *shortcut = purple_smiley_get_shortcut(smiley); | |
963 const JabberData *data = | |
964 jabber_data_find_local_by_alt(shortcut); | |
965 | |
966 /* the object has not been sent before */ | |
967 if (!data) { | |
968 PurpleStoredImage *image = | |
969 purple_smiley_get_stored_image(smiley); | |
970 const gchar *ext = purple_imgstore_get_extension(image); | |
971 JabberStream *js = jm->js; | |
972 | |
973 JabberData *new_data = | |
974 jabber_data_create_from_data(purple_imgstore_get_data(image), | |
975 purple_imgstore_get_size(image), | |
976 jabber_message_get_mimetype_from_ext(ext), js); | |
977 purple_debug_info("jabber", | |
978 "cache local smiley alt = %s, cid = %s\n", | |
979 shortcut, jabber_data_get_cid(new_data)); | |
980 jabber_data_associate_local(new_data, shortcut); | |
981 } | |
982 } | |
983 | |
984 smileyfied_xhtml = | |
985 jabber_message_get_smileyfied_xhtml(xhtml, found_smileys); | |
986 g_list_free(found_smileys); | |
987 | |
988 return smileyfied_xhtml; | |
989 } | |
990 } | |
991 | |
992 return NULL; | |
993 } | |
994 | |
943 void jabber_message_send(JabberMessage *jm) | 995 void jabber_message_send(JabberMessage *jm) |
944 { | 996 { |
945 xmlnode *message, *child; | 997 xmlnode *message, *child; |
946 const char *type = NULL; | 998 const char *type = NULL; |
947 | 999 |
1023 child = xmlnode_new_child(message, "body"); | 1075 child = xmlnode_new_child(message, "body"); |
1024 xmlnode_insert_data(child, jm->body, -1); | 1076 xmlnode_insert_data(child, jm->body, -1); |
1025 } | 1077 } |
1026 | 1078 |
1027 if(jm->xhtml) { | 1079 if(jm->xhtml) { |
1028 PurpleAccount *account = purple_connection_get_account(jm->js->gc); | 1080 if ((child = xmlnode_from_str(jm->xhtml, -1))) { |
1029 PurpleConversation *conv = | |
1030 purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, jm->to, | |
1031 account); | |
1032 | |
1033 if (jabber_conv_support_custom_smileys(jm->js->gc, conv, jm->to)) { | |
1034 GList *found_smileys = jabber_message_xhtml_find_smileys(jm->xhtml); | |
1035 | |
1036 if (found_smileys) { | |
1037 gchar *smileyfied_xhtml = NULL; | |
1038 const GList *iterator; | |
1039 | |
1040 for (iterator = found_smileys; iterator ; | |
1041 iterator = g_list_next(iterator)) { | |
1042 const PurpleSmiley *smiley = | |
1043 (PurpleSmiley *) iterator->data; | |
1044 const gchar *shortcut = purple_smiley_get_shortcut(smiley); | |
1045 const JabberData *data = | |
1046 jabber_data_find_local_by_alt(shortcut); | |
1047 | |
1048 /* the object has not been sent before */ | |
1049 if (!data) { | |
1050 PurpleStoredImage *image = | |
1051 purple_smiley_get_stored_image(smiley); | |
1052 const gchar *ext = purple_imgstore_get_extension(image); | |
1053 JabberStream *js = jm->js; | |
1054 | |
1055 JabberData *new_data = | |
1056 jabber_data_create_from_data(purple_imgstore_get_data(image), | |
1057 purple_imgstore_get_size(image), | |
1058 jabber_message_get_mimetype_from_ext(ext), js); | |
1059 purple_debug_info("jabber", | |
1060 "cache local smiley alt = %s, cid = %s\n", | |
1061 shortcut, jabber_data_get_cid(new_data)); | |
1062 jabber_data_associate_local(new_data, shortcut); | |
1063 } | |
1064 } | |
1065 | |
1066 smileyfied_xhtml = | |
1067 jabber_message_get_smileyfied_xhtml(jm->xhtml, found_smileys); | |
1068 child = xmlnode_from_str(smileyfied_xhtml, -1); | |
1069 g_free(smileyfied_xhtml); | |
1070 g_list_free(found_smileys); | |
1071 } else { | |
1072 child = xmlnode_from_str(jm->xhtml, -1); | |
1073 } | |
1074 } else { | |
1075 child = xmlnode_from_str(jm->xhtml, -1); | |
1076 } | |
1077 if(child) { | |
1078 xmlnode_insert_child(message, child); | 1081 xmlnode_insert_child(message, child); |
1079 } else { | 1082 } else { |
1080 purple_debug(PURPLE_DEBUG_ERROR, "jabber", | 1083 purple_debug(PURPLE_DEBUG_ERROR, "jabber", |
1081 "XHTML translation/validation failed, returning: %s\n", | 1084 "XHTML translation/validation failed, returning: %s\n", |
1082 jm->xhtml); | 1085 jm->xhtml); |
1086 jabber_send(jm->js, message); | 1089 jabber_send(jm->js, message); |
1087 | 1090 |
1088 xmlnode_free(message); | 1091 xmlnode_free(message); |
1089 } | 1092 } |
1090 | 1093 |
1094 /* | |
1095 * Compare the XHTML and plain strings passed in for "equality". Any HTML markup | |
1096 * other than <br/> (matches a newline) in the XHTML will cause this to return | |
1097 * FALSE. | |
1098 */ | |
1099 static gboolean | |
1100 jabber_xhtml_plain_equal(const char *xhtml_escaped, | |
1101 const char *plain) | |
1102 { | |
1103 int i = 0; | |
1104 int j = 0; | |
1105 gboolean ret; | |
1106 char *xhtml = purple_unescape_html(xhtml_escaped); | |
1107 | |
1108 while (xhtml[i] && plain[j]) { | |
1109 if (xhtml[i] == plain[j]) { | |
1110 i += 1; | |
1111 j += 1; | |
1112 continue; | |
1113 } | |
1114 | |
1115 if (plain[j] == '\n' && !strncmp(xhtml+i, "<br/>", 5)) { | |
1116 i += 5; | |
1117 j += 1; | |
1118 continue; | |
1119 } | |
1120 | |
1121 g_free(xhtml); | |
1122 return FALSE; | |
1123 } | |
1124 | |
1125 /* Are we at the end of both strings? */ | |
1126 ret = (xhtml[i] == plain[j]) && (xhtml[i] == '\0'); | |
1127 g_free(xhtml); | |
1128 return ret; | |
1129 } | |
1130 | |
1091 int jabber_message_send_im(PurpleConnection *gc, const char *who, const char *msg, | 1131 int jabber_message_send_im(PurpleConnection *gc, const char *who, const char *msg, |
1092 PurpleMessageFlags flags) | 1132 PurpleMessageFlags flags) |
1093 { | 1133 { |
1094 JabberMessage *jm; | 1134 JabberMessage *jm; |
1095 JabberBuddy *jb; | 1135 JabberBuddy *jb; |
1096 JabberBuddyResource *jbr; | 1136 JabberBuddyResource *jbr; |
1097 char *buf; | |
1098 char *xhtml; | 1137 char *xhtml; |
1138 char *tmp; | |
1099 char *resource; | 1139 char *resource; |
1100 | 1140 |
1101 if(!who || !msg) | 1141 if(!who || !msg) |
1102 return 0; | 1142 return 0; |
1103 | 1143 |
1128 | 1168 |
1129 if(jbr->chat_states != JABBER_CHAT_STATES_SUPPORTED) | 1169 if(jbr->chat_states != JABBER_CHAT_STATES_SUPPORTED) |
1130 jm->typing_style |= JM_TS_JEP_0022; | 1170 jm->typing_style |= JM_TS_JEP_0022; |
1131 } | 1171 } |
1132 | 1172 |
1133 buf = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", msg); | 1173 purple_markup_html_to_xhtml(msg, &xhtml, &jm->body); |
1134 | 1174 tmp = jabber_message_smileyfy_xhtml(jm, xhtml); |
1135 purple_markup_html_to_xhtml(buf, &xhtml, &jm->body); | 1175 if (tmp) { |
1136 g_free(buf); | |
1137 | |
1138 if(!jbr || jbr->capabilities & JABBER_CAP_XHTML) | |
1139 jm->xhtml = xhtml; | |
1140 else | |
1141 g_free(xhtml); | 1176 g_free(xhtml); |
1177 xhtml = tmp; | |
1178 } | |
1179 | |
1180 if ((!jbr || jbr->capabilities & JABBER_CAP_XHTML) && | |
1181 !jabber_xhtml_plain_equal(xhtml, jm->body)) | |
1182 jm->xhtml = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", xhtml); | |
1183 | |
1184 g_free(xhtml); | |
1142 | 1185 |
1143 jabber_message_send(jm); | 1186 jabber_message_send(jm); |
1144 jabber_message_free(jm); | 1187 jabber_message_free(jm); |
1145 return 1; | 1188 return 1; |
1146 } | 1189 } |
1148 int jabber_message_send_chat(PurpleConnection *gc, int id, const char *msg, PurpleMessageFlags flags) | 1191 int jabber_message_send_chat(PurpleConnection *gc, int id, const char *msg, PurpleMessageFlags flags) |
1149 { | 1192 { |
1150 JabberChat *chat; | 1193 JabberChat *chat; |
1151 JabberMessage *jm; | 1194 JabberMessage *jm; |
1152 JabberStream *js; | 1195 JabberStream *js; |
1153 char *buf; | 1196 char *xhtml; |
1154 | 1197 |
1155 if(!msg || !gc) | 1198 if(!msg || !gc) |
1156 return 0; | 1199 return 0; |
1157 | 1200 |
1158 js = gc->proto_data; | 1201 js = gc->proto_data; |
1165 jm->js = gc->proto_data; | 1208 jm->js = gc->proto_data; |
1166 jm->type = JABBER_MESSAGE_GROUPCHAT; | 1209 jm->type = JABBER_MESSAGE_GROUPCHAT; |
1167 jm->to = g_strdup_printf("%s@%s", chat->room, chat->server); | 1210 jm->to = g_strdup_printf("%s@%s", chat->room, chat->server); |
1168 jm->id = jabber_get_next_id(jm->js); | 1211 jm->id = jabber_get_next_id(jm->js); |
1169 | 1212 |
1170 buf = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", msg); | 1213 purple_markup_html_to_xhtml(msg, &xhtml, &jm->body); |
1171 purple_markup_html_to_xhtml(buf, &jm->xhtml, &jm->body); | 1214 |
1172 g_free(buf); | 1215 if (chat->xhtml && !jabber_xhtml_plain_equal(xhtml, jm->body)) |
1173 | 1216 jm->xhtml = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", xhtml); |
1174 if(!chat->xhtml) { | 1217 |
1175 g_free(jm->xhtml); | 1218 g_free(xhtml); |
1176 jm->xhtml = NULL; | |
1177 } | |
1178 | 1219 |
1179 jabber_message_send(jm); | 1220 jabber_message_send(jm); |
1180 jabber_message_free(jm); | 1221 jabber_message_free(jm); |
1181 | 1222 |
1182 return 1; | 1223 return 1; |