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 */
}