| 24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
| 25 * |
25 * |
| 26 */ |
26 */ |
| 27 |
27 |
| 28 #include "internal.h" |
28 #include "internal.h" |
| |
29 #include "debug.h" |
| 29 #include "pidgin.h" |
30 #include "pidgin.h" |
| 30 |
31 |
| 31 #include <gdk/gdkkeysyms.h> |
32 #include <gdk/gdkkeysyms.h> |
| 32 #include "gtkwebview.h" |
33 #include "gtkwebview.h" |
| 33 |
34 |
| 37 #define MAX_SCROLL_TIME 0.4 /* seconds */ |
38 #define MAX_SCROLL_TIME 0.4 /* seconds */ |
| 38 #define SCROLL_DELAY 33 /* milliseconds */ |
39 #define SCROLL_DELAY 33 /* milliseconds */ |
| 39 |
40 |
| 40 #define GTK_WEBVIEW_GET_PRIVATE(obj) \ |
41 #define GTK_WEBVIEW_GET_PRIVATE(obj) \ |
| 41 (G_TYPE_INSTANCE_GET_PRIVATE((obj), GTK_TYPE_WEBVIEW, GtkWebViewPriv)) |
42 (G_TYPE_INSTANCE_GET_PRIVATE((obj), GTK_TYPE_WEBVIEW, GtkWebViewPriv)) |
| |
43 |
| |
44 enum { |
| |
45 LOAD_HTML, |
| |
46 LOAD_JS |
| |
47 }; |
| 42 |
48 |
| 43 enum { |
49 enum { |
| 44 BUTTONS_UPDATE, |
50 BUTTONS_UPDATE, |
| 45 TOGGLE_FORMAT, |
51 TOGGLE_FORMAT, |
| 46 CLEAR_FORMAT, |
52 CLEAR_FORMAT, |
| 123 } |
129 } |
| 124 } |
130 } |
| 125 } |
131 } |
| 126 |
132 |
| 127 static gboolean |
133 static gboolean |
| 128 process_js_script_queue(GtkWebView *webview) |
134 process_load_queue(GtkWebView *webview) |
| 129 { |
135 { |
| 130 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
136 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
| 131 char *script; |
137 int type; |
| 132 |
138 char *str; |
| 133 if (priv->is_loading) |
|
| 134 return FALSE; /* we will be called when loaded */ |
|
| 135 if (!priv->js_queue || g_queue_is_empty(priv->js_queue)) |
|
| 136 return FALSE; /* nothing to do! */ |
|
| 137 |
|
| 138 script = g_queue_pop_head(priv->js_queue); |
|
| 139 webkit_web_view_execute_script(WEBKIT_WEB_VIEW(webview), script); |
|
| 140 g_free(script); |
|
| 141 |
|
| 142 return TRUE; /* there may be more for now */ |
|
| 143 } |
|
| 144 |
|
| 145 static gboolean |
|
| 146 process_html_queue(GtkWebView *webview) |
|
| 147 { |
|
| 148 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
|
| 149 char *html; |
|
| 150 WebKitDOMDocument *doc; |
139 WebKitDOMDocument *doc; |
| 151 WebKitDOMHTMLElement *body; |
140 WebKitDOMHTMLElement *body; |
| 152 |
141 |
| 153 if (priv->is_loading) |
142 if (priv->is_loading) { |
| |
143 priv->loader = 0; |
| 154 return FALSE; |
144 return FALSE; |
| 155 if (!priv->html_queue || g_queue_is_empty(priv->html_queue)) |
145 } |
| |
146 if (!priv->load_queue || g_queue_is_empty(priv->load_queue)) { |
| |
147 priv->loader = 0; |
| 156 return FALSE; |
148 return FALSE; |
| 157 |
149 } |
| 158 html = g_queue_pop_head(priv->html_queue); |
150 |
| 159 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview)); |
151 type = GPOINTER_TO_INT(g_queue_pop_head(priv->load_queue)); |
| 160 body = webkit_dom_document_get_body(doc); |
152 str = g_queue_pop_head(priv->load_queue); |
| 161 webkit_dom_html_element_insert_adjacent_html(body, "beforeend", html, NULL); |
153 |
| 162 g_free(html); |
154 switch (type) { |
| |
155 case LOAD_HTML: |
| |
156 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview)); |
| |
157 body = webkit_dom_document_get_body(doc); |
| |
158 webkit_dom_html_element_insert_adjacent_html(body, "beforeend", |
| |
159 str, NULL); |
| |
160 break; |
| |
161 |
| |
162 case LOAD_JS: |
| |
163 webkit_web_view_execute_script(WEBKIT_WEB_VIEW(webview), str); |
| |
164 break; |
| |
165 |
| |
166 default: |
| |
167 purple_debug_error("webview", |
| |
168 "Got unknown loading queue type: %d\n", type); |
| |
169 break; |
| |
170 } |
| |
171 |
| |
172 g_free(str); |
| 163 |
173 |
| 164 return TRUE; |
174 return TRUE; |
| 165 } |
175 } |
| 166 |
176 |
| 167 static void |
177 static void |
| 179 gpointer userdata) |
189 gpointer userdata) |
| 180 { |
190 { |
| 181 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
191 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
| 182 |
192 |
| 183 priv->is_loading = FALSE; |
193 priv->is_loading = FALSE; |
| 184 g_idle_add((GSourceFunc)process_js_script_queue, webview); |
194 if (priv->loader == 0) |
| |
195 priv->loader = g_idle_add((GSourceFunc)process_load_queue, webview); |
| 185 } |
196 } |
| 186 |
197 |
| 187 static gboolean |
198 static gboolean |
| 188 webview_link_clicked(WebKitWebView *webview, |
199 webview_link_clicked(WebKitWebView *webview, |
| 189 WebKitWebFrame *frame, |
200 WebKitWebFrame *frame, |
| 396 gtk_webview_finalize(GObject *webview) |
407 gtk_webview_finalize(GObject *webview) |
| 397 { |
408 { |
| 398 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
409 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
| 399 gpointer temp; |
410 gpointer temp; |
| 400 |
411 |
| 401 while ((temp = g_queue_pop_head(priv->html_queue))) |
412 g_source_remove(priv->loader); |
| |
413 |
| |
414 while (!g_queue_is_empty(priv->load_queue)) { |
| |
415 temp = g_queue_pop_head(priv->load_queue); |
| |
416 temp = g_queue_pop_head(priv->load_queue); |
| 402 g_free(temp); |
417 g_free(temp); |
| 403 g_queue_free(priv->html_queue); |
418 } |
| 404 |
419 g_queue_free(priv->load_queue); |
| 405 while ((temp = g_queue_pop_head(priv->js_queue))) |
|
| 406 g_free(temp); |
|
| 407 g_queue_free(priv->js_queue); |
|
| 408 |
420 |
| 409 G_OBJECT_CLASS(parent_class)->finalize(G_OBJECT(webview)); |
421 G_OBJECT_CLASS(parent_class)->finalize(G_OBJECT(webview)); |
| 410 } |
422 } |
| 411 |
423 |
| 412 static void |
424 static void |
| 484 static void |
496 static void |
| 485 gtk_webview_init(GtkWebView *webview, gpointer userdata) |
497 gtk_webview_init(GtkWebView *webview, gpointer userdata) |
| 486 { |
498 { |
| 487 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
499 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
| 488 |
500 |
| 489 priv->html_queue = g_queue_new(); |
501 priv->load_queue = g_queue_new(); |
| 490 priv->js_queue = g_queue_new(); |
|
| 491 |
502 |
| 492 g_signal_connect(webview, "navigation-policy-decision-requested", |
503 g_signal_connect(webview, "navigation-policy-decision-requested", |
| 493 G_CALLBACK(webview_link_clicked), NULL); |
504 G_CALLBACK(webview_link_clicked), NULL); |
| 494 |
505 |
| 495 g_signal_connect(webview, "load-started", |
506 g_signal_connect(webview, "load-started", |
| 565 GtkWebViewPriv *priv; |
576 GtkWebViewPriv *priv; |
| 566 |
577 |
| 567 g_return_if_fail(webview != NULL); |
578 g_return_if_fail(webview != NULL); |
| 568 |
579 |
| 569 priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
580 priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
| 570 g_queue_push_tail(priv->js_queue, g_strdup(script)); |
581 g_queue_push_tail(priv->load_queue, GINT_TO_POINTER(LOAD_JS)); |
| 571 g_idle_add((GSourceFunc)process_js_script_queue, webview); |
582 g_queue_push_tail(priv->load_queue, g_strdup(script)); |
| |
583 if (!priv->is_loading) |
| |
584 g_idle_add((GSourceFunc)process_load_queue, webview); |
| 572 } |
585 } |
| 573 |
586 |
| 574 void |
587 void |
| 575 gtk_webview_load_html_string(GtkWebView *webview, const char *html) |
588 gtk_webview_load_html_string(GtkWebView *webview, const char *html) |
| 576 { |
589 { |
| 605 GtkWebViewPriv *priv; |
618 GtkWebViewPriv *priv; |
| 606 |
619 |
| 607 g_return_if_fail(webview != NULL); |
620 g_return_if_fail(webview != NULL); |
| 608 |
621 |
| 609 priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
622 priv = GTK_WEBVIEW_GET_PRIVATE(webview); |
| 610 g_queue_push_tail(priv->html_queue, g_strdup(html)); |
623 g_queue_push_tail(priv->load_queue, GINT_TO_POINTER(LOAD_HTML)); |
| 611 g_idle_add((GSourceFunc)process_html_queue, webview); |
624 g_queue_push_tail(priv->load_queue, g_strdup(html)); |
| |
625 if (!priv->is_loading) |
| |
626 g_idle_add((GSourceFunc)process_load_queue, webview); |
| 612 } |
627 } |
| 613 |
628 |
| 614 void |
629 void |
| 615 gtk_webview_set_vadjustment(GtkWebView *webview, GtkAdjustment *vadj) |
630 gtk_webview_set_vadjustment(GtkWebView *webview, GtkAdjustment *vadj) |
| 616 { |
631 { |