pidgin/gtkwebview.c

changeset 33054
177359654a3d
parent 33030
4114ce42d094
child 33083
e96acbe0e928
child 33149
e1b50abc07bb
equal deleted inserted replaced
33053:6ba80150e4c3 33054:177359654a3d
51 /****************************************************************************** 51 /******************************************************************************
52 * Structs 52 * Structs
53 *****************************************************************************/ 53 *****************************************************************************/
54 54
55 typedef struct _GtkWebViewPriv { 55 typedef struct _GtkWebViewPriv {
56 GHashTable *images; /**< a map from id to temporary file for the image */
57 gboolean empty; /**< whether anything has been appended **/ 56 gboolean empty; /**< whether anything has been appended **/
58 57
59 /* JS execute queue */ 58 /* JS execute queue */
60 GQueue *js_queue; 59 GQueue *js_queue;
61 gboolean is_loading; 60 gboolean is_loading;
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 {
438 gpointer temp; 384 gpointer temp;
439 385
440 while ((temp = g_queue_pop_head(priv->js_queue))) 386 while ((temp = g_queue_pop_head(priv->js_queue)))
441 g_free(temp); 387 g_free(temp);
442 g_queue_free(priv->js_queue); 388 g_queue_free(priv->js_queue);
443
444 if (priv->images)
445 g_hash_table_unref(priv->images);
446 389
447 G_OBJECT_CLASS(parent_class)->finalize(G_OBJECT(webview)); 390 G_OBJECT_CLASS(parent_class)->finalize(G_OBJECT(webview));
448 } 391 }
449 392
450 static void 393 static void
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 {
610 } 556 }
611 557
612 void 558 void
613 gtk_webview_load_html_string(GtkWebView *webview, const char *html) 559 gtk_webview_load_html_string(GtkWebView *webview, const char *html)
614 { 560 {
615 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); 561 webkit_web_view_load_string(WEBKIT_WEB_VIEW(webview), html, NULL, NULL,
616 char *html_imged; 562 "file:///");
617
618 if (priv->images) {
619 g_hash_table_unref(priv->images);
620 priv->images = NULL;
621 }
622
623 html_imged = replace_img_id_with_src(priv, html);
624 webkit_web_view_load_string(WEBKIT_WEB_VIEW(webview), html_imged, NULL,
625 NULL, "file:///");
626 g_free(html_imged);
627 } 563 }
628 564
629 void 565 void
630 gtk_webview_append_html(GtkWebView *webview, const char *html) 566 gtk_webview_append_html(GtkWebView *webview, const char *html)
631 { 567 {
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);

mercurial