From 6ed0238a8925a7bdf67289e1804f9b4d5a4662d0 Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 22 Nov 2016 01:19:32 +0100 Subject: [PATCH] =?UTF-8?q?Add=20implementation=20for=20setting=20HTML=20R?= =?UTF-8?q?ange=E2=80=99s=20boundaries?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/HTMLKitDOMExceptions.m | 2 + Sources/HTMLRange.h | 4 +- Sources/HTMLRange.m | 83 ++++++++++++++++++++++++++ Sources/include/HTMLKitDOMExceptions.h | 3 + 4 files changed, 90 insertions(+), 2 deletions(-) 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;