diff --git a/HTMLKit/CSSSelectorParser.m b/HTMLKit/CSSSelectorParser.m
index 2fd98f2..909d01a 100644
--- a/HTMLKit/CSSSelectorParser.m
+++ b/HTMLKit/CSSSelectorParser.m
@@ -346,9 +346,9 @@
NSDecimalNumber *number = [[NSDecimalNumber alloc] initWithDecimal:decimal];
if ([pseudoClass isEqualToString:@"lt"]) {
- return ltSelector(number.unsignedIntegerValue);
+ return ltSelector(number.integerValue);
} else if ([pseudoClass isEqualToString:@"gt"]) {
- return gtSelector(number.unsignedIntegerValue);
+ return gtSelector(number.integerValue);
} else if ([pseudoClass isEqualToString:@"eq"]) {
return eqSelector(number.integerValue);
}
diff --git a/HTMLKit/CSSStructuralPseudoSelectors.h b/HTMLKit/CSSStructuralPseudoSelectors.h
index 4de361c..99b9d9f 100644
--- a/HTMLKit/CSSStructuralPseudoSelectors.h
+++ b/HTMLKit/CSSStructuralPseudoSelectors.h
@@ -113,22 +113,23 @@ extern CSSSelector * requiredSelector();
/**
Less-than selector, e.g. 'lt(2)'
- Selects all elements at an index less than the specified index.
+ Selects all elements at an index less than the specified index. A negative index counts backwards from the last element.
@param index The zero-based index of the element to match.
@returns A Less-Than selector.
*/
-extern CSSSelector * ltSelector(NSUInteger index);
+extern CSSSelector * ltSelector(NSInteger index);
/**
Greater-than selector, e.g. 'gt(2)'
- Selects all elements at an index greater than the specified index.
+ Selects all elements at an index greater than the specified index. A negative index counts backwards from the
+ last element.
@param index The zero-based index of the element to match.
@returns A Greater-Than selector.
*/
-extern CSSSelector * gtSelector(NSUInteger index);
+extern CSSSelector * gtSelector(NSInteger index);
/**
Equal selector, e.g. 'eq(3)'
diff --git a/HTMLKit/CSSStructuralPseudoSelectors.m b/HTMLKit/CSSStructuralPseudoSelectors.m
index 0b4bd43..ac51a9c 100644
--- a/HTMLKit/CSSStructuralPseudoSelectors.m
+++ b/HTMLKit/CSSStructuralPseudoSelectors.m
@@ -270,19 +270,31 @@ CSSSelector * requiredSelector()
#pragma mark - Positional
-CSSSelector * ltSelector(NSUInteger index)
+CSSSelector * ltSelector(NSInteger index)
{
NSString *name = [NSString stringWithFormat:@":lt(%lu)", (unsigned long)index];
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
- return [element.parentElement indexOfChildNode:element] < index;
+ NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
+
+ if (index > 0) {
+ return elementIndex < index;
+ } else {
+ return elementIndex < element.parentElement.childNodesCount - index - 1;
+ }
});
}
-CSSSelector * gtSelector(NSUInteger index)
+CSSSelector * gtSelector(NSInteger index)
{
NSString *name = [NSString stringWithFormat:@":gt(%lu)", (unsigned long)index];
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
- return [element.parentElement indexOfChildNode:element] > index;
+ NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
+
+ if (index > 0) {
+ return elementIndex > index;
+ } else {
+ return elementIndex > element.parentElement.childNodesCount - index - 1;
+ }
});
}