Skip to content

Commit

Permalink
prune fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
parisman committed May 29, 2009
1 parent 3feccd8 commit 0d2f647
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 17 deletions.
4 changes: 1 addition & 3 deletions Classes/CSSPartMatcher.h
Expand Up @@ -33,17 +33,15 @@
*/ */
@interface CSSPartMatcher : NSObject { @interface CSSPartMatcher : NSObject {
CSSSelectorMatcher* selectorMatcher; // not retained CSSSelectorMatcher* selectorMatcher; // not retained
Element* scopeElement;
Element* matchedElement; Element* matchedElement;
int matchedPartIndex; int matchedPartIndex;
NSMutableArray* matchersForNextPart; NSMutableArray* matchersForNextPart;
} }
@property (nonatomic, retain) Element* scopeElement;
@property (nonatomic, retain) Element* matchedElement; @property (nonatomic, retain) Element* matchedElement;
@property int matchedPartIndex; @property int matchedPartIndex;


-(id)initWithElement:(Element*) anElement selectorMatcher:(CSSSelectorMatcher*)aSelectorMatcher; -(id)initWithElement:(Element*) anElement selectorMatcher:(CSSSelectorMatcher*)aSelectorMatcher;
-(void)pruneMatchesForElement:(Element*)anElement; //-(void)pruneMatchesForElement:(Element*)anElement;
-(BOOL)matchNextElement:(Element*) nextElement forIndex: (int) index; -(BOOL)matchNextElement:(Element*) nextElement forIndex: (int) index;


@end @end
24 changes: 10 additions & 14 deletions Classes/CSSPartMatcher.m
Expand Up @@ -28,25 +28,24 @@


@implementation CSSPartMatcher @implementation CSSPartMatcher


@synthesize matchedElement, scopeElement, matchedPartIndex; @synthesize matchedElement, matchedPartIndex;


-(id)initWithElement:(Element*) anElement selectorMatcher:(CSSSelectorMatcher*)aSelectorMatcher{ -(id)initWithElement:(Element*) anElement selectorMatcher:(CSSSelectorMatcher*)aSelectorMatcher{
self = [super init]; self = [super init];
matchedElement = [anElement retain]; matchedElement = [anElement retain];
scopeElement = [anElement retain];
selectorMatcher = aSelectorMatcher; selectorMatcher = aSelectorMatcher;
return self; return self;
} }


-(void)dealloc{ -(void)dealloc{
// NSLog(@"pruned: %@", [self description]); // NSLog(@"pruned: %@", [self description]);
[matchedElement release]; [matchedElement release];
[scopeElement release];
[matchersForNextPart release]; [matchersForNextPart release];
[super dealloc]; [super dealloc];
} }


-(void)pruneMatchesForElement: (Element*)anElement{ /* we don't do this yet...
-(void)pruneMatchesForElement: (Element*)anElement{
if (!matchersForNextPart) return; if (!matchersForNextPart) return;
for (CSSPartMatcher* match in matchersForNextPart){ for (CSSPartMatcher* match in matchersForNextPart){
if ([match scopeElement] == anElement) if ([match scopeElement] == anElement)
Expand All @@ -55,13 +54,11 @@ -(void)pruneMatchesForElement: (Element*)anElement{
[match pruneMatchesForElement: anElement]; [match pruneMatchesForElement: anElement];
} }
} }
*/


-(void)addNextMatch:(Element*)nextElement withIndex:(int)index{ -(void)addNextMatch:(Element*)nextElement withIndex:(int)index{
CSSPartMatcher* nextMatch = [[CSSPartMatcher alloc] initWithElement: nextElement selectorMatcher: selectorMatcher]; CSSPartMatcher* nextMatch = [[CSSPartMatcher alloc] initWithElement: nextElement selectorMatcher: selectorMatcher];
nextMatch.matchedPartIndex = index; nextMatch.matchedPartIndex = index;
CSSVerb nextNextVerb = [[selectorMatcher selector] verbAfterIndex: index];
if (nextNextVerb == CSSVerbSuccessor)
[nextMatch setScopeElement: self.matchedElement];
if (!matchersForNextPart) if (!matchersForNextPart)
matchersForNextPart = [[NSMutableArray alloc] initWithCapacity: 4]; matchersForNextPart = [[NSMutableArray alloc] initWithCapacity: 4];
[matchersForNextPart addObject: nextMatch]; [matchersForNextPart addObject: nextMatch];
Expand All @@ -76,26 +73,25 @@ -(BOOL)matchNextElement:(Element*) nextElement forIndex: (int) index{
if (nextVerb == CSSVerbAny) if (nextVerb == CSSVerbAny)
verbMatches = YES; verbMatches = YES;
else if (nextVerb == CSSVerbDescendant) else if (nextVerb == CSSVerbDescendant)
verbMatches = YES;//because we prune verbMatches = [nextElement hasAncestor: self.matchedElement];//wasteful to not prune matches as they go out of scope
else if (nextVerb == CSSVerbChild) else if (nextVerb == CSSVerbChild)
verbMatches = nextElement.parent == self.matchedElement; verbMatches = nextElement.parent == self.matchedElement;
else if (nextVerb == CSSVerbSuccessor) else if (nextVerb == CSSVerbSuccessor)
verbMatches = nextElement == self.matchedElement.nextSybling; verbMatches = nextElement == self.matchedElement.nextSybling;
} }


BOOL completeMatch = verbMatches && (index == [[selectorMatcher selector] countOfParts] - 1); BOOL completeMatch = verbMatches && (index == [[selectorMatcher selector] countOfParts] - 1);

if (matchersForNextPart){ if (matchersForNextPart){
for (CSSPartMatcher* match in matchersForNextPart) for (CSSPartMatcher* match in matchersForNextPart){
completeMatch = completeMatch || [match matchNextElement: nextElement forIndex: index + 1]; completeMatch = completeMatch || [match matchNextElement: nextElement forIndex: index + 1];
}
} }


if (completeMatch) if (!completeMatch && verbMatches)//actually part and verb match
return YES;

if (verbMatches)
[self addNextMatch: nextElement withIndex: index]; [self addNextMatch: nextElement withIndex: index];


return NO; return completeMatch;
} }


-(CSSSelectorPart*)matchedPart{ -(CSSSelectorPart*)matchedPart{
Expand Down
1 change: 1 addition & 0 deletions Test/CSSSelectorTest.m
Expand Up @@ -85,6 +85,7 @@ +(void)testCSSSelector{
[self assertWithCSSSelectorString: @"foo#ids > bar.huh + img[title]"]; [self assertWithCSSSelectorString: @"foo#ids > bar.huh + img[title]"];


} }

+(void)testAll{ +(void)testAll{
[self testCSSSelector]; [self testCSSSelector];
} }
Expand Down
1 change: 1 addition & 0 deletions Test/ElementParserTest.h
Expand Up @@ -28,6 +28,7 @@
@interface ElementParser (Test) @interface ElementParser (Test)


+(void)testElementParser; +(void)testElementParser;
+(void)testNestedMatches;
+(void)testAll; +(void)testAll;




Expand Down
8 changes: 8 additions & 0 deletions Test/ElementParserTest.m
Expand Up @@ -73,6 +73,14 @@ +(void)testFeedPerf{
NSLog(@"%i runs processing feed: %f", runs, [NSDate timeIntervalSinceReferenceDate] - start); NSLog(@"%i runs processing feed: %f", runs, [NSDate timeIntervalSinceReferenceDate] - start);
} }


+(void)testNestedMatches{
NSString* source = @"<html><body><div class='x'><a href='1' /></div><a href='2' /></body></html>";
ElementParser* parser = [[[ElementParser alloc] init] autorelease];
DocumentRoot* root = [parser parseHTML: source];
NSArray* result = [root selectElements: @"div.x a"];
assert([result count] == 1);
}

+(void)testFeed{ +(void)testFeed{
NSString* file = [[NSBundle mainBundle] pathForResource: @"gizmodo" ofType: @"xml"]; NSString* file = [[NSBundle mainBundle] pathForResource: @"gizmodo" ofType: @"xml"];
NSString* source = [NSString stringWithContentsOfFile: file]; NSString* source = [NSString stringWithContentsOfFile: file];
Expand Down

0 comments on commit 0d2f647

Please sign in to comment.