summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/content.h8
-rw-r--r--desktop/browser.c123
-rw-r--r--desktop/browser.h3
-rw-r--r--gtk/scaffolding.c9
-rw-r--r--render/html.c45
-rw-r--r--render/html.h1
6 files changed, 139 insertions, 50 deletions
diff --git a/content/content.h b/content/content.h
index b288cb61e..eb8fbe689 100644
--- a/content/content.h
+++ b/content/content.h
@@ -72,7 +72,7 @@ typedef enum {
CONTENT_MSG_REDRAW, /**< needs redraw (eg. new animation frame) */
CONTENT_MSG_REFRESH, /**< wants refresh */
CONTENT_MSG_DOWNLOAD, /**< download, not for display */
- CONTENT_MSG_FAVICON_REFRESH, /**< favicon has been refreshed (eg. new animation frame) */
+ CONTENT_MSG_LINK, /**< RFC5988 link */
} content_msg;
/** Extra data for some content_msg messages. */
@@ -96,6 +96,12 @@ union content_msg_data {
bool background;
/** Low-level cache handle, for CONTENT_MSG_DOWNLOAD */
struct llcache_handle *download;
+ /** rfc5988 link data CONTENT_MSG_RFC5988_LINK */
+ struct {
+ nsurl *url;
+ char *rel;
+ char *type;
+ } rfc5988_link;
};
diff --git a/desktop/browser.c b/desktop/browser.c
index fbcac5297..ed1cfc345 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -80,7 +80,6 @@ static void browser_window_convert_to_download(struct browser_window *bw,
llcache_handle *stream);
static void browser_window_start_throbber(struct browser_window *bw);
static void browser_window_stop_throbber(struct browser_window *bw);
-static void browser_window_set_icon(struct browser_window *bw);
static void browser_window_destroy_children(struct browser_window *bw);
static void browser_window_destroy_internal(struct browser_window *bw);
static void browser_window_set_scale_internal(struct browser_window *bw,
@@ -878,6 +877,34 @@ void browser_window_go_post(struct browser_window *bw, const char *url,
nsurl_unref(nsref);
}
+/**
+ * Callback for fetchcache() for browser window favicon fetches.
+ */
+
+static nserror browser_window_favicon_callback(hlcache_handle *c,
+ const hlcache_event *event, void *pw)
+{
+ struct browser_window *bw = pw;
+
+ switch (event->type) {
+ case CONTENT_MSG_DONE:
+ LOG(("favicon contents for %p done!", bw));
+ /* content_get_bitmap on the bw->favicon should give
+ us the favicon at this point
+ */
+ if (bw->window != NULL) {
+ gui_window_set_icon(bw->window, bw->favicon);
+ } else {
+ LOG(("null browser window on favicon!"));
+ }
+ break;
+
+ default:
+ LOG(("favicon unhandled event"));
+ break;
+ }
+ return NSERROR_OK;
+}
/**
* Callback for fetchcache() for browser window fetches.
@@ -935,6 +962,18 @@ nserror browser_window_callback(hlcache_handle *c,
hlcache_handle_release(bw->current_content);
}
+ if (bw->favicon != NULL) {
+ content_status status =
+ content_get_status(bw->favicon);
+
+ if (status == CONTENT_STATUS_READY ||
+ status == CONTENT_STATUS_DONE)
+ content_close(bw->favicon);
+
+ hlcache_handle_release(bw->favicon);
+ bw->favicon = NULL;
+ }
+
bw->current_content = c;
bw->loading_content = NULL;
@@ -1001,7 +1040,32 @@ nserror browser_window_callback(hlcache_handle *c,
browser_window_update(bw, false);
browser_window_set_status(bw, content_get_status_message(c));
browser_window_stop_throbber(bw);
- browser_window_set_icon(bw);
+ if (bw->favicon == NULL) {
+ /* no favicon via link - try for the default location - bletch */
+ nsurl *nsref = NULL;
+ nsurl *nsurl;
+ nserror error;
+
+ error = nsurl_join(content_get_url(c), "/favicon.ico", &nsurl);
+ if (error == NSERROR_OK) {
+
+
+ hlcache_handle_retrieve(nsurl,
+ HLCACHE_RETRIEVE_MAY_DOWNLOAD |
+ HLCACHE_RETRIEVE_SNIFF_TYPE,
+ nsref,
+ NULL,
+ browser_window_favicon_callback,
+ bw,
+ NULL,
+ CONTENT_IMAGE,
+ &bw->favicon);
+
+ nsurl_unref(nsurl);
+
+ }
+
+ }
history_update(bw->history, c);
hotlist_visited(c);
@@ -1078,12 +1142,27 @@ nserror browser_window_callback(hlcache_handle *c,
bw->refresh_interval = event->data.delay * 100;
break;
- case CONTENT_MSG_FAVICON_REFRESH:
- /* Cause the GUI to update */
- if (bw->browser_window_type == BROWSER_WINDOW_NORMAL) {
- gui_window_set_icon(bw->window,
- html_get_favicon(bw->current_content));
+ case CONTENT_MSG_LINK: /* content has an rfc5988 link element */
+ {
+ nsurl *nsref = NULL;
+ if ((bw->favicon == NULL) &&
+ (strstr(event->data.rfc5988_link.rel, "icon") != NULL)) {
+ /* its a favicon start a fetch for it */
+ LOG(("fetching favicon rel:%s '%s'",
+ event->data.rfc5988_link.rel,
+ nsurl_access(event->data.rfc5988_link.url)));
+ hlcache_handle_retrieve(event->data.rfc5988_link.url,
+ HLCACHE_RETRIEVE_MAY_DOWNLOAD |
+ HLCACHE_RETRIEVE_SNIFF_TYPE,
+ nsref,
+ NULL,
+ browser_window_favicon_callback,
+ bw,
+ NULL,
+ CONTENT_IMAGE,
+ &bw->favicon);
}
+ }
break;
default:
@@ -1274,24 +1353,6 @@ bool browser_window_check_throbber(struct browser_window *bw)
}
/**
- * when ready, set icon at top level
- * \param bw browser_window
- * current implementation ignores lower-levels' link rels completely
- */
-void browser_window_set_icon(struct browser_window *bw)
-{
- while (bw->parent)
- bw = bw->parent;
-
- if (bw->current_content != NULL &&
- content_get_type(bw->current_content) == CONTENT_HTML)
- gui_window_set_icon(bw->window,
- html_get_favicon(bw->current_content));
- else
- gui_window_set_icon(bw->window, NULL);
-}
-
-/**
* Redraw browser window, set extent to content, and update title.
*
* \param bw browser_window
@@ -1663,6 +1724,18 @@ void browser_window_destroy_internal(struct browser_window *bw)
bw->current_content = NULL;
}
+ if (bw->favicon != NULL) {
+ content_status status =
+ content_get_status(bw->favicon);
+
+ if (status == CONTENT_STATUS_READY ||
+ status == CONTENT_STATUS_DONE)
+ content_close(bw->favicon);
+
+ hlcache_handle_release(bw->favicon);
+ bw->favicon = NULL;
+ }
+
if (bw->box != NULL) {
bw->box->iframe = NULL;
bw->box = NULL;
diff --git a/desktop/browser.h b/desktop/browser.h
index d7d996c5e..c96c4f177 100644
--- a/desktop/browser.h
+++ b/desktop/browser.h
@@ -75,6 +75,9 @@ struct browser_window {
/** Page being loaded, or 0. */
struct hlcache_handle *loading_content;
+ /** Page Favicon */
+ struct hlcache_handle *favicon;
+
/** Window history structure. */
struct history *history;
diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c
index 5c0366c08..b9a4b0909 100644
--- a/gtk/scaffolding.c
+++ b/gtk/scaffolding.c
@@ -2254,14 +2254,9 @@ void nsgtk_scaffolding_set_top_level (struct gui_window *gw)
nsgtk_search_set_forward_state(true, bw);
nsgtk_search_set_back_state(true, bw);
- /* Ensure the window's title bar as well as favicon are updated */
+ /* Ensure the window's title bar is updated */
if (bw->current_content != NULL) {
- gui_window_set_title(gw,
- content_get_title(bw->current_content));
-
- if (content_get_type(bw->current_content) == CONTENT_HTML)
- gui_window_set_icon(gw,
- html_get_favicon(bw->current_content));
+ gui_window_set_title(gw, content_get_title(bw->current_content));
}
}
diff --git a/render/html.c b/render/html.c
index 93b34cafb..4c08a6620 100644
--- a/render/html.c
+++ b/render/html.c
@@ -810,6 +810,35 @@ bool html_head(html_content *c, xmlNode *head)
}
xmlFree(s);
}
+ } else if (strcmp((const char *) node->name, "link") == 0) {
+ union content_msg_data msg_data;
+ char *href;
+ nserror error;
+
+ href = (char *) xmlGetProp(node, (const xmlChar *) "href");
+ if (href) {
+ error = nsurl_join(c->base_url, href, &msg_data.rfc5988_link.url);
+
+ xmlFree(href);
+ }
+
+ msg_data.rfc5988_link.rel = (char *)xmlGetProp(node,
+ (const xmlChar *)"rel");
+ msg_data.rfc5988_link.type = (char *)xmlGetProp(node,
+ (const xmlChar *)"type");
+
+ content_broadcast(&c->base, CONTENT_MSG_LINK, msg_data);
+
+ if (error == NSERROR_OK) {
+ nsurl_unref(msg_data.rfc5988_link.url);
+ }
+ if (msg_data.rfc5988_link.rel) {
+ xmlFree(msg_data.rfc5988_link.rel);
+ }
+ if (msg_data.rfc5988_link.type) {
+ xmlFree(msg_data.rfc5988_link.type);
+ }
+
}
}
return true;
@@ -2385,22 +2414,6 @@ struct content_html_object *html_get_objects(hlcache_handle *h, unsigned int *n)
}
/**
- * Retrieve favicon associated with an HTML document
- *
- * \param h HTML document to retrieve favicon from
- * \return Pointer to favicon, or NULL if none
- */
-hlcache_handle *html_get_favicon(hlcache_handle *h)
-{
- html_content *c = (html_content *) hlcache_handle_get_content(h);
-
- assert(c != NULL);
-
- return NULL;
-}
-
-
-/**
* Retrieve layout coordinates of box with given id
*
* \param h HTML document to search
diff --git a/render/html.h b/render/html.h
index 648c9751f..dba1ce427 100644
--- a/render/html.h
+++ b/render/html.h
@@ -169,7 +169,6 @@ struct html_stylesheet *html_get_stylesheets(struct hlcache_handle *h,
unsigned int *n);
struct content_html_object *html_get_objects(struct hlcache_handle *h,
unsigned int *n);
-struct hlcache_handle *html_get_favicon(struct hlcache_handle *h);
bool html_get_id_offset(struct hlcache_handle *h, const char *frag_id,
int *x, int *y);