From 0d7c57d75506d75f0c4c2b1a67bd90e31fcf9537 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 5 Jun 2015 22:09:02 +0200 Subject: [PATCH] Refactor common node traversal methods into separate class These will be used in the Tree Walker https://dom.spec.whatwg.org/#interface-treewalker --- HTMLKit.xcodeproj/project.pbxproj | 10 +++++ HTMLKit/HTMLNodeIterator.m | 56 ++-------------------------- HTMLKit/HTMLNodeTraversal.h | 16 ++++++++ HTMLKit/HTMLNodeTraversal.m | 61 +++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 53 deletions(-) create mode 100644 HTMLKit/HTMLNodeTraversal.h create mode 100644 HTMLKit/HTMLNodeTraversal.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 350eb6c..4e109d3 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -66,6 +66,9 @@ 624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */; }; 624493AD19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; }; 624493AE19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; }; + 624717181B22333200C11912 /* HTMLNodeTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = 624717161B22333200C11912 /* HTMLNodeTraversal.h */; }; + 624717191B22333200C11912 /* HTMLNodeTraversal.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717171B22333200C11912 /* HTMLNodeTraversal.m */; }; + 6247171A1B22333200C11912 /* HTMLNodeTraversal.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717171B22333200C11912 /* HTMLNodeTraversal.m */; }; 624717B81B21FE5400B38302 /* HTMLNodeFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717B71B21FE5400B38302 /* HTMLNodeFilter.m */; }; 624717B91B21FE5400B38302 /* HTMLNodeFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717B71B21FE5400B38302 /* HTMLNodeFilter.m */; }; 6247A9431B152F4F00CCF25C /* HTMLNodeIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 6247A9411B152F4F00CCF25C /* HTMLNodeIterator.h */; }; @@ -213,6 +216,8 @@ 624493A919CCE84A00BCDDF4 /* HTMLTokenizerStates.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokenizerStates.h; sourceTree = ""; }; 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLToken.h; sourceTree = ""; }; 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLToken.m; sourceTree = ""; }; + 624717161B22333200C11912 /* HTMLNodeTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNodeTraversal.h; sourceTree = ""; }; + 624717171B22333200C11912 /* HTMLNodeTraversal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLNodeTraversal.m; sourceTree = ""; }; 624717B71B21FE5400B38302 /* HTMLNodeFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLNodeFilter.m; sourceTree = ""; }; 6247A9411B152F4F00CCF25C /* HTMLNodeIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNodeIterator.h; sourceTree = ""; }; 6247A9421B152F4F00CCF25C /* HTMLNodeIterator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLNodeIterator.m; sourceTree = ""; }; @@ -340,6 +345,8 @@ 623406E01ADB04F9004677A3 /* HTMLTemplate.m */, 6247A9411B152F4F00CCF25C /* HTMLNodeIterator.h */, 6247A9421B152F4F00CCF25C /* HTMLNodeIterator.m */, + 624717161B22333200C11912 /* HTMLNodeTraversal.h */, + 624717171B22333200C11912 /* HTMLNodeTraversal.m */, 6247A9461B152F8C00CCF25C /* HTMLNodeFilter.h */, 624717B71B21FE5400B38302 /* HTMLNodeFilter.m */, 6238C9831AB8D6330006512E /* HTMLKitDOMExceptions.h */, @@ -553,6 +560,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 624717181B22333200C11912 /* HTMLNodeTraversal.h in Headers */, 6235CE9B1AA509430026937B /* NSString+HTMLKit.h in Headers */, 62D89DB11AE7081600B6243D /* HTMLTokenizerStates.h in Headers */, 62D89DB21AE7081600B6243D /* HTMLTokenizerCharacters.h in Headers */, @@ -753,6 +761,7 @@ 62AE593C19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */, 623406E31ADB04F9004677A3 /* HTMLTemplate.m in Sources */, 6238C9871AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */, + 6247171A1B22333200C11912 /* HTMLNodeTraversal.m in Sources */, 62F873ED19E088C90062683C /* HTMLParser.m in Sources */, 623803A11AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */, 6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */, @@ -806,6 +815,7 @@ 62AE593B19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */, 623406E21ADB04F9004677A3 /* HTMLTemplate.m in Sources */, 6238C9861AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */, + 624717191B22333200C11912 /* HTMLNodeTraversal.m in Sources */, 62F873EC19E088C90062683C /* HTMLParser.m in Sources */, 623803A01AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */, 6279F87519E1808D00F12EE5 /* HTMLElement.m in Sources */, diff --git a/HTMLKit/HTMLNodeIterator.m b/HTMLKit/HTMLNodeIterator.m index 1f72bed..2927ac0 100644 --- a/HTMLKit/HTMLNodeIterator.m +++ b/HTMLKit/HTMLNodeIterator.m @@ -9,8 +9,8 @@ #import "HTMLNodeIterator.h" #import "HTMLDocument.h" #import "HTMLNode.h" - -#import +#import "HTMLNodeFilter.h" +#import "HTMLNodeTraversal.h" typedef NS_ENUM(short, TraverseDirection) { @@ -139,63 +139,13 @@ typedef NS_ENUM(short, TraverseDirection) } beforeNode = YES; } - } while (!FilterNode(self, node)); + } while (!FilterNode(self.filter, self.whatToShow, node)); _referenceNode = node; _pointerBeforeReferenceNode = beforeNode; return node; } -NS_INLINE HTMLNode * PrecedingNode(HTMLNode *node, HTMLNode *root) -{ - HTMLNode *previous = node.previousSibling; - if (previous != nil) { - while (previous.lastChildNode != nil) { - previous = previous.lastChildNode; - } - return previous; - } - - if (node == root) { - return nil; - } - - return node.parentNode; -} - -NS_INLINE HTMLNode * FollowingNode(HTMLNode *node, HTMLNode *root) -{ - if (node.firstChiledNode != nil) { - return node.firstChiledNode; - } - - do { - if (node == root) { - return nil; - } - if (node.nextSibling != nil) { - return node.nextSibling; - } - node = node.parentNode; - } while (node != nil); - - return nil; -} - -NS_INLINE BOOL FilterNode(HTMLNodeIterator *iterator, HTMLNode *node) -{ - unsigned long nthBit = (1 << (node.nodeType - 1)) & iterator.whatToShow; - if (!nthBit) { - return NO; - } - - if (iterator.filter == nil) { - return YES; - } - - return [iterator.filter acceptNode:node]; -} - - (HTMLNode *)nextNode { return [self traverseInDirection:TraverseDirectionNext]; diff --git a/HTMLKit/HTMLNodeTraversal.h b/HTMLKit/HTMLNodeTraversal.h new file mode 100644 index 0000000..b3fe2f6 --- /dev/null +++ b/HTMLKit/HTMLNodeTraversal.h @@ -0,0 +1,16 @@ +// +// HTMLNodeTraversal.h +// HTMLKit +// +// Created by Iska on 05/06/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import +#import "HTMLNodeFilter.h" + +@class HTMLNode; + +extern HTMLNode * PrecedingNode(HTMLNode *node, HTMLNode *root); +extern HTMLNode * FollowingNode(HTMLNode *node, HTMLNode *root); +extern BOOL FilterNode(id filter, HTMLNodeFilterShowOptions whatToShow, HTMLNode *node); diff --git a/HTMLKit/HTMLNodeTraversal.m b/HTMLKit/HTMLNodeTraversal.m new file mode 100644 index 0000000..6f8b5eb --- /dev/null +++ b/HTMLKit/HTMLNodeTraversal.m @@ -0,0 +1,61 @@ +// +// HTMLNodeTraversal.m +// HTMLKit +// +// Created by Iska on 05/06/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLNodeTraversal.h" +#import "HTMLNode.h" +#import "HTMLNodeFilter.h" + +HTMLNode * PrecedingNode(HTMLNode *node, HTMLNode *root) +{ + HTMLNode *previous = node.previousSibling; + if (previous != nil) { + while (previous.lastChildNode != nil) { + previous = previous.lastChildNode; + } + return previous; + } + + if (node == root) { + return nil; + } + + return node.parentNode; +} + +HTMLNode * FollowingNode(HTMLNode *node, HTMLNode *root) +{ + if (node.firstChiledNode != nil) { + return node.firstChiledNode; + } + + do { + if (node == root) { + return nil; + } + if (node.nextSibling != nil) { + return node.nextSibling; + } + node = node.parentNode; + } while (node != nil); + + return nil; +} + +extern BOOL FilterNode(id filter, HTMLNodeFilterShowOptions whatToShow, HTMLNode *node) +{ + unsigned long nthBit = (1 << (node.nodeType - 1)) & whatToShow; + if (!nthBit) { + return NO; + } + + if (filter == nil) { + return YES; + } + + return [filter acceptNode:node]; +}