From e3c04c807e65d7de586ca4f17bb85464b8dfa426 Mon Sep 17 00:00:00 2001 From: iska Date: Sun, 1 Mar 2015 23:53:46 +0100 Subject: [PATCH] Add implementation for in-head, in-head-noscript & after-head insertion modes https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inheadnoscript https://html.spec.whatwg.org/multipage/syntax.html#the-after-head-insertion-mode --- HTMLKit/HTMLParser.m | 169 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/HTMLKit/HTMLParser.m b/HTMLKit/HTMLParser.m index 3b84a5a..0299e2d 100644 --- a/HTMLKit/HTMLParser.m +++ b/HTMLKit/HTMLParser.m @@ -532,17 +532,186 @@ - (void)HTMLInsertionModeInHead:(HTMLToken *)token { + switch (token.type) { + case HTMLTokenTypeCharacter: + { + HTMLCharacterToken *leadingWhiteSpace = [token.asCharacterToken tokenByRetainingLeadingWhitespace]; + if (leadingWhiteSpace) { + [self insertCharacters:leadingWhiteSpace.characters]; + } + if ([token.asCharacterToken isWhitespaceToken]) { + return; + } + break; + } + case HTMLTokenTypeComment: + [self insertComment:token.asCommentToken asChildOfNode:_document]; + return; + case HTMLTokenTypeDoctype: + [self emitParseError:@"Unexpected DOCTYPE Token in "]; + return; + case HTMLTokenTypeStartTag: + if ([token.asStartTagToken.tagName isEqualToString:@"html"]) { + [self HTMLInsertionModeInBody:token]; + return; + } else if (matches(token.asStartTagToken.tagName, @"base", @"basefont", @"bgsound", @"link")) { + [self insertElementForToken:token.asStartTagToken]; + [_stackOfOpenElements removeLastObject]; + return; + } else if ([token.asStartTagToken.tagName isEqualToString:@"meta"]) { + [self insertElementForToken:token.asStartTagToken]; + [_stackOfOpenElements removeLastObject]; + return; + } else if ([token.asStartTagToken.tagName isEqualToString:@"title"]) { + [self applyGenericParsingAlgorithmForToken:token.asStartTagToken withTokenizerState:HTMLTokenizerStateRCDATA]; + return; + } else if (matches(token.asStartTagToken.tagName, @"noscript", @"noframes", @"style")) { + [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]; +#warning Script Element Flags (https://html.spec.whatwg.org/multipage/scripting.html#parser-inserted) + [adjustedInsertionLocation appendChildNode:script]; + [_stackOfOpenElements addObject:script]; + _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; + } + break; +#warning Implement HTML Template + case HTMLTokenTypeEndTag: + if ([token.asEndTagToken.tagName isEqualToString:@"head"]) { + [_stackOfOpenElements removeLastObject]; + [self switchInsertionMode:HTMLInsertionModeAfterHead]; + return; + } else if (matches(token.asEndTagToken.tagName, @"body", @"html", @"br")) { + break; + } else { + [self emitParseError:@"Unexpected End Tag Token (%@) in ", token.asEndTagToken.tagName]; + return; + } + break; + default: + break; + } + [_stackOfOpenElements removeLastObject]; + [self switchInsertionMode:HTMLInsertionModeAfterHead]; + [self reprocessToken:token]; } - (void)HTMLInsertionModeInHeadNoscript:(HTMLToken *)token { + switch (token.type) { + case HTMLTokenTypeDoctype: + [self emitParseError:@"Unexpected DOCTYPE Token in