diff --git a/render/html.h b/render/html.h
index a17e4a50b..162541d72 100644
--- a/render/html.h
+++ b/render/html.h
@@ -56,9 +56,9 @@ struct selection;
* Container for stylesheets used by an HTML document
*/
struct html_stylesheet {
- /** Type of sheet */
struct dom_node *node; /**< dom node associated with sheet */
struct hlcache_handle *sheet;
+ bool modified;
};
/**
diff --git a/render/html_css.c b/render/html_css.c
index fbbcd6d3a..a87e0d512 100644
--- a/render/html_css.c
+++ b/render/html_css.c
@@ -33,6 +33,7 @@
#include "utils/corestrings.h"
#include "utils/config.h"
#include "utils/log.h"
+#include "utils/schedule.h"
static nsurl *html_default_stylesheet_url;
static nsurl *html_adblock_stylesheet_url;
@@ -254,35 +255,19 @@ 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->stylesheet_count++;
return c->stylesheets + (c->stylesheet_count - 1);
}
-bool html_css_update_style(html_content *c, dom_node *style)
+static bool html_css_process_modified_style(html_content *c,
+ struct html_stylesheet *s)
{
- nserror error;
- unsigned int i;
- struct html_stylesheet *s;
hlcache_handle *sheet = NULL;
+ nserror error;
- /* Find sheet */
- for (i = 0, s = c->stylesheets; i != c->stylesheet_count; i++, s++) {
- if (s->node == style)
- break;
- }
- if (i == c->stylesheet_count) {
- s = html_create_style_element(c, style);
- }
- if (s == NULL) {
- LOG(("Could not find or create inline stylesheet for %p",
- style));
- return false;
- }
-
- LOG(("Found sheet %p slot %d for node %p", s, i, style));
-
- error = html_stylesheet_from_domnode(c, style, &sheet);
+ error = html_stylesheet_from_domnode(c, s->node, &sheet);
if (error != NSERROR_OK) {
LOG(("Failed to update sheet"));
content_broadcast_errorcode(&c->base, error);
@@ -306,6 +291,53 @@ bool html_css_update_style(html_content *c, dom_node *style)
s->sheet = sheet;
}
+ s->modified = false;
+
+ return true;
+}
+
+static void html_css_process_modified_styles(void *pw)
+{
+ html_content *c = pw;
+ struct html_stylesheet *s;
+ unsigned int i;
+ bool all_done = true;
+
+ for (i = 0, s = c->stylesheets; i != c->stylesheet_count; i++, s++) {
+ if (c->stylesheets[i].modified) {
+ all_done &= html_css_process_modified_style(c, s);
+ }
+ }
+
+ /* If we failed to process any sheet, schedule a retry */
+ if (all_done == false) {
+ schedule(100, html_css_process_modified_styles, c);
+ }
+}
+
+bool html_css_update_style(html_content *c, dom_node *style)
+{
+ unsigned int i;
+ struct html_stylesheet *s;
+
+ /* Find sheet */
+ for (i = 0, s = c->stylesheets; i != c->stylesheet_count; i++, s++) {
+ if (s->node == style)
+ break;
+ }
+ if (i == c->stylesheet_count) {
+ s = html_create_style_element(c, style);
+ }
+ if (s == NULL) {
+ LOG(("Could not find or create inline stylesheet for %p",
+ style));
+ return false;
+ }
+
+ s->modified = true;
+
+ schedule(0, html_css_process_modified_styles, c);
+
return true;
}
@@ -384,6 +416,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;
/* start fetch */
child.charset = htmlc->encoding;
@@ -435,6 +468,8 @@ nserror html_css_free_stylesheets(html_content *html)
{
unsigned int i;
+ schedule_remove(html_css_process_modified_styles, html);
+
for (i = 0; i != html->stylesheet_count; i++) {
if (html->stylesheets[i].sheet != NULL) {
hlcache_handle_release(html->stylesheets[i].sheet);