diff --git a/Sources/HTMLKitDOMExceptions.m b/Sources/HTMLKitDOMExceptions.m
index 7a0d349..1a596a3 100644
--- a/Sources/HTMLKitDOMExceptions.m
+++ b/Sources/HTMLKitDOMExceptions.m
@@ -14,3 +14,5 @@ NSString * const HTMLKitNotFoundError = @"NotFoundError";
NSString * const HTMLKitNotSupportedError = @"NotSupportedError";
NSString * const HTMLKitSyntaxError = @"SyntaxError";
NSString * const HTMLKitInvalidCharacterError = @"InvalidCharacterError";
+NSString * const HTMLKitInvalidNodeTypeError = @"InvalidNodeTypeError";
+NSString * const HTMLKitIndexSizeError = @"IndexSizeError";
diff --git a/Sources/HTMLRange.h b/Sources/HTMLRange.h
index 1a15245..860a54d 100644
--- a/Sources/HTMLRange.h
+++ b/Sources/HTMLRange.h
@@ -67,7 +67,7 @@
@param startNode The new node of the start boundary.
@param startOffset The new offset of the start boundary.
*/
-- (void)setStartNode:(HTMLNode *)startNode startOffset:(NSUInteger)startOffset;
+- (void)setStartNode:(HTMLNode *)node startOffset:(NSUInteger)offset;
/**
Sets the end boundary.
@@ -75,7 +75,7 @@
@param startNode The new node of the end boundary.
@param startOffset The new offset of the end boundary.
*/
-- (void)setEndNode:(HTMLNode *)endNode endOffset:(NSUInteger)endOffset;
+- (void)setEndNode:(HTMLNode *)node endOffset:(NSUInteger)offset;
/**
Sets the start boundary before the given node.
diff --git a/Sources/HTMLRange.m b/Sources/HTMLRange.m
index f403df6..e7f2550 100644
--- a/Sources/HTMLRange.m
+++ b/Sources/HTMLRange.m
@@ -7,7 +7,90 @@
//
#import "HTMLRange.h"
+#import "HTMLKitDOMExceptions.h"
@implementation HTMLRange
+
+#pragma mark - Boundaries
+
+NS_INLINE void CheckValidBoundaryNode(HTMLNode *node, NSString *cmd)
+{
+ if (node == nil || node.nodeType == HTMLNodeDocumentType) {
+ [NSException raise:HTMLKitNotFoundError
+ format:@"%@: Invalid Node Type Error, %@ is not a valid range boundary node.",
+ cmd, node];
+ }
+}
+
+NS_INLINE void CheckValidBoundaryOffset(HTMLNode *node, NSUInteger offset, NSString *cmd)
+{
+ if (node == nil || node.nodeType == HTMLNodeDocumentType) {
+ [NSException raise:HTMLKitIndexSizeError
+ format:@"%@: Index Size Error, invalid index %lu for range boundary node %@.",
+ cmd, (unsigned long)offset, node];
+ }
+}
+
+NS_INLINE NSComparisonResult CompareBoundaries(HTMLNode *startNode, NSUInteger startOffset, HTMLNode *endNode, NSUInteger endOffset)
+{
+ if (startNode == endNode) {
+ if (startOffset == endOffset) {
+ return NSOrderedSame;
+ } else if (startOffset < endOffset) {
+ return NSOrderedAscending;
+ } else {
+ return NSOrderedDescending;
+ }
+ }
+
+ HTMLDocumentPosition position = [startNode compareDocumentPositionWithNode:endNode];
+ if ((position & HTMLDocumentPositionFollowing) == HTMLDocumentPositionFollowing) {
+ // Check Spec
+ }
+
+ if ([startNode containsNode:endNode]) {
+ HTMLNode *child = endNode;
+ while (child.parentNode != startNode) {
+ child = child.parentNode;
+ }
+ if ([child.parentNode indexOfChildNode:child] > startOffset) {
+ return NSOrderedDescending;
+ }
+ }
+
+ return NSOrderedAscending;
+}
+
+- (void)setStartNode:(HTMLNode *)node startOffset:(NSUInteger)offset
+{
+ CheckValidBoundaryNode(node, NSStringFromSelector(_cmd));
+
+ CheckValidBoundaryOffset(node, offset, NSStringFromSelector(_cmd));
+
+ if (self.rootNode != node.rootNode ||
+ CompareBoundaries(node, offset, _endContainer, _endOffset) == NSOrderedDescending) {
+ _endContainer = node;
+ _endOffset = offset;
+ }
+
+ _startContainer = node;
+ _startOffset = offset;
+}
+
+- (void)setEndNode:(HTMLNode *)node endOffset:(NSUInteger)offset
+{
+ CheckValidBoundaryNode(node, NSStringFromSelector(_cmd));
+
+ CheckValidBoundaryOffset(node, offset, NSStringFromSelector(_cmd));
+
+ if (self.rootNode != node.rootNode ||
+ CompareBoundaries(node, offset, _startContainer, _startOffset) == NSOrderedAscending) {
+ _startContainer = node;
+ _startOffset = offset;
+ }
+
+ _endContainer = node;
+ _endOffset = offset;
+}
@end
diff --git a/Sources/include/HTMLKitDOMExceptions.h b/Sources/include/HTMLKitDOMExceptions.h
index 115b884..f11518c 100644
--- a/Sources/include/HTMLKitDOMExceptions.h
+++ b/Sources/include/HTMLKitDOMExceptions.h
@@ -14,3 +14,6 @@ extern NSString * const HTMLKitNotSupportedError;
extern NSString * const HTMLKitSyntaxError;
extern NSString * const HTMLKitInvalidCharacterError;
+
+extern NSString * const HTMLKitInvalidNodeTypeError;
+extern NSString * const HTMLKitIndexSizeError;