summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parse/language.c282
-rw-r--r--src/parse/parse.c28
-rw-r--r--src/stylesheet.c185
-rw-r--r--src/stylesheet.h13
4 files changed, 356 insertions, 152 deletions
diff --git a/src/parse/language.c b/src/parse/language.c
index c031bd4..f4ba3ee 100644
--- a/src/parse/language.c
+++ b/src/parse/language.c
@@ -51,6 +51,11 @@ static inline css_error handleBlockContent(css_language *c,
static inline css_error handleDeclaration(css_language *c,
const parserutils_vector *vector);
+/* At-rule parsing */
+static inline css_error parseMediaList(css_language *c,
+ const parserutils_vector *vector, int *ctx,
+ uint64_t *media);
+
/* Selector list parsing */
static inline css_error parseClass(css_language *c,
const parserutils_vector *vector, int *ctx,
@@ -267,10 +272,17 @@ css_error handleStartRuleset(css_language *c, const parserutils_vector *vector)
parserutils_error perror;
css_error error;
context_entry entry = { CSS_PARSER_START_RULESET, NULL };
+ context_entry *cur;
+ css_rule *parent_rule = NULL;
css_rule *rule = NULL;
assert(c != NULL);
+ /* Retrieve parent rule from stack, if any */
+ cur = parserutils_stack_get_current(c->context);
+ if (cur != NULL && cur->type != CSS_PARSER_START_STYLESHEET)
+ parent_rule = cur->data;
+
error = css_stylesheet_rule_create(c->sheet, CSS_RULE_SELECTOR, &rule);
if (error != CSS_OK)
return error;
@@ -289,7 +301,7 @@ css_error handleStartRuleset(css_language *c, const parserutils_vector *vector)
return css_error_from_parserutils_error(perror);
}
- error = css_stylesheet_add_rule(c->sheet, rule);
+ error = css_stylesheet_add_rule(c->sheet, rule, parent_rule);
if (error != CSS_OK) {
parserutils_stack_pop(c->context, NULL);
css_stylesheet_rule_destroy(c->sheet, rule);
@@ -333,6 +345,8 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector)
const css_token *token = NULL;
const css_token *atkeyword = NULL;
int32_t ctx = 0;
+ css_rule *rule;
+ css_error error;
/* vector contains: ATKEYWORD ws any0 */
@@ -349,8 +363,6 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector)
if (atkeyword->ilower == c->strings[CHARSET]) {
if (c->state == BEFORE_CHARSET) {
const css_token *charset;
- css_rule *rule;
- css_error error;
/* any0 = STRING */
if (ctx == 0)
@@ -377,7 +389,7 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector)
return error;
}
- error = css_stylesheet_add_rule(c->sheet, rule);
+ error = css_stylesheet_add_rule(c->sheet, rule, NULL);
if (error != CSS_OK) {
css_stylesheet_rule_destroy(c->sheet, rule);
return error;
@@ -392,9 +404,7 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector)
}
} else if (atkeyword->ilower == c->strings[IMPORT]) {
if (c->state != HAD_RULE) {
- css_rule *rule;
- css_media_type media = 0;
- css_error error;
+ uint64_t media = 0;
/* any0 = (STRING | URI) ws
* (IDENT ws (',' ws IDENT ws)* )? */
@@ -407,54 +417,9 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector)
consumeWhitespace(vector, &ctx);
/* Parse media list */
- token = parserutils_vector_iterate(vector, &ctx);
-
- while (token != NULL) {
- if (token->type != CSS_TOKEN_IDENT)
- return CSS_INVALID;
-
- if (token->ilower == c->strings[AURAL]) {
- media |= CSS_MEDIA_AURAL;
- } else if (token->ilower ==
- c->strings[BRAILLE]) {
- media |= CSS_MEDIA_BRAILLE;
- } else if (token->ilower ==
- c->strings[EMBOSSED]) {
- media |= CSS_MEDIA_EMBOSSED;
- } else if (token->ilower ==
- c->strings[HANDHELD]) {
- media |= CSS_MEDIA_HANDHELD;
- } else if (token->ilower ==
- c->strings[PRINT]) {
- media |= CSS_MEDIA_PRINT;
- } else if (token->ilower ==
- c->strings[PROJECTION]) {
- media |= CSS_MEDIA_PROJECTION;
- } else if (token->ilower ==
- c->strings[SCREEN]) {
- media |= CSS_MEDIA_SCREEN;
- } else if (token->ilower ==
- c->strings[SPEECH]) {
- media |= CSS_MEDIA_SPEECH;
- } else if (token->ilower == c->strings[TTY]) {
- media |= CSS_MEDIA_TTY;
- } else if (token->ilower == c->strings[TV]) {
- media |= CSS_MEDIA_TV;
- } else if (token->ilower == c->strings[ALL]) {
- media |= CSS_MEDIA_ALL;
- } else
- return CSS_INVALID;
-
- consumeWhitespace(vector, &ctx);
-
- token = parserutils_vector_iterate(vector,
- &ctx);
- if (token != NULL && tokenIsChar(token, ',') ==
- false)
- return CSS_INVALID;
-
- consumeWhitespace(vector, &ctx);
- }
+ error = parseMediaList(c, vector, &ctx, &media);
+ if (error != CSS_OK)
+ return error;
error = css_stylesheet_rule_create(c->sheet,
CSS_RULE_IMPORT, &rule);
@@ -468,7 +433,7 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector)
return error;
}
- error = css_stylesheet_add_rule(c->sheet, rule);
+ error = css_stylesheet_add_rule(c->sheet, rule, NULL);
if (error != CSS_OK) {
css_stylesheet_rule_destroy(c->sheet, rule);
return error;
@@ -481,22 +446,82 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector)
} else {
return CSS_INVALID;
}
-#if 0
- /** \todo these depend on nested block support, so we'll disable them
- * until we have such a thing. This means that we'll ignore the entire
- * at-rule until then */
} else if (atkeyword->ilower == c->strings[MEDIA]) {
- /** \todo any0 = IDENT ws (',' ws IDENT ws)* */
+ uint64_t media = 0;
+
+ /* any0 = IDENT ws (',' ws IDENT ws)* */
+
+ error = parseMediaList(c, vector, &ctx, &media);
+ if (error != CSS_OK)
+ return error;
+
+ error = css_stylesheet_rule_create(c->sheet,
+ CSS_RULE_MEDIA, &rule);
+ if (error != CSS_OK)
+ return error;
+
+ error = css_stylesheet_rule_set_media(c->sheet, rule, media);
+ if (error != CSS_OK) {
+ css_stylesheet_rule_destroy(c->sheet, rule);
+ return error;
+ }
+
+ error = css_stylesheet_add_rule(c->sheet, rule, NULL);
+ if (error != CSS_OK) {
+ css_stylesheet_rule_destroy(c->sheet, rule);
+ return error;
+ }
+
+ /* Rule is now owned by the sheet,
+ * so no need to destroy it */
+
c->state = HAD_RULE;
} else if (atkeyword->ilower == c->strings[PAGE]) {
- /** \todo any0 = (':' IDENT)? ws */
+ const css_token *token;
+
+ /* any0 = (':' IDENT)? ws */
+
+ error = css_stylesheet_rule_create(c->sheet,
+ CSS_RULE_PAGE, &rule);
+ if (error != CSS_OK)
+ return error;
+
+ consumeWhitespace(vector, &ctx);
+
+ token = parserutils_vector_peek(vector, ctx);
+ if (token != NULL) {
+ css_selector *sel = NULL;
+
+ error = parseSelector(c, vector, &ctx, &sel);
+ if (error != CSS_OK) {
+ css_stylesheet_rule_destroy(c->sheet, rule);
+ return error;
+ }
+
+ error = css_stylesheet_rule_set_page_selector(c->sheet,
+ rule, sel);
+ if (error != CSS_OK) {
+ css_stylesheet_selector_destroy(c->sheet, sel);
+ css_stylesheet_rule_destroy(c->sheet, rule);
+ return error;
+ }
+ }
+
+ error = css_stylesheet_add_rule(c->sheet, rule, NULL);
+ if (error != CSS_OK) {
+ css_stylesheet_rule_destroy(c->sheet, rule);
+ return error;
+ }
+
+ /* Rule is now owned by the sheet,
+ * so no need to destroy it */
+
c->state = HAD_RULE;
-#endif
} else {
return CSS_INVALID;
}
- entry.data = (void *) atkeyword->ilower;
+ entry.data = rule;
perror = parserutils_stack_push(c->context, (void *) &entry);
if (perror != PARSERUTILS_OK) {
@@ -529,36 +554,83 @@ css_error handleEndAtRule(css_language *c, const parserutils_vector *vector)
css_error handleStartBlock(css_language *c, const parserutils_vector *vector)
{
- UNUSED(c);
+ parserutils_error perror;
+ context_entry entry = { CSS_PARSER_START_BLOCK, NULL };
+ context_entry *cur;
+
UNUSED(vector);
- /* We don't care about blocks. In CSS2.1 they're always attached to
- * rulesets or at-rules. */
+ /* If the current item on the stack isn't a block,
+ * then clone its data field. This ensures that the relevant rule
+ * is available when parsing the block contents. */
+ cur = parserutils_stack_get_current(c->context);
+ if (cur != NULL && cur->type != CSS_PARSER_START_BLOCK)
+ entry.data = cur->data;
+
+ perror = parserutils_stack_push(c->context, (void *) &entry);
+ if (perror != PARSERUTILS_OK) {
+ return css_error_from_parserutils_error(perror);
+ }
return CSS_OK;
}
css_error handleEndBlock(css_language *c, const parserutils_vector *vector)
{
- UNUSED(c);
+ parserutils_error perror;
+ context_entry *entry;
+ css_rule *rule;
+
UNUSED(vector);
- /* We don't care about blocks. In CSS 2.1 they're always attached to
- * rulesets or at-rules. */
+ entry = parserutils_stack_get_current(c->context);
+ if (entry == NULL || entry->type != CSS_PARSER_START_BLOCK)
+ return CSS_INVALID;
+
+ rule = entry->data;
+
+ perror = parserutils_stack_pop(c->context, NULL);
+ if (perror != PARSERUTILS_OK) {
+ return css_error_from_parserutils_error(perror);
+ }
+
+ /* If the block we just popped off the stack was associated with a
+ * non-block stack entry, and that entry is not a top-level statement,
+ * then report the end of that entry, too. */
+ if (rule != NULL && rule->ptype != CSS_RULE_PARENT_STYLESHEET) {
+ if (rule->type == CSS_RULE_SELECTOR)
+ return handleEndRuleset(c, vector);
+ }
return CSS_OK;
}
css_error handleBlockContent(css_language *c, const parserutils_vector *vector)
{
- UNUSED(c);
- UNUSED(vector);
+ context_entry *entry;
+ css_rule *rule;
/* In CSS 2.1, block content comprises either declarations (if the
* current block is associated with @page or a selector), or rulesets
* (if the current block is associated with @media). */
- /** \todo implement nested blocks */
+ entry = parserutils_stack_get_current(c->context);
+ if (entry == NULL || entry->data == NULL)
+ return CSS_INVALID;
+
+ rule = entry->data;
+ if (rule == NULL || (rule->type != CSS_RULE_SELECTOR &&
+ rule->type != CSS_RULE_PAGE &&
+ rule->type != CSS_RULE_MEDIA))
+ return CSS_INVALID;
+
+ if (rule->type == CSS_RULE_MEDIA) {
+ /* Expect rulesets */
+ return handleStartRuleset(c, vector);
+ } else {
+ /* Expect declarations */
+ return handleDeclaration(c, vector);
+ }
return CSS_OK;
}
@@ -577,8 +649,7 @@ css_error handleDeclaration(css_language *c, const parserutils_vector *vector)
* + In ruleset
*/
entry = parserutils_stack_get_current(c->context);
- if (entry == NULL || (entry->type != CSS_PARSER_START_RULESET &&
- entry->type != CSS_PARSER_START_ATRULE))
+ if (entry == NULL || entry->data == NULL)
return CSS_INVALID;
rule = entry->data;
@@ -586,6 +657,9 @@ css_error handleDeclaration(css_language *c, const parserutils_vector *vector)
rule->type != CSS_RULE_PAGE))
return CSS_INVALID;
+ /* Strip any leading whitespace (can happen if in nested block) */
+ consumeWhitespace(vector, &ctx);
+
/* IDENT ws ':' ws value
*
* In CSS 2.1, value is any1, so '{' or ATKEYWORD => parse error
@@ -610,6 +684,61 @@ css_error handleDeclaration(css_language *c, const parserutils_vector *vector)
}
/******************************************************************************
+ * At-rule parsing functions *
+ ******************************************************************************/
+css_error parseMediaList(css_language *c,
+ const parserutils_vector *vector, int *ctx,
+ uint64_t *media)
+{
+ uint64_t ret = 0;
+ const css_token *token;
+
+ token = parserutils_vector_iterate(vector, ctx);
+
+ while (token != NULL) {
+ if (token->type != CSS_TOKEN_IDENT)
+ return CSS_INVALID;
+
+ if (token->ilower == c->strings[AURAL]) {
+ ret |= CSS_MEDIA_AURAL;
+ } else if (token->ilower == c->strings[BRAILLE]) {
+ ret |= CSS_MEDIA_BRAILLE;
+ } else if (token->ilower == c->strings[EMBOSSED]) {
+ ret |= CSS_MEDIA_EMBOSSED;
+ } else if (token->ilower == c->strings[HANDHELD]) {
+ ret |= CSS_MEDIA_HANDHELD;
+ } else if (token->ilower == c->strings[PRINT]) {
+ ret |= CSS_MEDIA_PRINT;
+ } else if (token->ilower == c->strings[PROJECTION]) {
+ ret |= CSS_MEDIA_PROJECTION;
+ } else if (token->ilower == c->strings[SCREEN]) {
+ ret |= CSS_MEDIA_SCREEN;
+ } else if (token->ilower == c->strings[SPEECH]) {
+ ret |= CSS_MEDIA_SPEECH;
+ } else if (token->ilower == c->strings[TTY]) {
+ ret |= CSS_MEDIA_TTY;
+ } else if (token->ilower == c->strings[TV]) {
+ ret |= CSS_MEDIA_TV;
+ } else if (token->ilower == c->strings[ALL]) {
+ ret |= CSS_MEDIA_ALL;
+ } else
+ return CSS_INVALID;
+
+ consumeWhitespace(vector, ctx);
+
+ token = parserutils_vector_iterate(vector, ctx);
+ if (token != NULL && tokenIsChar(token, ',') == false)
+ return CSS_INVALID;
+
+ consumeWhitespace(vector, ctx);
+ }
+
+ *media = ret;
+
+ return CSS_OK;
+}
+
+/******************************************************************************
* Selector list parsing functions *
******************************************************************************/
@@ -969,6 +1098,9 @@ css_error parseSelectorList(css_language *c, const parserutils_vector *vector,
css_selector *selector = NULL;
int ctx = 0;
+ /* Strip any leading whitespace (can happen if in nested block) */
+ consumeWhitespace(vector, &ctx);
+
/* selector_list -> selector [ ',' ws selector ]* */
error = parseSelector(c, vector, &ctx, &selector);
diff --git a/src/parse/parse.c b/src/parse/parse.c
index f7fd2fb..452658f 100644
--- a/src/parse/parse.c
+++ b/src/parse/parse.c
@@ -1273,7 +1273,7 @@ css_error parseBlockContent(css_parser *parser)
if (parser->event != NULL) {
parser->event(
CSS_PARSER_BLOCK_CONTENT,
- parser->tokens,
+ parser->tokens,
parser->event_pw);
}
@@ -1282,6 +1282,30 @@ css_error parseBlockContent(css_parser *parser)
} else if (lwc_string_length(token->ilower) == 1 &&
lwc_string_data(token->ilower)[0] == ';') {
/* Grammar ambiguity. Assume semi */
+ error = pushBack(parser, token);
+ if (error != CSS_OK)
+ return error;
+
+#if !defined(NDEBUG) && defined(DEBUG_EVENTS)
+ parserutils_vector_dump(parser->tokens,
+ __func__, tprinter);
+#endif
+ if (parser->event != NULL) {
+ parser->event(
+ CSS_PARSER_BLOCK_CONTENT,
+ parser->tokens,
+ parser->event_pw);
+ }
+
+ error = getToken(parser, &token);
+ if (error != CSS_OK)
+ return error;
+
+ unref_interned_strings_in_tokens(
+ parser);
+ parserutils_vector_clear(
+ parser->tokens);
+
state->substate = WS;
} else if (lwc_string_length(token->ilower) == 1 &&
lwc_string_data(token->ilower)[0] == '}') {
@@ -2298,7 +2322,7 @@ static void tprinter(void *token)
css_token *t = token;
if (t->data.data)
- printf("%d: %.*s", t->type, t->data.len, t->data.data);
+ printf("%d: %.*s", t->type, (int) t->data.len, t->data.data);
else
printf("%d", t->type);
}
diff --git a/src/stylesheet.c b/src/stylesheet.c
index 41a3341..c48240a 100644
--- a/src/stylesheet.c
+++ b/src/stylesheet.c
@@ -281,7 +281,8 @@ css_error css_stylesheet_next_pending_import(css_stylesheet *parent,
break;
if (r->type == CSS_RULE_IMPORT && i->sheet == NULL) {
- *url = lwc_context_string_ref(parent->dictionary, i->url);
+ *url = lwc_context_string_ref(parent->dictionary,
+ i->url);
*media = i->media;
return CSS_OK;
@@ -604,9 +605,14 @@ css_error css_stylesheet_selector_destroy(css_stylesheet *sheet,
d = c->combinator;
for (detail = &c->data; detail;) {
- lwc_context_string_unref(sheet->dictionary, detail->name);
- if (detail->value != NULL)
- lwc_context_string_unref(sheet->dictionary, detail->value);
+ lwc_context_string_unref(sheet->dictionary,
+ detail->name);
+
+ if (detail->value != NULL) {
+ lwc_context_string_unref(sheet->dictionary,
+ detail->value);
+ }
+
if (detail->next)
detail++;
else
@@ -618,8 +624,12 @@ css_error css_stylesheet_selector_destroy(css_stylesheet *sheet,
for (detail = &selector->data; detail;) {
lwc_context_string_unref(sheet->dictionary, detail->name);
- if (detail->value != NULL)
- lwc_context_string_unref(sheet->dictionary, detail->value);
+
+ if (detail->value != NULL) {
+ lwc_context_string_unref(sheet->dictionary,
+ detail->value);
+ }
+
if (detail->next)
detail++;
else
@@ -911,20 +921,12 @@ css_error css_stylesheet_rule_destroy(css_stylesheet *sheet, css_rule *rule)
case CSS_RULE_PAGE:
{
css_rule_page *page = (css_rule_page *) rule;
- uint32_t i;
-
- for (i = 0; i < rule->items; i++) {
- css_selector *sel = page->selectors[i];
-
- /* Detach from rule */
- sel->rule = NULL;
- css_stylesheet_selector_destroy(sheet, sel);
+ if (page->selector != NULL) {
+ page->selector->rule = NULL;
+ css_stylesheet_selector_destroy(sheet, page->selector);
}
- if (page->selectors != NULL)
- sheet->alloc(page->selectors, 0, sheet->pw);
-
if (page->style != NULL)
css_stylesheet_style_destroy(sheet, page->style);
}
@@ -1085,13 +1087,70 @@ css_error css_stylesheet_rule_set_nascent_import(css_stylesheet *sheet,
}
/**
+ * Set the media of an @media rule
+ *
+ * \param sheet The stylesheet context
+ * \param rule The rule to add to (must be of type CSS_RULE_MEDIA)
+ * \param media The applicable media types for the rule
+ * \return CSS_OK on success, appropriate error otherwise
+ */
+css_error css_stylesheet_rule_set_media(css_stylesheet *sheet,
+ css_rule *rule, uint64_t media)
+{
+ css_rule_media *r = (css_rule_media *) rule;
+
+ if (sheet == NULL || rule == NULL)
+ return CSS_BADPARM;
+
+ /* Ensure rule is a CSS_RULE_MEDIA */
+ assert(rule->type == CSS_RULE_MEDIA);
+
+ /* Set the rule's media */
+ r->media = media;
+
+ return CSS_OK;
+}
+
+/**
+ * Set an @page rule selector
+ *
+ * \param sheet The stylesheet context
+ * \param rule The rule to add to (must be of type CSS_RULE_PAGE)
+ * \param selector The page selector
+ * \return CSS_OK on success, appropriate error otherwise
+ */
+css_error css_stylesheet_rule_set_page_selector(css_stylesheet *sheet,
+ css_rule *rule, css_selector *selector)
+{
+ css_rule_page *r = (css_rule_page *) rule;
+
+ if (sheet == NULL || rule == NULL || selector == NULL)
+ return CSS_BADPARM;
+
+ /* Ensure rule is a CSS_RULE_PAGE */
+ assert(rule->type == CSS_RULE_PAGE);
+
+ /** \todo validate selector */
+
+ /* Set the rule's selector */
+ r->selector = selector;
+
+ /* Set selector's rule field */
+ selector->rule = rule;
+
+ return CSS_OK;
+}
+
+/**
* Add a rule to a stylesheet
*
- * \param sheet The stylesheet to add to
- * \param rule The rule to add
+ * \param sheet The stylesheet to add to
+ * \param rule The rule to add
+ * \param parent The parent rule, or NULL for a top-level rule
* \return CSS_OK on success, appropriate error otherwise
*/
-css_error css_stylesheet_add_rule(css_stylesheet *sheet, css_rule *rule)
+css_error css_stylesheet_add_rule(css_stylesheet *sheet, css_rule *rule,
+ css_rule *parent)
{
css_error error;
@@ -1108,19 +1167,41 @@ css_error css_stylesheet_add_rule(css_stylesheet *sheet, css_rule *rule)
if (error != CSS_OK)
return error;
- /* Add rule to sheet */
- rule->ptype = CSS_RULE_PARENT_STYLESHEET;
- rule->parent = sheet;
- sheet->rule_count++;
-
- if (sheet->last_rule == NULL) {
- rule->prev = rule->next = NULL;
- sheet->rule_list = sheet->last_rule = rule;
+ if (parent != NULL) {
+ css_rule_media *media = (css_rule_media *) parent;
+
+ /* Parent must be an @media rule, or NULL */
+ assert(parent->type == CSS_RULE_MEDIA);
+
+ /* Add rule to parent */
+ rule->ptype = CSS_RULE_PARENT_RULE;
+ rule->parent = parent;
+ sheet->rule_count++;
+
+ if (media->last_child == NULL) {
+ rule->prev = rule->next = NULL;
+ media->first_child = media->last_child = rule;
+ } else {
+ media->last_child->next = rule;
+ rule->prev = media->last_child;
+ rule->next = NULL;
+ media->last_child = rule;
+ }
} else {
- sheet->last_rule->next = rule;
- rule->prev = sheet->last_rule;
- rule->next = NULL;
- sheet->last_rule = rule;
+ /* Add rule to sheet */
+ rule->ptype = CSS_RULE_PARENT_STYLESHEET;
+ rule->parent = sheet;
+ sheet->rule_count++;
+
+ if (sheet->last_rule == NULL) {
+ rule->prev = rule->next = NULL;
+ sheet->rule_list = sheet->last_rule = rule;
+ } else {
+ sheet->last_rule->next = rule;
+ rule->prev = sheet->last_rule;
+ rule->next = NULL;
+ sheet->last_rule = rule;
+ }
}
/** \todo needs to trigger some event announcing styles have changed */
@@ -1225,7 +1306,7 @@ css_error _add_selectors(css_stylesheet *sheet, css_rule *rule)
for (r = m->first_child; r != NULL; r = r->next) {
error = _add_selectors(sheet, r);
if (error != CSS_OK) {
- /* Failed, revert out changes */
+ /* Failed, revert our changes */
for (r = r->prev; r != NULL; r = r->prev) {
_remove_selectors(sheet, r);
}
@@ -1235,30 +1316,6 @@ css_error _add_selectors(css_stylesheet *sheet, css_rule *rule)
}
}
break;
- case CSS_RULE_PAGE:
- {
- css_rule_page *p = (css_rule_page *) rule;
- int32_t i;
-
- for (i = 0; i < rule->items; i++) {
- css_selector *sel = p->selectors[i];
-
- error = css_selector_hash_insert(sheet->selectors, sel);
- if (error != CSS_OK) {
- /* Failed, revert our changes */
- for (i--; i >= 0; i--) {
- sel = p->selectors[i];
-
- /* Ignore errors */
- css_selector_hash_remove(
- sheet->selectors, sel);
- }
-
- return error;
- }
- }
- }
- break;
}
return CSS_OK;
@@ -1305,20 +1362,6 @@ css_error _remove_selectors(css_stylesheet *sheet, css_rule *rule)
}
}
break;
- case CSS_RULE_PAGE:
- {
- css_rule_page *p = (css_rule_page *) rule;
- int32_t i;
-
- for (i = 0; i < rule->items; i++) {
- css_selector *sel = p->selectors[i];
-
- error = css_selector_hash_remove(sheet->selectors, sel);
- if (error != CSS_OK)
- return error;
- }
- }
- break;
}
return CSS_OK;
diff --git a/src/stylesheet.h b/src/stylesheet.h
index 4cb890e..1fab87e 100644
--- a/src/stylesheet.h
+++ b/src/stylesheet.h
@@ -111,7 +111,7 @@ typedef struct css_rule_selector {
typedef struct css_rule_media {
css_rule base;
- uint32_t media;
+ uint64_t media;
css_rule *first_child;
css_rule *last_child;
@@ -126,7 +126,7 @@ typedef struct css_rule_font_face {
typedef struct css_rule_page {
css_rule base;
- css_selector **selectors;
+ css_selector *selector;
css_style *style;
} css_rule_page;
@@ -213,9 +213,14 @@ css_error css_stylesheet_rule_set_charset(css_stylesheet *sheet,
css_error css_stylesheet_rule_set_nascent_import(css_stylesheet *sheet,
css_rule *rule, lwc_string *url, uint64_t media);
-/** \todo registering other rule-type data with css_rules */
+css_error css_stylesheet_rule_set_media(css_stylesheet *sheet,
+ css_rule *rule, uint64_t media);
+
+css_error css_stylesheet_rule_set_page_selector(css_stylesheet *sheet,
+ css_rule *rule, css_selector *sel);
-css_error css_stylesheet_add_rule(css_stylesheet *sheet, css_rule *rule);
+css_error css_stylesheet_add_rule(css_stylesheet *sheet, css_rule *rule,
+ css_rule *parent);
css_error css_stylesheet_remove_rule(css_stylesheet *sheet, css_rule *rule);
#endif