From bed2edf22a2e39321bcb7b5ec2c3073cc793d28c Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 21 Oct 2015 22:32:09 +0200 Subject: [PATCH] Remove obsolete CSS Tokenizer and Token classes --- HTMLKit.xcodeproj/project.pbxproj | 20 - HTMLKit/CSSToken.h | 86 ---- HTMLKit/CSSToken.m | 69 ---- HTMLKit/CSSTokenizer.h | 18 - HTMLKit/CSSTokenizer.m | 663 ------------------------------ 5 files changed, 856 deletions(-) delete mode 100644 HTMLKit/CSSToken.h delete mode 100644 HTMLKit/CSSToken.m delete mode 100644 HTMLKit/CSSTokenizer.h delete mode 100644 HTMLKit/CSSTokenizer.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index a4c407d..bf20a73 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ 62079BE91AF56F1E00D3B402 /* CSSSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62079BE71AF56F1E00D3B402 /* CSSSelector.h */; }; - 620802021AFD939200F2962F /* CSSTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 623F13A81AFC11D900C90BF4 /* CSSTokenizer.h */; }; 620C877B1BD44CBE00FB3EEE /* CSSCompoundSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 620C87791BD44CBE00FB3EEE /* CSSCompoundSelector.h */; settings = {ASSET_TAGS = (); }; }; 620C877C1BD44CBE00FB3EEE /* CSSCompoundSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */; settings = {ASSET_TAGS = (); }; }; 620C877D1BD44CBE00FB3EEE /* CSSCompoundSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */; settings = {ASSET_TAGS = (); }; }; @@ -70,8 +69,6 @@ 6239755F1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 6239755D1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m */; }; 623CAF9D1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */ = {isa = PBXBuildFile; fileRef = 623CAF9C1AD88BEA00E34C32 /* HTMLKitParserPerformance.m */; }; 623CAF9E1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */ = {isa = PBXBuildFile; fileRef = 623CAF9C1AD88BEA00E34C32 /* HTMLKitParserPerformance.m */; }; - 623F13AB1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 623F13A91AFC11D900C90BF4 /* CSSTokenizer.m */; }; - 623F13AC1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 623F13A91AFC11D900C90BF4 /* CSSTokenizer.m */; }; 624493A619CCC54100BCDDF4 /* HTMLTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493A419CCC54100BCDDF4 /* HTMLTokenizer.h */; }; 624493A719CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493A519CCC54100BCDDF4 /* HTMLTokenizer.m */; }; 624493A819CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493A519CCC54100BCDDF4 /* HTMLTokenizer.m */; }; @@ -116,9 +113,6 @@ 624B371E1B24E9BA0010BDDF /* CSSInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B371C1B24E9BA0010BDDF /* CSSInputStream.h */; }; 624B371F1B24E9BA0010BDDF /* CSSInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B371D1B24E9BA0010BDDF /* CSSInputStream.m */; }; 624B37201B24E9BA0010BDDF /* CSSInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B371D1B24E9BA0010BDDF /* CSSInputStream.m */; }; - 624B7DDC1B2E3AAB00A4BD61 /* CSSToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B7DDA1B2E3AAB00A4BD61 /* CSSToken.h */; }; - 624B7DDD1B2E3AAB00A4BD61 /* CSSToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B7DDB1B2E3AAB00A4BD61 /* CSSToken.m */; }; - 624B7DDE1B2E3AAB00A4BD61 /* CSSToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B7DDB1B2E3AAB00A4BD61 /* CSSToken.m */; }; 624B9FB21AE0313300646C4C /* HTMLKitStringCategoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B9FB11AE0313300646C4C /* HTMLKitStringCategoryTests.m */; }; 624B9FB31AE0313300646C4C /* HTMLKitStringCategoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B9FB11AE0313300646C4C /* HTMLKitStringCategoryTests.m */; }; 624B9FB51AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B9FB41AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m */; }; @@ -274,8 +268,6 @@ 6239755C1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTML5LibTreeConstructionTest.h; sourceTree = ""; }; 6239755D1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTML5LibTreeConstructionTest.m; sourceTree = ""; }; 623CAF9C1AD88BEA00E34C32 /* HTMLKitParserPerformance.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitParserPerformance.m; sourceTree = ""; }; - 623F13A81AFC11D900C90BF4 /* CSSTokenizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSTokenizer.h; sourceTree = ""; }; - 623F13A91AFC11D900C90BF4 /* CSSTokenizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTokenizer.m; 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 = ""; }; @@ -307,8 +299,6 @@ 624B371C1B24E9BA0010BDDF /* CSSInputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSInputStream.h; sourceTree = ""; }; 624B371D1B24E9BA0010BDDF /* CSSInputStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSInputStream.m; sourceTree = ""; }; 624B37211B250BB50010BDDF /* CSSCodePoints.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSCodePoints.h; sourceTree = ""; }; - 624B7DDA1B2E3AAB00A4BD61 /* CSSToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSToken.h; sourceTree = ""; }; - 624B7DDB1B2E3AAB00A4BD61 /* CSSToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSToken.m; sourceTree = ""; }; 624B9FB11AE0313300646C4C /* HTMLKitStringCategoryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitStringCategoryTests.m; sourceTree = ""; }; 624B9FB41AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitOrderedDictionaryTests.m; sourceTree = ""; }; 624FC3791AE591D80015DDF9 /* HTMLKitNodesTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitNodesTests.m; sourceTree = ""; }; @@ -418,10 +408,6 @@ 624B371D1B24E9BA0010BDDF /* CSSInputStream.m */, 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */, 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */, - 623F13A81AFC11D900C90BF4 /* CSSTokenizer.h */, - 623F13A91AFC11D900C90BF4 /* CSSTokenizer.m */, - 624B7DDA1B2E3AAB00A4BD61 /* CSSToken.h */, - 624B7DDB1B2E3AAB00A4BD61 /* CSSToken.m */, 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, 62FC60451BD0519B0042BBE7 /* CSSSelector.m */, 62FA98061BD5A7E200A2AF86 /* CSSSelectorBlock.h */, @@ -711,7 +697,6 @@ 62D89DB21AE7081600B6243D /* HTMLTokenizerCharacters.h in Headers */, 62D89DB31AE7081600B6243D /* HTMLNamespaces.h in Headers */, 624B28BC1B03DAB70048D328 /* HTMLNodeFilter.h in Headers */, - 624B7DDC1B2E3AAB00A4BD61 /* CSSToken.h in Headers */, 624B28BF1B0413200048D328 /* CSSAttributeSelector.h in Headers */, 62D89DB41AE7081600B6243D /* HTMLElementTypes.h in Headers */, 628AF6331BC9A63D00496128 /* CSSNthExpressionSelector.h in Headers */, @@ -747,7 +732,6 @@ 625A150819C78ABA00AD0C32 /* HTMLInputStreamReader.h in Headers */, 62FA04E31BCC360D009ABF98 /* CSSCombinatorSelector.h in Headers */, 6238579B1A9E8934003A45D9 /* HTMLComment.h in Headers */, - 620802021AFD939200F2962F /* CSSTokenizer.h in Headers */, 62AE593519F97D880043F069 /* HTMLParseErrorToken.h in Headers */, 62AE594919F9948A0043F069 /* HTMLCharacterToken.h in Headers */, 623857961A9E8606003A45D9 /* HTMLDocumentType.h in Headers */, @@ -935,12 +919,10 @@ 625A150A19C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */, 628AF6351BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */, 623857931A9E772B003A45D9 /* HTMLDocument.m in Sources */, - 624B7DDE1B2E3AAB00A4BD61 /* CSSToken.m in Sources */, 623406E81ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */, 624717B91B21FE5400B38302 /* HTMLNodeFilter.m in Sources */, 620EE94B1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */, 624493A819CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, - 623F13AC1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, 624B28BA1B03DA820048D328 /* CSSTypeSelector.m in Sources */, 625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */, 62FC60471BD0519B0042BBE7 /* CSSSelector.m in Sources */, @@ -1009,12 +991,10 @@ 620C877C1BD44CBE00FB3EEE /* CSSCompoundSelector.m in Sources */, 625A150919C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */, 623857921A9E772B003A45D9 /* HTMLDocument.m in Sources */, - 624B7DDD1B2E3AAB00A4BD61 /* CSSToken.m in Sources */, 623406E71ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */, 624717B81B21FE5400B38302 /* HTMLNodeFilter.m in Sources */, 620EE94A1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */, 624493A719CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, - 623F13AB1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, 624B28B91B03DA820048D328 /* CSSTypeSelector.m in Sources */, 625A150219C783DE00AD0C32 /* HTMLKit.m in Sources */, 623857971A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, diff --git a/HTMLKit/CSSToken.h b/HTMLKit/CSSToken.h deleted file mode 100644 index bc3383e..0000000 --- a/HTMLKit/CSSToken.h +++ /dev/null @@ -1,86 +0,0 @@ -// -// CSSToken.h -// HTMLKit -// -// Created by Iska on 15/06/15. -// Copyright (c) 2015 BrainCookie. All rights reserved. -// - -#import - -typedef NS_ENUM(NSUInteger, CSSTokenType) -{ - CSSTokenTypeIdent, - CSSTokenTypeFunction, - CSSTokenTypeAtKeyword, - CSSTokenTypeHash, - CSSTokenTypeString, - CSSTokenTypeBadString, - CSSTokenTypeURL, - CSSTokenTypeBadURL, - CSSTokenTypeDelim, - CSSTokenTypeNumber, - CSSTokenTypePercentage, - CSSTokenTypeDimension, - CSSTokenTypeUnicodeRange, - CSSTokenTypeIncludeMatch, - CSSTokenTypeDashMatch, - CSSTokenTypePrefixMatch, - CSSTokenTypeSuffixMatch, - CSSTokenTypeSubstringMatch, - CSSTokenTypeColumn, - CSSTokenTypeWhitespace, - CSSTokenTypeCommentDeclarationOpen, - CSSTokenTypeCommentDeclarationClose, - CSSTokenTypeColon, - CSSTokenTypeSemicolon, - CSSTokenTypeComma, - CSSTokenTypeSquareBracketOpen, - CSSTokenTypeSquareBracketClose, - CSSTokenTypeParenthesisOpen, - CSSTokenTypeParenthesisClose, - CSSTokenTypeCurlyBracketOpen, - CSSTokenTypeCurlyBracketClose, - CSSTokenTypeEOF -}; - -@interface CSSToken : NSObject - -@property (nonatomic, assign) CSSTokenType type; -@property (nonatomic, assign) NSUInteger location; -@property (nonatomic, assign) NSUInteger length; -@property (nonatomic, copy) NSString *text; - -+ (instancetype)tokenWithType:(CSSTokenType)type; - -@end - -#pragma mark - Unicode Range - -@interface CSSUnicodeRangeToken : CSSToken -@property (nonatomic, assign) unsigned int start; -@property (nonatomic, assign) unsigned int end; -@end - -#pragma mark - Numeric Tokens - -typedef NS_ENUM(NSUInteger, CSSNumericTokenType) -{ - CSSNumericTokenTypeInteger, - CSSNumericTokenTypeNumber -}; - -@interface CSSNumericToken : CSSToken -@property (nonatomic, assign) CSSNumericTokenType numericType; -@property (nonatomic, strong) NSNumber *value; -@end - -@interface CSSDimensionToken : CSSNumericToken -@property (nonatomic, copy) NSString *unit; -@end - -@interface CSSNumberToken : CSSNumericToken -@end - -@interface CSSPercentageToken : CSSNumericToken -@end diff --git a/HTMLKit/CSSToken.m b/HTMLKit/CSSToken.m deleted file mode 100644 index c91fb0a..0000000 --- a/HTMLKit/CSSToken.m +++ /dev/null @@ -1,69 +0,0 @@ -// -// CSSToken.m -// HTMLKit -// -// Created by Iska on 15/06/15. -// Copyright (c) 2015 BrainCookie. All rights reserved. -// - -#import "CSSToken.h" - -@implementation CSSToken - -+ (instancetype)tokenWithType:(CSSTokenType)type -{ - CSSToken *token = [[self alloc] init]; - token.type = type; - return token; -} - -- (instancetype)initWithType:(CSSTokenType)type -{ - self = [super init]; - if (self) { - self.type = type; - } - return self; -} - -@end - -#pragma mark - Unicode Range - -@implementation CSSUnicodeRangeToken -@end - -#pragma mark - Numeric - -@implementation CSSNumericToken -@end - -@implementation CSSDimensionToken - -- (instancetype)init -{ - self = [self initWithType:CSSTokenTypeDimension]; - return self; -} - -@end - -@implementation CSSNumberToken - -- (instancetype)init -{ - self = [self initWithType:CSSTokenTypeNumber]; - return self; -} - -@end - -@implementation CSSPercentageToken - -- (instancetype)init -{ - self = [self initWithType:CSSTokenTypePercentage]; - return self; -} - -@end \ No newline at end of file diff --git a/HTMLKit/CSSTokenizer.h b/HTMLKit/CSSTokenizer.h deleted file mode 100644 index 262468d..0000000 --- a/HTMLKit/CSSTokenizer.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// CSSTokenizer.h -// HTMLKit -// -// Created by Iska on 07/05/15. -// Copyright (c) 2015 BrainCookie. All rights reserved. -// - -#import -#import "CSSToken.h" - -@interface CSSTokenizer : NSEnumerator - -@property (nonatomic, readonly, strong) NSString *string; - -- (instancetype)initWithString:(NSString *)string; - -@end diff --git a/HTMLKit/CSSTokenizer.m b/HTMLKit/CSSTokenizer.m deleted file mode 100644 index b22c808..0000000 --- a/HTMLKit/CSSTokenizer.m +++ /dev/null @@ -1,663 +0,0 @@ - // -// CSSTokenizer.m -// HTMLKit -// -// Created by Iska on 07/05/15. -// Copyright (c) 2015 BrainCookie. All rights reserved. -// - -#import "CSSTokenizer.h" -#import "CSSInputStream.h" -#import "CSSTokenizerCodePoints.h" -#import "NSString+HTMLKit.h" - -@interface CSSTokenizer () -{ - NSString *_string; - CSSInputStream *_inputStream; -} -@end - -@implementation CSSTokenizer -@synthesize string = _string; - -#pragma mark - Lifecycle - -- (instancetype)initWithString:(NSString *)string -{ - self = [super init]; - if (self) { - _string = [self preprocessInput:string]; - _inputStream = [[CSSInputStream alloc] initWithString:_string]; - } - return self; -} - -#pragma mark - Preprocess - -- (NSString *)preprocessInput:(NSString *)string -{ - string = [string stringByReplacingOccurrencesOfString:@"\r\n" withString:@"\n"]; - string = [string stringByReplacingOccurrencesOfString:@"\r" withString:@"\n"]; - string = [string stringByReplacingOccurrencesOfString:@"\f" withString:@"\n"]; - string = [string stringByReplacingOccurrencesOfString:@"\0" withString:@"\uFFFD"]; - - return string; -} - -#pragma mark - Enumerator - -- (id)nextObject -{ - CSSToken *token = [self consumeToken]; - if (token.type == CSSTokenTypeEOF) { - return nil; - } - return token; -} - -#pragma mark - Tokenize - -- (void)parseError -{ - NSString *errorMessage = [NSString stringWithFormat:@"Parse error at %lu", (unsigned long)_inputStream.location]; - NSLog(@"%@", errorMessage); -} - -- (CSSToken *)consumeToken -{ - [self consumeComments]; - - NSUInteger start = _inputStream.location; - UniChar codePoint = [_inputStream consumeNextCodePoint]; - CSSToken *token = nil; - - if (isWhitespace(codePoint)) { - token = [self consumeWhitespace]; - } else if (isQuote(codePoint)) { - token = [self consumeStringTokenWithEndingCodePoint:codePoint]; - } else if (isDigit(codePoint)) { - token = [self consumeNumericToken]; - } else if (codePoint == NUMBER_SIGN) { - if (isName([_inputStream nextCodePoint]) || - isValidEscape([_inputStream nextCodePoint], [_inputStream nextCodePointAtOffset:1])) { - token = [CSSToken tokenWithType:CSSTokenTypeHash]; - if (isIdentifierStart([_inputStream nextCodePoint], - [_inputStream nextCodePointAtOffset:1], - [_inputStream nextCodePointAtOffset:2])) { - token.type = CSSTokenTypeIdent; - } - token.text = [self consumeName]; - } else { - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - } else if (codePoint == DOLLAR_SIGN) { - if ([_inputStream nextCodePoint] == EQUALS_SIGN) { - [_inputStream consumeNextCodePoint]; - token = [CSSToken tokenWithType:CSSTokenTypeSuffixMatch]; - } else { - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - } else if (codePoint == LEFT_PARENTHESIS) { - token = [CSSToken tokenWithType:CSSTokenTypeParenthesisOpen]; - } else if (codePoint == RIGHT_PARENTHESIS) { - token = [CSSToken tokenWithType:CSSTokenTypeParenthesisClose]; - } else if (codePoint == ASTERIX) { - if ([_inputStream nextCodePoint] == EQUALS_SIGN) { - [_inputStream consumeNextCodePoint]; - token = [CSSToken tokenWithType:CSSTokenTypeSubstringMatch]; - } else { - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - } else if (codePoint == PLUS_SIGN) { - if (isNumberStart([_inputStream currentCodePoint], - [_inputStream nextCodePoint], - [_inputStream nextCodePointAtOffset:1])) { - [_inputStream reconsumeCurrentCodePoint]; - token = [self consumeNumericToken]; - } else { - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - } else if (codePoint == COMMA) { - token = [CSSToken tokenWithType:CSSTokenTypeComma]; - } else if (codePoint == HYPHEN_MINUS) { - if (isNumberStart([_inputStream currentCodePoint], - [_inputStream nextCodePoint], - [_inputStream nextCodePointAtOffset:1])) { - [_inputStream reconsumeCurrentCodePoint]; - token = [self consumeNumericToken]; - } else if (isIdentifierStart([_inputStream currentCodePoint], - [_inputStream nextCodePoint], - [_inputStream nextCodePointAtOffset:1])){ - [_inputStream reconsumeCurrentCodePoint]; - token = [self consumeIdentLikeToken]; - } else if ([_inputStream nextCodePoint] == HYPHEN_MINUS && - [_inputStream nextCodePointAtOffset:1] == GREATERTHAN) { - [_inputStream consumeNextCodePoint]; - [_inputStream consumeNextCodePoint]; - token = [CSSToken tokenWithType:CSSTokenTypeCommentDeclarationClose]; - } - } else if (codePoint == FULL_STOP) { - if (isNumberStart(codePoint, [_inputStream nextCodePoint], [_inputStream nextCodePointAtOffset:2])) { - [_inputStream reconsumeCurrentCodePoint]; - token = [self consumeNumericToken]; - } else { - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - } else if (codePoint == SOLIDUS) { - if ([_inputStream nextCodePoint] == ASTERIX) { - [_inputStream reconsumeCurrentCodePoint]; - [self consumeComments]; - token = [self consumeToken]; - } else { - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - } else if (codePoint == COLON) { - token = [CSSToken tokenWithType:CSSTokenTypeColon]; - } else if (codePoint == SEMICOLON) { - token = [CSSToken tokenWithType:CSSTokenTypeSemicolon]; - } else if (codePoint == LESS_THAN_SIGN) { - if ([_inputStream nextCodePoint] == EXCLAMATION_MARK && - [_inputStream nextCodePointAtOffset:1] == HYPHEN_MINUS && - [_inputStream nextCodePointAtOffset:2] == HYPHEN_MINUS) { - [_inputStream consumeNextCodePoint]; - [_inputStream consumeNextCodePoint]; - [_inputStream consumeNextCodePoint]; - token = [CSSToken tokenWithType:CSSTokenTypeCommentDeclarationOpen]; - } else { - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - } else if (codePoint == COMMERCIAL_AT) { - if (isIdentifierStart([_inputStream nextCodePoint], - [_inputStream nextCodePointAtOffset:1], - [_inputStream nextCodePointAtOffset:2])) { - NSString *name = [self consumeName]; - token = [CSSToken tokenWithType:CSSTokenTypeAtKeyword]; - token.text = name; - } else { - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - } else if (codePoint == LEFT_SQUARE_BRACKET) { - token = [CSSToken tokenWithType:CSSTokenTypeSquareBracketOpen]; - } else if (codePoint == REVERSE_SOLIDUS) { - if (isValidEscape(codePoint, [_inputStream nextCodePoint])) { - [_inputStream reconsumeCurrentCodePoint]; - token = [self consumeIdentLikeToken]; - } else { - [self parseError]; - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - } else if (codePoint == RIGHT_SQUARE_BRACKET) { - token = [CSSToken tokenWithType:CSSTokenTypeSquareBracketClose]; - } else if (codePoint == CIRCUMFLEX_ACCENT) { - if ([_inputStream nextCodePoint] == EQUALS_SIGN) { - [_inputStream consumeNextCodePoint]; - token = [CSSToken tokenWithType:CSSTokenTypePrefixMatch]; - } else { - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - } else if (codePoint == LEFT_CURLY_BRACKET) { - token = [CSSToken tokenWithType:CSSTokenTypeCurlyBracketOpen]; - } else if (codePoint == RIGHT_CURLY_BRACKET) { - token = [CSSToken tokenWithType:CSSTokenTypeCurlyBracketClose]; - } else if (codePoint == LATIN_CAPITAL_LETTER_U || codePoint == LATIN_SMALL_LETTER_U) { - if ([_inputStream nextCodePoint] == PLUS_SIGN && - (isHexDigit([_inputStream nextCodePointAtOffset:1]) || - [_inputStream nextCodePointAtOffset:1] == QUOTATION_MARK)) { - [_inputStream consumeNextCodePoint]; - token = [self consumeUnicodeRange]; - } else { - [_inputStream reconsumeCurrentCodePoint]; - token = [self consumeIdentLikeToken]; - } - } else if (codePoint == VERTICAL_LINE) { - if ([_inputStream nextCodePoint] == EQUALS_SIGN) { - [_inputStream consumeNextCodePoint]; - token = [CSSToken tokenWithType:CSSTokenTypeDashMatch]; - } else if ([_inputStream nextCodePoint] == VERTICAL_LINE) { - [_inputStream consumeNextCodePoint]; - token = [CSSToken tokenWithType:CSSTokenTypeColumn]; - } else { - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - } else if (codePoint == TILDE) { - if ([_inputStream nextCodePoint] == EQUALS_SIGN) { - [_inputStream consumeNextCodePoint]; - token = [CSSToken tokenWithType:CSSTokenTypeIncludeMatch]; - } else { - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - } else if (codePoint == EOF_CHARACTER) { - token = [CSSToken tokenWithType:CSSTokenTypeEOF]; - } else { - token = [CSSToken tokenWithType:CSSTokenTypeDelim]; - } - - token.location = start; - token.length = _inputStream.location - start; - token.text = [_string substringWithRange:NSMakeRange(token.location, token.length)]; - - return token; -} - -- (void)consumeComments -{ - while ([_inputStream nextCodePointAtOffset:0] == SOLIDUS && - [_inputStream nextCodePointAtOffset:1] == ASTERIX) { - [_inputStream consumeNextCodePoint]; - [_inputStream consumeNextCodePoint]; - while (YES) { - UniChar codePoint = [_inputStream consumeNextCodePoint]; - if (codePoint == EOF_CHARACTER) { - return; - } - if (codePoint == ASTERIX && [_inputStream nextCodePoint] == SOLIDUS) { - [_inputStream consumeNextCodePoint]; - break; - } - } - } -} - -- (CSSToken *)consumeWhitespace -{ - CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); - - while (isWhitespace([_inputStream nextCodePoint])) { - UniChar codePoint = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(value, &codePoint, 1); - } - - CSSToken *token = [CSSToken tokenWithType:CSSTokenTypeWhitespace]; - token.text = (__bridge_transfer NSString *)(value); - return token; -} - -- (CSSToken *)consumeNumericToken -{ - NSNumber *value = nil; - CSSNumericTokenType type = [self consumeNumber:&value]; - - if (isIdentifierStart([_inputStream nextCodePoint], - [_inputStream nextCodePointAtOffset:1], - [_inputStream nextCodePointAtOffset:2])) { - CSSDimensionToken *token = [CSSDimensionToken new]; - token.numericType = type; - token.value = value; - token.unit = [self consumeName]; - return token; - } else if ([_inputStream nextCodePoint] == PERCENTAGE_SIGN) { - CSSPercentageToken *token = [CSSPercentageToken tokenWithType:CSSTokenTypePercentage]; - token.value = value; - return token; - } else { - CSSNumericToken *token = [CSSNumericToken tokenWithType:CSSTokenTypeNumber]; - token.numericType = type; - token.value = value; - return token; - } -} - -- (CSSToken *)consumeIdentLikeToken -{ - NSString *name = [self consumeName]; - - if ([name isEqualToStringIgnoringCase:@"url"] && - [_inputStream nextCodePoint] == LEFT_PARENTHESIS) { - [_inputStream consumeNextCodePoint]; - return [self consumeURLToken]; - } else if ([_inputStream nextCodePoint] == LEFT_PARENTHESIS) { - [_inputStream consumeNextCodePoint]; - CSSToken *token = [CSSToken tokenWithType:CSSTokenTypeFunction]; - token.text = name; - return token; - } else { - CSSToken *token = [CSSToken tokenWithType:CSSTokenTypeIdent]; - token.text = name; - return token; - } -} - -- (CSSToken *)consumeStringTokenWithEndingCodePoint:(UniChar)endingCodePoint -{ - CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); - CSSToken *token = [CSSToken tokenWithType:CSSTokenTypeString]; - - while (YES) { - UniChar codePoint = [_inputStream consumeNextCodePoint]; - - if (codePoint == endingCodePoint || codePoint == EOF_CHARACTER) { - break; - } else if (isNewLine(codePoint)) { - [self parseError]; - [_inputStream reconsumeCurrentCodePoint]; - token.type = CSSTokenTypeBadString; - break; - } else if (codePoint == REVERSE_SOLIDUS) { - if ([_inputStream nextCodePoint] == EOF_CHARACTER) { - break; - } else if (isNewLine([_inputStream nextCodePoint])) { - [_inputStream consumeNextCodePoint]; - } else { - UTF32Char escapedCodePoint = [self consumeEscapedCodePoint]; - AppendCodePoint(value, escapedCodePoint); - } - } else { - CFStringAppendCharacters(value, &codePoint, 1); - } - } - - token.text = (__bridge_transfer NSString *)(value); - return token; -} - -- (CSSToken *)consumeURLToken -{ - void (^ consumeWhitespace)() = ^ { - while (isWhitespace([_inputStream nextCodePoint])) { - [_inputStream consumeNextCodePoint]; - } - }; - - CSSToken *token = [CSSToken tokenWithType:CSSTokenTypeURL]; - token.text = @""; - - consumeWhitespace(); - - if ([_inputStream nextCodePoint] == EOF_CHARACTER) { - return token; - } - - UniChar codePoint = [_inputStream consumeNextCodePoint]; - if (codePoint == QUOTATION_MARK || codePoint == APOSTROPHE) { - CSSToken *stringToken = [self consumeStringTokenWithEndingCodePoint:codePoint]; - if (stringToken.type == CSSTokenTypeBadString) { - [self consumeRemnantsOfBadURL]; - return [CSSToken tokenWithType:CSSTokenTypeBadURL]; - } - token.text = stringToken.text; - consumeWhitespace(); - - if ([_inputStream nextCodePoint] == RIGHT_PARENTHESIS || - [_inputStream nextCodePoint] == EOF_CHARACTER) { - [_inputStream consumeNextCodePoint]; - return token; - } else { - [self consumeRemnantsOfBadURL]; - return [CSSToken tokenWithType:CSSTokenTypeBadURL]; - } - } - - CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); - - while (YES) { - UniChar codePoint = [_inputStream consumeNextCodePoint]; - - if (codePoint == RIGHT_PARENTHESIS || codePoint == EOF_CHARACTER) { - return token; - } - - if (isWhitespace(codePoint)) { - consumeWhitespace(); - if ([_inputStream nextCodePoint] == RIGHT_PARENTHESIS || - [_inputStream nextCodePoint] == EOF_CHARACTER) { - [_inputStream consumeNextCodePoint]; - return token; - } else { - [self consumeRemnantsOfBadURL]; - return [CSSToken tokenWithType:CSSTokenTypeBadURL]; - } - } - - if (codePoint == QUOTATION_MARK || - codePoint == APOSTROPHE || - codePoint == LEFT_PARENTHESIS || - isNonPrintable(codePoint)) { - [self parseError]; - [self consumeRemnantsOfBadURL]; - return [CSSToken tokenWithType:CSSTokenTypeBadURL]; - } - - if (codePoint == REVERSE_SOLIDUS) { - if (isValidEscape([_inputStream currentCodePoint], [_inputStream nextCodePoint])) { - UTF32Char escapedCodePoint = [self consumeEscapedCodePoint]; - AppendCodePoint(value, escapedCodePoint); - } else { - [self parseError]; - [self consumeRemnantsOfBadURL]; - return [CSSToken tokenWithType:CSSTokenTypeBadURL]; - } - } - - CFStringAppendCharacters(value, &codePoint, 1); - } - - return token; -} - -- (CSSToken *)consumeUnicodeRange -{ - unsigned int (^ parseHexInt) (NSString *) = ^ unsigned int (NSString *string) { - NSScanner *scanner = [NSScanner scannerWithString:string]; - unsigned int num; - [scanner scanHexInt:&num]; - return num; - }; - - void (^ consumeHexDigits)(CFMutableStringRef) = ^ (CFMutableStringRef ref) { - while (isHexDigit([_inputStream nextCodePoint]) && CFStringGetLength(ref) < 6) { - UniChar codePoint = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(ref, &codePoint, 1); - } - }; - - CFMutableStringRef hexDigits = CFStringCreateMutable(kCFAllocatorDefault, 6); - consumeHexDigits(hexDigits); - - unsigned int rangeStart = 0; - unsigned int rangeEnd = 0; - - CFIndex length = CFStringGetLength(hexDigits); - if (length < 6) { - while ([_inputStream nextCodePoint] == QUESTION_MARK && CFStringGetLength(hexDigits) < 6) { - UniChar codePoint = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(hexDigits, &codePoint, 1); - } - - NSString *string = (__bridge NSString *)(hexDigits); - - if (string.length > length) { - rangeStart = parseHexInt([string stringByReplacingOccurrencesOfString:@"?" withString:@"0"]); - rangeEnd = parseHexInt([string stringByReplacingOccurrencesOfString:@"?" withString:@"F"]); - - CSSUnicodeRangeToken *token = [CSSUnicodeRangeToken new]; - token.start = rangeStart; - token.end = rangeEnd; - return token; - } else { - rangeStart = parseHexInt(string); - } - } - - if ([_inputStream nextCodePoint] == HYPHEN_MINUS && isDigit([_inputStream nextCodePointAtOffset:1])) { - [_inputStream consumeNextCodePoint]; - consumeHexDigits(hexDigits); - rangeEnd = parseHexInt((__bridge NSString *)(hexDigits)); - } else { - rangeEnd = rangeStart; - } - - CSSUnicodeRangeToken *token = [CSSUnicodeRangeToken new]; - token.start = rangeStart; - token.end = rangeEnd; - return token; -} - -- (UTF32Char)consumeEscapedCodePoint -{ - UniChar codePoint = [_inputStream consumeNextCodePoint]; - - if (isHexDigit(codePoint)) { - CFMutableStringRef hexString = CFStringCreateMutable(kCFAllocatorDefault, 6); - CFStringAppendCharacters(hexString, &codePoint, 1); - - while (isHexDigit([_inputStream nextCodePoint]) && CFStringGetLength(hexString) <= 6) { - UniChar codePoint = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(hexString, &codePoint, 1); - } - - if (isWhitespace([_inputStream nextCodePoint])) { - [_inputStream consumeNextCodePoint]; - } - - NSScanner *scanner = [NSScanner scannerWithString:(__bridge NSString *)(hexString)]; - UTF32Char number; - [scanner scanHexInt:&number]; - - return isValidEscapedCodePoint(number) ? number : REPLACEMENT_CHARACTER; - } else if (codePoint == EOF_CHARACTER) { - return REPLACEMENT_CHARACTER; - } - - return codePoint; -} - -- (NSString *)consumeName -{ - CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); - while (YES) { - UniChar codePoint = [_inputStream consumeNextCodePoint]; - if (isName(codePoint)) { - CFStringAppendCharacters(value, &codePoint, 1); - } else if (isValidEscape([_inputStream nextCodePoint], [_inputStream nextCodePointAtOffset:1])) { - UTF32Char escapedCodePoint = [self consumeEscapedCodePoint]; - AppendCodePoint(value, escapedCodePoint); - } else { - break; - } - } - - return (__bridge_transfer NSString *)(value); -} - -- (CSSNumericTokenType)consumeNumber:(NSNumber **)number -{ - CFMutableStringRef repr = CFStringCreateMutable(kCFAllocatorDefault, 0); - CSSNumericTokenType type = CSSNumericTokenTypeInteger; - - void (^ consumeDigits)() = ^{ - while (isDigit([_inputStream nextCodePoint])) { - UniChar next = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(repr, &next, 1); - } - }; - - if ([_inputStream nextCodePoint] == PLUS_SIGN || - [_inputStream nextCodePoint] == HYPHEN_MINUS) { - UniChar next = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(repr, &next, 1); - } - - consumeDigits(); - - if ([_inputStream nextCodePoint] == FULL_STOP && - isDigit([_inputStream nextCodePointAtOffset:1])) { - UniChar next = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(repr, &next, 1); - next = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(repr, &next, 1); - type = CSSNumericTokenTypeNumber; - consumeDigits(); - } - - UniChar first = [_inputStream nextCodePoint]; - UniChar second = [_inputStream nextCodePointAtOffset:1]; - UniChar third = [_inputStream nextCodePointAtOffset:2]; - - if (first == LATIN_CAPITAL_LETTER_E || first == LATIN_SMALL_LETTER_E) { - if (isDigit(second)) { - UniChar next = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(repr, &next, 1); - next = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(repr, &next, 1); - consumeDigits(); - } else if ((second == PLUS_SIGN || second == HYPHEN_MINUS) && isDigit(third)) { - UniChar next = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(repr, &next, 1); - next = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(repr, &next, 1); - next = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(repr, &next, 1); - consumeDigits(); - } - } - - NSNumber *value = [self convertStringToNumber:(__bridge NSString *)(repr)]; - *number = value; - - return type; -} - -- (NSNumber *)convertStringToNumber:(NSString *)string -{ - NSInteger s = 1; - if ([string hasPrefix:@"-"]) { - s = -1; - string = [string substringFromIndex:1]; - } else if ([string hasPrefix:@"+"]) { - s = 1; - string = [string substringFromIndex:1]; - } - - NSScanner *scanner = [NSScanner scannerWithString:string]; - - NSInteger i = 0; - NSString *digits = nil; - if ([scanner scanCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] intoString:&digits]) { - i = [digits integerValue]; - } - - [scanner scanString:@"0x002E" intoString:nil]; - - NSInteger f = 0; - NSInteger d = 0; - digits = nil; - if ([scanner scanCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] intoString:&digits]) { - f = [digits integerValue]; - d = digits.length; - } - - [scanner scanString:@"e" intoString:nil]; - [scanner scanString:@"E" intoString:nil]; - - NSInteger t = 1; - if ([scanner scanString:@"-" intoString:nil]) { - t = -1; - } else if ([scanner scanString:@"+" intoString:nil]) { - t = 1; - } - - NSInteger e = 0; - digits = nil; - if ([scanner scanCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] intoString:&digits]) { - e = [digits integerValue]; - } - - return @(s * (i + f * pow(10, -d)) * pow(10, t * e)); -} - -- (void)consumeRemnantsOfBadURL -{ - while (YES) { - UniChar codePoint = [_inputStream consumeNextCodePoint]; - if (codePoint == RIGHT_PARENTHESIS || codePoint == EOF_CHARACTER) { - return; - } - - if (isValidEscape([_inputStream currentCodePoint], [_inputStream nextCodePoint])) { - [self consumeEscapedCodePoint]; - } - } -} - -@end