From 0d2d6dedebd8d9f1aa262cd781993fcde1b19b74 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 14 Mar 2015 01:56:37 +0100 Subject: [PATCH] Add implementation for the rest of the insertion modes "in table text", "in caption", "in column group", "in table body", "in row", "in cell", "in select", "in select in table", "in template", "after body", "in frameset", "after frameset", "after after body", "after after frameset" --- HTMLKit/HTMLParser.h | 2 - HTMLKit/HTMLParser.m | 814 ++++++++++++++++++++++++++++-- HTMLKit/HTMLStackOfOpenElements.m | 4 +- 3 files changed, 765 insertions(+), 55 deletions(-) diff --git a/HTMLKit/HTMLParser.h b/HTMLKit/HTMLParser.h index 4313bf1..61dc920 100644 --- a/HTMLKit/HTMLParser.h +++ b/HTMLKit/HTMLParser.h @@ -10,6 +10,4 @@ @interface HTMLParser : NSObject -- (id)adjustedCurrentNode; - @end diff --git a/HTMLKit/HTMLParser.m b/HTMLKit/HTMLParser.m index 85e104c..e85b384 100644 --- a/HTMLKit/HTMLParser.m +++ b/HTMLKit/HTMLParser.m @@ -37,7 +37,7 @@ HTMLElement *_headElementPointer; HTMLElement *_formElementPointer; - id _pendingTableCharacterTokens; + HTMLCharacterToken *_pendingTableCharacterTokens; BOOL _scriptingFlag; BOOL _framesetOkFlag; @@ -65,6 +65,8 @@ _listOfActiveFormattingElements = [NSMutableArray new]; _tokenizer = [[HTMLTokenizer alloc] initWithString:string]; + _pendingTableCharacterTokens = [[HTMLCharacterToken alloc] initWithString:@""]; + _scriptingFlag = NO; _framesetOkFlag = YES; _fragmentParsingAlgorithm = NO; @@ -334,27 +336,6 @@ } } -- (void)processTokenByApplyingRulesForParsingTokensInForeignContent:(HTMLToken *)token -{ - switch (token.type) { - case HTMLTokenTypeCharacter: - - break; - case HTMLTokenTypeComment: - - break; - case HTMLTokenTypeDoctype: - - break; - case HTMLTokenTypeStartTag: - - break; - case HTMLTokenTypeEndTag: - - break; - } -} - - (void)stopParsing { [_stackOfOpenElements popAll]; @@ -631,6 +612,25 @@ return NO; } +- (void)clearListOfActiveFormattingElementsUpToLastMarker +{ + while (![_listOfActiveFormattingElements.lastObject isEqual:[HTMLMarker marker]]) { + [_listOfActiveFormattingElements removeLastObject]; + } + [_listOfActiveFormattingElements removeLastObject]; +} + +- (void)closeTheCell +{ + [self generateImpliedEndTagsExceptForElement:nil]; + if (![self.currentNode.tagName isEqualToAny:@"td", @"th", nil]) { + [self emitParseError:@"Misnested Cell"]; + } + [_stackOfOpenElements popElementsUntilAnElementPoppedWithAnyOfTagNames:@[@"td", @"th"]]; + [self clearListOfActiveFormattingElementsUpToLastMarker]; + [self switchInsertionMode:HTMLInsertionModeInRow]; +} + #pragma mark - Insertion Modes - (void)HTMLInsertionModeInitial:(HTMLToken *)token @@ -735,6 +735,8 @@ HTMLElement *head = [self insertElementForToken:token.asTagToken]; _headElementPointer = head; [self switchInsertionMode:HTMLInsertionModeInHead]; + } else { + break; } return; case HTMLTokenTypeEndTag: @@ -777,21 +779,16 @@ case HTMLTokenTypeStartTag: if ([token.asStartTagToken.tagName isEqualToString:@"html"]) { [self HTMLInsertionModeInBody:token]; - return; } else if ([token.asStartTagToken.tagName isEqualToAny:@"base", @"basefont", @"bgsound", @"link", nil]) { [self insertElementForToken:token.asStartTagToken]; [_stackOfOpenElements popCurrentNode]; - return; } else if ([token.asStartTagToken.tagName isEqualToString:@"meta"]) { [self insertElementForToken:token.asStartTagToken]; [_stackOfOpenElements popCurrentNode]; - return; } else if ([token.asStartTagToken.tagName isEqualToString:@"title"]) { [self applyGenericParsingAlgorithmForToken:token.asStartTagToken withTokenizerState:HTMLTokenizerStateRCDATA]; - return; } else if ([token.asStartTagToken.tagName isEqualToAny:@"noscript", @"noframes", @"style", nil]) { [self applyGenericParsingAlgorithmForToken:token.asStartTagToken withTokenizerState:HTMLTokenizerStateRAWTEXT]; - return; } else if ([token.asStartTagToken.tagName isEqualToString:@"script"]) { HTMLNode *adjustedInsertionLocation = [self appropriatePlaceForInsertingANodeWithOverrideTarget:nil]; HTMLElement *script = [self createElementForToken:token.asStartTagToken inNamespace:HTMLNamespaceHTML]; @@ -801,25 +798,24 @@ _tokenizer.state = HTMLTokenizerStateScriptData; _originalInsertionMode = _insertionMode; [self switchInsertionMode:HTMLInsertionModeText]; - return; } else if ([token.asStartTagToken.tagName isEqualToString:@"head"]) { [self emitParseError:@"Unexpected Start Tag Token (head) in "]; - return; + } else { + break; } - break; + return; #warning Implement HTML Template case HTMLTokenTypeEndTag: if ([token.asEndTagToken.tagName isEqualToString:@"head"]) { [_stackOfOpenElements popCurrentNode]; [self switchInsertionMode:HTMLInsertionModeAfterHead]; - return; } else if ([token.asEndTagToken.tagName isEqualToAny:@"body", @"html", @"br", nil]) { break; } else { [self emitParseError:@"Unexpected End Tag Token (%@) in ", token.asEndTagToken.tagName]; return; } - break; + return; default: break; } @@ -846,8 +842,10 @@ } else if ([token.asStartTagToken.tagName isEqualToAny:@"head", @"noscript", nil]) { [self emitParseError:@"Unexpected Start Tag Token (%@) in