Merge branch 'release/2.0.6'

This commit is contained in:
iska
2017-05-02 15:49:15 +02:00
10 changed files with 208 additions and 138 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
module: HTMLKit
module_version: 2.0.5
module_version: 2.0.6
author: Iskandar Abudiab
author_url: https://twitter.com/iabudiab
github_url: https://github.com/iabudiab/HTMLKit
+9 -11
View File
@@ -1,5 +1,5 @@
language: objective-c
osx_image: xcode8.2
osx_image: xcode8.3
branches:
except:
@@ -17,21 +17,19 @@ env:
- MACOS_FRAMEWORK_SCHEME=HTMLKit-macOS
- WATCHOS_FRAMEWORK_SCHEME="HTMLKit-watchOS"
- TVOS_FRAMEWORK_SCHEME="HTMLKit-tvOS"
- IOS_SDK=iphonesimulator10.2
- IOS_SDK=iphonesimulator10.3
- MACOS_SDK=macosx10.12
- WATCHOS_SDK=watchsimulator3.1
- TVOS_SDK=appletvsimulator10.1
- WATCHOS_SDK=watchsimulator3.2
- TVOS_SDK=appletvsimulator10.2
matrix:
- DESTINATION="arch=x86_64" SIMULATOR="" SCHEME="$MACOS_FRAMEWORK_SCHEME" SDK="$MACOS_SDK"
- DESTINATION="OS=9.0,name=iPhone 6" SIMULATOR="iPhone 6 (9.0)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=9.1,name=iPhone 6 Plus" SIMULATOR="iPhone 6 Plus (9.1)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=9.2,name=iPhone 6S" SIMULATOR="iPhone 6S (9.2)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=8.4,name=iPhone 6 Plus" SIMULATOR="iPhone 6 Plus (8.4)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=9.3,name=iPhone 6S Plus" SIMULATOR="iPhone 6S Plus (9.3)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=10.1,name=iPhone 7 Plus" SIMULATOR="iPhone 7 Plus (10.1)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=10.3,name=iPhone 7 Plus" SIMULATOR="iPhone 7 Plus (10.3)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=2.2,name=Apple Watch - 42mm" SIMULATOR="Apple Watch - 42mm (2.2)" SCHEME="$WATCHOS_FRAMEWORK_SCHEME" SDK="$WATCHOS_SDK"
- DESTINATION="OS=3.1,name=Apple Watch Series 2 - 42mm" SIMULATOR="Apple Watch Series 2 - 42mm (3.1)" SCHEME="$WATCHOS_FRAMEWORK_SCHEME" SDK="$WATCHOS_SDK"
- DESTINATION="OS=9.0,name=Apple TV 1080p" SIMULATOR="Apple TV 1080p (9.2)" SCHEME="$TVOS_FRAMEWORK_SCHEME" SDK="$TVOS_SDK"
- DESTINATION="OS=10.0,name=Apple TV 1080p" SIMULATOR="Apple TV 1080p (10.0)" SCHEME="$TVOS_FRAMEWORK_SCHEME" SDK="$TVOS_SDK"
- DESTINATION="OS=3.2,name=Apple Watch Series 2 - 42mm" SIMULATOR="Apple Watch Series 2 - 42mm (3.2)" SCHEME="$WATCHOS_FRAMEWORK_SCHEME" SDK="$WATCHOS_SDK"
- DESTINATION="OS=9.2,name=Apple TV 1080p" SIMULATOR="Apple TV 1080p (9.2)" SCHEME="$TVOS_FRAMEWORK_SCHEME" SDK="$TVOS_SDK"
- DESTINATION="OS=10.2,name=Apple TV 1080p" SIMULATOR="Apple TV 1080p (10.2)" SCHEME="$TVOS_FRAMEWORK_SCHEME" SDK="$TVOS_SDK"
script:
- set -o pipefail
+19
View File
@@ -1,15 +1,30 @@
# Change Log
## [2.0.6](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.6)
Released on 2017.05.02
### Added
- Memory consumption improvements (issue #10)
- Allocate `childNodes` collection in `HTMLNode` only when inserting child nodes
- Replace `NSStringFromSelector` calls with constants in `HTMLNode` validations
- Improve `reverseObjectEnumerator` usage while parsing HTML
- Rewrite internal logic of the `HTMLStackOfOpenElements` to prevent excessive allocations
## [2.0.5](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.5)
Released on 2017.04.19
### Fixed
- Xcode 8.3 issue with modulemaps
- Temporary workaround (renamed modulemap file)
- Memory Leaks in `CSSInputStream`
### Added
- Minor memory consumption improvements
- Collections for child nodes or attributes of HTML Nodes or Elements are allocated lazily
- Underyling data string of `CharacterData` is allocated on first access
@@ -21,10 +36,12 @@ Released on 2017.04.19
Released on 2017.04.2
### Fixed
- Testing with Swift 3.1
- Fixed by @tali in PR #8
### Deprecated
- `HTMLRange` initializers with typo
- `initWithDowcument:startContainer:startOffset:endContainer:endOffset:`
@@ -34,6 +51,7 @@ Released on 2017.04.2
Released on 2017.03.6
### Fixed
- Compilation for Swift 3.1
- Fixed by @tali in PR #6
@@ -43,6 +61,7 @@ Released on 2017.03.6
Released on 2017.02.26
### Fixed
- Retain cycles in `HTMLNodeIterator` (issue #4)
- Retain cycles in `HTMLRange` (issue #5)
- The layout of `HTMLKit` tests module for Swift Package Manager
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "HTMLKit"
s.version = "2.0.5"
s.version = "2.0.6"
s.summary = "HTMLKit, an Objective-C framework for your everyday HTML needs."
s.license = "MIT"
s.homepage = "https://github.com/iabudiab/HTMLKit"
+1 -1
View File
@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.0.5</string>
<string>2.0.6</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+1 -1
View File
@@ -46,7 +46,7 @@
- (void)addElement:(HTMLElement *)element
{
NSUInteger existing = 0;
for (HTMLElement *node in _list.reverseObjectEnumerator.allObjects) {
for (HTMLElement *node in _list.reverseObjectEnumerator) {
if ([node isEqual:[HTMLMarker marker]]) {
break;
}
+40 -32
View File
@@ -19,6 +19,10 @@
#import "HTMLDocument+Private.h"
#import "HTMLDOMUtils.h"
NSString * const ValidationNodePreInsertion = @"-ensurePreInsertionValidityOfNode:beforeChildNode:";
NSString * const ValidationNodeReplacement = @"-ensureReplacementValidityOfChildNode:withNode:";
NSString * const RemoveChildNode = @"-removeChildNode:";
@interface HTMLNode ()
{
NSMutableOrderedSet *_childNodes;
@@ -64,7 +68,7 @@
- (void)setOwnerDocument:(HTMLDocument *)ownerDocument
{
_ownerDocument = ownerDocument;
for (HTMLNode *child in self.childNodes) {
for (HTMLNode *child in _childNodes) {
[child setOwnerDocument:ownerDocument];
}
}
@@ -86,12 +90,12 @@
- (HTMLNode *)firstChild
{
return self.childNodes.firstObject;
return _childNodes.firstObject;
}
- (HTMLNode *)lastChild
{
return self.childNodes.lastObject;
return _childNodes.lastObject;
}
- (HTMLNode *)previousSibling
@@ -132,7 +136,7 @@
- (NSUInteger)index
{
return [self.parentNode indexOfChildNode:self];
return [_parentNode indexOfChildNode:self];
}
- (NSString *)textContent
@@ -156,12 +160,16 @@
- (BOOL)hasChildNodes
{
return self.childNodes.count > 0;
return _childNodes.count > 0;
}
- (BOOL)hasChildNodeOfType:(HTMLNodeType)type
{
NSUInteger index = [self.childNodes indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
if (_childNodes == nil) {
return NO;
}
NSUInteger index = [_childNodes indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
if ([(HTMLNode *)obj nodeType] == type) {
*stop = YES;
return YES;
@@ -174,7 +182,7 @@
- (NSUInteger)childNodesCount
{
return self.childNodes.count;
return _childNodes.count;
}
- (BOOL)isEmpty
@@ -184,25 +192,25 @@
- (HTMLNode *)childNodeAtIndex:(NSUInteger)index
{
return [self.childNodes objectAtIndex:index];
return [_childNodes objectAtIndex:index];
}
- (NSUInteger)childElementsCount
{
return [self.childNodes indexesOfObjectsPassingTest:^BOOL(HTMLNode * _Nonnull node, NSUInteger idx, BOOL * _Nonnull stop) {
return [_childNodes indexesOfObjectsPassingTest:^BOOL(HTMLNode * _Nonnull node, NSUInteger idx, BOOL * _Nonnull stop) {
return node.nodeType == HTMLNodeElement;
}].count;
}
- (NSUInteger)indexOfChildNode:(HTMLNode *)node
{
return [self.childNodes indexOfObject:node];
return [_childNodes indexOfObject:node];
}
- (HTMLElement *)childElementAtIndex:(NSUInteger)index
{
NSUInteger counter = 0;
for (HTMLNode *node in self.childNodes) {
for (HTMLNode *node in _childNodes) {
if (node.nodeType == HTMLNodeElement) {
if (counter == index) {
return node.asElement;
@@ -216,7 +224,7 @@
- (NSUInteger)indexOfChildElement:(HTMLElement *)element
{
NSUInteger counter = 0;
for (HTMLNode *node in self.childNodes) {
for (HTMLNode *node in _childNodes) {
if (node.nodeType == HTMLNodeElement) {
if (node == element) {
return counter;
@@ -303,7 +311,7 @@
- (void)removeFromParentNode
{
[self.parentNode removeChildNode:self];
[_parentNode removeChildNode:self];
}
- (HTMLNode *)removeChildNode:(HTMLNode *)child
@@ -311,7 +319,7 @@
if (child.parentNode != self) {
[NSException raise:HTMLKitNotFoundError
format:@"%@: Not Fount Error, removing non-child node %@. The object can not be found here.",
NSStringFromSelector(_cmd), child];
RemoveChildNode, child];
}
HTMLNode *oldNode = child;
@@ -335,18 +343,18 @@
- (void)reparentChildNodesIntoNode:(HTMLNode *)node
{
for (HTMLNode *child in self.childNodes) {
for (HTMLNode *child in _childNodes) {
[node appendNode:child];
}
[(NSMutableOrderedSet *)self.childNodes removeAllObjects];
[(NSMutableOrderedSet *)_childNodes removeAllObjects];
}
- (void)removeAllChildNodes
{
for (HTMLNode *child in self.childNodes) {
for (HTMLNode *child in _childNodes) {
[child setParentNode:nil];
}
[(NSMutableOrderedSet *)self.childNodes removeAllObjects];
[(NSMutableOrderedSet *)_childNodes removeAllObjects];
}
- (HTMLDocumentPosition)compareDocumentPositionWithNode:(HTMLNode *)otherNode
@@ -417,7 +425,7 @@
return self.nodeType != HTMLNodeDocument && self.ownerDocument == otherNode;
}
for (HTMLNode *parentNode = self.parentNode; parentNode; parentNode = parentNode.parentNode) {
for (HTMLNode *parentNode = _parentNode; parentNode; parentNode = parentNode.parentNode) {
if (parentNode == otherNode) {
return YES;
}
@@ -439,7 +447,7 @@
return;
}
[self.childNodes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[_childNodes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
block(obj, idx, stop);
}];
}
@@ -450,7 +458,7 @@
return;
}
[self.childNodes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[_childNodes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[HTMLElement class]]) {
block([obj asElement], idx, stop);
}
@@ -573,18 +581,18 @@ NS_INLINE void CheckInvalidCombination(HTMLNode *parent, HTMLNode *node, NSStrin
- (void)ensurePreInsertionValidityOfNode:(HTMLNode *)node beforeChildNode:(HTMLNode *)child
{
CheckParentValid(self, NSStringFromSelector(_cmd));
CheckParentValid(self, ValidationNodePreInsertion);
CheckChildsParent(self, child, NSStringFromSelector(_cmd));
CheckChildsParent(self, child, ValidationNodePreInsertion);
CheckInsertedNodeValid(node, NSStringFromSelector(_cmd));
CheckInsertedNodeValid(node, ValidationNodePreInsertion);
CheckInvalidCombination(self, node, NSStringFromSelector(_cmd));
CheckInvalidCombination(self, node, ValidationNodePreInsertion);
void (^ hierarchyError)() = ^{
[NSException raise:HTMLKitHierarchyRequestError
format:@"%@: Hierarchy Request Error, inserting (%@) into (%@). The operation would yield an incorrect node tree.",
NSStringFromSelector(_cmd), self, node];
ValidationNodePreInsertion, self, node];
};
if (self.nodeType == HTMLNodeDocument) {
@@ -623,18 +631,18 @@ NS_INLINE void CheckInvalidCombination(HTMLNode *parent, HTMLNode *node, NSStrin
- (void)ensureReplacementValidityOfChildNode:(HTMLNode *)child withNode:(HTMLNode *)node
{
CheckParentValid(self, NSStringFromSelector(_cmd));
CheckParentValid(self, ValidationNodeReplacement);
CheckChildsParent(self, child, NSStringFromSelector(_cmd));
CheckChildsParent(self, child, ValidationNodeReplacement);
CheckInsertedNodeValid(node, NSStringFromSelector(_cmd));
CheckInsertedNodeValid(node, ValidationNodeReplacement);
CheckInvalidCombination(self, node, NSStringFromSelector(_cmd));
CheckInvalidCombination(self, node, ValidationNodeReplacement);
void (^ hierarchyError)() = ^{
[NSException raise:HTMLKitHierarchyRequestError
format:@"%@: Hierarchy Request Error. The operation would yield an incorrect node tree.",
NSStringFromSelector(_cmd)];
ValidationNodeReplacement];
};
void (^ checkParentHasAnotherChildOfType)(HTMLNodeType) = ^ void (HTMLNodeType type) {
@@ -690,7 +698,7 @@ NS_INLINE void CheckInvalidCombination(HTMLNode *parent, HTMLNode *node, NSStrin
HTMLNode *copy = [self copy];
if (deep) {
for (HTMLNode *child in self.childNodes) {
for (HTMLNode *child in _childNodes) {
[copy appendNode:[child cloneNodeDeep:YES]];
}
}
+5 -5
View File
@@ -1272,7 +1272,7 @@
@"dd": @[@"dd", @"dt"],
@"dt": @[@"dd", @"dt"]};
for (HTMLElement *node in _stackOfOpenElements.reverseObjectEnumerator.allObjects) {
for (HTMLElement *node in _stackOfOpenElements.reverseObjectEnumerator) {
if ([map[tagName] containsObject:node.tagName]) {
[self generateImpliedEndTagsExceptForElement:node.tagName];
if (![self.currentNode.tagName isEqualToString:node.tagName]) {
@@ -1529,7 +1529,7 @@
}
[self closePElement];
} else if ([tagName isEqualToString:@"li"]) {
if (![_stackOfOpenElements hasElementInListItemScopeWithTagName:@"li"]) {
if (![_stackOfOpenElements hasElementInListItemScopeWithTagName:tagName]) {
[self emitParseError:@"Unexpected <li> element in <body>"];
return;
}
@@ -1549,7 +1549,7 @@
}
[_stackOfOpenElements popElementsUntilElementPoppedWithTagName:tagName];
} else if ([tagName isEqualToAny:@"h1", @"h2", @"h3", @"h4", @"h5", @"h6", nil]) {
if (![_stackOfOpenElements hasAnyElementInScopeWithAnyOfTagNames:@[@"h1", @"h2", @"h3", @"h4", @"h5", @"h6"]]) {
if (![_stackOfOpenElements hasHeaderElementInScope]) {
[self emitParseError:@"Unexpected <%@> element in <body>", tagName];
return;
}
@@ -1569,7 +1569,7 @@
return;
}
} else if ([tagName isEqualToAny:@"applet", @"marquee", @"object", nil]) {
if (![_stackOfOpenElements hasAnyElementInScopeWithAnyOfTagNames:@[@"applet", @"marquee", @"object"]]) {
if (![_stackOfOpenElements hasElementInScopeWithTagName:tagName]) {
[self emitParseError:@"Unexpected <%@> element in <body>", tagName];
return;
}
@@ -1590,7 +1590,7 @@
- (void)processAnyOtherEndTagTokenInBody:(HTMLTagToken *)token
{
for (HTMLElement *node in _stackOfOpenElements.reverseObjectEnumerator.allObjects) {
for (HTMLElement *node in _stackOfOpenElements.reverseObjectEnumerator) {
if ([node.tagName isEqualToString:token.tagName]) {
[self generateImpliedEndTagsExceptForElement:token.tagName];
if (![node.tagName isEqualToString:self.currentNode.tagName]) {
+128 -83
View File
@@ -14,7 +14,6 @@
@interface HTMLStackOfOpenElements ()
{
NSMutableArray *_stack;
NSDictionary *_specificScopeElementTypes;
}
@end
@@ -27,26 +26,6 @@
self = [super init];
if (self) {
_stack = [NSMutableArray new];
_specificScopeElementTypes = @{
@"applet": @(HTMLNamespaceHTML),
@"caption": @(HTMLNamespaceHTML),
@"html": @(HTMLNamespaceHTML),
@"table": @(HTMLNamespaceHTML),
@"td": @(HTMLNamespaceHTML),
@"th": @(HTMLNamespaceHTML),
@"marquee": @(HTMLNamespaceHTML),
@"object": @(HTMLNamespaceHTML),
@"template": @(HTMLNamespaceHTML),
@"mi": @(HTMLNamespaceMathML),
@"mo": @(HTMLNamespaceMathML),
@"mn": @(HTMLNamespaceMathML),
@"ms": @(HTMLNamespaceMathML),
@"mtext": @(HTMLNamespaceMathML),
@"annotation-xml": @(HTMLNamespaceMathML),
@"foreignObject": @(HTMLNamespaceSVG),
@"desc": @(HTMLNamespaceSVG),
@"title": @(HTMLNamespaceSVG)
};
}
return self;
}
@@ -195,82 +174,148 @@
#pragma mark - Element Scope
NS_INLINE BOOL IsSpecificScopeElement(HTMLElement *element)
{
switch (element.htmlNamespace) {
case HTMLNamespaceHTML:
return [element.tagName isEqualToAny:@"applet", @"caption", @"html", @"table", @"td", @"th", @"marquee", @"object", @"template", nil];
case HTMLNamespaceMathML:
return [element.tagName isEqualToAny:@"mi", @"mo", @"mn", @"ms", @"mtext", @"annotation-xml", nil];
case HTMLNamespaceSVG:
return [element.tagName isEqualToAny:@"foreignObject", @"desc", @"title", nil];
}
}
NS_INLINE BOOL IsHeaderElement(HTMLElement *element)
{
if (element.htmlNamespace != HTMLNamespaceHTML) {
return NO;
}
return [element.tagName isEqualToAny:@"h1", @"h2", @"h3", @"h4", @"h5", @"h6", nil];
}
NS_INLINE BOOL IsTableScopeElement(HTMLElement *element)
{
if (element.htmlNamespace != HTMLNamespaceHTML) {
return NO;
}
return [element.tagName isEqualToAny:@"html", @"table", @"template", nil];
}
NS_INLINE BOOL IsListItemScopeElement(HTMLElement *element)
{
if (element.htmlNamespace != HTMLNamespaceHTML) {
return NO;
}
return [element.tagName isEqualToAny:@"ol", @"ul", nil];
}
NS_INLINE BOOL IsSelectScopeElement(HTMLElement *element)
{
if (element.htmlNamespace != HTMLNamespaceHTML) {
return NO;
}
return ![element.tagName isEqualToString:@"optgroup"] && ![element.tagName isEqualToString:@"option"];
}
NS_INLINE BOOL IsButtonScopeElement(HTMLElement *element)
{
if (element.htmlNamespace != HTMLNamespaceHTML) {
return NO;
}
return [element.tagName isEqualToString:@"button"];
}
- (HTMLElement *)hasElementInScopeWithTagName:(NSString *)tagName;
{
return [self hasAnyElementInSpecificScopeWithTagNames:@[tagName] andElementTypes:_specificScopeElementTypes];
}
- (HTMLElement *)hasAnyElementInScopeWithAnyOfTagNames:(NSArray *)tagNames
{
return [self hasAnyElementInSpecificScopeWithTagNames:tagNames andElementTypes:_specificScopeElementTypes];
}
- (HTMLElement *)hasElementInListItemScopeWithTagName:(NSString *)tagName
{
NSMutableDictionary *elementTypes = [NSMutableDictionary dictionaryWithDictionary:_specificScopeElementTypes];
[elementTypes addEntriesFromDictionary:@{@"ol": @(HTMLNamespaceHTML),
@"ul": @(HTMLNamespaceHTML)}];
return [self hasElementInSpecificScopeWithTagName:tagName
andElementTypes:elementTypes];
}
- (HTMLElement *)hasElementInButtonScopeWithTagName:(NSString *)tagName
{
NSMutableDictionary *elementTypes = [NSMutableDictionary dictionaryWithDictionary:_specificScopeElementTypes];
[elementTypes addEntriesFromDictionary:@{@"button": @(HTMLNamespaceHTML)}];
return [self hasElementInSpecificScopeWithTagName:tagName
andElementTypes:elementTypes];
}
- (HTMLElement *)hasElementInTableScopeWithTagName:(NSString *)tagName
{
return [self hasElementInSpecificScopeWithTagName:tagName
andElementTypes:@{@"html": @(HTMLNamespaceHTML),
@"table": @(HTMLNamespaceHTML),
@"template": @(HTMLNamespaceHTML)}];
}
- (HTMLElement *)hasElementInTableScopeWithAnyOfTagNames:(NSArray *)tagNames
{
return [self hasAnyElementInSpecificScopeWithTagNames:tagNames
andElementTypes:@{@"html": @(HTMLNamespaceHTML),
@"table": @(HTMLNamespaceHTML),
@"template": @(HTMLNamespaceHTML)}];
}
- (HTMLElement *)hasElementInSelectScopeWithTagName:(NSString *)tagName
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if ([node.tagName isEqualToString:tagName]) {
if (node.htmlNamespace == HTMLNamespaceHTML && [tagName isEqualToString:node.tagName]) {
return node;
}
if (!(node.htmlNamespace == HTMLNamespaceHTML &&
[node.tagName isEqualToAny:@"optgroup", @"option", nil])) {
if (IsSpecificScopeElement(node)) {
return nil;
}
}
return nil;
}
- (HTMLElement *)hasElementInSpecificScopeWithTagName:(NSString *)tagName
andElementTypes:(NSDictionary *)elementTypes
{
return [self hasAnyElementInSpecificScopeWithTagNames:@[tagName] andElementTypes:elementTypes];
}
- (HTMLElement *)hasAnyElementInSpecificScopeWithTagNames:(NSArray *)tagNames
andElementTypes:(NSDictionary *)elementTypes
- (HTMLElement *)hasHeaderElementInScope
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if ([tagNames containsObject:node.tagName]) {
NSNumber *namespace = elementTypes[node.tagName] ?: @(HTMLNamespaceHTML);
if ([namespace isEqual:@(node.htmlNamespace)]) {
return node;
}
if (IsHeaderElement(node)) {
return node;
}
if ([elementTypes[node.tagName] isEqual:@(node.htmlNamespace)]) {
if (IsSpecificScopeElement(node)) {
return nil;
}
}
return nil;
}
- (HTMLElement *)hasElementInTableScopeWithTagName:(NSString *)tagName
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if (node.htmlNamespace == HTMLNamespaceHTML && [tagName isEqualToString:node.tagName]) {
return node;
}
if (IsTableScopeElement(node)) {
return nil;
}
}
return nil;
}
- (HTMLElement *)hasElementInTableScopeWithAnyOfTagNames:(NSArray *)tagNames
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if (node.htmlNamespace == HTMLNamespaceHTML && [tagNames containsObject:node.tagName]) {
return node;
}
if (IsTableScopeElement(node)) {
return nil;
}
}
return nil;
}
- (HTMLElement *)hasElementInListItemScopeWithTagName:(NSString *)tagName
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if (node.htmlNamespace == HTMLNamespaceHTML && [tagName isEqualToString:node.tagName]) {
return node;
}
if (IsSpecificScopeElement(node) || IsListItemScopeElement(node)) {
return nil;
}
}
return nil;
}
- (HTMLElement *)hasElementInButtonScopeWithTagName:(NSString *)tagName
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if (node.htmlNamespace == HTMLNamespaceHTML && [tagName isEqualToString:node.tagName]) {
return node;
}
if (IsSpecificScopeElement(node) || IsButtonScopeElement(node)) {
return nil;
}
}
return nil;
}
- (HTMLElement *)hasElementInSelectScopeWithTagName:(NSString *)tagName
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if (node.htmlNamespace == HTMLNamespaceHTML && [tagName isEqualToString:node.tagName]) {
return node;
}
if (IsSelectScopeElement(node)) {
return nil;
}
}
+3 -3
View File
@@ -163,11 +163,11 @@
https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-the-specific-scope
*/
- (HTMLElement *)hasElementInScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasAnyElementInScopeWithAnyOfTagNames:(NSArray *)tagNames;
- (HTMLElement *)hasElementInListItemScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasElementInButtonScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasHeaderElementInScope;
- (HTMLElement *)hasElementInTableScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasElementInTableScopeWithAnyOfTagNames:(NSArray *)tagNames;
- (HTMLElement *)hasElementInListItemScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasElementInButtonScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasElementInSelectScopeWithTagName:(NSString *)tagName;
/**