initial favicon support
svn path=/trunk/netsurf/; revision=12975
This commit is contained in:
parent
3fde9589c1
commit
52ad2c1e25
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
@ -1273,24 +1352,6 @@ bool browser_window_check_throbber(struct browser_window *bw)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -2384,22 +2413,6 @@ struct content_html_object *html_get_objects(hlcache_handle *h, unsigned int *n)
|
|||
return c->object_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue