Add implementation for Active Formatting Element Reconstruction
https://html.spec.whatwg.org/multipage/syntax.html#reconstruct-the-active-formatting-elements
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
@property (nonatomic, copy, readonly) NSString *tagName;
|
||||
|
||||
@property (nonatomic, strong) NSMutableDictionary *attributes;
|
||||
|
||||
@property (nonatomic, copy) NSString *id;
|
||||
|
||||
@property (nonatomic, copy) NSString *className;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// HTMLMarker.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 02/03/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface HTMLMarker : NSObject
|
||||
|
||||
+ (instancetype)marker;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// HTMLMarker.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 02/03/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "HTMLMarker.h"
|
||||
|
||||
@implementation HTMLMarker
|
||||
|
||||
+ (instancetype)marker
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
static HTMLMarker *singleton = nil;
|
||||
dispatch_once(&onceToken, ^{
|
||||
singleton = [[self alloc] init];
|
||||
});
|
||||
return singleton;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -12,6 +12,7 @@
|
||||
#import "HTMLParserInsertionModes.h"
|
||||
#import "HTMLNodes.h"
|
||||
#import "HTMLElementTypes.h"
|
||||
#import "HTMLMarker.h"
|
||||
#import "NSString+HTMLKit.h"
|
||||
|
||||
@interface HTMLParser ()
|
||||
@@ -25,6 +26,7 @@
|
||||
HTMLInsertionMode _originalInsertionMode;
|
||||
|
||||
NSMutableArray *_stackOfOpenElements;
|
||||
NSMutableArray *_listOfActiveFormattingElements;
|
||||
|
||||
HTMLDocument *_document;
|
||||
|
||||
@@ -56,6 +58,7 @@
|
||||
[self setupStateMachine];
|
||||
|
||||
_stackOfOpenElements = [NSMutableArray new];
|
||||
_listOfActiveFormattingElements = [NSMutableArray new];
|
||||
_tokenizer = [[HTMLTokenizer alloc] initWithString:string];
|
||||
|
||||
_scriptingFlag = NO;
|
||||
@@ -424,6 +427,59 @@
|
||||
[self switchInsertionMode:HTMLInsertionModeText];
|
||||
}
|
||||
|
||||
- (void)reconstructActiveFormattingElements
|
||||
{
|
||||
if (_listOfActiveFormattingElements.count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
id last = _listOfActiveFormattingElements.lastObject;
|
||||
if (last == [HTMLMarker marker] || [_stackOfOpenElements containsObject:last]) {
|
||||
return;
|
||||
}
|
||||
|
||||
__block NSUInteger index = _listOfActiveFormattingElements.count - 1;
|
||||
__block id entry = _listOfActiveFormattingElements[index];
|
||||
|
||||
// Reconstruct the active formatting elements
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#reconstruct-the-active-formatting-elements
|
||||
// No cycles ~> blocks instead of gotos
|
||||
|
||||
dispatch_block_t advance = ^{
|
||||
entry = _listOfActiveFormattingElements[index++];
|
||||
};
|
||||
|
||||
dispatch_block_t create = ^{
|
||||
HTMLElement *entry = _listOfActiveFormattingElements[index];
|
||||
HTMLStartTagToken *token = [[HTMLStartTagToken alloc] initWithTagName:entry.tagName
|
||||
attributes:entry.attributes];
|
||||
HTMLElement *element = [self insertElementForToken:token];
|
||||
[_listOfActiveFormattingElements replaceObjectAtIndex:index withObject:element];
|
||||
if (index++ != _listOfActiveFormattingElements.count) {
|
||||
advance();
|
||||
}
|
||||
};
|
||||
|
||||
dispatch_block_t rewind = ^{
|
||||
if (index == 0) {
|
||||
create();
|
||||
}
|
||||
entry = _listOfActiveFormattingElements[index--];
|
||||
if (entry != [HTMLMarker marker] && ![_stackOfOpenElements containsObject:entry]) {
|
||||
rewind();
|
||||
}
|
||||
};
|
||||
|
||||
rewind();
|
||||
}
|
||||
|
||||
- (void)clearListOfActiveFormattingElementsUptoLastMarker
|
||||
{
|
||||
while (_listOfActiveFormattingElements.lastObject != [HTMLMarker marker]) {
|
||||
[_listOfActiveFormattingElements removeLastObject];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Insertion Modes
|
||||
|
||||
- (void)HTMLInsertionModeInitial:(HTMLToken *)token
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
@property (nonatomic, assign, getter = isSelfClosing) BOOL selfClosing;
|
||||
|
||||
- (instancetype)initWithTagName:(NSString *)tagName;
|
||||
- (instancetype)initWithTagName:(NSString *)tagName attributes:(NSMutableDictionary *)attributes;
|
||||
|
||||
- (void)appendStringToTagName:(NSString *)string;
|
||||
|
||||
|
||||
+21
-2
@@ -21,10 +21,19 @@
|
||||
@synthesize tagName = _tagName;
|
||||
|
||||
- (instancetype)initWithTagName:(NSString *)tagName
|
||||
{
|
||||
return [self initWithTagName:tagName attributes:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithTagName:(NSString *)tagName attributes:(NSMutableDictionary *)attributes
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_tagName = [tagName mutableCopy];
|
||||
_attributes = [NSMutableDictionary new];
|
||||
if (attributes != nil) {
|
||||
[_attributes addEntriesFromDictionary:attributes];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -44,7 +53,12 @@
|
||||
|
||||
- (instancetype)initWithTagName:(NSString *)tagName
|
||||
{
|
||||
self = [super initWithTagName:tagName];
|
||||
return [self initWithTagName:tagName attributes:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithTagName:(NSString *)tagName attributes:(NSMutableDictionary *)attributes
|
||||
{
|
||||
self = [super initWithTagName:tagName attributes:attributes];
|
||||
if (self) {
|
||||
self.type = HTMLTokenTypeStartTag;
|
||||
}
|
||||
@@ -80,7 +94,12 @@
|
||||
|
||||
- (instancetype)initWithTagName:(NSString *)tagName
|
||||
{
|
||||
self = [super initWithTagName:tagName];
|
||||
return [self initWithTagName:tagName attributes:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithTagName:(NSString *)tagName attributes:(NSMutableDictionary *)attributes
|
||||
{
|
||||
self = [super initWithTagName:tagName attributes:attributes];
|
||||
if (self) {
|
||||
self.type = HTMLTokenTypeEndTag;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user