forked from veritech/CSSApply
-
Notifications
You must be signed in to change notification settings - Fork 4
/
UIView+CSS.m
109 lines (90 loc) · 3.64 KB
/
UIView+CSS.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//
// UIVIew+CSS.m
// CSSSample
//
// Created by Jonathan Dalrymple on 16/07/2011.
// Copyright 2011 Float:Right Ltd. All rights reserved.
#import <Foundation/Foundation.h>
#import "UIView+CSS.h"
#import "NSObject+CSS.h"
@implementation UIView (CSS)
- (void)applyProperties:(NSDictionary*)props {
NSArray *keys = [props allKeys];
for (NSString *key in keys) {
@try {
[self setValue:[props objectForKey:key] forKeyPath:key];
}
@catch (NSException *exception) {
NSLog(@"Key does not exist when trying to set from css: %@", [exception reason]);
}
}
}
- (void)applyStylesToChildren:(CSSSelectorTree *)treeNode
withInheirtedStyleDict:(NSDictionary *)mdict
recurse:(BOOL)doRecurse{
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:mdict];
for (CSSSelectorTree *node in treeNode.nodes) {
//first level is always most specific, do we match?
if ([node.selector doesMatchIntoSelector:self.CSSSelector]) {
if (node.rules) {
// will replace inherited (as expected)
[dict addEntriesFromDictionary:node.rules];
}
// if it has nodes, we need to match upwards in the tree.
if (node.nodes) {
// we need to check if we match all the way up the tree
// we always go all the way to the root bc we do descendant matching not just child matching but descendant
BOOL doesMatch = YES;
//move through nodes as we move up
NSEnumerator *node_iter = [node.nodes objectEnumerator];
CSSSelectorTree *subtree = nil;
UIView *parent = nil;
while ((subtree = [node_iter nextObject]) && doesMatch) {
// try to find the appropriate match up the tree
doesMatch = NO;
while ((parent = [self CSSParent])) {
if ([parent.CSSSelector doesMatchIntoSelector:subtree.selector]) {
doesMatch = YES;
//parent will be left where it is on purpose. We don't want rematch a parent.
break;
}
}
}
if (doesMatch) {
//we can now use the style
CSSSelectorTree *tree = [node.nodes objectAtIndex:0];
if (tree.rules) {
[dict addEntriesFromDictionary:tree.rules];
}
}
}
}
}
[self applyProperties:dict];
if (doRecurse) {
//tell all the children to do the rule merging
//also we pass our styles down for inheritance.
[self applyStylesToChildren:treeNode withInheirtedStyleDict:dict recurse:YES];
}
}
#pragma mark Actual application methods
//** Applies styles only to this node and doesn't recurse.*/
- (void)apply:(CSSStyleSheet*)sheet {
[self applyStylesToChildren:[sheet root] withInheirtedStyleDict:[NSDictionary dictionary] recurse:NO];
}
- (void)applyAll:(CSSStyleSheet *)sheet {
[self applyStylesToChildren:[sheet root] withInheirtedStyleDict:[NSDictionary dictionary] recurse:YES];
}
#pragma mark Searching though the "DOM"
/** Searches through the "DOM" for a specific set of subviews specified
by the selector.*/
- (NSArray*)find:(CSSSelector*)selector {
return nil;
}
- (NSArray*)findAll:(CSSSelector*)selector {
return nil;
}
-(id) CSSParent{
return [self superview];
}
@end