28#include <Objectively.h>
43 release(this->attributes);
44 release(this->selectors);
56 return $((Array *) this->selectors, componentsJoinedByCharacters,
", ");
62static int hash(
const Object *self) {
68 hash = HashForObject(
hash, this->attributes);
69 hash = HashForObject(
hash, this->selectors);
77static _Bool
isEqual(
const Object *self,
const Object *other) {
79 if (super(Object, self,
isEqual, other)) {
83 if (other && $(other, isKindOfClass,
_Style())) {
107 char *key = strtrim(attr);
110 $((MutableDictionary *) self->
attributes, setObjectForKeyPath, value, key);
123 $((MutableDictionary *) self->
attributes, addEntriesFromDictionary, attributes);
140 String *
string = $$(String, stringWithCharacters, value);
153 Number *r = $$(Number, numberWithValue, color->r);
154 Number *g = $$(Number, numberWithValue, color->g);
155 Number *b = $$(Number, numberWithValue, color->b);
156 Number *a = $$(Number, numberWithValue, color->a);
158 Array *array = $$(Array, arrayWithObjects, r, g, b, a, NULL);
175 Number *number = $$(Number, numberWithValue, value);
188 String *
string = nameof(names, value);
217 Number *x = $$(Number, numberWithValue, value->x);
218 Number *y = $$(Number, numberWithValue, value->y);
220 Array *array = $$(Array, arrayWithObjects, x, y, NULL);
235 Number *x = $$(Number, numberWithValue, value->x);
236 Number *y = $$(Number, numberWithValue, value->y);
237 Number *w = $$(Number, numberWithValue, value->w);
238 Number *h = $$(Number, numberWithValue, value->h);
240 Array *array = $$(Array, arrayWithObjects, x, y, w, h, NULL);
259 $((MutableArray *) self->
selectors, addObject, selector);
268 Number *w = $$(Number, numberWithValue, value->
w);
269 Number *h = $$(Number, numberWithValue, value->
h);
271 Array *array = $$(Array, arrayWithObjects, w, h, NULL);
285 return $((Dictionary *) self->
attributes, objectForKeyPath, attr);
310 self = (
Style *) super(Object, self,
init);
316 for (
size_t i = 0; i < self->
selectors->count; i++) {
320 self->
attributes = (Dictionary *) $$(MutableDictionary, dictionaryWithCapacity, 4);
337 for (
size_t i = 0; i < self->
selectors->count; i++) {
342 if (strcmp(this->rule, that->
rule)) {
362 String *trimmed = $(
string, trimmedString);
365 StringReader *reader = $(alloc(StringReader),
initWithString, trimmed);
368 const Unicode *charset = L
", \n\t";
371 String *token = $(reader, readToken, charset, &stop);
374 NumberFormatter *formatter = $(alloc(NumberFormatter), initWithFormat, NULL);
377 Number *number = $(formatter, numberFromString, token);
379 if (stop == READER_EOF) {
382 value = retain(number);
383 }
else if (strcmp(
"true", token->chars) == 0) {
384 value = $$(Boole, True);
385 }
else if (strcmp(
"false", token->chars) == 0) {
386 value = $$(Boole, False);
388 value = $((Object *) token, copy);
392 value = $$(MutableArray, arrayWithCapacity, 4);
396 $((MutableArray *) value, addObject,
parseValue(token));
399 token = $(reader, readToken, charset, NULL);
402 value = retain(trimmed);
420static Array *
parse(
const char *css) {
422 MutableArray *styles = $$(MutableArray, array);
435 const Unicode *charset = style ? L
"{:;}" : L
"{}";
438 String *token = $(reader, readToken, charset, &stop);
447 attr = strtrim(token->chars);
465 $(styles, addObject, style);
466 style = release(style);
480 return (Array *) styles;
488 $((MutableDictionary *) self->
attributes, removeObjectForKeyPath, attr);
496 $((MutableDictionary *) self->
attributes, removeAllObjects);
499#pragma mark - Class lifecycle
506 ((ObjectInterface *) clazz->interface)->dealloc =
dealloc;
507 ((ObjectInterface *) clazz->interface)->description =
description;
508 ((ObjectInterface *) clazz->interface)->hash =
hash;
509 ((ObjectInterface *) clazz->interface)->isEqual =
isEqual;
511 ((StyleInterface *) clazz->interface)->addAttribute =
addAttribute;
512 ((StyleInterface *) clazz->interface)->addAttributes =
addAttributes;
522 ((StyleInterface *) clazz->interface)->addSelector =
addSelector;
524 ((StyleInterface *) clazz->interface)->attributeValue =
attributeValue;
528 ((StyleInterface *) clazz->interface)->parse =
parse;
530 ((StyleInterface *) clazz->interface)->removeAttribute =
removeAttribute;
542 clazz = _initialize(&(
const ClassDef) {
544 .superclass = _Object(),
545 .instanceSize =
sizeof(
Style),
546 .interfaceOffset = offsetof(
Style, interface),
547 .interfaceSize =
sizeof(StyleInterface),
static String * description(const Object *self)
static _Bool isEqual(const Object *self, const Object *other)
static void dealloc(Object *self)
static void initialize(Class *clazz)
static ident parseValue(String *string)
static int hash(const Object *self)
CollectionView * init(CollectionView *self, const SDL_Rect *frame)
Initializes this CollectionView with the specified frame and style.
Selectors are comprised of one or more SelectorSequences.
char * rule
The rule, as provided by the user.
Array * parse(const char *rules)
Parses the null-terminated C string of Selector rules into an Array of Selectors.
void addSelector(Style *self, Selector *selector)
Adds the given Selector to this Style.
Style * initWithAttributes(Style *self, const Dictionary *attributes)
Initializes this Style with the given attributes.
_Bool isComputedEqual(const Style *self, const Style *other)
Performs a fast, rule-based comparison of this Style to the given Style.
void addIntegerAttribute(Style *self, const char *attr, int value)
Adds or replaces the given attribute with value.
void addSizeAttribute(Style *self, const char *attr, const SDL_Size *value)
Adds or replaces the given attribute with value.
void removeAttribute(Style *self, const char *attr)
Removes the attribute with the given name.
Array * selectors
The Selectors.
void addEnumAttribute(Style *self, const char *attr, const EnumName *names, int value)
Adds or replaces the given attribute with value.
void addPointAttribute(Style *self, const char *attr, const SDL_Point *value)
Adds or replaces the given attribute with value.
void addRectangleAttribute(Style *self, const char *attr, const SDL_Rect *value)
Adds or replaces the given attribute with value.
Style * initWithRules(Style *self, const char *rules)
Initializes this Style with the given CSS selector rules.
void removeAllAttributes(Style *self)
Removes all attributes from this Style.
void addFloatAttribute(Style *self, const char *attr, float value)
Adds or replaces the given attribute with value.
void addAttribute(Style *self, const char *attr, ident value)
Adds or replaces the given attribute with value.
void addCharactersAttribute(Style *self, const char *attr, const char *value)
Adds or replaces the given attribute with value.
void addAttributes(Style *self, const Dictionary *attributes)
Adds or replaces the attribtues in attributes to this Style.
void addDoubleAttribute(Style *self, const char *attr, double value)
Adds or replaces the given attribute with value.
Class * _Style(void)
The Style archetype.
void addBoolAttribute(Style *self, const char *attr, _Bool value)
Adds or replaces the given attribute with value.
ident attributeValue(const Style *self, const char *attr)
void addColorAttribute(Style *self, const char *attr, const SDL_Color *value)
Adds or replaces the given attribute with value.
Stylesheet * initWithCharacters(Stylesheet *self, const char *chars)
Initializes this Stylesheet with the given CSS definitions.
Stylesheet * initWithString(Stylesheet *self, const String *string)
Initializes this Stylesheet with the CSS definitions in string.