diff --git a/src/ghtml-gtkhtml.c b/src/ghtml-gtkhtml.c index 5785988..0c9d9e4 100644 --- a/src/ghtml-gtkhtml.c +++ b/src/ghtml-gtkhtml.c @@ -17,6 +17,7 @@ #include #include +#include #include #include "ghtml.h" @@ -25,16 +26,25 @@ /* private */ typedef struct _GHtml { - GtkWidget * html_view; + /* FIXME implement history */ + + /* html widget */ + gchar * html_base; HtmlDocument * html_document; + gchar * html_title; + GtkWidget * html_view; } GHtml; /* prototypes */ -static gboolean _ghtml_document_load(HtmlDocument * document, - const gchar * url); +static gboolean _ghtml_document_load(GHtml * ghtml, gchar const * base, + gchar const * url); /* callbacks */ static void _on_link_clicked(HtmlDocument * document, const gchar * url); +static void _on_request_url(HtmlDocument * document, const gchar * url, + HtmlStream * stream); +static void _on_set_base(HtmlDocument * document, const gchar * url); +static void _on_title_changed(HtmlDocument * document, const gchar * title); /* public */ @@ -46,11 +56,21 @@ GtkWidget * ghtml_new(Surfer * surfer) if((ghtml = malloc(sizeof(*ghtml))) == NULL) return NULL; + ghtml->html_base = NULL; ghtml->html_view = html_view_new(); ghtml->html_document = html_document_new(); + ghtml->html_title = NULL; + g_object_set_data(G_OBJECT(ghtml->html_document), "ghtml", ghtml); g_signal_connect(G_OBJECT(ghtml->html_document), "link-clicked", G_CALLBACK(_on_link_clicked), NULL); - html_view_set_document(ghtml->html_view, ghtml->html_document); + g_signal_connect(G_OBJECT(ghtml->html_document), "request-url", + G_CALLBACK(_on_request_url), NULL); + g_signal_connect(G_OBJECT(ghtml->html_document), "set-base", G_CALLBACK( + _on_set_base), NULL); + g_signal_connect(G_OBJECT(ghtml->html_document), "title-changed", + G_CALLBACK(_on_title_changed), NULL); + html_view_set_document(HTML_VIEW(ghtml->html_view), + ghtml->html_document); widget = gtk_scrolled_window_new(NULL, NULL); g_object_set_data(G_OBJECT(widget), "ghtml", ghtml); gtk_container_add(GTK_CONTAINER(widget), ghtml->html_view); @@ -88,10 +108,12 @@ char const * ghtml_get_location(GtkWidget * ghtml) } -char const * ghtml_get_title(GtkWidget * ghtml) +char const * ghtml_get_title(GtkWidget * widget) { - /* FIXME implement */ - return NULL; + GHtml * ghtml; + + ghtml = g_object_get_data(G_OBJECT(widget), "ghtml"); + return ghtml->html_title; } @@ -110,23 +132,40 @@ gboolean ghtml_go_forward(GtkWidget * ghtml) } +/* ghtml_load_url */ void ghtml_load_url(GtkWidget * widget, char const * url) { GHtml * ghtml; +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, url); +#endif ghtml = g_object_get_data(G_OBJECT(widget), "ghtml"); - _ghtml_document_load(ghtml->html_document, url); + if(_ghtml_document_load(ghtml, "", url) != TRUE) + return; + /* FIXME with current code another base may have been set in between */ + g_free(ghtml->html_base); + ghtml->html_base = g_strdup(url); } -void ghtml_refresh(GtkWidget * ghtml) + +/* ghtml_refresh */ +void ghtml_refresh(GtkWidget * widget) { - /* FIXME implement */ + GHtml * ghtml; + + ghtml = g_object_get_data(G_OBJECT(widget), "ghtml"); + if(ghtml->html_base == NULL) + return; + /* FIXME should differentiate URL and base */ + _ghtml_document_load(ghtml, "", ghtml->html_base); } +/* ghtml_reload */ void ghtml_reload(GtkWidget * ghtml) { - /* FIXME implement */ + ghtml_refresh(ghtml); } @@ -138,18 +177,47 @@ void ghtml_stop(GtkWidget * ghtml) /* private */ /* functions */ -static gboolean _ghtml_document_load(HtmlDocument * document, - const gchar * url) +/* ghtml_document_load */ +static gboolean _load_write_stream(HtmlStream * stream, gchar const * base, + gchar const * url); + +static gboolean _ghtml_document_load(GHtml * ghtml, gchar const * base, + gchar const * url) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(\"%s\", \"%s\")\n", __func__, base, url); +#endif + html_document_open_stream(ghtml->html_document, "text/html"); + if(_load_write_stream(ghtml->html_document->current_stream, base, url) + != TRUE) + { + html_document_write_stream(ghtml->html_document, "500", 3); + html_document_close_stream(ghtml->html_document); + return FALSE; /* FIXME report error */ + } + html_document_close_stream(ghtml->html_document); + return TRUE; +} + +static gboolean _load_write_stream(HtmlStream * stream, gchar const * base, + gchar const * url) { gchar * buf = NULL; - gsize length = 0; + gsize len = 0; guint response; - if(gnet_http_get(url, &buf, &length, &response) != TRUE) + url = rfc1738_make_full_url(base, url); +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() url=\"%s\"\n", __func__, url); +#endif + if(gnet_http_get(url, &buf, &len, &response) != TRUE) + { +#ifdef DEBUG + fprintf(stderr, "DEBUG: gnet_http_get() => %u\n", response); +#endif return FALSE; /* FIXME report error */ - html_document_open_stream(document, "text/html"); - html_document_write_stream(document, buf, length); - html_document_close_stream(document); + } + html_stream_write(stream, buf, len); return TRUE; } @@ -157,8 +225,52 @@ static gboolean _ghtml_document_load(HtmlDocument * document, /* callbacks */ static void _on_link_clicked(HtmlDocument * document, const gchar * url) { + GHtml * ghtml; + #ifdef DEBUG - fprintf(stderr, "DEBUG: %s(%p, \"%s\")\n", __func__, document, url); + fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, url); #endif - _ghtml_document_load(document, url); + ghtml = g_object_get_data(G_OBJECT(document), "ghtml"); + _ghtml_document_load(ghtml, ghtml->html_base, url); +} + + +static void _on_request_url(HtmlDocument * document, const gchar * url, + HtmlStream * stream) +{ + GHtml * ghtml; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, url); +#endif + ghtml = g_object_get_data(G_OBJECT(document), "ghtml"); + _load_write_stream(stream, ghtml->html_base, url); + html_stream_close(stream); +} + + +static void _on_set_base(HtmlDocument * document, const gchar * url) +{ + GHtml * ghtml; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, url); +#endif + ghtml = g_object_get_data(G_OBJECT(document), "ghtml"); + g_free(ghtml->html_base); + ghtml->html_base = g_strdup(url); +} + + +static void _on_title_changed(HtmlDocument * document, const gchar * title) +{ + GHtml * ghtml; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, title); +#endif + ghtml = g_object_get_data(G_OBJECT(document), "ghtml"); + g_free(ghtml->html_title); + ghtml->html_title = g_strdup(title); + /* FIXME emit signal */ }