Add initial implementation for "appropriate place for inserting a node"

https://html.spec.whatwg.org/multipage/syntax.html#creating-and-inserting-nodes
This commit is contained in:
iska
2015-02-22 01:46:13 +01:00
parent 3915487ca7
commit 4e3c758f8c
5 changed files with 86 additions and 7 deletions
+1
View File
@@ -17,4 +17,5 @@
- (void)appendString:(NSString *)string;
- (BOOL)isWhitespaceToken;
@end
+6
View File
@@ -33,6 +33,12 @@
[_characters appendString:string];
}
- (BOOL)isWhitespaceToken
{
NSCharacterSet *set = [[NSCharacterSet characterSetWithCharactersInString:@" \t\n\f"] invertedSet];
return [_characters rangeOfCharacterFromSet:set].location == NSNotFound;
}
#pragma mark - NSObject
- (BOOL)isEqual:(id)other
+1
View File
@@ -13,5 +13,6 @@
@property (nonatomic, strong, readonly) NSString *tagName;
@property (nonatomic, assign, readonly) HTMLNamespace namespace;
@property (nonatomic, strong, readonly) id parentNode;
@end
+69 -6
View File
@@ -9,6 +9,7 @@
#import "HTMLParser.h"
#import "HTMLTokenizer.h"
#import "HTMLTokens.h"
#import "HTMLCharacterToken.h"
#import "HTMLParserInsertionModes.h"
#import "HTMLElement.h"
#import "HTMLElementTypes.h"
@@ -17,6 +18,8 @@
{
HTMLTokenizer *_tokenizer;
NSMutableArray *_errors;
NSMutableDictionary *_insertionModes;
HTMLInsertionMode _insertionMode;
HTMLInsertionMode _originalInsertionMode;
@@ -31,6 +34,7 @@
BOOL _scriptingFlag;
BOOL _fragmentParsingAlgorithm;
BOOL _fosterParting;
}
@end
@@ -42,6 +46,8 @@
{
self = [super init];
if (self) {
_errors = [NSMutableArray new];
_insertionModes = [NSMutableDictionary new];
_insertionMode = HTMLInsertionModeInitial;
[self setupStateMachine];
@@ -76,6 +82,17 @@
return [self currentNode];
}
#pragma mark - Emits
- (void)emitParseError:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2)
{
va_list args;
va_start(args, format);
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
[_errors addObject:message];
va_end(args);
}
#pragma mark - State Machine
- (void)switchInsertionMode:(HTMLInsertionMode)mode
@@ -206,12 +223,13 @@
- (id)parse
{
for (HTMLToken *token in _tokenizer) {
[self handleToken:token];
[self processToken:token];
}
return nil;
}
- (void)handleToken:(HTMLToken *)token
- (void)processToken:(HTMLToken *)token
{
BOOL (^ treeConstructionDispatcher)(HTMLElement *node) = ^BOOL(HTMLElement *node){
@@ -245,13 +263,18 @@
};
if (treeConstructionDispatcher(self.adjustedCurrentNode)) {
[self handleToken:token byApplyingRulesForInsertionMode:_insertionMode];
[self processToken:token byApplyingRulesForInsertionMode:_insertionMode];
} else {
[self handleTokenByApplyingRulesForParsingTokensInForeignContent:token];
[self processTokenByApplyingRulesForParsingTokensInForeignContent:token];
}
}
- (void)handleToken:(HTMLToken *)token byApplyingRulesForInsertionMode:(HTMLInsertionMode)insertionMode
- (void)reprocessToken:(HTMLToken *)token
{
[self processToken:token];
}
- (void)processToken:(HTMLToken *)token byApplyingRulesForInsertionMode:(HTMLInsertionMode)insertionMode
{
SEL selector = [[_insertionModes objectForKey:@(_insertionMode)] pointerValue];
if ([self respondsToSelector:selector]) {
@@ -263,9 +286,49 @@
}
}
- (void)handleTokenByApplyingRulesForParsingTokensInForeignContent:(HTMLToken *)token
- (void)processTokenByApplyingRulesForParsingTokensInForeignContent:(HTMLToken *)token
{
#pragma mark -
- (HTMLElement *)appropriatePlaceForInsertingANodeWithOverrideTarget:(id)overrideTarget
{
HTMLElement *target = self.currentNode;
if (overrideTarget == nil) {
target = overrideTarget;
}
if (_fosterParting && matches(target.tagName, @"table", @"tbody", @"tfoot", @"thead", @"tr")) {
HTMLElement *lastTemplate = nil;
HTMLElement *lastTable = nil;
for (HTMLElement *element in _stackOfOpenElements.reverseObjectEnumerator) {
if ([element.tagName isEqualToString:@"template"]) {
lastTemplate = element;
break;
}
if ([element.tagName isEqualToString:@"table"]) {
lastTable = element;
break;
}
}
if (lastTemplate != nil) {
#warning Implement HTML Template
return nil;
}
if (lastTable == nil) {
HTMLElement *htmlElement = _stackOfOpenElements.firstObject;
return htmlElement;
}
if (lastTable.parentNode != nil) {
return lastTable.parentNode;
}
NSUInteger lastTableIndex = [_stackOfOpenElements indexOfObject:lastTable];
HTMLElement *previousNode = _stackOfOpenElements[lastTableIndex];
return previousNode;
} else {
return target;
}
}
#pragma mark - Insertion Modes
+9 -1
View File
@@ -29,7 +29,9 @@
MODE_ENTRY( HTMLInsertionModeInFrameset, ) \
MODE_ENTRY( HTMLInsertionModeAfterFrameset, ) \
MODE_ENTRY( HTMLInsertionModeAfterAfterBody, ) \
MODE_ENTRY( HTMLInsertionModeAfterAfterFrameset, )
MODE_ENTRY( HTMLInsertionModeAfterAfterFrameset, ) \
MODE_ENTRY( HTMLInsertionModeCurrentTemplate, ) \
MODE_ENTRY( HTMLInsertionModesCount, )
typedef NS_ENUM(NSUInteger, HTMLInsertionMode)
{
@@ -37,3 +39,9 @@ typedef NS_ENUM(NSUInteger, HTMLInsertionMode)
INSERTION_MODES
#undef MODE_ENTRY
};
static NSString * HTMLInsertionModesTable[] = {
#define MODE_ENTRY( name, value ) [name] = @#name,
INSERTION_MODES
#undef MODE_ENTRY
};