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;