summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <michael.drake@codethink.co.uk>2016-02-05 10:48:45 (GMT)
committer Michael Drake <michael.drake@codethink.co.uk>2016-02-05 10:48:45 (GMT)
commitd4b2c5ca526b7a4574aeca48236cd410efd74b74 (patch)
treee34db76f0bbb2e4f975c91eb2ed114ff856acc84
parent842120bede2ef48f04f8bb3a1c8967d0d7457cac (diff)
parent761a9a99b72cfd2aa9e4d159c1bbd859cf70bd3f (diff)
downloadlibcss-d4b2c5ca526b7a4574aeca48236cd410efd74b74.tar.gz
libcss-d4b2c5ca526b7a4574aeca48236cd410efd74b74.tar.bz2
Merge branch 'tlsa/upfront-hints'
-rw-r--r--include/libcss/hint.h3
-rw-r--r--include/libcss/select.h4
-rw-r--r--src/select/select.c69
-rw-r--r--test/select-common.c13
4 files changed, 47 insertions, 42 deletions
diff --git a/include/libcss/hint.h b/include/libcss/hint.h
index c3e928d..629d2f6 100644
--- a/include/libcss/hint.h
+++ b/include/libcss/hint.h
@@ -49,7 +49,8 @@ typedef struct css_hint {
lwc_string **strings;
} data;
- uint8_t status;
+ uint32_t prop; /**< Property index */
+ uint8_t status; /**< Property value */
} css_hint;
#ifdef __cplusplus
diff --git a/include/libcss/select.h b/include/libcss/select.h
index d504e81..bd2fed2 100644
--- a/include/libcss/select.h
+++ b/include/libcss/select.h
@@ -117,8 +117,8 @@ typedef struct css_select_handler {
css_error (*node_is_lang)(void *pw, void *node,
lwc_string *lang, bool *match);
- css_error (*node_presentational_hint)(void *pw, void *node,
- uint32_t property, css_hint *hint);
+ css_error (*node_presentational_hint)(void *pw, void *node,
+ uint32_t *nhints, css_hint **hints);
css_error (*ua_default_for_property)(void *pw, uint32_t property,
css_hint *hint);
diff --git a/src/select/select.c b/src/select/select.c
index 17dff31..2c14eb6 100644
--- a/src/select/select.c
+++ b/src/select/select.c
@@ -110,7 +110,7 @@ typedef struct css_select_rule_source {
} css_select_rule_source;
-static css_error set_hint(css_select_state *state, uint32_t prop);
+static css_error set_hint(css_select_state *state, css_hint *hint);
static css_error set_initial(css_select_state *state,
uint32_t prop, css_pseudo_element pseudo,
void *parent);
@@ -433,10 +433,11 @@ css_error css_select_style(css_select_ctx *ctx, void *node,
css_select_handler *handler, void *pw,
css_select_results **result)
{
- uint32_t i, j;
+ uint32_t i, j, nhints;
css_error error;
css_select_state state;
void *parent = NULL;
+ css_hint *hints = NULL;
css_bloom *bloom = NULL;
css_bloom *parent_bloom = NULL;
@@ -536,6 +537,29 @@ css_error css_select_style(css_select_ctx *ctx, void *node,
if (error != CSS_OK)
goto cleanup;
+ /* Apply presentational hints */
+ error = handler->node_presentational_hint(pw, node, &nhints, &hints);
+ if (error != CSS_OK)
+ goto cleanup;
+ if (nhints > 0) {
+ /* Ensure that the appropriate computed style exists */
+ struct css_computed_style *computed_style =
+ state.results->styles[CSS_PSEUDO_ELEMENT_NONE];
+ if (computed_style == NULL) {
+ error = css_computed_style_create(&computed_style);
+ if (error != CSS_OK)
+ return error;
+ }
+ state.results->styles[CSS_PSEUDO_ELEMENT_NONE] = computed_style;
+ state.computed = computed_style;
+
+ for (i = 0; i < nhints; i++) {
+ error = set_hint(&state, &hints[i]);
+ if (error != CSS_OK)
+ goto cleanup;
+ }
+ }
+
/* Iterate through the top-level stylesheets, selecting styles
* from those which apply to our current media requirements and
* are not disabled */
@@ -577,8 +601,7 @@ css_error css_select_style(css_select_ctx *ctx, void *node,
}
}
- /* Take account of presentational hints and fix up any remaining
- * unset properties. */
+ /* Fix up any remaining unset properties. */
/* Base element */
state.current_pseudo = CSS_PSEUDO_ELEMENT_NONE;
@@ -587,17 +610,6 @@ css_error css_select_style(css_select_ctx *ctx, void *node,
const prop_state *prop =
&state.props[i][CSS_PSEUDO_ELEMENT_NONE];
- /* Apply presentational hints if the property is unset or
- * the existing property value did not come from an author
- * stylesheet or a user sheet using !important. */
- if (prop->set == false ||
- (prop->origin != CSS_ORIGIN_AUTHOR &&
- prop->important == false)) {
- error = set_hint(&state, i);
- if (error != CSS_OK)
- goto cleanup;
- }
-
/* If the property is still unset or it's set to inherit
* and we're the root element, then set it to its initial
* value. */
@@ -1118,32 +1130,23 @@ void destroy_strings(css_select_ctx *ctx)
lwc_string_unref(ctx->after);
}
-css_error set_hint(css_select_state *state, uint32_t prop)
+css_error set_hint(css_select_state *state, css_hint *hint)
{
- css_hint hint;
+ uint32_t prop = hint->prop;
+ prop_state *existing = &state->props[prop][CSS_PSEUDO_ELEMENT_NONE];
css_error error;
- /* Initialise hint */
- memset(&hint, 0, sizeof(css_hint));
-
- /* Retrieve this property's hint from the client */
- error = state->handler->node_presentational_hint(state->pw,
- state->node, prop, &hint);
- if (error != CSS_OK)
- return (error == CSS_PROPERTY_NOT_SET) ? CSS_OK : error;
-
/* Hint defined -- set it in the result */
- error = prop_dispatch[prop].set_from_hint(&hint, state->computed);
+ error = prop_dispatch[prop].set_from_hint(hint, state->computed);
if (error != CSS_OK)
return error;
/* Keep selection state in sync with reality */
- state->props[prop][CSS_PSEUDO_ELEMENT_NONE].set = 1;
- state->props[prop][CSS_PSEUDO_ELEMENT_NONE].specificity = 0;
- state->props[prop][CSS_PSEUDO_ELEMENT_NONE].origin = CSS_ORIGIN_AUTHOR;
- state->props[prop][CSS_PSEUDO_ELEMENT_NONE].important = 0;
- state->props[prop][CSS_PSEUDO_ELEMENT_NONE].inherit =
- (hint.status == 0);
+ existing->set = 1;
+ existing->specificity = 0;
+ existing->origin = CSS_ORIGIN_AUTHOR;
+ existing->important = 0;
+ existing->inherit = (hint->status == 0);
return CSS_OK;
}
diff --git a/test/select-common.c b/test/select-common.c
index f1762a6..432bd54 100644
--- a/test/select-common.c
+++ b/test/select-common.c
@@ -156,9 +156,9 @@ static css_error node_is_target(void *pw, void *node, bool *match);
static css_error node_is_lang(void *pw, void *node,
lwc_string *lang, bool *match);
static css_error node_presentational_hint(void *pw, void *node,
- uint32_t property, css_hint *hint);
+ uint32_t *nhints, css_hint **hints);
static css_error ua_default_for_property(void *pw, uint32_t property,
- css_hint *hint);
+ css_hint *hints);
static css_error compute_font_size(void *pw, const css_hint *parent,
css_hint *size);
static css_error set_libcss_node_data(void *pw, void *n,
@@ -1566,14 +1566,15 @@ css_error node_is_lang(void *pw, void *n,
}
css_error node_presentational_hint(void *pw, void *node,
- uint32_t property, css_hint *hint)
+ uint32_t *nhints, css_hint **hints)
{
UNUSED(pw);
UNUSED(node);
- UNUSED(property);
- UNUSED(hint);
- return CSS_PROPERTY_NOT_SET;
+ *nhints = 0;
+ *hints = NULL;
+
+ return CSS_OK;
}
css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)