diff options
Diffstat (limited to 'render')
-rw-r--r-- | render/favicon.c | 232 | ||||
-rw-r--r-- | render/favicon.h | 27 | ||||
-rw-r--r-- | render/html.c | 8 | ||||
-rw-r--r-- | render/html.h | 3 | ||||
-rw-r--r-- | render/html_redraw.c | 9 | ||||
-rw-r--r-- | render/layout.c | 2 | ||||
-rw-r--r-- | render/textplain.c | 12 |
7 files changed, 283 insertions, 10 deletions
diff --git a/render/favicon.c b/render/favicon.c new file mode 100644 index 000000000..fdf6e25f1 --- /dev/null +++ b/render/favicon.c @@ -0,0 +1,232 @@ +/* + * Copyright 2007 James Bursa <bursa@users.sourceforge.net> + * Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include "content/fetch.h" +#include "content/fetchcache.h" +#include "render/favicon.h" +#include "render/html.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/talloc.h" +#include "utils/url.h" +#include "utils/utils.h" + +static char *favicon_get_icon_ref(struct content *c, xmlNode *html); +static void favicon_callback(content_msg msg, struct content *icon, + intptr_t p1, intptr_t p2, union content_msg_data data); + +/** + * retrieve 1 url reference to 1 favicon + * \param html xml node of html element + * \return pointer to url; NULL for no icon; caller owns returned pointer + */ +char *favicon_get_icon_ref(struct content *c, xmlNode *html) +{ + xmlNode *node; + char *rel, *href, *url, *url2; + url2 = NULL; + url_func_result res; + + union content_msg_data msg_data; + + node = html; + while (node) { + if (node->children) { /* children */ + node = node->children; + } else if (node->next) { /* siblings */ + node = node->next; + } else { /* ancestor siblings */ + while (node && !node->next) + node = node->parent; + if (!node) + break; + node = node->next; + } + assert(node); + + if (node->type != XML_ELEMENT_NODE) + continue; + if (strcmp((const char *) node->name, "link") == 0) { + /* rel=<space separated list, including 'icon'> */ + if ((rel = (char *) xmlGetProp(node, + (const xmlChar *) "rel")) == NULL) + continue; + if (strcasestr(rel, "icon") == 0) { + xmlFree(rel); + continue; + } + LOG(("icon node found")); + if (strcasecmp(rel, "apple-touch-icon") == 0) { + xmlFree(rel); + continue; + } + xmlFree(rel); + if (( href = (char *) xmlGetProp(node, + (const xmlChar *) "href")) == NULL) + continue; + res = url_join(href, c->data.html.base_url, + &url); + xmlFree(href); + if (res != URL_FUNC_OK) + continue; + LOG(("most recent favicon '%s'", url)); + if (url2 != NULL) { + free(url2); + url2 = NULL; + } + res = url_normalize(url, &url2); + if (res != URL_FUNC_OK) { + url2 = NULL; + if (res == URL_FUNC_NOMEM) + goto no_memory; + continue; + } + free(url); + + } + } + if (url2 == NULL) { + if (url_join("/favicon.ico", c->data.html.base_url, &url2) + != URL_FUNC_OK) + return NULL; + } + LOG(("favicon %s", url2)); + return url2; +no_memory: + msg_data.error = messages_get("NoMemory"); + /* content_broadcast(c, CONTENT_MSG_ERROR, msg_data); */ + return false; +} + +/** + * retrieve 1 favicon + * \param c content structure + * \param html xml node of html element + * \return true for success, false for error + */ + +bool favicon_get_icon(struct content *c, xmlNode *html) +{ + char *url = favicon_get_icon_ref(c, html); + struct content *favcontent = NULL; + if (url == NULL) + return false; + + favcontent = fetchcache(url, favicon_callback, (intptr_t) c, 0, + c->width, c->height, true, 0, 0, false, false); + free(url); + if (favcontent == NULL) + return false; + + c->data.html.favicon = favcontent; + + fetchcache_go(favcontent, c->url, favicon_callback, (intptr_t) c, 0, + c->width, c->height, 0, 0, false, c); + + return true; +} + +/** + * Callback for fetchcache() for linked favicon + */ + +void favicon_callback(content_msg msg, struct content *icon, + intptr_t p1, intptr_t p2, union content_msg_data data) +{ + struct content *c = (struct content *) p1; + unsigned int i = p2; + switch (msg) { + case CONTENT_MSG_LOADING: + /* check that the favicon is really a correct image type */ + if (!((icon->type == CONTENT_ICO) || + (icon->type == CONTENT_PNG) || + (icon->type == CONTENT_GIF))) { + c->data.html.favicon = 0; + LOG(("%s is not a favicon", icon->url)); + content_add_error(c, "NotFavIco", 0); + html_set_status(c, messages_get("NotFavIco")); + content_broadcast(c, CONTENT_MSG_STATUS, data); + content_remove_user(icon, + favicon_callback, + (intptr_t) c, i); + if (!icon->user_list->next) { + /* we were the only user and we don't want this + * content, so stop it fetching and mark it as + * having an error so it gets removed from the + * cache next time content_clean() gets called + */ + fetch_abort(icon->fetch); + icon->fetch = 0; + icon->status = CONTENT_STATUS_ERROR; + } + } + break; + + case CONTENT_MSG_READY: + break; + + case CONTENT_MSG_DONE: + LOG(("got favicon '%s'", icon->url)); + break; + + case CONTENT_MSG_LAUNCH: + /* Fall through */ + case CONTENT_MSG_ERROR: + LOG(("favicon %s failed: %s", icon->url, data.error)); + /* The favicon we were fetching may have been + * redirected, in that case, the object pointers + * will differ, so ensure that the object that's + * in error is still in use by us before invalidating + * the pointer */ + if (c->data.html.favicon == icon) { + c->data.html.favicon = 0; + content_add_error(c, "?", 0); + } + break; + + case CONTENT_MSG_STATUS: + html_set_status(c, icon->status_message); + content_broadcast(c, CONTENT_MSG_STATUS, data); + break; + + case CONTENT_MSG_NEWPTR: + c->data.html.favicon = icon; + break; + + case CONTENT_MSG_AUTH: + c->data.html.favicon = 0; + content_add_error(c, "?", 0); + break; + + case CONTENT_MSG_SSL: + c->data.html.favicon = 0; + content_add_error(c, "?", 0); + break; + case CONTENT_MSG_REDRAW: + /* currently no support for favicon animations */ + case CONTENT_MSG_REFRESH: + break; + case CONTENT_MSG_REFORMAT: + /* would be unusual :) */ + break; + default: + assert(0); + } +} diff --git a/render/favicon.h b/render/favicon.h new file mode 100644 index 000000000..30030101a --- /dev/null +++ b/render/favicon.h @@ -0,0 +1,27 @@ +/* + * Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _NETSURF_RENDER_FAVICON_H_ +#define _NETSURF_RENDER_FAVICON_H_ + +#include <libxml/tree.h> +#include "content/content.h" + +bool favicon_get_icon(struct content *c, xmlNode *html); + +#endif diff --git a/render/html.c b/render/html.c index 241d61350..8592ad6e2 100644 --- a/render/html.c +++ b/render/html.c @@ -37,6 +37,7 @@ #include "desktop/options.h" #include "image/bitmap.h" #include "render/box.h" +#include "render/favicon.h" #include "render/font.h" #include "render/form.h" #include "render/html.h" @@ -74,7 +75,6 @@ static bool html_object_type_permitted(const content_type type, static void html_object_refresh(void *p); static void html_destroy_frameset(struct content_html_frames *frameset); static void html_destroy_iframe(struct content_html_iframe *iframe); -static void html_set_status(struct content *c, const char *extra); #if ALWAYS_DUMP_FRAMESET static void html_dump_frameset(struct content_html_frames *frame, unsigned int depth); @@ -307,6 +307,7 @@ encoding_change: * * - parsing to an XML tree is completed * - stylesheets are fetched + * - favicon is retrieved * - the XML tree is converted to a box tree and object fetches are started * - the box tree is laid out * @@ -424,6 +425,9 @@ bool html_convert(struct content *c, int width, int height) if (!html_find_stylesheets(c, html)) return false; + /* get icon */ + favicon_get_icon(c, html); + /* Retrieve forms from parser */ c->data.html.forms = binding_get_forms(c->data.html.parser_binding); for (f = c->data.html.forms; f != NULL; f = f->prev) { @@ -792,7 +796,7 @@ bool html_meta_refresh(struct content *c, xmlNode *head) * Uses STYLE and LINK elements inside and outside HEAD * * \param c content structure - * \param head xml node of html element + * \param html xml node of html element * \return true on success, false if an error occurred */ diff --git a/render/html.h b/render/html.h index e18c33a2c..51abba3ba 100644 --- a/render/html.h +++ b/render/html.h @@ -133,6 +133,8 @@ struct content_html_data { colour background_colour; /**< Document background colour. */ const struct font_functions *font_func; + struct content *favicon; /**< the favicon for the page */ + /** Number of entries in stylesheet_content. */ unsigned int stylesheet_count; /** Stylesheets. Each may be 0. */ @@ -189,6 +191,7 @@ void html_open(struct content *c, struct browser_window *bw, struct content *page, unsigned int index, struct box *box, struct object_params *params); void html_close(struct content *c); +void html_set_status(struct content *c, const char *extra); /* in render/html_redraw.c */ bool html_redraw(struct content *c, int x, int y, diff --git a/render/html_redraw.c b/render/html_redraw.c index becf99fe4..2a5154035 100644 --- a/render/html_redraw.c +++ b/render/html_redraw.c @@ -41,6 +41,7 @@ #include "desktop/textinput.h" #include "desktop/options.h" #include "desktop/print.h" +#include "desktop/search.h" #include "desktop/scroll.h" #include "image/bitmap.h" #include "render/box.h" @@ -880,12 +881,14 @@ bool text_redraw(const char *utf8_text, size_t utf8_len, } /* what about the current search operation, if any? */ - if (!highlighted && search_current_window == - current_redraw_browser->window && + if (!highlighted && (current_redraw_browser->search_context + != NULL) && gui_search_term_highlighted( current_redraw_browser->window, offset, offset + len, - &start_idx, &end_idx)) { + &start_idx, &end_idx, + current_redraw_browser-> + search_context)) { highlighted = true; } diff --git a/render/layout.c b/render/layout.c index c83753195..3463210bc 100644 --- a/render/layout.c +++ b/render/layout.c @@ -4435,7 +4435,7 @@ void layout_calculate_descendant_bboxes(struct box *box) { struct box *child; - if (box->width == UNKNOWN_WIDTH || box->height == AUTO /*|| + if ((box->width == UNKNOWN_WIDTH) || (box->height == AUTO) /*|| box->width < 0 || box->height < 0*/) { LOG(("%p has bad width or height", box)); /*while (box->parent) diff --git a/render/textplain.c b/render/textplain.c index 05d2fbe33..07f37610c 100644 --- a/render/textplain.c +++ b/render/textplain.c @@ -34,6 +34,7 @@ #include "desktop/gui.h" #include "desktop/options.h" #include "desktop/plotters.h" +#include "desktop/search.h" #include "desktop/selection.h" #include "render/box.h" #include "render/font.h" @@ -437,11 +438,14 @@ bool textplain_redraw(struct content *c, int x, int y, highlighted = true; } - if (!highlighted && search_current_window == bw->window) { + if (!highlighted && (bw->search_context + != NULL)) { unsigned start_idx, end_idx; - if (gui_search_term_highlighted(bw->window, - tab_ofst, tab_ofst + 1, - &start_idx, &end_idx)) + if (gui_search_term_highlighted( + bw->window, + tab_ofst, tab_ofst + 1, + &start_idx, &end_idx, + bw->search_context)) highlighted = true; } |