summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/select/computed.c78
-rw-r--r--src/select/dispatch.c8
-rw-r--r--src/select/propset.h157
3 files changed, 213 insertions, 30 deletions
diff --git a/src/select/computed.c b/src/select/computed.c
index 72d3922..57f50cb 100644
--- a/src/select/computed.c
+++ b/src/select/computed.c
@@ -114,17 +114,69 @@ css_error css_computed_style_destroy(css_computed_style *style)
if (style->uncommon != NULL) {
if (style->uncommon->counter_increment != NULL) {
+ css_computed_counter *c;
+
+ for (c = style->uncommon->counter_increment;
+ c->name != NULL; c++) {
+ lwc_string_unref(c->name);
+ }
+
style->alloc(style->uncommon->counter_increment, 0,
style->pw);
}
if (style->uncommon->counter_reset != NULL) {
+ css_computed_counter *c;
+
+ for (c = style->uncommon->counter_reset;
+ c->name != NULL; c++) {
+ lwc_string_unref(c->name);
+ }
+
style->alloc(style->uncommon->counter_reset, 0,
style->pw);
}
- if (style->uncommon->cursor != NULL)
+ if (style->uncommon->cursor != NULL) {
+ lwc_string **s;
+
+ for (s = style->uncommon->cursor; *s != NULL; s++) {
+ lwc_string_unref(*s);
+ }
+
style->alloc(style->uncommon->cursor, 0, style->pw);
+ }
+
+ if (style->uncommon->content != NULL) {
+ css_computed_content_item *c;
+
+ for (c = style->uncommon->content;
+ c->type != CSS_COMPUTED_CONTENT_NONE;
+ c++) {
+ switch (c->type) {
+ case CSS_COMPUTED_CONTENT_STRING:
+ lwc_string_unref(c->data.string);
+ break;
+ case CSS_COMPUTED_CONTENT_URI:
+ lwc_string_unref(c->data.uri);
+ break;
+ case CSS_COMPUTED_CONTENT_ATTR:
+ lwc_string_unref(c->data.attr);
+ break;
+ case CSS_COMPUTED_CONTENT_COUNTER:
+ lwc_string_unref(c->data.counter.name);
+ break;
+ case CSS_COMPUTED_CONTENT_COUNTERS:
+ lwc_string_unref(c->data.counters.name);
+ lwc_string_unref(c->data.counters.sep);
+ break;
+ default:
+ break;
+ }
+ }
+
+ style->alloc(style->uncommon->content, 0, style->pw);
+ }
style->alloc(style->uncommon, 0, style->pw);
}
@@ -137,11 +189,31 @@ css_error css_computed_style_destroy(css_computed_style *style)
style->alloc(style->aural, 0, style->pw);
}
- if (style->font_family != NULL)
+ if (style->font_family != NULL) {
+ lwc_string **s;
+
+ for (s = style->font_family; *s != NULL; s++) {
+ lwc_string_unref(*s);
+ }
+
style->alloc(style->font_family, 0, style->pw);
+ }
+
+ if (style->quotes != NULL) {
+ lwc_string **s;
+
+ for (s = style->quotes; *s != NULL; s++) {
+ lwc_string_unref(*s);
+ }
- if (style->quotes != NULL)
style->alloc(style->quotes, 0, style->pw);
+ }
+
+ if (style->list_style_image != NULL)
+ lwc_string_unref(style->list_style_image);
+
+ if (style->background_image != NULL)
+ lwc_string_unref(style->background_image);
style->alloc(style, 0, style->pw);
diff --git a/src/select/dispatch.c b/src/select/dispatch.c
index 113ea0f..a0ac4aa 100644
--- a/src/select/dispatch.c
+++ b/src/select/dispatch.c
@@ -12,10 +12,10 @@
* Dispatch table for properties, indexed by opcode
*/
#define PROPERTY_FUNCS(pname) \
- cascade_##pname , \
- set_##pname##_from_hint, \
- initial_##pname , \
- compose_##pname , \
+ cascade_##pname, \
+ set_##pname##_from_hint, \
+ initial_##pname, \
+ compose_##pname, \
destroy_##pname
struct prop_table prop_dispatch[CSS_N_PROPERTIES] = {
diff --git a/src/select/propset.h b/src/select/propset.h
index 69dba45..97d76b9 100644
--- a/src/select/propset.h
+++ b/src/select/propset.h
@@ -174,22 +174,32 @@ static inline css_error set_counter_increment(
css_computed_counter *counters)
{
uint8_t *bits;
+ css_computed_counter *oldcounters;
+ css_computed_counter *c;
ENSURE_UNCOMMON;
bits = &style->uncommon->bits[COUNTER_INCREMENT_INDEX];
+ oldcounters = style->uncommon->counter_increment;
/* 1bit: type */
*bits = (*bits & ~COUNTER_INCREMENT_MASK) |
((type & 0x1) << COUNTER_INCREMENT_SHIFT);
- /* Free existing array */
- if (style->uncommon->counter_increment != NULL &&
- style->uncommon->counter_increment != counters)
- style->alloc(style->uncommon->counter_increment, 0, style->pw);
+ for (c = counters; c != NULL && c->name != NULL; c++)
+ lwc_string_ref(c->name);
style->uncommon->counter_increment = counters;
+ /* Free existing array */
+ if (oldcounters != NULL) {
+ for (c = oldcounters; c->name != NULL; c++)
+ lwc_string_unref(c->name);
+
+ if (oldcounters != counters)
+ style->alloc(oldcounters, 0, style->pw);
+ }
+
return CSS_OK;
}
#undef COUNTER_INCREMENT_MASK
@@ -204,22 +214,32 @@ static inline css_error set_counter_reset(
css_computed_counter *counters)
{
uint8_t *bits;
+ css_computed_counter *oldcounters;
+ css_computed_counter *c;
ENSURE_UNCOMMON;
bits = &style->uncommon->bits[COUNTER_RESET_INDEX];
+ oldcounters = style->uncommon->counter_reset;
/* 1bit: type */
*bits = (*bits & ~COUNTER_RESET_MASK) |
((type & 0x1) << COUNTER_RESET_SHIFT);
- /* Free existing array */
- if (style->uncommon->counter_reset != NULL &&
- style->uncommon->counter_reset != counters)
- style->alloc(style->uncommon->counter_reset, 0, style->pw);
+ for (c = counters; c != NULL && c->name != NULL; c++)
+ lwc_string_ref(c->name);
style->uncommon->counter_reset = counters;
+ /* Free existing array */
+ if (oldcounters != NULL) {
+ for (c = oldcounters; c->name != NULL; c++)
+ lwc_string_unref(c->name);
+
+ if (oldcounters != counters)
+ style->alloc(oldcounters, 0, style->pw);
+ }
+
return CSS_OK;
}
#undef COUNTER_RESET_MASK
@@ -234,21 +254,32 @@ static inline css_error set_cursor(
lwc_string **urls)
{
uint8_t *bits;
+ lwc_string **oldurls;
+ lwc_string **s;
ENSURE_UNCOMMON;
bits = &style->uncommon->bits[CURSOR_INDEX];
+ oldurls = style->uncommon->cursor;
/* 5bits: type */
*bits = (*bits & ~CURSOR_MASK) |
((type & 0x1f) << CURSOR_SHIFT);
- /* Free existing array */
- if (style->uncommon->cursor != NULL && style->uncommon->cursor != urls)
- style->alloc(style->uncommon->cursor, 0, style->pw);
+ for (s = urls; s != NULL && *s != NULL; s++)
+ lwc_string_ref(*s);
style->uncommon->cursor = urls;
+ /* Free existing array */
+ if (oldurls != NULL) {
+ for (s = oldurls; *s != NULL; s++)
+ lwc_string_unref(*s);
+
+ if (oldurls != urls)
+ style->alloc(oldurls, 0, style->pw);
+ }
+
return CSS_OK;
}
#undef CURSOR_MASK
@@ -322,22 +353,74 @@ static inline css_error set_content(
css_computed_content_item *content)
{
uint8_t *bits;
+ css_computed_content_item *oldcontent;
+ css_computed_content_item *c;
ENSURE_UNCOMMON;
/* 2bits: type */
bits = &style->uncommon->bits[CONTENT_INDEX];
+ oldcontent = style->uncommon->content;
*bits = (*bits & ~CONTENT_MASK) |
((type & 0x3) << CONTENT_SHIFT);
- /* Free existing array */
- if (style->uncommon->content != NULL &&
- style->uncommon->content != content)
- style->alloc(style->uncommon->content, 0, style->pw);
+ for (c = content; c != NULL &&
+ c->type != CSS_COMPUTED_CONTENT_NONE; c++) {
+ switch (c->type) {
+ case CSS_COMPUTED_CONTENT_STRING:
+ lwc_string_ref(c->data.string);
+ break;
+ case CSS_COMPUTED_CONTENT_URI:
+ lwc_string_ref(c->data.uri);
+ break;
+ case CSS_COMPUTED_CONTENT_ATTR:
+ lwc_string_ref(c->data.attr);
+ break;
+ case CSS_COMPUTED_CONTENT_COUNTER:
+ lwc_string_ref(c->data.counter.name);
+ break;
+ case CSS_COMPUTED_CONTENT_COUNTERS:
+ lwc_string_ref(c->data.counters.name);
+ lwc_string_ref(c->data.counters.sep);
+ break;
+ default:
+ break;
+ }
+ }
style->uncommon->content = content;
+ /* Free existing array */
+ if (oldcontent != NULL) {
+ for (c = oldcontent;
+ c->type != CSS_COMPUTED_CONTENT_NONE; c++) {
+ switch (c->type) {
+ case CSS_COMPUTED_CONTENT_STRING:
+ lwc_string_unref(c->data.string);
+ break;
+ case CSS_COMPUTED_CONTENT_URI:
+ lwc_string_unref(c->data.uri);
+ break;
+ case CSS_COMPUTED_CONTENT_ATTR:
+ lwc_string_unref(c->data.attr);
+ break;
+ case CSS_COMPUTED_CONTENT_COUNTER:
+ lwc_string_unref(c->data.counter.name);
+ break;
+ case CSS_COMPUTED_CONTENT_COUNTERS:
+ lwc_string_unref(c->data.counters.name);
+ lwc_string_unref(c->data.counters.sep);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (oldcontent != content)
+ style->alloc(oldcontent, 0, style->pw);
+ }
+
return CSS_OK;
}
#undef CONTENT_MASK
@@ -479,17 +562,21 @@ static inline css_error set_background_image(
lwc_string *url)
{
uint8_t *bits = &style->bits[BACKGROUND_IMAGE_INDEX];
+ lwc_string *oldurl = style->background_image;
/* 1bit: type */
*bits = (*bits & ~BACKGROUND_IMAGE_MASK) |
((type & 0x1) << BACKGROUND_IMAGE_SHIFT);
if (url != NULL) {
- style->background_image = url;
+ style->background_image = lwc_string_ref(url);
} else {
style->background_image = NULL;
}
+ if (oldurl != NULL)
+ lwc_string_unref(oldurl);
+
return CSS_OK;
}
#undef BACKGROUND_IMAGE_MASK
@@ -525,17 +612,21 @@ static inline css_error set_list_style_image(
lwc_string *url)
{
uint8_t *bits = &style->bits[LIST_STYLE_IMAGE_INDEX];
+ lwc_string *oldurl = style->list_style_image;
/* 1bit: type */
*bits = (*bits & ~LIST_STYLE_IMAGE_MASK) |
((type & 0x1) << LIST_STYLE_IMAGE_SHIFT);
if (url != NULL) {
- style->list_style_image = url;
+ style->list_style_image = lwc_string_ref(url);
} else {
style->list_style_image = NULL;
}
+ if (oldurl != NULL)
+ lwc_string_unref(oldurl);
+
return CSS_OK;
}
#undef LIST_STYLE_IMAGE_MASK
@@ -550,17 +641,27 @@ static inline css_error set_quotes(
lwc_string **quotes)
{
uint8_t *bits = &style->bits[QUOTES_INDEX];
+ lwc_string **oldquotes = style->quotes;
+ lwc_string **s;
/* 1bit: type */
*bits = (*bits & ~QUOTES_MASK) |
((type & 0x1) << QUOTES_SHIFT);
- /* Free current quotes */
- if (style->quotes != NULL && style->quotes != quotes)
- style->alloc(style->quotes, 0, style->pw);
+ for (s = quotes; s != NULL && *s != NULL; s++)
+ lwc_string_ref(*s);
style->quotes = quotes;
+ /* Free current quotes */
+ if (oldquotes != NULL) {
+ for (s = oldquotes; *s != NULL; s++)
+ lwc_string_unref(*s);
+
+ if (oldquotes != quotes)
+ style->alloc(oldquotes, 0, style->pw);
+ }
+
return CSS_OK;
}
#undef QUOTES_MASK
@@ -1446,17 +1547,27 @@ static inline css_error set_font_family(
lwc_string **names)
{
uint8_t *bits = &style->bits[FONT_FAMILY_INDEX];
+ lwc_string **oldnames = style->font_family;
+ lwc_string **s;
/* 3bits: type */
*bits = (*bits & ~FONT_FAMILY_MASK) |
((type & 0x7) << FONT_FAMILY_SHIFT);
- /* Free existing families */
- if (style->font_family != NULL && style->font_family != names)
- style->alloc(style->font_family, 0, style->pw);
+ for (s = names; s != NULL && *s != NULL; s++)
+ lwc_string_ref(*s);
style->font_family = names;
+ /* Free existing families */
+ if (oldnames != NULL) {
+ for (s = oldnames; *s != NULL; s++)
+ lwc_string_unref(*s);
+
+ if (oldnames != names)
+ style->alloc(oldnames, 0, style->pw);
+ }
+
return CSS_OK;
}
#undef FONT_FAMILY_MASK