| 82 |
81 |
| 83 /****************************************************************************** |
82 /****************************************************************************** |
| 84 * Helpers |
83 * Helpers |
| 85 *****************************************************************************/ |
84 *****************************************************************************/ |
| 86 |
85 |
| 87 static const char * |
86 static void |
| 88 get_image_src_from_id(GtkWebViewPriv *priv, int id) |
87 webview_resource_loading(WebKitWebView *webview, |
| 89 { |
88 WebKitWebFrame *frame, |
| 90 char *src; |
89 WebKitWebResource *resource, |
| 91 PurpleStoredImage *img; |
90 WebKitNetworkRequest *request, |
| 92 |
91 WebKitNetworkResponse *response, |
| 93 if (priv->images) { |
92 gpointer user_data) |
| 94 /* Check for already loaded image */ |
93 { |
| 95 src = (char *)g_hash_table_lookup(priv->images, GINT_TO_POINTER(id)); |
94 const gchar *uri; |
| 96 if (src) |
95 |
| 97 return src; |
96 uri = webkit_network_request_get_uri(request); |
| 98 } else { |
97 if (purple_str_has_prefix(uri, PURPLE_STORED_IMAGE_PROTOCOL)) { |
| 99 priv->images = g_hash_table_new_full(g_direct_hash, g_direct_equal, |
98 int id; |
| 100 NULL, g_free); |
99 PurpleStoredImage *img; |
| |
100 const char *filename; |
| |
101 |
| |
102 uri += sizeof(PURPLE_STORED_IMAGE_PROTOCOL) - 1; |
| |
103 id = strtoul(uri, NULL, 10); |
| |
104 |
| |
105 img = purple_imgstore_find_by_id(id); |
| |
106 if (!img) |
| |
107 return; |
| |
108 |
| |
109 filename = purple_imgstore_get_filename(img); |
| |
110 if (filename && g_path_is_absolute(filename)) { |
| |
111 char *tmp = g_strdup_printf("file://%s", filename); |
| |
112 webkit_network_request_set_uri(request, tmp); |
| |
113 g_free(tmp); |
| |
114 } else { |
| |
115 char *b64 = purple_base64_encode(purple_imgstore_get_data(img), |
| |
116 purple_imgstore_get_size(img)); |
| |
117 const char *type = purple_imgstore_get_extension(img); |
| |
118 char *tmp = g_strdup_printf("data:image/%s;base64,%s", type, b64); |
| |
119 webkit_network_request_set_uri(request, tmp); |
| |
120 g_free(b64); |
| |
121 g_free(tmp); |
| |
122 } |
| 101 } |
123 } |
| 102 |
|
| 103 /* Find image in store */ |
|
| 104 img = purple_imgstore_find_by_id(id); |
|
| 105 |
|
| 106 src = (char *)purple_imgstore_get_filename(img); |
|
| 107 if (src) { |
|
| 108 src = g_strdup_printf("file://%s", src); |
|
| 109 } else { |
|
| 110 char *tmp; |
|
| 111 tmp = purple_base64_encode(purple_imgstore_get_data(img), |
|
| 112 purple_imgstore_get_size(img)); |
|
| 113 src = g_strdup_printf("data:base64,%s", tmp); |
|
| 114 g_free(tmp); |
|
| 115 } |
|
| 116 |
|
| 117 g_hash_table_insert(priv->images, GINT_TO_POINTER(id), src); |
|
| 118 |
|
| 119 return src; |
|
| 120 } |
|
| 121 |
|
| 122 /* |
|
| 123 * Replace all <img id=""> tags with <img src="">. I hoped to never |
|
| 124 * write any HTML parsing code, but I'm forced to do this, until |
|
| 125 * purple changes the way it works. |
|
| 126 */ |
|
| 127 static char * |
|
| 128 replace_img_id_with_src(GtkWebViewPriv *priv, const char *html) |
|
| 129 { |
|
| 130 GString *buffer = g_string_new(NULL); |
|
| 131 const char *cur = html; |
|
| 132 char *id; |
|
| 133 int nid; |
|
| 134 |
|
| 135 while (*cur) { |
|
| 136 const char *img = strstr(cur, "<img"); |
|
| 137 if (!img) { |
|
| 138 g_string_append(buffer, cur); |
|
| 139 break; |
|
| 140 } else |
|
| 141 g_string_append_len(buffer, cur, img - cur); |
|
| 142 |
|
| 143 cur = strstr(img, "/>"); |
|
| 144 if (!cur) |
|
| 145 cur = strstr(img, ">"); |
|
| 146 |
|
| 147 if (!cur) { /* invalid html? */ |
|
| 148 g_string_printf(buffer, "%s", html); |
|
| 149 break; |
|
| 150 } |
|
| 151 |
|
| 152 if (strstr(img, "src=") || !strstr(img, "id=")) { |
|
| 153 g_string_printf(buffer, "%s", html); |
|
| 154 break; |
|
| 155 } |
|
| 156 |
|
| 157 /* |
|
| 158 * if this is valid HTML, then I can be sure that it |
|
| 159 * has an id= and does not have an src=, since |
|
| 160 * '=' cannot appear in parameters. |
|
| 161 */ |
|
| 162 |
|
| 163 id = strstr(img, "id=") + 3; |
|
| 164 |
|
| 165 /* *id can't be \0, since a ">" appears after this */ |
|
| 166 if (isdigit(*id)) |
|
| 167 nid = atoi(id); |
|
| 168 else |
|
| 169 nid = atoi(id + 1); |
|
| 170 |
|
| 171 /* let's dump this, tag and then dump the src information */ |
|
| 172 g_string_append_len(buffer, img, cur - img); |
|
| 173 |
|
| 174 g_string_append_printf(buffer, " src='%s' ", get_image_src_from_id(priv, nid)); |
|
| 175 } |
|
| 176 |
|
| 177 return g_string_free(buffer, FALSE); |
|
| 178 } |
124 } |
| 179 |
125 |
| 180 static gboolean |
126 static gboolean |
| 181 process_js_script_queue(GtkWebView *webview) |
127 process_js_script_queue(GtkWebView *webview) |
| 182 { |
128 { |
| 533 g_signal_connect(webview, "load-started", |
476 g_signal_connect(webview, "load-started", |
| 534 G_CALLBACK(webview_load_started), NULL); |
477 G_CALLBACK(webview_load_started), NULL); |
| 535 |
478 |
| 536 g_signal_connect(webview, "load-finished", |
479 g_signal_connect(webview, "load-finished", |
| 537 G_CALLBACK(webview_load_finished), NULL); |
480 G_CALLBACK(webview_load_finished), NULL); |
| |
481 |
| |
482 g_signal_connect(G_OBJECT(webview), "resource-request-starting", |
| |
483 G_CALLBACK(webview_resource_loading), NULL); |
| 538 } |
484 } |
| 539 |
485 |
| 540 GType |
486 GType |
| 541 gtk_webview_get_type(void) |
487 gtk_webview_get_type(void) |
| 542 { |
488 { |
| 1065 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
1001 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
| 1066 WebKitDOMDocument *dom; |
1002 WebKitDOMDocument *dom; |
| 1067 char *img; |
1003 char *img; |
| 1068 |
1004 |
| 1069 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview)); |
1005 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview)); |
| 1070 img = g_strdup_printf("<img src='%s'/>", get_image_src_from_id(priv, id)); |
1006 img = g_strdup_printf("<img src='" PURPLE_STORED_IMAGE_PROTOCOL "%d'/>", |
| |
1007 id); |
| 1071 |
1008 |
| 1072 priv->edit.block_changed = TRUE; |
1009 priv->edit.block_changed = TRUE; |
| 1073 webkit_dom_document_exec_command(dom, "insertHTML", FALSE, img); |
1010 webkit_dom_document_exec_command(dom, "insertHTML", FALSE, img); |
| 1074 priv->edit.block_changed = FALSE; |
1011 priv->edit.block_changed = FALSE; |
| 1075 g_free(img); |
1012 g_free(img); |