diff options
author | Michael Drake <tlsa@netsurf-browser.org> | 2008-09-23 10:44:10 +0000 |
---|---|---|
committer | Michael Drake <tlsa@netsurf-browser.org> | 2008-09-23 10:44:10 +0000 |
commit | 9de2adbdf1ed8310894de18992e10dc26b4ae160 (patch) | |
tree | d516e2cc31a642f4bdb3b652ccf8c7749e43587a /render | |
parent | a2a28e0c0a490953fe18a8ce646c2247c4705f37 (diff) | |
download | netsurf-9de2adbdf1ed8310894de18992e10dc26b4ae160.tar.gz netsurf-9de2adbdf1ed8310894de18992e10dc26b4ae160.tar.bz2 |
Use stylesheets from LINK elements outside HEAD. (We already supported STYLE elements outside HEAD.) Fixes amazon.co.uk problem.
svn path=/trunk/netsurf/; revision=5415
Diffstat (limited to 'render')
-rw-r--r-- | render/html.c | 212 |
1 files changed, 97 insertions, 115 deletions
diff --git a/render/html.c b/render/html.c index 14563f9f4..1e063e3a6 100644 --- a/render/html.c +++ b/render/html.c @@ -53,9 +53,7 @@ static void html_convert_css_callback(content_msg msg, struct content *css, intptr_t p1, intptr_t p2, union content_msg_data data); static bool html_meta_refresh(struct content *c, xmlNode *head); static bool html_head(struct content *c, xmlNode *head); -static bool html_find_stylesheets(struct content *c, xmlNode *html, - xmlNode *head); -static bool html_find_inline_stylesheets(struct content *c, xmlNode *html); +static bool html_find_stylesheets(struct content *c, xmlNode *html); static bool html_process_style_element(struct content *c, xmlNode *style); static void html_object_callback(content_msg msg, struct content *object, intptr_t p1, intptr_t p2, union content_msg_data data); @@ -169,7 +167,7 @@ bool html_process_data(struct content *c, char *data, unsigned int size) } LOG(("Parsing %lu bytes", (size - x))); - err = binding_parse_chunk(c->data.html.parser_binding, + err = binding_parse_chunk(c->data.html.parser_binding, (uint8_t *) data + x, (size - x)); if (err == BINDING_ENCODINGCHANGE) { goto encoding_change; @@ -183,7 +181,7 @@ encoding_change: /* Retrieve new encoding */ const char *encoding = binding_get_encoding( - c->data.html.parser_binding, + c->data.html.parser_binding, &c->data.html.encoding_source); c->data.html.encoding = strdup(encoding); @@ -244,7 +242,7 @@ bool html_convert(struct content *c, int width, int height) } binding_parse_completed(c->data.html.parser_binding); - c->data.html.document = + c->data.html.document = binding_get_document(c->data.html.parser_binding); /*xmlDebugDumpDocument(stderr, c->data.html.document);*/ binding_destroy_tree(c->data.html.parser_binding); @@ -287,7 +285,7 @@ bool html_convert(struct content *c, int width, int height) } /* get stylesheets */ - if (!html_find_stylesheets(c, html, head)) + if (!html_find_stylesheets(c, html)) return false; /* convert xml tree to box tree */ @@ -608,14 +606,14 @@ bool html_meta_refresh(struct content *c, xmlNode *head) /** * Process inline stylesheets and fetch linked stylesheets. * + * Uses STYLE and LINK elements inside and outside HEAD + * * \param c content structure * \param head xml node of html element - * \param head xml node of head element, or 0 if none * \return true on success, false if an error occurred */ -bool html_find_stylesheets(struct content *c, xmlNode *html, - xmlNode *head) +bool html_find_stylesheets(struct content *c, xmlNode *html) { xmlNode *node; char *rel, *type, *media, *href, *url; @@ -667,91 +665,116 @@ bool html_find_stylesheets(struct content *c, xmlNode *html, c->height, 0, 0, false, 0); } - for (node = head == 0 ? 0 : head->children; node; node = node->next) { + node = html; + + /* depth-first search the tree for link elements */ + while (node) { + if (node->children) { /* 1. children */ + node = node->children; + } else if (node->next) { /* 2. siblings */ + node = node->next; + } else { /* 3. 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) - continue; + if (strcmp((const char *) node->name, "link") == 0) { - /* rel=<space separated list, including 'stylesheet'> */ - if ((rel = (char *) xmlGetProp(node, (const xmlChar *) "rel")) == NULL) - continue; - if (strcasestr(rel, "stylesheet") == 0) { - xmlFree(rel); - continue; - } else if (strcasestr(rel, "alternate")) { - /* Ignore alternate stylesheets */ + /* rel=<space separated list, including 'stylesheet'> */ + if ((rel = (char *) xmlGetProp(node, + (const xmlChar *) "rel")) == NULL) + continue; + if (strcasestr(rel, "stylesheet") == 0) { + xmlFree(rel); + continue; + } else if (strcasestr(rel, "alternate")) { + /* Ignore alternate stylesheets */ + xmlFree(rel); + continue; + } xmlFree(rel); - continue; - } - xmlFree(rel); - /* type='text/css' or not present */ - if ((type = (char *) xmlGetProp(node, (const xmlChar *) "type")) != NULL) { - if (strcmp(type, "text/css") != 0) { + /* type='text/css' or not present */ + if ((type = (char *) xmlGetProp(node, + (const xmlChar *) "type")) != NULL) { + if (strcmp(type, "text/css") != 0) { + xmlFree(type); + continue; + } xmlFree(type); - continue; } - xmlFree(type); - } - /* media contains 'screen' or 'all' or not present */ - if ((media = (char *) xmlGetProp(node, (const xmlChar *) "media")) != NULL) { - if (strcasestr(media, "screen") == 0 && - strcasestr(media, "all") == 0) { + /* media contains 'screen' or 'all' or not present */ + if ((media = (char *) xmlGetProp(node, + (const xmlChar *) "media")) != NULL) { + if (strcasestr(media, "screen") == 0 && + strcasestr(media, "all") == 0) { + xmlFree(media); + continue; + } xmlFree(media); - continue; } - xmlFree(media); - } - /* href='...' */ - if ((href = (char *) xmlGetProp(node, (const xmlChar *) "href")) == NULL) - continue; + /* href='...' */ + if ((href = (char *) xmlGetProp(node, + (const xmlChar *) "href")) == NULL) + continue; - /* TODO: only the first preferred stylesheets (ie. those with a - * title attribute) should be loaded (see HTML4 14.3) */ + /* TODO: only the first preferred stylesheets (ie. + * those with a title attribute) should be loaded + * (see HTML4 14.3) */ - res = url_join(href, c->data.html.base_url, &url); - xmlFree(href); - if (res != URL_FUNC_OK) - continue; + res = url_join(href, c->data.html.base_url, &url); + xmlFree(href); + if (res != URL_FUNC_OK) + continue; - LOG(("linked stylesheet %i '%s'", i, url)); + LOG(("linked stylesheet %i '%s'", i, url)); - /* start fetch */ - stylesheet_content = talloc_realloc(c, - c->data.html.stylesheet_content, - struct content *, i + 1); - if (!stylesheet_content) - goto no_memory; - c->data.html.stylesheet_content = stylesheet_content; - c->data.html.stylesheet_content[i] = fetchcache(url, - html_convert_css_callback, - (intptr_t) c, i, c->width, c->height, - true, 0, 0, false, false); - if (!c->data.html.stylesheet_content[i]) - goto no_memory; - c->active++; - fetchcache_go(c->data.html.stylesheet_content[i], - c->url, - html_convert_css_callback, - (intptr_t) c, i, c->width, c->height, - 0, 0, false, c->url); - free(url); - i++; + /* start fetch */ + stylesheet_content = talloc_realloc(c, + c->data.html.stylesheet_content, + struct content *, i + 1); + if (!stylesheet_content) + goto no_memory; + c->data.html.stylesheet_content = stylesheet_content; + c->data.html.stylesheet_content[i] = fetchcache(url, + html_convert_css_callback, + (intptr_t) c, i, c->width, c->height, + true, 0, 0, false, false); + if (!c->data.html.stylesheet_content[i]) + goto no_memory; + c->active++; + fetchcache_go(c->data.html.stylesheet_content[i], + c->url, + html_convert_css_callback, + (intptr_t) c, i, c->width, c->height, + 0, 0, false, c->url); + free(url); + i++; + } else if (strcmp((const char *) node->name, "style") == 0) { + + if (!html_process_style_element(c, node)) + return false; + } } c->data.html.stylesheet_count = i; - if (!html_find_inline_stylesheets(c, html)) - return false; - if (c->data.html.stylesheet_content[STYLESHEET_STYLE] != 0) { - if (css_convert(c->data.html.stylesheet_content[STYLESHEET_STYLE], c->width, + if (css_convert(c->data.html. + stylesheet_content[STYLESHEET_STYLE], c->width, c->height)) { - if (!content_add_user(c->data.html.stylesheet_content[STYLESHEET_STYLE], + if (!content_add_user(c->data.html. + stylesheet_content[STYLESHEET_STYLE], html_convert_css_callback, (intptr_t) c, STYLESHEET_STYLE)) { /* no memory */ @@ -815,47 +838,6 @@ no_memory: /** - * Process inline stylesheets in the document. - * - * \param c content structure - * \param head xml node of html element - * \return true on success, false if an error occurred - */ - -bool html_find_inline_stylesheets(struct content *c, xmlNode *html) -{ - xmlNode *node = html; - - /* depth-first search the tree for style elements */ - while (node) { - if (node->children) { /* 1. children */ - node = node->children; - } else if (node->next) { /* 2. siblings */ - node = node->next; - } else { /* 3. 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, "style") != 0) - continue; - - if (!html_process_style_element(c, node)) - return false; - } - - return true; -} - - -/** * Process an inline stylesheet in the document. * * \param c content structure @@ -1308,7 +1290,7 @@ void html_object_callback(content_msg msg, struct content *object, unsigned int time_before = wallclock(), time_taken; content_reformat(c, c->available_width, c->height); time_taken = wallclock() - time_before; - c->reformat_time = wallclock() + + c->reformat_time = wallclock() + ((time_taken < option_min_reflow_period ? option_min_reflow_period : time_taken * 1.25)); } |