Reintroduce the HTMLNodeFilterValue for Tree Walker implementation

While the Node Iterator treats skip & reject the same way, the Tree Walker can skip over a node
and all its children if rejected.

This reverses dc3de7a470
This commit is contained in:
iska
2015-06-05 23:00:50 +02:00
parent 0c82f6891b
commit a390edf599
10 changed files with 61 additions and 50 deletions
+1 -1
View File
@@ -119,7 +119,7 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition)
- (HTMLNodeIterator *)nodeIteratorWithShowOptions:(HTMLNodeFilterShowOptions)showOptions
filter:(id<HTMLNodeFilter>)filter;
- (HTMLNodeIterator *)nodeIteratorWithShowOptions:(HTMLNodeFilterShowOptions)showOptions
filterBlock:(BOOL (^)(HTMLNode *node))filter;
filterBlock:(HTMLNodeFilterValue (^)(HTMLNode *node))filter;
- (NSString *)treeDescription;
+1 -1
View File
@@ -381,7 +381,7 @@
}
- (HTMLNodeIterator *)nodeIteratorWithShowOptions:(HTMLNodeFilterShowOptions)showOptions
filterBlock:(BOOL (^)(HTMLNode *node))filter
filterBlock:(HTMLNodeFilterValue (^)(HTMLNode *node))filter
{
return [HTMLNodeIterator iteratorWithNode:self showOptions:showOptions filter:filter];
}
+10 -3
View File
@@ -8,6 +8,13 @@
#import <Foundation/Foundation.h>
typedef NS_ENUM(unsigned short, HTMLNodeFilterValue)
{
HTMLNodeFilterAccept = 1,
HTMLNodeFilterReject = 2,
HTMLNodeFilterSkip = 3
};
typedef NS_ENUM(unsigned long, HTMLNodeFilterShowOptions)
{
HTMLNodeFilterShowAll = 0xFFFFFFFF,
@@ -23,12 +30,12 @@ typedef NS_ENUM(unsigned long, HTMLNodeFilterShowOptions)
@protocol HTMLNodeFilter <NSObject>
- (BOOL)acceptNode:(HTMLNode *)node;
- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node;
@end
@interface HTMLNodeFilterBlock : NSObject <HTMLNodeFilter>
+ (instancetype)filterWithBlock:(BOOL (^)(HTMLNode *node))block;
+ (instancetype)filterWithBlock:(HTMLNodeFilterValue (^)(HTMLNode *node))block;
@end
@end
+4 -4
View File
@@ -16,12 +16,12 @@
@implementation HTMLNodeFilterBlock
+ (instancetype)filterWithBlock:(BOOL (^)(HTMLNode *))block
+ (instancetype)filterWithBlock:(HTMLNodeFilterValue (^)(HTMLNode *))block
{
return [[self alloc] initWithBlock:block];
}
- (instancetype)initWithBlock:(BOOL (^)(HTMLNode *))block
- (instancetype)initWithBlock:(HTMLNodeFilterValue (^)(HTMLNode *))block
{
self = [super init];
if (self) {
@@ -30,10 +30,10 @@
return self;
}
- (BOOL)acceptNode:(HTMLNode *)node
- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node
{
if (!_block) {
return NO;
return HTMLNodeFilterSkip;
}
return _block(node);
+1 -1
View File
@@ -21,7 +21,7 @@
+ (instancetype)iteratorWithNode:(HTMLNode *)node
showOptions:(HTMLNodeFilterShowOptions)showOptions
filter:(BOOL (^)(HTMLNode *node))filter;
filter:(HTMLNodeFilterValue (^)(HTMLNode *node))filter;
- (instancetype)initWithNode:(HTMLNode *)node;
- (instancetype)initWithNode:(HTMLNode *)node
+2 -2
View File
@@ -35,7 +35,7 @@ typedef NS_ENUM(short, TraverseDirection)
+ (instancetype)iteratorWithNode:(HTMLNode *)node
showOptions:(HTMLNodeFilterShowOptions)showOptions
filter:(BOOL (^)(HTMLNode *))filter
filter:(HTMLNodeFilterValue (^)(HTMLNode *))filter
{
return [[self alloc] initWithNode:node
showOptions:showOptions
@@ -139,7 +139,7 @@ typedef NS_ENUM(short, TraverseDirection)
}
beforeNode = YES;
}
} while (!FilterNode(self.filter, self.whatToShow, node));
} while (FilterNode(self.filter, self.whatToShow, node) != HTMLNodeFilterAccept);
_referenceNode = node;
_pointerBeforeReferenceNode = beforeNode;
+1 -1
View File
@@ -14,4 +14,4 @@
extern HTMLNode * PrecedingNode(HTMLNode *node, HTMLNode *root);
extern HTMLNode * FollowingNode(HTMLNode *node, HTMLNode *root);
extern HTMLNode * FollowingNodeSkippingChildren(HTMLNode *node, HTMLNode *root);
extern BOOL FilterNode(id<HTMLNodeFilter> filter, HTMLNodeFilterShowOptions whatToShow, HTMLNode *node);
extern HTMLNodeFilterValue FilterNode(id<HTMLNodeFilter> filter, HTMLNodeFilterShowOptions whatToShow, HTMLNode *node);
+3 -3
View File
@@ -61,15 +61,15 @@ HTMLNode * FollowingNodeSkippingChildren(HTMLNode *node, HTMLNode *root)
return nil;
}
BOOL FilterNode(id<HTMLNodeFilter> filter, HTMLNodeFilterShowOptions whatToShow, HTMLNode *node)
HTMLNodeFilterValue FilterNode(id<HTMLNodeFilter> filter, HTMLNodeFilterShowOptions whatToShow, HTMLNode *node)
{
unsigned long nthBit = (1 << (node.nodeType - 1)) & whatToShow;
if (!nthBit) {
return NO;
return HTMLNodeFilterSkip;
}
if (filter == nil) {
return YES;
return HTMLNodeFilterAccept;
}
return [filter acceptNode:node];
+34 -31
View File
@@ -43,6 +43,20 @@ typedef NS_ENUM(short, HTMLTreeWalkerSiblingsType)
#pragma mark - Traversal
- (HTMLNode *)parentNode
{
HTMLNode *node = _currentNode;
while (node != nil && node != _root) {
node = node.parentNode;
if (node != nil && FilterNode(self.filter, self.whatToShow, node) == HTMLNodeFilterAccept) {
_currentNode = node;
return node;
}
}
return nil;
}
- (HTMLNode *)traverseChildrenOfType:(HTMLTreeWalkerChildrenType)type
{
HTMLNode *node = _currentNode;
@@ -50,16 +64,18 @@ typedef NS_ENUM(short, HTMLTreeWalkerSiblingsType)
node = (type == HTMLTreeWalkerChildrenTypeFirst) ? node.firstChiledNode : node.lastChildNode;
while (node != nil) {
BOOL result = FilterNode(self.filter, self.whatToShow, node);
if (result) {
HTMLNodeFilterValue result = FilterNode(self.filter, self.whatToShow, node);
if (result == HTMLNodeFilterAccept) {
_currentNode = node;
return node;
}
HTMLNode *child = (type == HTMLTreeWalkerChildrenTypeFirst) ? node.firstChiledNode : node.lastChildNode;
if (child != nil) {
node = child;
continue;
if (result == HTMLNodeFilterSkip) {
HTMLNode *child = (type == HTMLTreeWalkerChildrenTypeFirst) ? node.firstChiledNode : node.lastChildNode;
if (child != nil) {
node = child;
continue;
}
}
while (node != nil) {
@@ -80,20 +96,6 @@ typedef NS_ENUM(short, HTMLTreeWalkerSiblingsType)
return nil;
}
- (HTMLNode *)parentNode
{
HTMLNode *node = _currentNode;
while (node != nil && node != _root) {
node = node.parentNode;
if (node != nil && FilterNode(self.filter, self.whatToShow, node)) {
_currentNode = node;
return node;
}
}
return nil;
}
- (HTMLNode *)firstChild
{
return [self traverseChildrenOfType:HTMLTreeWalkerChildrenTypeFirst];
@@ -116,8 +118,8 @@ typedef NS_ENUM(short, HTMLTreeWalkerSiblingsType)
HTMLNode *sibling = (type == HTMLTreeWalkerSiblingsTypeNext) ? node.nextSibling : node.previousSibling;
while (sibling != nil) {
node = sibling;
BOOL result = FilterNode(self.filter, self.whatToShow, node);
if (result) {
HTMLNodeFilterValue result = FilterNode(self.filter, self.whatToShow, node);
if (result == HTMLNodeFilterAccept) {
_currentNode = node;
return node;
}
@@ -133,10 +135,11 @@ typedef NS_ENUM(short, HTMLTreeWalkerSiblingsType)
return nil;
}
if (FilterNode(self.filter, self.whatToShow, node)) {
if (FilterNode(self.filter, self.whatToShow, node) == HTMLNodeFilterAccept) {
return nil;
}
}
return nil;
}
@@ -160,13 +163,13 @@ typedef NS_ENUM(short, HTMLTreeWalkerSiblingsType)
while (sibling != nil) {
node = sibling;
BOOL result = FilterNode(self.filter, self.whatToShow, node);
while (result && node.hasChildNodes) {
HTMLNodeFilterValue result = FilterNode(self.filter, self.whatToShow, node);
while (result != HTMLNodeFilterReject && node.hasChildNodes) {
node = node.lastChildNode;
result = FilterNode(self.filter, self.whatToShow, node);
}
if (result) {
if (result == HTMLNodeFilterAccept) {
_currentNode = node;
return node;
}
@@ -179,7 +182,7 @@ typedef NS_ENUM(short, HTMLTreeWalkerSiblingsType)
}
node = node.parentNode;
if (FilterNode(self.filter, self.whatToShow, node)) {
if (FilterNode(self.filter, self.whatToShow, node) == HTMLNodeFilterAccept) {
_currentNode = node;
return node;
}
@@ -192,13 +195,13 @@ typedef NS_ENUM(short, HTMLTreeWalkerSiblingsType)
{
HTMLNode *node = _currentNode;
BOOL result = YES;
HTMLNodeFilterValue result = YES;
while (YES) {
while (!result && node.hasChildNodes) {
while (result != HTMLNodeFilterReject && node.hasChildNodes) {
node = node.firstChiledNode;
result = FilterNode(self.filter, self.whatToShow, node);
if (result) {
if (result == HTMLNodeFilterAccept) {
_currentNode = node;
return node;
}
@@ -208,7 +211,7 @@ typedef NS_ENUM(short, HTMLTreeWalkerSiblingsType)
while ((nextSibling = FollowingNodeSkippingChildren(node, _root)) != nil) {
node = nextSibling;
result = FilterNode(self.filter, self.whatToShow, node);
if (result) {
if (result == HTMLNodeFilterAccept) {
_currentNode = node;
return node;
}
+4 -3
View File
@@ -310,13 +310,14 @@
{
HTMLDocument *document = self.mixedTree;
HTMLNodeIterator *iterator = [document nodeIteratorWithShowOptions:HTMLNodeFilterShowAll filterBlock:^BOOL(HTMLNode *node) {
HTMLNodeIterator *iterator = [document nodeIteratorWithShowOptions:HTMLNodeFilterShowAll
filterBlock:^HTMLNodeFilterValue(HTMLNode *node) {
if (node.nodeType == HTMLNodeComment) {
if ([[(HTMLComment *)node data] rangeOfString:@"second"].location != NSNotFound) {
return YES;
return HTMLNodeFilterAccept;
}
}
return NO;
return HTMLNodeFilterSkip;
}];
NSArray *result = iterator.allObjects;