Skip to content

Commit

Permalink
Added CSSSelector and added tree building code
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Stewart committed Jul 17, 2011
1 parent bc85681 commit 078cfeb
Show file tree
Hide file tree
Showing 19 changed files with 370 additions and 155 deletions.
16 changes: 0 additions & 16 deletions CSSDOMManager.h

This file was deleted.

14 changes: 0 additions & 14 deletions CSSDOMManager.m

This file was deleted.

7 changes: 7 additions & 0 deletions CSSParser.h
Expand Up @@ -8,9 +8,16 @@

#import <Foundation/Foundation.h>

@class CSSParser;


@class CSSParser;
@interface CSSParser : NSObject {

}

- (NSDictionary*)parseURL:(NSURL*)url;

//make sure this is a week property.
@property (assign, nonatomic) id <CSSParserDelegate> delegate;
@end
4 changes: 4 additions & 0 deletions CSSParser.m
Expand Up @@ -10,5 +10,9 @@


@implementation CSSParser
@synthesize delegate;

- (void)dealloc {
[super dealloc];
}
@end
1 change: 1 addition & 0 deletions CSSPlistMapper.h
Expand Up @@ -13,4 +13,5 @@

}


@end
5 changes: 5 additions & 0 deletions CSSPlistMapper.m
Expand Up @@ -11,4 +11,9 @@

@implementation CSSPlistMapper

#pragma mark Required Mapper Methods
- (NSDictionary*)loadMappings {
return [NSDictionary dictionaryWithObjectsAndKeys:@"backgroundImage",
@"background-image", nil];
}
@end
38 changes: 38 additions & 0 deletions CSSRuleset.h
@@ -0,0 +1,38 @@
//
// CSSRuleset.h
// CSSSample
//
// Created by Sam Stewart on 7/16/11.
// Copyright 2011 Float:Right Ltd. All rights reserved.
//
/** This class represents a single CSS ruleset. It allows us to load
resources and provids a storage container for a given ruleset.
For example, this class represents the rule section of a selector group.
{
background-image: url('test.jpg');
color: #FFFFFF
}
This class does lazy loading of resources so it only loads when you call getRuleValue. If it doesn't have the resource
cached it will load and cache it.
*/
#import <Foundation/Foundation.h>


@interface CSSRuleset : NSObject {
// string rep of the ruleset
NSDictionary *parsedRuleset;

// dictionary with actual loaded resources (like UIImage)
// this thing acts as a cache.
NSDictionary *loadedRuleset;
}
- (id)initWithDict:(NSDictionary*)dictionary;
/** Grabs the rule value for the specified key. It'll load the resource if it doesn't
already exist.*/
- (NSObject*)getRuleValue:(NSString*)key;
/** Sets the resource uri (like background-image for css) for the specified ruleset key.*/
- (void)setRuleValue:(NSString*)value forKey:(NSString*)key;
@end
42 changes: 42 additions & 0 deletions CSSRuleset.m
@@ -0,0 +1,42 @@
//
// CSSRuleset.m
// CSSSample
//
// Created by Sam Stewart on 7/16/11.
// Copyright 2011 Float:Right Ltd. All rights reserved.
//

#import "CSSRuleset.h"
@interface CSSRuleset()
- (NSObject*)loadResource:(NSString*)resource_uri;
@end

@implementation CSSRuleset

- (id)initWithDict:(NSDictionary *)dictionary {
self = [super init];
if (self) {
parsedRuleset = [dictionary retain];
}
return self;
}
- (NSObject*)getRuleValue:(NSString *)key {
NSObject *value = [loadedRuleset objectForKey:key];
if (!value) {
// since not in cache grab string uri and load
value = [self loadResource:[parsedRuleset objectForKey:key]];
[loadedRuleset setValue:value forKey:key]; // save for next time.
}
return value;
}
- (void)setRuleValue:(NSObject *)value forKey:(NSString *)key {
[parsedRuleset setValue:value forKey:key];
}


- (void)dealloc {
[super dealloc];
[parsedRuleset release], parsedRuleset = nil;
[loadedRuleset release], loadedRuleset = nil;
}
@end
30 changes: 18 additions & 12 deletions CSSSample.xcodeproj/project.pbxproj
Expand Up @@ -7,11 +7,12 @@
objects = {

/* Begin PBXBuildFile section */
1DEC907E13D24BE7005BCF07 /* CSSRuleset.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DEC907D13D24BE7005BCF07 /* CSSRuleset.m */; };
1DEC908213D262A9005BCF07 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DEC908113D262A8005BCF07 /* CSSSelector.m */; };
1DEE03CC13D234FD007C87FE /* CSSResourceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DEE03CB13D234FD007C87FE /* CSSResourceManager.m */; };
1DEE03CF13D23508007C87FE /* CSSTreeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DEE03CE13D23508007C87FE /* CSSTreeManager.m */; };
1DEE03D213D23514007C87FE /* CSSParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DEE03D113D23514007C87FE /* CSSParser.m */; };
1DEE03D713D235EA007C87FE /* CSSPlistMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DEE03D613D235EA007C87FE /* CSSPlistMapper.m */; };
1DEE03DB13D238FE007C87FE /* CSSDOMManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DEE03DA13D238FE007C87FE /* CSSDOMManager.m */; };
1DEE03DE13D24349007C87FE /* CSSStyleSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DEE03DD13D24349007C87FE /* CSSStyleSheet.m */; };
AB50CF8913D22017001113D0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB50CF8813D22017001113D0 /* UIKit.framework */; };
AB50CF8B13D22017001113D0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB50CF8A13D22017001113D0 /* Foundation.framework */; };
AB50CF8D13D22017001113D0 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB50CF8C13D22017001113D0 /* CoreGraphics.framework */; };
Expand Down Expand Up @@ -41,17 +42,19 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
1DEC907C13D24BE7005BCF07 /* CSSRuleset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSRuleset.h; sourceTree = "<group>"; };
1DEC907D13D24BE7005BCF07 /* CSSRuleset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSRuleset.m; sourceTree = "<group>"; };
1DEC908013D262A8005BCF07 /* CSSSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelector.h; sourceTree = "<group>"; };
1DEC908113D262A8005BCF07 /* CSSSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelector.m; sourceTree = "<group>"; };
1DEE03CA13D234FD007C87FE /* CSSResourceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSResourceManager.h; sourceTree = "<group>"; };
1DEE03CB13D234FD007C87FE /* CSSResourceManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSResourceManager.m; sourceTree = "<group>"; };
1DEE03CD13D23508007C87FE /* CSSTreeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSTreeManager.h; sourceTree = "<group>"; };
1DEE03CE13D23508007C87FE /* CSSTreeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTreeManager.m; sourceTree = "<group>"; };
1DEE03D013D23514007C87FE /* CSSParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSParser.h; sourceTree = "<group>"; };
1DEE03D113D23514007C87FE /* CSSParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSParser.m; sourceTree = "<group>"; };
1DEE03D413D23591007C87FE /* CSSMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSMapper.h; sourceTree = "<group>"; };
1DEE03D513D235EA007C87FE /* CSSPlistMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPlistMapper.h; sourceTree = "<group>"; };
1DEE03D613D235EA007C87FE /* CSSPlistMapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSPlistMapper.m; sourceTree = "<group>"; };
1DEE03D913D238FE007C87FE /* CSSDOMManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSDOMManager.h; sourceTree = "<group>"; };
1DEE03DA13D238FE007C87FE /* CSSDOMManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSDOMManager.m; sourceTree = "<group>"; };
1DEE03DC13D24349007C87FE /* CSSStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSStyleSheet.h; sourceTree = "<group>"; };
1DEE03DD13D24349007C87FE /* CSSStyleSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSStyleSheet.m; sourceTree = "<group>"; };
AB50CF8413D22017001113D0 /* CSSSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CSSSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
AB50CF8813D22017001113D0 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
AB50CF8A13D22017001113D0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -105,6 +108,12 @@
children = (
1DEE03D013D23514007C87FE /* CSSParser.h */,
1DEE03D113D23514007C87FE /* CSSParser.m */,
1DEE03DC13D24349007C87FE /* CSSStyleSheet.h */,
1DEE03DD13D24349007C87FE /* CSSStyleSheet.m */,
1DEC907C13D24BE7005BCF07 /* CSSRuleset.h */,
1DEC907D13D24BE7005BCF07 /* CSSRuleset.m */,
1DEC908013D262A8005BCF07 /* CSSSelector.h */,
1DEC908113D262A8005BCF07 /* CSSSelector.m */,
);
name = parser;
sourceTree = "<group>";
Expand All @@ -116,10 +125,6 @@
1DEE03D313D2357C007C87FE /* mapper */,
1DEE03CA13D234FD007C87FE /* CSSResourceManager.h */,
1DEE03CB13D234FD007C87FE /* CSSResourceManager.m */,
1DEE03CD13D23508007C87FE /* CSSTreeManager.h */,
1DEE03CE13D23508007C87FE /* CSSTreeManager.m */,
1DEE03D913D238FE007C87FE /* CSSDOMManager.h */,
1DEE03DA13D238FE007C87FE /* CSSDOMManager.m */,
);
name = managers;
sourceTree = "<group>";
Expand Down Expand Up @@ -356,10 +361,11 @@
AB50CF9F13D22017001113D0 /* CSSSampleViewController.m in Sources */,
AB5B475213D2272B00FB2A74 /* UIView+CSS.m in Sources */,
1DEE03CC13D234FD007C87FE /* CSSResourceManager.m in Sources */,
1DEE03CF13D23508007C87FE /* CSSTreeManager.m in Sources */,
1DEE03D213D23514007C87FE /* CSSParser.m in Sources */,
1DEE03D713D235EA007C87FE /* CSSPlistMapper.m in Sources */,
1DEE03DB13D238FE007C87FE /* CSSDOMManager.m in Sources */,
1DEE03DE13D24349007C87FE /* CSSStyleSheet.m in Sources */,
1DEC907E13D24BE7005BCF07 /* CSSRuleset.m in Sources */,
1DEC908213D262A9005BCF07 /* CSSSelector.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
33 changes: 33 additions & 0 deletions CSSSelector.h
@@ -0,0 +1,33 @@
//
// CSSSelector.h
// CSSSample
//
// Created by Sam Stewart on 7/16/11.
// Copyright 2011 Float:Right Ltd. All rights reserved.
//
/**
This class represents a css selector. Each selector is a bit like a uri with the ending element called
a "slug". For example, in the css selector "ul.red#hello" "#hello" would be the slug.
You can get the entire selector by calling "description" on this.
This is a simple wrapper class which allows us to manage selectors.*/
#import <Foundation/Foundation.h>


@interface CSSSelector : NSObject {
// the ending component
NSString *slug;
// the main selector (without slug)
NSString *main;
}
- (id)initWithSelector:(NSString*)selector;
/** Returns the components of the the selector (including the slug).
The components which are separated by spaces (mainly descendant selectors).
*/
- (NSArray*)selectorComponents;

//not the best idea to update these directly.
@property (nonatomic, retain) NSString *main;
@property (nonatomic, retain) NSString *slug;
@end
56 changes: 56 additions & 0 deletions CSSSelector.m
@@ -0,0 +1,56 @@
//
// CSSSelector.m
// CSSSample
//
// Created by Sam Stewart on 7/16/11.
// Copyright 2011 Float:Right Ltd. All rights reserved.
//

#import "CSSSelector.h"
@interface CSSSelector ()
- (void)breakIntoSlugAndMain:(NSString*)selector;
@end

@implementation CSSSelector
@synthesize main, slug;

- (id)initWithSelector:(NSString *)selector {
self = [super init];
if (self) {
[self breakIntoSlugAndMain:selector];
}
return self;
}

/** Breaks into main url and slug.*/
- (void)breakIntoSlugAndMain:(NSString*)selector {
// find slug (start at the end of the string and stop when we find control character)
unichar control_chars[5] = {'.', '#', ' ', '>', ':'};

for (int i = [selector length]; i>=0; i--) {
unichar cur_char = [selector characterAtIndex:i];

for (int j = 0; j<5;i++) {
if (cur_char == control_chars[j]) {
NSRange range = NSMakeRange(i-1, i+j+1);
self.slug = [selector substringWithRange:range];
self.main = [selector substringToIndex:i];
return;
}
}
}
}
- (NSArray*)selectorComponents {
// just split on spaces..
return [[self description] componentsSeparatedByString:@" "];
}

- (NSString*)description {
return [NSString stringWithFormat:@"%@%@", main, slug];
}
- (void)dealloc {
[super dealloc];
[main release], main = nil;
[slug release], slug = nil;
}
@end
42 changes: 42 additions & 0 deletions CSSStyleSheet.h
@@ -0,0 +1,42 @@
//
// CSSStyleSheet.h
// CSSSample
//
// Created by Sam Stewart on 7/16/11.
// Copyright 2011 Float:Right Ltd. All rights reserved.
//
/**
Represents css style sheet which has been parsed and loaded into our custom format.
Each rule is represented backwards. For example you might have div.red#hello which would turn into
#hello -> .red -> div
Most specific to least specific. This setup allows us to ensure the correct properties take precendence.
Thus, each entry (like #hello) has is a dictionary with a a few built in keys. We always have:
1. score
2. All (is a default ruleset in case we don't have any parent selectors). For example, #hello would have an "All" key.
All is usually an instance of CSSRuleset since it's a toplevel namespace.
3. any other selectors that are up a level. (for example, we'd have .red)
This structure continues all the way up the tree.
*/
#import <Foundation/Foundation.h>


@class CSSParser;
@class CSSSelector;
@interface CSSStyleSheet : NSObject {
// main css style tree. Custom format.
NSMutableDictionary *mainTree;

CSSParser *parser;
}
- (NSDictionary*)lookup:(CSSSelector*)selector;

- (void)loadFromURL:(NSURL*)url;
- (void)loadFromString:(NSString*)css_code;

+ (CSSStyleSheet*)styleSheetFromURL:(NSURL*)url;
+ (CSSStyleSheet*)styleSheetFromString:(NSString*)css_code;
@end

0 comments on commit 078cfeb

Please sign in to comment.