diff --git a/HTMLKit/HTMLCharacterToken.h b/HTMLKit/HTMLCharacterToken.h index be3d4ee..0341991 100644 --- a/HTMLKit/HTMLCharacterToken.h +++ b/HTMLKit/HTMLCharacterToken.h @@ -16,10 +16,12 @@ - (instancetype)initWithString:(NSString *)string; - (void)appendString:(NSString *)string; - - (BOOL)isWhitespaceToken; -- (HTMLCharacterToken *)tokenByRetainingLeadingWhitespace; -- (HTMLCharacterToken *)tokenByTrimmingLeadingWhitespace; -- (HTMLCharacterToken *)tokenByTrimmingFormIndex:(NSUInteger)index; +- (BOOL)isEmpty; + +- (void)retainLeadingWhitespace; +- (void)trimLeadingWhitespace; +- (void)trimFormIndex:(NSUInteger)index; +- (HTMLCharacterToken *)tokenBySplitingLeadingWhiteSpace; @end diff --git a/HTMLKit/HTMLCharacterToken.m b/HTMLKit/HTMLCharacterToken.m index 2548558..1425778 100644 --- a/HTMLKit/HTMLCharacterToken.m +++ b/HTMLKit/HTMLCharacterToken.m @@ -39,31 +39,44 @@ return [_characters isHTMLWhitespaceString]; } -- (HTMLCharacterToken *)tokenByRetainingLeadingWhitespace +- (BOOL)isEmpty +{ + return _characters.length == 0; +} + +- (void)retainLeadingWhitespace +{ + NSUInteger index = _characters.leadingWhitespaceLength; + if (index > 0) { + [_characters setString:[_characters substringToIndex:index]]; + } +} + +- (void)trimLeadingWhitespace +{ + NSUInteger index = _characters.leadingWhitespaceLength; + if (index > 0) { + [_characters setString:[_characters substringFromIndex:index]]; + } +} + +- (void)trimFormIndex:(NSUInteger)index +{ + [_characters setString:[_characters substringFromIndex:index]]; +} + +- (HTMLCharacterToken *)tokenBySplitingLeadingWhiteSpace { NSUInteger index = _characters.leadingWhitespaceLength; if (index > 0) { NSString *leading = [_characters substringToIndex:index]; + [_characters setString:[_characters substringFromIndex:index]]; return [[HTMLCharacterToken alloc] initWithString:leading]; } - return nil; -} -- (HTMLCharacterToken *)tokenByTrimmingLeadingWhitespace -{ - NSUInteger index = _characters.leadingWhitespaceLength; - if (index < _characters.length) { - NSString *remaining = [_characters substringFromIndex:index]; - return [[HTMLCharacterToken alloc] initWithString:remaining]; - } return nil; } -- (HTMLCharacterToken *)tokenByTrimmingFormIndex:(NSUInteger)index -{ - return [[HTMLCharacterToken alloc] initWithString:[_characters substringFromIndex:index]]; -} - #pragma mark - NSObject - (BOOL)isEqual:(id)other diff --git a/HTMLKit/HTMLParser.m b/HTMLKit/HTMLParser.m index 4b9b8db..5a28b5d 100644 --- a/HTMLKit/HTMLParser.m +++ b/HTMLKit/HTMLParser.m @@ -253,7 +253,7 @@ if (characters.length <= 1) { return; } - token = [token.asCharacterToken tokenByTrimmingFormIndex:1]; + [token.asCharacterToken trimFormIndex:1]; } } } @@ -713,10 +713,14 @@ { switch (token.type) { case HTMLTokenTypeCharacter: - if ([token.asCharacterToken isWhitespaceToken]) { + { + [token.asCharacterToken trimLeadingWhitespace]; + + if (token.asCharacterToken.isEmpty) { return; } break; + } case HTMLTokenTypeComment: [self insertComment:token.asCommentToken asChildOfNode:_document]; return; @@ -761,10 +765,14 @@ [self insertComment:token.asCommentToken asChildOfNode:_document]; return; case HTMLTokenTypeCharacter: - if ([token.asCharacterToken isWhitespaceToken]) { + { + [token.asCharacterToken trimLeadingWhitespace]; + + if (token.asCharacterToken.isEmpty) { return; } break; + } case HTMLTokenTypeStartTag: if ([token.asStartTagToken.tagName isEqualToString:@"html"]) { HTMLElement *html = [self createElementForToken:token.asTagToken inNamespace:HTMLNamespaceHTML]; @@ -795,10 +803,14 @@ { switch (token.type) { case HTMLTokenTypeCharacter: - if ([token.asCharacterToken isWhitespaceToken]) { + { + [token.asCharacterToken trimLeadingWhitespace]; + + if (token.asCharacterToken.isEmpty) { return; } break; + } case HTMLTokenTypeComment: [self insertComment:token.asCommentToken]; return; @@ -838,11 +850,12 @@ switch (token.type) { case HTMLTokenTypeCharacter: { - HTMLCharacterToken *leadingWhiteSpace = [token.asCharacterToken tokenByRetainingLeadingWhitespace]; + HTMLCharacterToken *leadingWhiteSpace = [token.asCharacterToken tokenBySplitingLeadingWhiteSpace]; if (leadingWhiteSpace) { [self insertCharacters:leadingWhiteSpace.characters]; } - if ([token.asCharacterToken isWhitespaceToken]) { + + if (token.asCharacterToken.isEmpty) { return; } break; @@ -955,11 +968,12 @@ switch (token.type) { case HTMLTokenTypeCharacter: { - HTMLCharacterToken *leadingWhiteSpace = [token.asCharacterToken tokenByRetainingLeadingWhitespace]; + HTMLCharacterToken *leadingWhiteSpace = [token.asCharacterToken tokenBySplitingLeadingWhiteSpace]; if (leadingWhiteSpace) { [self insertCharacters:leadingWhiteSpace.characters]; } - if ([token.asCharacterToken isWhitespaceToken]) { + + if (token.asCharacterToken.isEmpty) { return; } break; @@ -1037,7 +1051,7 @@ if (charactes.length > 0) { [self reconstructActiveFormattingElements]; [self insertCharacters:charactes]; - if (![charactes containsHTMLWhitespace]) { + if (!charactes.isHTMLWhitespaceString) { _framesetOkFlag = NO; } } @@ -1740,11 +1754,12 @@ switch (token.type) { case HTMLTokenTypeCharacter: { - HTMLCharacterToken *leadingWhiteSpace = [token.asCharacterToken tokenByRetainingLeadingWhitespace]; + HTMLCharacterToken *leadingWhiteSpace = [token.asCharacterToken tokenBySplitingLeadingWhiteSpace]; if (leadingWhiteSpace) { [self insertCharacters:leadingWhiteSpace.characters]; } - if ([token.asCharacterToken isWhitespaceToken]) { + + if (token.asCharacterToken.isEmpty) { return; } break; @@ -2110,11 +2125,12 @@ switch (token.type) { case HTMLTokenTypeCharacter: { - HTMLCharacterToken *leadingWhiteSpace = [token.asCharacterToken tokenByRetainingLeadingWhitespace]; + HTMLCharacterToken *leadingWhiteSpace = [token.asCharacterToken tokenBySplitingLeadingWhiteSpace]; if (leadingWhiteSpace) { [self insertCharacters:leadingWhiteSpace.characters]; } - if ([token.asCharacterToken isWhitespaceToken]) { + + if (token.asCharacterToken.isEmpty) { return; } break; @@ -2158,14 +2174,19 @@ switch (token.type) { case HTMLTokenTypeCharacter: { - HTMLCharacterToken *leadingWhiteSpace = [token.asCharacterToken tokenByRetainingLeadingWhitespace]; - if (leadingWhiteSpace) { - [self insertCharacters:leadingWhiteSpace.characters]; - } - if ([token.asCharacterToken isWhitespaceToken]) { - return; - } - break; + NSString *characters = token.asCharacterToken.characters; + + [characters enumerateSubstringsInRange:NSMakeRange(0, characters.length) + options:NSStringEnumerationByComposedCharacterSequences + usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { + if (substring.isHTMLWhitespaceString) { + [self insertCharacters:substring]; + } else { + [self emitParseError:@"Unexpected Character (%@) in