From 7b78ef336122f28c2d2b4cce253683941a31b797 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sat, 24 Sep 2016 12:44:28 +0100 Subject: Style: Fix ignoring of STYLE elements with non-screen media. We were handling the STYLE tag getting added in the dom_default_action_DOMSubtreeModified_cb callback, however, the media attribute dadn't been added by that point. We now check it in the dom_default_action_DOMNodeInserted_cb callback, at which time the media attribute is available for checking. Note, we should probably store the media type in the html_stylesheet structure, but for now we just have an `unused` boolean. Also, it may be possible to optimise to avoid parsing non- screen media STYLE element data if we could detect the media earlier. --- render/html.c | 3 +++ render/html.h | 1 + render/html_css.c | 38 ++++++++++++++++++++++++++++++++++++++ render/html_internal.h | 1 + 4 files changed, 43 insertions(+) diff --git a/render/html.c b/render/html.c index 5a2aa4f98..3ddcdc3e1 100644 --- a/render/html.c +++ b/render/html.c @@ -670,6 +670,9 @@ dom_default_action_DOMNodeInserted_cb(struct dom_event *evt, void *pw) case DOM_HTML_ELEMENT_TYPE_IMG: html_process_img(htmlc, (dom_node *) node); break; + case DOM_HTML_ELEMENT_TYPE_STYLE: + html_css_process_style(htmlc, (dom_node *) node); + break; default: break; } diff --git a/render/html.h b/render/html.h index 1052cb26e..871eb331e 100644 --- a/render/html.h +++ b/render/html.h @@ -60,6 +60,7 @@ struct html_stylesheet { struct dom_node *node; /**< dom node associated with sheet */ struct hlcache_handle *sheet; bool modified; + bool unused; }; /** diff --git a/render/html_css.c b/render/html_css.c index ba887167e..4d5469361 100644 --- a/render/html_css.c +++ b/render/html_css.c @@ -239,6 +239,7 @@ html_create_style_element(html_content *c, dom_node *style) c->stylesheets[c->stylesheet_count].node = dom_node_ref(style); c->stylesheets[c->stylesheet_count].sheet = NULL; c->stylesheets[c->stylesheet_count].modified = false; + c->stylesheets[c->stylesheet_count].unused = false; c->stylesheet_count++; return c->stylesheets + (c->stylesheet_count - 1); @@ -323,6 +324,37 @@ bool html_css_update_style(html_content *c, dom_node *style) return true; } +bool html_css_process_style(html_content *c, dom_node *node) +{ + unsigned int i; + dom_string *val; + dom_exception exc; + struct html_stylesheet *s; + + /* Find sheet */ + for (i = 0, s = c->stylesheets; i != c->stylesheet_count; i++, s++) { + if (s->node == node) + break; + } + + /* Should already exist */ + if (i == c->stylesheet_count) { + return false; + } + + exc = dom_element_get_attribute(node, corestring_dom_media, &val); + if (exc == DOM_NO_ERR && val != NULL) { + if (strcasestr(dom_string_data(val), "screen") == NULL && + strcasestr(dom_string_data(val), + "all") == NULL) { + s->unused = true; + } + dom_string_unref(val); + } + + return true; +} + bool html_css_process_link(html_content *htmlc, dom_node *node) { dom_string *rel, *type_attr, *media, *href; @@ -400,6 +432,7 @@ bool html_css_process_link(html_content *htmlc, dom_node *node) htmlc->stylesheets = stylesheets; htmlc->stylesheets[htmlc->stylesheet_count].node = NULL; htmlc->stylesheets[htmlc->stylesheet_count].modified = false; + htmlc->stylesheets[htmlc->stylesheet_count].unused = false; /* start fetch */ child.charset = htmlc->encoding; @@ -584,6 +617,11 @@ html_css_new_selection_context(html_content *c, css_select_ctx **ret_select_ctx) css_stylesheet *sheet = NULL; css_origin origin = CSS_ORIGIN_AUTHOR; + /* Filter out stylesheets for non-screen media. */ + if (hsheet->unused) { + continue; + } + if (i < STYLESHEET_USER) { origin = CSS_ORIGIN_UA; } else if (i < STYLESHEET_START) { diff --git a/render/html_internal.h b/render/html_internal.h index f0e98158f..fd65707ce 100644 --- a/render/html_internal.h +++ b/render/html_internal.h @@ -321,6 +321,7 @@ nserror html_css_quirks_stylesheets(html_content *c); nserror html_css_free_stylesheets(html_content *html); bool html_css_process_link(html_content *htmlc, dom_node *node); +bool html_css_process_style(html_content *htmlc, dom_node *node); bool html_css_update_style(html_content *c, dom_node *style); nserror html_css_new_selection_context(html_content *c, -- cgit v1.2.3