From f9c8743106009c428504c3523fceab1a69769a80 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 21 Feb 2015 14:30:44 +0100 Subject: [PATCH] Add "tree construction dispatcher" and token handling stub https://html.spec.whatwg.org/multipage/syntax.html#tree-construction --- HTMLKit.xcodeproj/project.pbxproj | 2 ++ HTMLKit/HTMLElement.h | 2 ++ HTMLKit/HTMLElementTypes.h | 27 ++++++++++++++ HTMLKit/HTMLParser.m | 60 +++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 HTMLKit/HTMLElementTypes.h diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 869af18..3a4744d 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -98,6 +98,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 6223211D1A969B9300BACED5 /* HTMLElementTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLElementTypes.h; sourceTree = ""; }; 624493A419CCC54100BCDDF4 /* HTMLTokenizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLTokenizer.h; sourceTree = ""; }; 624493A519CCC54100BCDDF4 /* HTMLTokenizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTokenizer.m; sourceTree = ""; }; 624493A919CCE84A00BCDDF4 /* HTMLTokenizerStates.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokenizerStates.h; sourceTree = ""; }; @@ -242,6 +243,7 @@ 62F873E919E088C90062683C /* HTMLParser.h */, 62F873EA19E088C90062683C /* HTMLParser.m */, 628B7CE61A080E1000602C87 /* HTMLNamespaces.h */, + 6223211D1A969B9300BACED5 /* HTMLElementTypes.h */, 6279F87119E17DC700F12EE5 /* HTMLParserInsertionModes.h */, 6279F87219E1808D00F12EE5 /* HTMLElement.h */, 6279F87319E1808D00F12EE5 /* HTMLElement.m */, diff --git a/HTMLKit/HTMLElement.h b/HTMLKit/HTMLElement.h index 4b71e68..012b88d 100644 --- a/HTMLKit/HTMLElement.h +++ b/HTMLKit/HTMLElement.h @@ -7,9 +7,11 @@ // #import +#import "HTMLNamespaces.h" @interface HTMLElement : NSObject @property (nonatomic, strong, readonly) NSString *tagName; +@property (nonatomic, assign, readonly) HTMLNamespace namespace; @end diff --git a/HTMLKit/HTMLElementTypes.h b/HTMLKit/HTMLElementTypes.h new file mode 100644 index 0000000..3cc9c95 --- /dev/null +++ b/HTMLKit/HTMLElementTypes.h @@ -0,0 +1,27 @@ +// +// HTMLElementTypes.h +// HTMLKit +// +// Created by Iska on 19/02/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLElement.h" +#import "HTMLNamespaces.h" + +#define matches(x, ...) [[NSSet setWithObjects:__VA_ARGS__, nil] containsObject:x] + +NS_INLINE BOOL IsNodeMathMLTextIntegrationPoint(HTMLElement *node) +{ + return (node.namespace == HTMLNamespaceMathML && matches(node.tagName, @"mi", @"mo", @"mn", @"ms", @"mtext")); +} + +NS_INLINE BOOL IsNodeHTMLIntegrationPoint(HTMLElement *node) +{ + if (node.namespace == HTMLNamespaceMathML && [node.tagName isEqualToString:@"annotation-xml"]) { +#warning Implement HTML Element Attributes + } else if (node.namespace == HTMLNamespaceSVG) { + return matches(node.tagName, @"foreignObject", @"desc", @"title"); + } + return NO; +} diff --git a/HTMLKit/HTMLParser.m b/HTMLKit/HTMLParser.m index d2a08cc..a1b6f01 100644 --- a/HTMLKit/HTMLParser.m +++ b/HTMLKit/HTMLParser.m @@ -24,4 +24,64 @@ @implementation HTMLParser +#pragma mark - Parse + +- (id)parse +{ + for (HTMLToken *token in _tokenizer) { + [self handleToken:token]; + } + return nil; +} + +- (void)handleToken:(HTMLToken *)token +{ + BOOL (^ treeConstructionDispatcher)(HTMLElement *node) = ^BOOL(HTMLElement *node){ + + if (node == nil) { + return YES; + } + if (node.namespace == HTMLNamespaceHTML) { + return YES; + } + if (IsNodeMathMLTextIntegrationPoint(node)) { + if (token.type == HTMLTokenTypeStartTag) { + return !matches([(HTMLStartTagToken *)token tagName], @"mglyph", @"malignmark"); + } + if (token.type == HTMLTokenTypeCharacter) { + return YES; + } + } + if (node.namespace == HTMLNamespaceMathML && [node.tagName isEqualToString:@"annotation-xml"]) { + if (token.type == HTMLTokenTypeStartTag) { + return [[(HTMLStartTagToken *)token tagName] isEqualToString:@"svg"]; + } + } + if (IsNodeHTMLIntegrationPoint(node)) { + return token.type == HTMLTokenTypeStartTag || token.type == HTMLTokenTypeCharacter; + } + if (token.type == HTMLTokenTypeEOF) { + return YES; + } + + return NO; + }; + + if (treeConstructionDispatcher(self.adjustedCurrentNode)) { + [self handleToken:token byApplyingRulesForInsertionMode:_insertionMode]; + } else { + [self handleTokenByApplyingRulesForParsingTokensInForeignContent:token]; + } +} + +- (void)handleToken:(HTMLToken *)token byApplyingRulesForInsertionMode:(HTMLInsertionMode)insertionMode +{ + +} + +- (void)handleTokenByApplyingRulesForParsingTokensInForeignContent:(HTMLToken *)token +{ + +} + @end