diff --git a/Sources/HTMLText.m b/Sources/HTMLText.m index 24e2728..605a924 100644 --- a/Sources/HTMLText.m +++ b/Sources/HTMLText.m @@ -10,6 +10,8 @@ #import "HTMLElement.h" #import "NSString+HTMLKit.h" #import "HTMLCharacterData+Private.h" +#import "HTMLKitDOMExceptions.h" +#import "HTMLDocument+Private.h" @implementation HTMLText @@ -28,6 +30,42 @@ [self appendData:string]; } +NS_INLINE void CheckValidOffset(HTMLNode *node, NSUInteger offset, NSString *cmd) +{ + if (offset > node.length) { + [NSException raise:HTMLKitIndexSizeError + format:@"%@: Index Size Error, invalid offset %lu for splitting text node %@.", + cmd, (unsigned long)offset, node]; + } +} + +- (HTMLNode *)splitTextAtOffset:(NSUInteger)offset +{ + CheckValidOffset(self, offset, NSStringFromSelector(_cmd)); + + NSUInteger length = self.length; + NSUInteger count = length - offset; + NSRange range = NSMakeRange(offset, count); + + NSString *newData = [self.data substringWithRange:range]; + HTMLText *newNode = [[HTMLText alloc] initWithData:newData]; + [self.ownerDocument adoptNode:newNode]; + + HTMLNode *parent = self.parentNode; + if (parent != nil) { + [parent insertNode:newNode beforeChildNode:self.nextSibling]; + [self.ownerDocument didInsertNewTextNode:newNode intoParent:parent afterSplittingTextNode:self atOffset:offset]; + } + + [self deleteDataInRange:range]; + + if (parent != nil) { + [self.ownerDocument clampRangesAfterSplittingTextNode:self atOffset:offset]; + } + + return newNode; +} + #pragma mark - Serialization - (NSString *)outerHTML diff --git a/Sources/include/HTMLText.h b/Sources/include/HTMLText.h index 8578c55..872550d 100644 --- a/Sources/include/HTMLText.h +++ b/Sources/include/HTMLText.h @@ -30,6 +30,8 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)appendString:(NSString *)string __attribute__((deprecated("Use `appendData:` instead."))); +- (HTMLNode *)splitTextAtOffset:(NSUInteger)offset; + @end NS_ASSUME_NONNULL_END