From 4fcaf4c810336cce85e5cedf494433a53c39712c Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 8 May 2015 00:31:39 +0200 Subject: [PATCH 001/103] Add implementation for a CSS Selector Tokenizer The Tokenizer is based on a flex-generated lexer for the grammar defined in the CSS Selectors Level 3 Spec http://www.w3.org/TR/css3-selectors/#lex --- HTMLKit.xcodeproj/project.pbxproj | 28 + HTMLKit/CSSLexer.c | 3156 +++++++++++++++++++++++++++++ HTMLKit/CSSLexer.h | 329 +++ HTMLKit/CSSTokenizer.h | 44 + HTMLKit/CSSTokenizer.m | 56 + 5 files changed, 3613 insertions(+) create mode 100644 HTMLKit/CSSLexer.c create mode 100644 HTMLKit/CSSLexer.h create mode 100644 HTMLKit/CSSTokenizer.h create mode 100644 HTMLKit/CSSTokenizer.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index e00d8ff..3eed2ab 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 620802021AFD939200F2962F /* CSSTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 623F13A81AFC11D900C90BF4 /* CSSTokenizer.h */; }; 623406E11ADB04F9004677A3 /* HTMLTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 623406DF1ADB04F9004677A3 /* HTMLTemplate.h */; }; 623406E21ADB04F9004677A3 /* HTMLTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E01ADB04F9004677A3 /* HTMLTemplate.m */; }; 623406E31ADB04F9004677A3 /* HTMLTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E01ADB04F9004677A3 /* HTMLTemplate.m */; }; @@ -63,12 +64,17 @@ 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 */; }; 624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */; }; 624493AD19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; }; 624493AE19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; }; + 62491C471AFE51F100ACF9E2 /* CSSLexer.c in Sources */ = {isa = PBXBuildFile; fileRef = 62491C451AFE51F100ACF9E2 /* CSSLexer.c */; }; + 62491C481AFE51F100ACF9E2 /* CSSLexer.c in Sources */ = {isa = PBXBuildFile; fileRef = 62491C451AFE51F100ACF9E2 /* CSSLexer.c */; }; + 62491C491AFE51F100ACF9E2 /* CSSLexer.h in Headers */ = {isa = PBXBuildFile; fileRef = 62491C461AFE51F100ACF9E2 /* CSSLexer.h */; }; 624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */; }; 624AC90119FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; 624AC90219FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; @@ -207,11 +213,15 @@ 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 = ""; }; 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLToken.h; sourceTree = ""; }; 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLToken.m; sourceTree = ""; }; + 62491C451AFE51F100ACF9E2 /* CSSLexer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CSSLexer.c; sourceTree = ""; }; + 62491C461AFE51F100ACF9E2 /* CSSLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSLexer.h; sourceTree = ""; }; 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokens.h; sourceTree = ""; }; 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitTokenizerTests.m; sourceTree = ""; }; 624AC90419FBFE8A00BD3C4A /* html5lib-tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "html5lib-tests"; sourceTree = ""; }; @@ -302,6 +312,17 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 62079BE61AF5656600D3B402 /* Selectors */ = { + isa = PBXGroup; + children = ( + 623F13A81AFC11D900C90BF4 /* CSSTokenizer.h */, + 623F13A91AFC11D900C90BF4 /* CSSTokenizer.m */, + 62491C461AFE51F100ACF9E2 /* CSSLexer.h */, + 62491C451AFE51F100ACF9E2 /* CSSLexer.c */, + ); + name = Selectors; + sourceTree = ""; + }; 6236738C1AC0CD2400FF89B3 /* Tokenizer */ = { isa = PBXGroup; children = ( @@ -424,6 +445,7 @@ 623719441AA1472B002E03C8 /* Nodes */, 628E16ED1ADAE73700B15A06 /* Categories */, 628E16EE1ADAE75300B15A06 /* Structures */, + 62079BE61AF5656600D3B402 /* Selectors */, 625A14B619C7829400AD0C32 /* Supporting Files */, ); name = "Source Code"; @@ -567,7 +589,9 @@ 625A150419C783EB00AD0C32 /* HTMLKit.h in Headers */, 625A150819C78ABA00AD0C32 /* HTMLInputStreamReader.h in Headers */, 6238579B1A9E8934003A45D9 /* HTMLComment.h in Headers */, + 620802021AFD939200F2962F /* CSSTokenizer.h in Headers */, 62AE593519F97D880043F069 /* HTMLParseErrorToken.h in Headers */, + 62491C491AFE51F100ACF9E2 /* CSSLexer.h in Headers */, 62AE594919F9948A0043F069 /* HTMLCharacterToken.h in Headers */, 623857961A9E8606003A45D9 /* HTMLDocumentType.h in Headers */, 623406E61ADB05AD004677A3 /* HTMLDocumentFragment.h in Headers */, @@ -744,6 +768,8 @@ 623857931A9E772B003A45D9 /* HTMLDocument.m in Sources */, 623406E81ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */, 624493A819CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, + 623F13AC1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, + 62491C481AFE51F100ACF9E2 /* CSSLexer.c in Sources */, 625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */, 623857981A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, 62AE594B19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, @@ -796,6 +822,8 @@ 623857921A9E772B003A45D9 /* HTMLDocument.m in Sources */, 623406E71ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */, 624493A719CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, + 623F13AB1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, + 62491C471AFE51F100ACF9E2 /* CSSLexer.c in Sources */, 625A150219C783DE00AD0C32 /* HTMLKit.m in Sources */, 623857971A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, 62AE594A19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, diff --git a/HTMLKit/CSSLexer.c b/HTMLKit/CSSLexer.c new file mode 100644 index 0000000..219d14c --- /dev/null +++ b/HTMLKit/CSSLexer.c @@ -0,0 +1,3156 @@ + +#line 3 "CSSLexer.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +typedef uint64_t flex_uint64_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yyg->yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yyg->yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE cssrestart(yyin ,yyscanner ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +#define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ +do \ +{ \ +/* Undo effects of setting up yytext. */ \ +int yyless_macro_arg = (n); \ +YY_LESS_LINENO(yyless_macro_arg);\ +*yy_cp = yyg->yy_hold_char; \ +YY_RESTORE_YY_MORE_OFFSET \ +yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ +YY_DO_BEFORE_ACTION; /* set up yytext again */ \ +} \ +while ( 0 ) + +#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state +{ + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via cssrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + +}; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ +? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ +: NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] + +void cssrestart (FILE *input_file ,yyscan_t yyscanner ); +void css_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE css_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void css_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void css_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void csspush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void csspop_buffer_state (yyscan_t yyscanner ); + +static void cssensure_buffer_stack (yyscan_t yyscanner ); +static void css_load_buffer_state (yyscan_t yyscanner ); +static void css_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); + +#define YY_FLUSH_BUFFER css_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) + +YY_BUFFER_STATE css_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE css_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE css_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); + +void *cssalloc (yy_size_t ,yyscan_t yyscanner ); +void *cssrealloc (void *,yy_size_t ,yyscan_t yyscanner ); +void cssfree (void * ,yyscan_t yyscanner ); + +#define yy_new_buffer css_create_buffer + +#define yy_set_interactive(is_interactive) \ +{ \ +if ( ! YY_CURRENT_BUFFER ){ \ +cssensure_buffer_stack (yyscanner); \ +YY_CURRENT_BUFFER_LVALUE = \ +css_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ +} \ +YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ +} + +#define yy_set_bol(at_bol) \ +{ \ +if ( ! YY_CURRENT_BUFFER ){\ +cssensure_buffer_stack (yyscanner); \ +YY_CURRENT_BUFFER_LVALUE = \ +css_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ +} \ +YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ +} + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +#define csswrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +typedef yyconst struct yy_trans_info *yy_state_type; + +#define yytext_ptr yytext_r + +static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); +static int yy_get_next_buffer (yyscan_t yyscanner ); +static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ +yyg->yytext_ptr = yy_bp; \ +yyleng = (yy_size_t) (yy_cp - yy_bp); \ +yyg->yy_hold_char = *yy_cp; \ +*yy_cp = '\0'; \ +yyg->yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 25 +#define YY_END_OF_BUFFER 26 +struct yy_trans_info +{ + flex_int16_t yy_verify; + flex_int16_t yy_nxt; +}; +static yyconst struct yy_trans_info yy_transition[5613] = +{ + { 0, 0 }, { 0,5567 }, { 0, 0 }, { 0,5565 }, { 1, 96 }, + { 2, 98 }, { 3, 105 }, { 4, 98 }, { 5, 98 }, { 6, 96 }, + { 7, 145 }, { 8, 193 }, { 9, 115 }, { 10, 96 }, { 11, 241 }, + { 12, 96 }, { 13, 122 }, { 14, 124 }, { 15, 128 }, { 16, 289 }, + { 17, 291 }, { 18, 135 }, { 19, 317 }, { 20, 317 }, { 21, 317 }, + { 22, 317 }, { 23, 317 }, { 24, 317 }, { 25, 343 }, { 26, 362 }, + { 27, 96 }, { 28, 365 }, { 29, 367 }, { 30, 412 }, { 31, 412 }, + { 32, 412 }, { 33, 412 }, { 34, 412 }, { 35, 412 }, { 36, 412 }, + { 37, 460 }, { 38, 387 }, { 39, 412 }, { 40, 412 }, { 41, 412 }, + { 42, 412 }, { 43, 412 }, { 44, 389 }, { 45, 391 }, { 46, 412 }, + + { 0, 0 }, { 0,5517 }, { 1, 48 }, { 2, 50 }, { 3, 57 }, + { 4, 50 }, { 5, 50 }, { 6, 48 }, { 7, 97 }, { 8, 145 }, + { 9, 67 }, { 10, 48 }, { 11, 193 }, { 12, 48 }, { 13, 74 }, + { 14, 76 }, { 15, 80 }, { 16, 241 }, { 17, 243 }, { 18, 87 }, + { 19, 269 }, { 20, 269 }, { 21, 269 }, { 22, 269 }, { 23, 269 }, + { 24, 269 }, { 25, 295 }, { 26, 314 }, { 27, 48 }, { 28, 317 }, + { 29, 319 }, { 30, 364 }, { 31, 364 }, { 32, 364 }, { 33, 364 }, + { 34, 364 }, { 35, 364 }, { 36, 364 }, { 37, 412 }, { 38, 339 }, + { 39, 364 }, { 40, 364 }, { 41, 364 }, { 42, 364 }, { 43, 364 }, + { 44, 341 }, { 45, 343 }, { 46, 364 }, { 0, 24 }, { 0,5469 }, + + { 0, 1 }, { 0,5467 }, { 0, 0 }, { 2, 410 }, { 3, 410 }, + { 4, 410 }, { 5, 410 }, { 0, 1 }, { 0,5460 }, { 0, 0 }, + { 2, 403 }, { 3, 403 }, { 4, 403 }, { 5, 403 }, { 0, 0 }, + { 14, 295 }, { 15, 297 }, { 0, 24 }, { 0,5450 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 14, 288 }, { 15, 290 }, { 0, 24 }, + { 0,5443 }, { 0, 12 }, { 0,5441 }, { 0, 0 }, { 28, 322 }, + { 0, 14 }, { 0,5437 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 28, 315 }, { 0, 24 }, { 0,5430 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 27, 315 }, { 45, 324 }, { 0, 18 }, { 0,5420 }, { 1, 403 }, + + { 2, 403 }, { 13, 941 }, { 27, 316 }, { 45, 317 }, { 6, 403 }, + { 7, 281 }, { 8, 403 }, { 9, 403 }, { 10, 403 }, { 11, 403 }, + { 12, 403 }, { 13, 403 }, { 14, 403 }, { 15, 403 }, { 16, 403 }, + { 17, 403 }, { 18, 403 }, { 19, 403 }, { 20, 403 }, { 21, 403 }, + { 22, 403 }, { 23, 403 }, { 24, 403 }, { 25, 403 }, { 26, 403 }, + { 27, 403 }, { 28, 403 }, { 29, 403 }, { 30, 403 }, { 31, 403 }, + { 32, 403 }, { 33, 403 }, { 34, 403 }, { 35, 403 }, { 36, 403 }, + { 37, 451 }, { 38, 403 }, { 39, 403 }, { 40, 403 }, { 41, 403 }, + { 42, 403 }, { 43, 403 }, { 44, 403 }, { 45, 403 }, { 46, 499 }, + { 0, 24 }, { 0,5372 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 16, 499 }, { 0, 0 }, { 0, 0 }, + { 19, 499 }, { 20, 499 }, { 21, 499 }, { 22, 499 }, { 23, 499 }, + { 24, 499 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 30, 499 }, { 31, 499 }, { 32, 499 }, { 33, 499 }, + { 34, 499 }, { 35, 499 }, { 36, 499 }, { 37, 547 }, { 0, 0 }, + { 39, 499 }, { 40, 499 }, { 41, 499 }, { 42, 499 }, { 43, 499 }, + { 0, 0 }, { 0, 0 }, { 46, 499 }, { 0, 18 }, { 0,5324 }, + { 1, 547 }, { 2, 547 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 6, 547 }, { 7, 547 }, { 8, 547 }, { 9, 547 }, { 10, 547 }, + { 11, 185 }, { 12, 547 }, { 13, 547 }, { 14, 547 }, { 15, 547 }, + { 16, 547 }, { 17, 547 }, { 18, 547 }, { 19, 547 }, { 20, 547 }, + { 21, 547 }, { 22, 547 }, { 23, 547 }, { 24, 547 }, { 25, 547 }, + { 26, 547 }, { 27, 547 }, { 28, 547 }, { 29, 547 }, { 30, 547 }, + { 31, 547 }, { 32, 547 }, { 33, 547 }, { 34, 547 }, { 35, 547 }, + { 36, 547 }, { 37, 595 }, { 38, 547 }, { 39, 547 }, { 40, 547 }, + { 41, 547 }, { 42, 547 }, { 43, 547 }, { 44, 547 }, { 45, 547 }, + { 46, 643 }, { 0, 24 }, { 0,5276 }, { 0, 24 }, { 0,5274 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16, 226 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 19, 737 }, { 20, 737 }, + { 21, 737 }, { 22, 737 }, { 23, 737 }, { 24, 737 }, { 0, 10 }, + { 0,5248 }, { 0, 0 }, { 30, 643 }, { 31, 643 }, { 32, 643 }, + { 33, 643 }, { 34, 643 }, { 35, 643 }, { 36, 643 }, { 37, 691 }, + { 10, 200 }, { 39, 643 }, { 40, 643 }, { 41, 643 }, { 42, 643 }, + { 43, 643 }, { 16, 807 }, { 17, 809 }, { 46, 643 }, { 19, 835 }, + { 20, 835 }, { 21, 835 }, { 22, 835 }, { 23, 835 }, { 24, 835 }, + { 0, 24 }, { 0,5222 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 30, 863 }, { 31, 863 }, { 32, 863 }, { 33, 863 }, { 34, 863 }, + { 35, 863 }, { 36, 863 }, { 37, 911 }, { 0, 0 }, { 39, 863 }, + { 40, 863 }, { 41, 863 }, { 42, 863 }, { 43, 863 }, { 0, 24 }, + { 0,5203 }, { 46, 863 }, { 0, 13 }, { 0,5200 }, { 0, 24 }, + { 0,5198 }, { 6, 918 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 34, 933 }, { 0, 0 }, { 0, 0 }, { 37, 935 }, { 0, 0 }, + { 0, 0 }, { 16, 923 }, { 41, 933 }, { 0, 0 }, { 0, 24 }, + { 0,5178 }, { 0, 24 }, { 0,5176 }, { 0, 15 }, { 0,5174 }, + { 0, 12 }, { 0,5172 }, { 0, 14 }, { 0,5170 }, { 0, 0 }, + + { 30, 968 }, { 31, 968 }, { 32, 968 }, { 33, 968 }, { 34, 968 }, + { 35, 968 }, { 36, 968 }, { 37,1016 }, { 0, 0 }, { 39, 968 }, + { 40, 968 }, { 41, 968 }, { 42, 968 }, { 43, 968 }, { 0, 7 }, + { 0,5153 }, { 46, 968 }, { 27, 897 }, { 0, 0 }, { 27, 897 }, + { 0, 0 }, { 27, 897 }, { 0, 13 }, { 0,5145 }, { 0, 15 }, + { 0,5143 }, { 0, 0 }, { 12, 870 }, { 0, 8 }, { 0,5139 }, + { 0, 0 }, { 16,1019 }, { 0, 5 }, { 0,5135 }, { 19,1019 }, + { 20,1019 }, { 21,1019 }, { 22,1019 }, { 23,1019 }, { 24,1019 }, + { 0, 6 }, { 0,5127 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30,1019 }, { 31,1019 }, { 32,1019 }, { 33,1019 }, { 34,1019 }, + + { 35,1019 }, { 36,1019 }, { 37,1067 }, { 0, 0 }, { 39,1019 }, + { 40,1019 }, { 41,1019 }, { 42,1019 }, { 43,1019 }, { 0, 0 }, + { 0, 0 }, { 46,1019 }, { 0, 24 }, { 0,5105 }, { 1,1067 }, + { 2,1067 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6,1067 }, + { 7,1067 }, { 8,1067 }, { 9,1067 }, { 10,1067 }, { 11,1067 }, + { 12,1067 }, { 13,1067 }, { 14,1067 }, { 15,1067 }, { 16,1067 }, + { 17,1067 }, { 18,1067 }, { 19,1112 }, { 20,1112 }, { 21,1112 }, + { 22,1112 }, { 23,1112 }, { 24,1112 }, { 25,1067 }, { 26,1067 }, + { 27,1067 }, { 28,1067 }, { 29,1067 }, { 30,1112 }, { 31,1112 }, + { 32,1112 }, { 33,1067 }, { 34,1067 }, { 35,1067 }, { 36,1067 }, + + { 37,1067 }, { 38,1067 }, { 39,1112 }, { 40,1112 }, { 41,1067 }, + { 42,1067 }, { 43,1067 }, { 44,1067 }, { 45,1067 }, { 46,1067 }, + { 0, 1 }, { 0,5057 }, { 0, 0 }, { 2, 0 }, { 3, 0 }, + { 4, 0 }, { 5, 0 }, { 0, 0 }, { 0,5050 }, { 0, 19 }, + { 0,5048 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 14,-115 }, { 15,-113 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 28, -88 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 28, 777 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 0, 18 }, { 0,5017 }, { 1, 0 }, { 2, 0 }, { 0, 0 }, + { 0, 0 }, { 45, -86 }, { 6, 0 }, { 7,-122 }, { 8, 0 }, + { 9, 0 }, { 10, 0 }, { 11, 0 }, { 12, 0 }, { 13, 0 }, + { 14, 0 }, { 15, 0 }, { 16, 0 }, { 17, 0 }, { 18, 0 }, + { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, { 23, 0 }, + { 24, 0 }, { 25, 0 }, { 26, 0 }, { 27, 0 }, { 28, 0 }, + { 29, 0 }, { 30, 0 }, { 31, 0 }, { 32, 0 }, { 33, 0 }, + { 34, 0 }, { 35, 0 }, { 36, 0 }, { 37, 48 }, { 38, 0 }, + { 39, 0 }, { 40, 0 }, { 41, 0 }, { 42, 0 }, { 43, 0 }, + { 44, 0 }, { 45, 0 }, { 46, 96 }, { 0, 0 }, { 0,4969 }, + + { 1,1024 }, { 2,1024 }, { 3, -48 }, { 4, -48 }, { 5,1072 }, + { 6,1024 }, { 7,1024 }, { 8,1024 }, { 9,1024 }, { 10,1024 }, + { 11,1024 }, { 12,1024 }, { 13,1024 }, { 14,1024 }, { 15,1024 }, + { 16,1024 }, { 17,1024 }, { 18,1024 }, { 19,1120 }, { 20,1120 }, + { 21,1120 }, { 22,1120 }, { 23,1120 }, { 24,1120 }, { 25,1024 }, + { 26,1024 }, { 27,1024 }, { 28,1024 }, { 29,1024 }, { 30,1120 }, + { 31,1120 }, { 32,1120 }, { 33,1024 }, { 34,1024 }, { 35,1024 }, + { 36,1024 }, { 37,1024 }, { 38,1024 }, { 39,1120 }, { 40,1120 }, + { 41,1024 }, { 42,1024 }, { 43,1024 }, { 44,1024 }, { 45,1024 }, + { 46,1024 }, { 0, 18 }, { 0,4921 }, { 1, -96 }, { 2, -96 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, -96 }, { 7,-218 }, + { 8, -96 }, { 9, -96 }, { 10, -96 }, { 11, -96 }, { 12, -96 }, + { 13, -96 }, { 14, -96 }, { 15, -96 }, { 16, -96 }, { 17, -96 }, + { 18, -96 }, { 19, -96 }, { 20, -96 }, { 21, -96 }, { 22, -96 }, + { 23, -96 }, { 24, -96 }, { 25, -96 }, { 26, -96 }, { 27, -96 }, + { 28, -96 }, { 29, -96 }, { 30, -96 }, { 31, -96 }, { 32, -96 }, + { 33, -96 }, { 34, -96 }, { 35, -96 }, { 36, -96 }, { 37, -48 }, + { 38, -96 }, { 39, -96 }, { 40, -96 }, { 41, -96 }, { 42, -96 }, + { 43, -96 }, { 44, -96 }, { 45, -96 }, { 46, 0 }, { 0, 11 }, + { 0,4873 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16, 0 }, { 0, 0 }, { 0, 0 }, { 19, 0 }, + { 20, 0 }, { 21, 0 }, { 22, 0 }, { 23, 0 }, { 24, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, 0 }, { 31, 0 }, { 32, 0 }, { 33, 0 }, { 34, 0 }, + { 35, 0 }, { 36, 0 }, { 37, 48 }, { 0, 0 }, { 39, 0 }, + { 40, 0 }, { 41, 0 }, { 42, 0 }, { 43, 0 }, { 0, 0 }, + { 0, 0 }, { 46, 0 }, { 0, 0 }, { 0,4825 }, { 1,1024 }, + { 2,1024 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6,1024 }, + + { 7,1024 }, { 8,1024 }, { 9,1024 }, { 10,1024 }, { 11,1024 }, + { 12,1024 }, { 13,1024 }, { 14,1024 }, { 15,1024 }, { 16,1024 }, + { 17,1024 }, { 18,1024 }, { 19,1069 }, { 20,1069 }, { 21,1069 }, + { 22,1069 }, { 23,1069 }, { 24,1069 }, { 25,1024 }, { 26,1024 }, + { 27,1024 }, { 28,1024 }, { 29,1024 }, { 30,1069 }, { 31,1069 }, + { 32,1069 }, { 33,1024 }, { 34,1024 }, { 35,1024 }, { 36,1024 }, + { 37,1024 }, { 38,1024 }, { 39,1069 }, { 40,1069 }, { 41,1024 }, + { 42,1024 }, { 43,1024 }, { 44,1024 }, { 45,1024 }, { 46,1024 }, + { 0, 18 }, { 0,4777 }, { 1, 0 }, { 2, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 6, 0 }, { 7, 0 }, { 8, 0 }, + + { 9, 0 }, { 10, 0 }, { 11,-362 }, { 12, 0 }, { 13, 0 }, + { 14, 0 }, { 15, 0 }, { 16, 0 }, { 17, 0 }, { 18, 0 }, + { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, { 23, 0 }, + { 24, 0 }, { 25, 0 }, { 26, 0 }, { 27, 0 }, { 28, 0 }, + { 29, 0 }, { 30, 0 }, { 31, 0 }, { 32, 0 }, { 33, 0 }, + { 34, 0 }, { 35, 0 }, { 36, 0 }, { 37, 48 }, { 38, 0 }, + { 39, 0 }, { 40, 0 }, { 41, 0 }, { 42, 0 }, { 43, 0 }, + { 44, 0 }, { 45, 0 }, { 46, 96 }, { 0, 0 }, { 0,4729 }, + { 1,1021 }, { 2,1021 }, { 3, -48 }, { 4, -48 }, { 5,1069 }, + { 6,1021 }, { 7,1021 }, { 8,1021 }, { 9,1021 }, { 10,1021 }, + + { 11,1021 }, { 12,1021 }, { 13,1021 }, { 14,1021 }, { 15,1021 }, + { 16,1021 }, { 17,1021 }, { 18,1021 }, { 19,1117 }, { 20,1117 }, + { 21,1117 }, { 22,1117 }, { 23,1117 }, { 24,1117 }, { 25,1021 }, + { 26,1021 }, { 27,1021 }, { 28,1021 }, { 29,1021 }, { 30,1117 }, + { 31,1117 }, { 32,1117 }, { 33,1021 }, { 34,1021 }, { 35,1021 }, + { 36,1021 }, { 37,1021 }, { 38,1021 }, { 39,1117 }, { 40,1117 }, + { 41,1021 }, { 42,1021 }, { 43,1021 }, { 44,1021 }, { 45,1021 }, + { 46,1021 }, { 0, 18 }, { 0,4681 }, { 1, -96 }, { 2, -96 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, -96 }, { 7, -96 }, + { 8, -96 }, { 9, -96 }, { 10, -96 }, { 11,-458 }, { 12, -96 }, + + { 13, -96 }, { 14, -96 }, { 15, -96 }, { 16, -96 }, { 17, -96 }, + { 18, -96 }, { 19, -96 }, { 20, -96 }, { 21, -96 }, { 22, -96 }, + { 23, -96 }, { 24, -96 }, { 25, -96 }, { 26, -96 }, { 27, -96 }, + { 28, -96 }, { 29, -96 }, { 30, -96 }, { 31, -96 }, { 32, -96 }, + { 33, -96 }, { 34, -96 }, { 35, -96 }, { 36, -96 }, { 37, -48 }, + { 38, -96 }, { 39, -96 }, { 40, -96 }, { 41, -96 }, { 42, -96 }, + { 43, -96 }, { 44, -96 }, { 45, -96 }, { 46, 0 }, { 0, 7 }, + { 0,4633 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 12, 350 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 16, 499 }, { 0, 0 }, { 0, 0 }, { 19, 499 }, + { 20, 499 }, { 21, 499 }, { 22, 499 }, { 23, 499 }, { 24, 499 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, 499 }, { 31, 499 }, { 32, 499 }, { 33, 499 }, { 34, 499 }, + { 35, 499 }, { 36, 499 }, { 37, 547 }, { 0, 0 }, { 39, 499 }, + { 40, 499 }, { 41, 499 }, { 42, 499 }, { 43, 499 }, { 0, 0 }, + { 0, 0 }, { 46, 499 }, { 0, 0 }, { 0,4585 }, { 1, 547 }, + { 2, 547 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, 547 }, + { 7, 547 }, { 8, 547 }, { 9, 547 }, { 10, 547 }, { 11, 547 }, + { 12, 547 }, { 13, 547 }, { 14, 547 }, { 15, 547 }, { 16, 547 }, + + { 17, 547 }, { 18, 547 }, { 19, 592 }, { 20, 592 }, { 21, 592 }, + { 22, 592 }, { 23, 592 }, { 24, 592 }, { 25, 547 }, { 26, 547 }, + { 27, 547 }, { 28, 547 }, { 29, 547 }, { 30, 592 }, { 31, 592 }, + { 32, 592 }, { 33, 547 }, { 34, 547 }, { 35, 547 }, { 36, 547 }, + { 37, 547 }, { 38, 547 }, { 39, 592 }, { 40, 592 }, { 41, 547 }, + { 42, 547 }, { 43, 547 }, { 44, 547 }, { 45, 547 }, { 46, 547 }, + { 0, 10 }, { 0,4537 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 10,-511 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 16, 96 }, { 0, 0 }, { 0, 0 }, + + { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, { 23, 0 }, + { 24, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 30, 152 }, { 31, 152 }, { 32, 152 }, { 33, 152 }, + { 34, 152 }, { 35, 152 }, { 36, 152 }, { 37, 200 }, { 0, 0 }, + { 39, 152 }, { 40, 152 }, { 41, 152 }, { 42, 152 }, { 43, 152 }, + { 0, 0 }, { 0, 0 }, { 46, 152 }, { 0, 0 }, { 0,4489 }, + { 1, 925 }, { 2, 925 }, { 3, 925 }, { 4, 925 }, { 5, 925 }, + { 6, 925 }, { 7, 925 }, { 8, 925 }, { 9, 925 }, { 10, 925 }, + { 11, 925 }, { 12, 925 }, { 13, 973 }, { 14, 925 }, { 15, 925 }, + { 16, 925 }, { 17, 925 }, { 18, 925 }, { 19, 925 }, { 20, 925 }, + + { 21, 925 }, { 22, 925 }, { 23, 925 }, { 24, 925 }, { 25, 925 }, + { 26, 925 }, { 27, 925 }, { 28, 925 }, { 29, 925 }, { 30, 925 }, + { 31, 925 }, { 32, 925 }, { 33, 925 }, { 34, 925 }, { 35, 925 }, + { 36, 925 }, { 37, 925 }, { 38, 925 }, { 39, 925 }, { 40, 925 }, + { 41, 925 }, { 42, 925 }, { 43, 925 }, { 44, 925 }, { 45, 925 }, + { 46, 925 }, { 0, 0 }, { 0,4441 }, { 0, 0 }, { 0,4439 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 19, -98 }, { 20, -98 }, + + { 21, -98 }, { 22, -98 }, { 23, -98 }, { 24, -98 }, { 0, 10 }, + { 0,4413 }, { 0, 0 }, { 30, 56 }, { 31, 56 }, { 32, 56 }, + { 33, 56 }, { 34, 56 }, { 35, 56 }, { 36, 56 }, { 37, 104 }, + { 10,-635 }, { 39, 56 }, { 40, 56 }, { 41, 56 }, { 42, 56 }, + { 43, 56 }, { 16, -28 }, { 17, -26 }, { 46, 56 }, { 19, 0 }, + { 20, 0 }, { 21, 0 }, { 22, 0 }, { 23, 0 }, { 24, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 20 }, { 0,4385 }, { 0, 0 }, + { 30, 28 }, { 31, 28 }, { 32, 28 }, { 33, 28 }, { 34, 28 }, + { 35, 28 }, { 36, 28 }, { 37, 76 }, { 0, 0 }, { 39, 28 }, + { 40, 28 }, { 41, 28 }, { 42, 28 }, { 43, 28 }, { 16, 917 }, + + { 0, 0 }, { 46, 28 }, { 19, 917 }, { 20, 917 }, { 21, 917 }, + { 22, 917 }, { 23, 917 }, { 24, 917 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 917 }, { 31, 917 }, + { 32, 917 }, { 33, 917 }, { 34, 917 }, { 35, 917 }, { 36, 917 }, + { 37, 965 }, { 0, 0 }, { 39, 917 }, { 40, 917 }, { 41, 917 }, + { 42, 917 }, { 43, 917 }, { 0, 0 }, { 0, 0 }, { 46, 917 }, + { 0, 0 }, { 0,4337 }, { 1, 965 }, { 2, 965 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 6, 965 }, { 7, 965 }, { 8, 965 }, + { 9, 965 }, { 10, 965 }, { 11, 965 }, { 12, 965 }, { 13, 965 }, + { 14, 965 }, { 15, 965 }, { 16, 965 }, { 17, 965 }, { 18, 965 }, + + { 19,1010 }, { 20,1010 }, { 21,1010 }, { 22,1010 }, { 23,1010 }, + { 24,1010 }, { 25, 965 }, { 26, 965 }, { 27, 965 }, { 28, 965 }, + { 29, 965 }, { 30,1010 }, { 31,1010 }, { 32,1010 }, { 33, 965 }, + { 34, 965 }, { 35, 965 }, { 36, 965 }, { 37, 965 }, { 38, 965 }, + { 39,1010 }, { 40,1010 }, { 41, 965 }, { 42, 965 }, { 43, 965 }, + { 44, 965 }, { 45, 965 }, { 46, 965 }, { 0, 0 }, { 0,4289 }, + { 0, 0 }, { 0,4287 }, { 0, 0 }, { 0,4285 }, { 0, 9 }, + { 0,4283 }, { 0, 4 }, { 0,4281 }, { 0, 3 }, { 0,4279 }, + { 0, 2 }, { 0,4277 }, { 0, 0 }, { 0,4275 }, { 0, 22 }, + { 0,4273 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16, 541 }, + + { 19, 159 }, { 0, 0 }, { 21, 167 }, { 0, 0 }, { 23, 308 }, + { 0, 0 }, { 0,4262 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 35, 27 }, + { 34, 504 }, { 37, 988 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 42, 27 }, { 41, 504 }, { 30, 45 }, { 31, 45 }, + { 32, 45 }, { 33, 45 }, { 34, 45 }, { 35, 45 }, { 36, 45 }, + { 37, 93 }, { 0, 0 }, { 39, 45 }, { 40, 45 }, { 41, 45 }, + { 42, 45 }, { 43, 45 }, { 0, 17 }, { 0,4230 }, { 46, 45 }, + { 0, 0 }, { 0, 0 }, { 36, 532 }, { 37,1945 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 43, 532 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16, 954 }, + { 0, 0 }, { 0, 0 }, { 19, 954 }, { 20, 954 }, { 21, 954 }, + { 22, 954 }, { 23, 954 }, { 24, 954 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 954 }, { 31, 954 }, + { 32, 954 }, { 33, 954 }, { 34, 954 }, { 35, 954 }, { 36, 954 }, + { 37,1002 }, { 0, 0 }, { 39, 954 }, { 40, 954 }, { 41, 954 }, + { 42, 954 }, { 43, 954 }, { 0, 0 }, { 0, 0 }, { 46, 954 }, + { 0, 0 }, { 0,4182 }, { 1,1002 }, { 2,1002 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 6,1002 }, { 7,1002 }, { 8,1002 }, + { 9,1002 }, { 10,1002 }, { 11,1002 }, { 12,1002 }, { 13,1002 }, + + { 14,1002 }, { 15,1002 }, { 16,1002 }, { 17,1002 }, { 18,1002 }, + { 19,1047 }, { 20,1047 }, { 21,1047 }, { 22,1047 }, { 23,1047 }, + { 24,1047 }, { 25,1002 }, { 26,1002 }, { 27,1002 }, { 28,1002 }, + { 29,1002 }, { 30,1047 }, { 31,1047 }, { 32,1047 }, { 33,1002 }, + { 34,1002 }, { 35,1002 }, { 36,1002 }, { 37,1002 }, { 38,1002 }, + { 39,1047 }, { 40,1047 }, { 41,1002 }, { 42,1002 }, { 43,1002 }, + { 44,1002 }, { 45,1002 }, { 46,1002 }, { 0, 7 }, { 0,4134 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0,4128 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 12,-149 }, { 0, 0 }, { 0,4120 }, { 0, 0 }, + + { 16, 0 }, { 0, 0 }, { 0, 0 }, { 19, 0 }, { 20, 0 }, + { 21, 0 }, { 22, 0 }, { 23, 0 }, { 24, 0 }, { 19, 954 }, + { 0, 0 }, { 21, 8 }, { 0, 0 }, { 23, 149 }, { 30, 0 }, + { 31, 0 }, { 32, 0 }, { 33, 0 }, { 34, 0 }, { 35, 0 }, + { 36, 0 }, { 37, 48 }, { 0, 0 }, { 39, 0 }, { 40, 0 }, + { 41, 0 }, { 42, 0 }, { 43, 0 }, { 0, 0 }, { 31,1829 }, + { 46, 0 }, { 0, 0 }, { 0,4086 }, { 1, 996 }, { 2, 996 }, + { 0, 0 }, { 0, 0 }, { 39,1829 }, { 6, 996 }, { 7, 996 }, + { 8, 996 }, { 9, 996 }, { 10, 996 }, { 11, 996 }, { 12, 996 }, + { 13, 996 }, { 14, 996 }, { 15, 996 }, { 16, 996 }, { 17, 996 }, + + { 18, 996 }, { 19,1041 }, { 20,1041 }, { 21,1041 }, { 22,1041 }, + { 23,1041 }, { 24,1041 }, { 25, 996 }, { 26, 996 }, { 27, 996 }, + { 28, 996 }, { 29, 996 }, { 30,1041 }, { 31,1041 }, { 32,1041 }, + { 33, 996 }, { 34, 996 }, { 35, 996 }, { 36, 996 }, { 37, 996 }, + { 38, 996 }, { 39,1041 }, { 40,1041 }, { 41, 996 }, { 42, 996 }, + { 43, 996 }, { 44, 996 }, { 45, 996 }, { 46, 996 }, { 0, 7 }, + { 0,4038 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 12,-245 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16, -96 }, { 0, 0 }, { 0, 0 }, { 19, -96 }, + + { 20, -96 }, { 21, -96 }, { 22, -96 }, { 23, -96 }, { 24, -96 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, -96 }, { 31, -96 }, { 32, -96 }, { 33, -96 }, { 34, -96 }, + { 35, -96 }, { 36, -96 }, { 37, -48 }, { 0, 0 }, { 39, -96 }, + { 40, -96 }, { 41, -96 }, { 42, -96 }, { 43, -96 }, { 0, 7 }, + { 0,3993 }, { 46, -96 }, { 2, -45 }, { 3, -45 }, { 4, -45 }, + { 5, 993 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 12,-290 }, { 0, 0 }, { 0,3979 }, + { 0, 0 }, { 16,-141 }, { 0, 0 }, { 0, 0 }, { 19,1038 }, + { 20,1038 }, { 21,1038 }, { 22,1038 }, { 23,1038 }, { 24,1038 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30,1038 }, { 31,1038 }, { 32,1038 }, { 33,-141 }, { 34,-141 }, + { 35,-141 }, { 36,-141 }, { 37, -93 }, { 0, 0 }, { 39,1038 }, + { 40,1038 }, { 41,-141 }, { 42,-141 }, { 43,-141 }, { 0, 0 }, + { 31,1697 }, { 46,-141 }, { 0, 18 }, { 0,3945 }, { 1,-1072 }, + { 2,-1072 }, { 0, 0 }, { 0, 0 }, { 39,1697 }, { 6,-1072 }, + { 7,-1194 }, { 8,-1072 }, { 9,-1072 }, { 10,-1072 }, { 11,-1072 }, + { 12,-1072 }, { 13,-1072 }, { 14,-1072 }, { 15,-1072 }, { 16,-1072 }, + { 17,-1072 }, { 18,-1072 }, { 19,-1072 }, { 20,-1072 }, { 21,-1072 }, + { 22,-1072 }, { 23,-1072 }, { 24,-1072 }, { 25,-1072 }, { 26,-1072 }, + + { 27,-1072 }, { 28,-1072 }, { 29,-1072 }, { 30,-1072 }, { 31,-1072 }, + { 32,-1072 }, { 33,-1072 }, { 34,-1072 }, { 35,-1072 }, { 36,-1072 }, + { 37,-1024 }, { 38,-1072 }, { 39,-1072 }, { 40,-1072 }, { 41,-1072 }, + { 42,-1072 }, { 43,-1072 }, { 44,-1072 }, { 45,-1072 }, { 46,-976 }, + { 0, 18 }, { 0,3897 }, { 1,-1120 }, { 2,-1120 }, { 3,-1120 }, + { 0, 0 }, { 0, 0 }, { 6,-1120 }, { 7,-1242 }, { 8,-1120 }, + { 9,-1120 }, { 10,-1120 }, { 11,-1120 }, { 12,-1120 }, { 13,-1120 }, + { 14,-1120 }, { 15,-1120 }, { 16,-1120 }, { 17,-1120 }, { 18,-1120 }, + { 19,-1120 }, { 20,-1120 }, { 21,-1120 }, { 22,-1120 }, { 23,-1120 }, + { 24,-1120 }, { 25,-1120 }, { 26,-1120 }, { 27,-1120 }, { 28,-1120 }, + + { 29,-1120 }, { 30,-1120 }, { 31,-1120 }, { 32,-1120 }, { 33,-1120 }, + { 34,-1120 }, { 35,-1120 }, { 36,-1120 }, { 37,-1072 }, { 38,-1120 }, + { 39,-1120 }, { 40,-1120 }, { 41,-1120 }, { 42,-1120 }, { 43,-1120 }, + { 44,-1120 }, { 45,-1120 }, { 46,-1024 }, { 0, 18 }, { 0,3849 }, + { 1,-1168 }, { 2, 942 }, { 3, -96 }, { 4, -96 }, { 5, 990 }, + { 6,-1168 }, { 7,-1290 }, { 8,-1168 }, { 9,-1168 }, { 10,-1168 }, + { 11,-1168 }, { 12,-1168 }, { 13,-1168 }, { 14,-1168 }, { 15,-1168 }, + { 16,-1168 }, { 17,-1168 }, { 18,-1168 }, { 19,1038 }, { 20,1038 }, + { 21,1038 }, { 22,1038 }, { 23,1038 }, { 24,1038 }, { 25,-1168 }, + { 26,-1168 }, { 27,-1168 }, { 28,-1168 }, { 29,-1168 }, { 30,1038 }, + + { 31,1038 }, { 32,1038 }, { 33,-1168 }, { 34,-1168 }, { 35,-1168 }, + { 36,-1168 }, { 37,-1120 }, { 38,-1168 }, { 39,1038 }, { 40,1038 }, + { 41,-1168 }, { 42,-1168 }, { 43,-1168 }, { 44,-1168 }, { 45,-1168 }, + { 46,-1072 }, { 0, 11 }, { 0,3801 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1072 }, { 0, 0 }, + { 0,3783 }, { 19,-1072 }, { 20,-1072 }, { 21,-1072 }, { 22,-1072 }, + { 23,-1072 }, { 24,-1072 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 30,-1072 }, { 31,-1072 }, { 32,-1072 }, + + { 33,-1072 }, { 34,-1072 }, { 35,-1072 }, { 36,-1072 }, { 37,-1024 }, + { 0, 0 }, { 39,-1072 }, { 40,-1072 }, { 41,-1072 }, { 42,-1072 }, + { 43,-1072 }, { 0, 11 }, { 0,3756 }, { 46,-1072 }, { 2, -45 }, + { 3, -45 }, { 4, -45 }, { 5, 993 }, { 0, 0 }, { 0, 0 }, + { 35,-479 }, { 0, 0 }, { 37, 482 }, { 0, 0 }, { 0,3744 }, + { 0, 23 }, { 0,3742 }, { 42,-479 }, { 16,-1117 }, { 0, 0 }, + { 0, 0 }, { 19,1038 }, { 20,1038 }, { 21,1038 }, { 22,1038 }, + { 23,1038 }, { 24,1038 }, { 0, 0 }, { 0,3730 }, { 0, 0 }, + { 16, 572 }, { 0, 0 }, { 30,1038 }, { 31,1038 }, { 32,1038 }, + { 33,-1117 }, { 34,-1117 }, { 35,-1117 }, { 36,-1117 }, { 37,-1069 }, + + { 12, 560 }, { 39,1038 }, { 40,1038 }, { 41,-1117 }, { 42,-1117 }, + { 43,-1117 }, { 0, 0 }, { 0, 0 }, { 46,-1117 }, { 0, 18 }, + { 0,3708 }, { 1,-1069 }, { 2,-1069 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 6,-1069 }, { 7,-1069 }, { 8,-1069 }, { 9,-1069 }, + { 10,-1069 }, { 11,-1431 }, { 12,-1069 }, { 13,-1069 }, { 14,-1069 }, + { 15,-1069 }, { 16,-1069 }, { 17,-1069 }, { 18,-1069 }, { 19,-1069 }, + { 20,-1069 }, { 21,-1069 }, { 22,-1069 }, { 23,-1069 }, { 24,-1069 }, + { 25,-1069 }, { 26,-1069 }, { 27,-1069 }, { 28,-1069 }, { 29,-1069 }, + { 30,-1069 }, { 31,-1069 }, { 32,-1069 }, { 33,-1069 }, { 34,-1069 }, + { 35,-1069 }, { 36,-1069 }, { 37,-1021 }, { 38,-1069 }, { 39,-1069 }, + + { 40,-1069 }, { 41,-1069 }, { 42,-1069 }, { 43,-1069 }, { 44,-1069 }, + { 45,-1069 }, { 46,-973 }, { 0, 18 }, { 0,3660 }, { 1,-1117 }, + { 2,-1117 }, { 3,-1117 }, { 0, 0 }, { 0, 0 }, { 6,-1117 }, + { 7,-1117 }, { 8,-1117 }, { 9,-1117 }, { 10,-1117 }, { 11,-1479 }, + { 12,-1117 }, { 13,-1117 }, { 14,-1117 }, { 15,-1117 }, { 16,-1117 }, + { 17,-1117 }, { 18,-1117 }, { 19,-1117 }, { 20,-1117 }, { 21,-1117 }, + { 22,-1117 }, { 23,-1117 }, { 24,-1117 }, { 25,-1117 }, { 26,-1117 }, + { 27,-1117 }, { 28,-1117 }, { 29,-1117 }, { 30,-1117 }, { 31,-1117 }, + { 32,-1117 }, { 33,-1117 }, { 34,-1117 }, { 35,-1117 }, { 36,-1117 }, + { 37,-1069 }, { 38,-1117 }, { 39,-1117 }, { 40,-1117 }, { 41,-1117 }, + + { 42,-1117 }, { 43,-1117 }, { 44,-1117 }, { 45,-1117 }, { 46,-1021 }, + { 0, 18 }, { 0,3612 }, { 1,-1165 }, { 2, 942 }, { 3, -96 }, + { 4, -96 }, { 5, 990 }, { 6,-1165 }, { 7,-1165 }, { 8,-1165 }, + { 9,-1165 }, { 10,-1165 }, { 11,-1527 }, { 12,-1165 }, { 13,-1165 }, + { 14,-1165 }, { 15,-1165 }, { 16,-1165 }, { 17,-1165 }, { 18,-1165 }, + { 19,1038 }, { 20,1038 }, { 21,1038 }, { 22,1038 }, { 23,1038 }, + { 24,1038 }, { 25,-1165 }, { 26,-1165 }, { 27,-1165 }, { 28,-1165 }, + { 29,-1165 }, { 30,1038 }, { 31,1038 }, { 32,1038 }, { 33,-1165 }, + { 34,-1165 }, { 35,-1165 }, { 36,-1165 }, { 37,-1117 }, { 38,-1165 }, + { 39,1038 }, { 40,1038 }, { 41,-1165 }, { 42,-1165 }, { 43,-1165 }, + + { 44,-1165 }, { 45,-1165 }, { 46,-1069 }, { 0, 0 }, { 0,3564 }, + { 1, 0 }, { 2, 0 }, { 3, 0 }, { 4, 0 }, { 5, 0 }, + { 6, 0 }, { 7, 0 }, { 8, 0 }, { 9, 0 }, { 10, 0 }, + { 11, 0 }, { 12, 0 }, { 13, 48 }, { 14, 0 }, { 15, 0 }, + { 16, 0 }, { 17, 0 }, { 18, 0 }, { 19, 0 }, { 20, 0 }, + { 21, 0 }, { 22, 0 }, { 23, 0 }, { 24, 0 }, { 25, 0 }, + { 26, 0 }, { 27, 0 }, { 28, 0 }, { 29, 0 }, { 30, 0 }, + { 31, 0 }, { 32, 0 }, { 33, 0 }, { 34, 0 }, { 35, 0 }, + { 36, 0 }, { 37, 0 }, { 38, 0 }, { 39, 0 }, { 40, 0 }, + { 41, 0 }, { 42, 0 }, { 43, 0 }, { 44, 0 }, { 45, 0 }, + + { 46, 0 }, { 0, 0 }, { 0,3516 }, { 1, 990 }, { 2, 990 }, + { 3, 990 }, { 4, 990 }, { 5, 990 }, { 6, 990 }, { 7, 990 }, + { 8, 990 }, { 9, 990 }, { 10, 990 }, { 11, 990 }, { 12, 990 }, + { 13, 0 }, { 14, 990 }, { 15, 990 }, { 16, 990 }, { 17, 990 }, + { 18,-226 }, { 19, 990 }, { 20, 990 }, { 21, 990 }, { 22, 990 }, + { 23, 990 }, { 24, 990 }, { 25, 990 }, { 26, 990 }, { 27, 990 }, + { 28, 990 }, { 29, 990 }, { 30, 990 }, { 31, 990 }, { 32, 990 }, + { 33, 990 }, { 34, 990 }, { 35, 990 }, { 36, 990 }, { 37, 990 }, + { 38, 990 }, { 39, 990 }, { 40, 990 }, { 41, 990 }, { 42, 990 }, + { 43, 990 }, { 44, 990 }, { 45, 990 }, { 46, 990 }, { 0, 20 }, + + { 0,3468 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0,3462 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0,3456 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16, 0 }, { 0, 0 }, { 0, 0 }, { 19, 0 }, + { 20, 0 }, { 21, 0 }, { 22, 0 }, { 23, 0 }, { 24, 0 }, + { 19, 468 }, { 0, 0 }, { 21, 6 }, { 0, 0 }, { 23, 147 }, + { 30, 0 }, { 31, 0 }, { 32, 0 }, { 33, 0 }, { 34, 0 }, + { 35, 0 }, { 36, 0 }, { 37, 48 }, { 0, 0 }, { 39, 0 }, + { 40, 0 }, { 41, 0 }, { 42, 0 }, { 43, 0 }, { 32,1854 }, + { 0, 0 }, { 46, 0 }, { 0, 0 }, { 0,3420 }, { 1, 942 }, + + { 2, 942 }, { 0, 0 }, { 40,1854 }, { 0, 0 }, { 6, 942 }, + { 7, 942 }, { 8, 942 }, { 9, 942 }, { 10, 942 }, { 11, 942 }, + { 12, 942 }, { 13, 942 }, { 14, 942 }, { 15, 942 }, { 16, 942 }, + { 17, 942 }, { 18, 942 }, { 19, 987 }, { 20, 987 }, { 21, 987 }, + { 22, 987 }, { 23, 987 }, { 24, 987 }, { 25, 942 }, { 26, 942 }, + { 27, 942 }, { 28, 942 }, { 29, 942 }, { 30, 987 }, { 31, 987 }, + { 32, 987 }, { 33, 942 }, { 34, 942 }, { 35, 942 }, { 36, 942 }, + { 37, 942 }, { 38, 942 }, { 39, 987 }, { 40, 987 }, { 41, 942 }, + { 42, 942 }, { 43, 942 }, { 44, 942 }, { 45, 942 }, { 46, 942 }, + { 0, 20 }, { 0,3372 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 16, -96 }, { 0, 0 }, { 0, 0 }, + { 19, -96 }, { 20, -96 }, { 21, -96 }, { 22, -96 }, { 23, -96 }, + { 24, -96 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 30, -96 }, { 31, -96 }, { 32, -96 }, { 33, -96 }, + { 34, -96 }, { 35, -96 }, { 36, -96 }, { 37, -48 }, { 0, 0 }, + { 39, -96 }, { 40, -96 }, { 41, -96 }, { 42, -96 }, { 43, -96 }, + { 0, 20 }, { 0,3327 }, { 46, -96 }, { 2, -45 }, { 3, -45 }, + { 4, -45 }, { 5, 939 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0,3315 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 16,-141 }, { 0, 0 }, { 0, 0 }, + { 19, 984 }, { 20, 984 }, { 21, 984 }, { 22, 984 }, { 23, 984 }, + { 24, 984 }, { 0, 0 }, { 0,3301 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 30, 984 }, { 31, 984 }, { 32, 984 }, { 33,-141 }, + { 34,-141 }, { 35,-141 }, { 36,-141 }, { 37, -93 }, { 0, 0 }, + { 39, 984 }, { 40, 984 }, { 41,-141 }, { 42,-141 }, { 43,-141 }, + { 32,1755 }, { 19,-161 }, { 46,-141 }, { 21,-155 }, { 0, 0 }, + { 23, -14 }, { 0, 17 }, { 0,3276 }, { 40,1755 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 0,3268 }, { 0, 0 }, { 35, 33 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16, 0 }, { 42, 33 }, + { 0, 0 }, { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, + { 23, 0 }, { 24, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 30, 0 }, { 31, 0 }, { 32, 0 }, + { 33, 0 }, { 34, 0 }, { 35, 0 }, { 36, 0 }, { 37, 48 }, + { 0, 0 }, { 39, 0 }, { 40, 0 }, { 41, 0 }, { 42, 0 }, + { 43, 0 }, { 36,-462 }, { 37, 951 }, { 46, 0 }, { 0, 0 }, + { 0,3228 }, { 1, 970 }, { 2, 970 }, { 43,-462 }, { 0, 0 }, + { 0, 0 }, { 6, 970 }, { 7, 970 }, { 8, 970 }, { 9, 970 }, + + { 10, 970 }, { 11, 970 }, { 12, 970 }, { 13, 970 }, { 14, 970 }, + { 15, 970 }, { 16, 970 }, { 17, 970 }, { 18, 970 }, { 19,1015 }, + { 20,1015 }, { 21,1015 }, { 22,1015 }, { 23,1015 }, { 24,1015 }, + { 25, 970 }, { 26, 970 }, { 27, 970 }, { 28, 970 }, { 29, 970 }, + { 30,1015 }, { 31,1015 }, { 32,1015 }, { 33, 970 }, { 34, 970 }, + { 35, 970 }, { 36, 970 }, { 37, 970 }, { 38, 970 }, { 39,1015 }, + { 40,1015 }, { 41, 970 }, { 42, 970 }, { 43, 970 }, { 44, 970 }, + { 45, 970 }, { 46, 970 }, { 0, 17 }, { 0,3180 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0,3174 }, + { 0, 21 }, { 0,3172 }, { 0, 16 }, { 0,3170 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16, -96 }, + { 0, 0 }, { 0, 0 }, { 19, -96 }, { 20, -96 }, { 21, -96 }, + { 22, -96 }, { 23, -96 }, { 24, -96 }, { 19, 417 }, { 0, 0 }, + { 21,-946 }, { 0, 0 }, { 23,-805 }, { 30, -96 }, { 31, -96 }, + { 32, -96 }, { 33, -96 }, { 34, -96 }, { 35, -96 }, { 36, -96 }, + { 37, -48 }, { 0, 0 }, { 39, -96 }, { 40, -96 }, { 41, -96 }, + { 42, -96 }, { 43, -96 }, { 0, 17 }, { 0,3135 }, { 46, -96 }, + { 2, -45 }, { 3, -45 }, { 4, -45 }, { 5, 967 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-141 }, + + { 0, 0 }, { 0, 0 }, { 19,1012 }, { 20,1012 }, { 21,1012 }, + { 22,1012 }, { 23,1012 }, { 24,1012 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0,3107 }, { 0, 0 }, { 30,1012 }, { 31,1012 }, + { 32,1012 }, { 33,-141 }, { 34,-141 }, { 35,-141 }, { 36,-141 }, + { 37, -93 }, { 0, 0 }, { 39,1012 }, { 40,1012 }, { 41,-141 }, + { 42,-141 }, { 43,-141 }, { 0, 7 }, { 0,3090 }, { 46,-141 }, + { 19, 823 }, { 0, 0 }, { 0,3086 }, { 22, 21 }, { 0, 0 }, + { 24, 69 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 12,-1193 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1044 }, + { 0, 0 }, { 0, 0 }, { 19,-1044 }, { 20,-1044 }, { 21,-1044 }, + + { 22,-1044 }, { 23,-1044 }, { 24,-1044 }, { 21,2013 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30,-1044 }, { 31,-1044 }, + { 32,-1044 }, { 33,-1044 }, { 34,-1044 }, { 35,-1044 }, { 36,-1044 }, + { 37,-996 }, { 0, 0 }, { 39,-1044 }, { 40,-1044 }, { 41,-1044 }, + { 42,-1044 }, { 43,-1044 }, { 0, 7 }, { 0,3045 }, { 46,-1044 }, + { 2, -45 }, { 3, -45 }, { 4, -45 }, { 5, 967 }, { 0, 0 }, + { 0,3038 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 12,-1238 }, { 0, 0 }, { 0,3031 }, { 0, 0 }, { 16,-1089 }, + { 0, 0 }, { 0, 0 }, { 19,1012 }, { 20,1012 }, { 21,1012 }, + { 22,1012 }, { 23,1012 }, { 24,1012 }, { 0, 0 }, { 12,-139 }, + + { 0, 0 }, { 21,1965 }, { 0, 0 }, { 30,1012 }, { 31,1012 }, + { 32,1012 }, { 33,-1089 }, { 34,-1089 }, { 35,-1089 }, { 36,-1089 }, + { 37,-1041 }, { 0, 0 }, { 39,1012 }, { 40,1012 }, { 41,-1089 }, + { 42,-1089 }, { 43,-1089 }, { 0, 7 }, { 0,3000 }, { 46,-1089 }, + { 0, 0 }, { 3,-1038 }, { 0, 0 }, { 0, 0 }, { 0,2994 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 12,-1283 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1134 }, + { 0, 0 }, { 0, 0 }, { 19,-1134 }, { 20,-1134 }, { 21,-1134 }, + { 22,-1134 }, { 23,-1134 }, { 24,-1134 }, { 19, 723 }, { 0, 0 }, + { 21,-462 }, { 0, 0 }, { 23,-321 }, { 30,-1134 }, { 31,-1134 }, + + { 32,-1134 }, { 33,-1134 }, { 34,-1134 }, { 35,-1134 }, { 36,-1134 }, + { 37,-1086 }, { 0, 0 }, { 39,-1134 }, { 40,-1134 }, { 41,-1134 }, + { 42,-1134 }, { 43,-1134 }, { 0, 7 }, { 0,2955 }, { 46,-1134 }, + { 2,-1083 }, { 3,-1083 }, { 4,-1083 }, { 5, -45 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 12,-1328 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1179 }, + { 0, 0 }, { 0, 0 }, { 19, 967 }, { 20, 967 }, { 21, 967 }, + { 22, 967 }, { 23, 967 }, { 24, 967 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 967 }, { 31, 967 }, + { 32, 967 }, { 33,-1179 }, { 34,-1179 }, { 35,-1179 }, { 36,-1179 }, + + { 37,-1131 }, { 0, 0 }, { 39, 967 }, { 40, 967 }, { 41,-1179 }, + { 42,-1179 }, { 43,-1179 }, { 0, 0 }, { 0, 0 }, { 46,-1179 }, + { 0, 18 }, { 0,2907 }, { 1,-2110 }, { 2,-2110 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 6,-2110 }, { 7,-2232 }, { 8,-2110 }, + { 9,-2110 }, { 10,-2110 }, { 11,-2110 }, { 12,-2110 }, { 13,-2110 }, + { 14,-2110 }, { 15,-2110 }, { 16,-2110 }, { 17,-2110 }, { 18,-2110 }, + { 19,-2110 }, { 20,-2110 }, { 21,-2110 }, { 22,-2110 }, { 23,-2110 }, + { 24,-2110 }, { 25,-2110 }, { 26,-2110 }, { 27,-2110 }, { 28,-2110 }, + { 29,-2110 }, { 30,-2110 }, { 31,-2110 }, { 32,-2110 }, { 33,-2110 }, + { 34,-2110 }, { 35,-2110 }, { 36,-2110 }, { 37,-2062 }, { 38,-2110 }, + + { 39,-2110 }, { 40,-2110 }, { 41,-2110 }, { 42,-2110 }, { 43,-2110 }, + { 44,-2110 }, { 45,-2110 }, { 46,-2014 }, { 0, 18 }, { 0,2859 }, + { 1,-2158 }, { 2,-2158 }, { 3,-1086 }, { 0, 0 }, { 0, 0 }, + { 6,-2158 }, { 7,-2280 }, { 8,-2158 }, { 9,-2158 }, { 10,-2158 }, + { 11,-2158 }, { 12,-2158 }, { 13,-2158 }, { 14,-2158 }, { 15,-2158 }, + { 16,-2158 }, { 17,-2158 }, { 18,-2158 }, { 19,-2158 }, { 20,-2158 }, + { 21,-2158 }, { 22,-2158 }, { 23,-2158 }, { 24,-2158 }, { 25,-2158 }, + { 26,-2158 }, { 27,-2158 }, { 28,-2158 }, { 29,-2158 }, { 30,-2158 }, + { 31,-2158 }, { 32,-2158 }, { 33,-2158 }, { 34,-2158 }, { 35,-2158 }, + { 36,-2158 }, { 37,-2110 }, { 38,-2158 }, { 39,-2158 }, { 40,-2158 }, + + { 41,-2158 }, { 42,-2158 }, { 43,-2158 }, { 44,-2158 }, { 45,-2158 }, + { 46,-2062 }, { 0, 18 }, { 0,2811 }, { 1,-2206 }, { 2, -96 }, + { 3,-1134 }, { 4,-1134 }, { 5, -48 }, { 6,-2206 }, { 7,-2328 }, + { 8,-2206 }, { 9,-2206 }, { 10,-2206 }, { 11,-2206 }, { 12,-2206 }, + { 13,-2206 }, { 14,-2206 }, { 15,-2206 }, { 16,-2206 }, { 17,-2206 }, + { 18,-2206 }, { 19, 871 }, { 20, 871 }, { 21, 871 }, { 22, 871 }, + { 23, 871 }, { 24, 871 }, { 25,-2206 }, { 26,-2206 }, { 27,-2206 }, + { 28,-2206 }, { 29,-2206 }, { 30, 871 }, { 31, 871 }, { 32, 871 }, + { 33,-2206 }, { 34,-2206 }, { 35,-2206 }, { 36,-2206 }, { 37,-2158 }, + { 38,-2206 }, { 39, 871 }, { 40, 871 }, { 41,-2206 }, { 42,-2206 }, + + { 43,-2206 }, { 44,-2206 }, { 45,-2206 }, { 46,-2110 }, { 0, 11 }, + { 0,2763 }, { 0, 0 }, { 0, 0 }, { 3,-1038 }, { 0, 0 }, + { 0, 0 }, { 0,2757 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-2110 }, { 0, 0 }, { 0,2745 }, { 19,-2110 }, + { 20,-2110 }, { 21,-2110 }, { 22,-2110 }, { 23,-2110 }, { 24,-2110 }, + { 19, 570 }, { 0, 0 }, { 21,-1363 }, { 0, 0 }, { 23,-1222 }, + { 30,-2110 }, { 31,-2110 }, { 32,-2110 }, { 33,-2110 }, { 34,-2110 }, + { 35,-2110 }, { 36,-2110 }, { 37,-2062 }, { 0, 0 }, { 39,-2110 }, + { 40,-2110 }, { 41,-2110 }, { 42,-2110 }, { 43,-2110 }, { 0, 11 }, + + { 0,2718 }, { 46,-2110 }, { 2,-1083 }, { 3,-1083 }, { 4,-1083 }, + { 5, -45 }, { 0, 0 }, { 0, 0 }, { 35,-1517 }, { 0, 0 }, + { 37,-556 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 42,-1517 }, { 16,-2155 }, { 0, 0 }, { 0, 0 }, { 19, 826 }, + { 20, 826 }, { 21, 826 }, { 22, 826 }, { 23, 826 }, { 24, 826 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, 826 }, { 31, 826 }, { 32, 826 }, { 33,-2155 }, { 34,-2155 }, + { 35,-2155 }, { 36,-2155 }, { 37,-2107 }, { 0, 0 }, { 39, 826 }, + { 40, 826 }, { 41,-2155 }, { 42,-2155 }, { 43,-2155 }, { 0, 0 }, + { 0, 0 }, { 46,-2155 }, { 0, 18 }, { 0,2670 }, { 1,-2107 }, + + { 2,-2107 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6,-2107 }, + { 7,-2107 }, { 8,-2107 }, { 9,-2107 }, { 10,-2107 }, { 11,-2469 }, + { 12,-2107 }, { 13,-2107 }, { 14,-2107 }, { 15,-2107 }, { 16,-2107 }, + { 17,-2107 }, { 18,-2107 }, { 19,-2107 }, { 20,-2107 }, { 21,-2107 }, + { 22,-2107 }, { 23,-2107 }, { 24,-2107 }, { 25,-2107 }, { 26,-2107 }, + { 27,-2107 }, { 28,-2107 }, { 29,-2107 }, { 30,-2107 }, { 31,-2107 }, + { 32,-2107 }, { 33,-2107 }, { 34,-2107 }, { 35,-2107 }, { 36,-2107 }, + { 37,-2059 }, { 38,-2107 }, { 39,-2107 }, { 40,-2107 }, { 41,-2107 }, + { 42,-2107 }, { 43,-2107 }, { 44,-2107 }, { 45,-2107 }, { 46,-2011 }, + { 0, 18 }, { 0,2622 }, { 1,-2155 }, { 2,-2155 }, { 3,-1086 }, + + { 0, 0 }, { 0, 0 }, { 6,-2155 }, { 7,-2155 }, { 8,-2155 }, + { 9,-2155 }, { 10,-2155 }, { 11,-2517 }, { 12,-2155 }, { 13,-2155 }, + { 14,-2155 }, { 15,-2155 }, { 16,-2155 }, { 17,-2155 }, { 18,-2155 }, + { 19,-2155 }, { 20,-2155 }, { 21,-2155 }, { 22,-2155 }, { 23,-2155 }, + { 24,-2155 }, { 25,-2155 }, { 26,-2155 }, { 27,-2155 }, { 28,-2155 }, + { 29,-2155 }, { 30,-2155 }, { 31,-2155 }, { 32,-2155 }, { 33,-2155 }, + { 34,-2155 }, { 35,-2155 }, { 36,-2155 }, { 37,-2107 }, { 38,-2155 }, + { 39,-2155 }, { 40,-2155 }, { 41,-2155 }, { 42,-2155 }, { 43,-2155 }, + { 44,-2155 }, { 45,-2155 }, { 46,-2059 }, { 0, 18 }, { 0,2574 }, + { 1,-2203 }, { 2, -96 }, { 3,-1134 }, { 4,-1134 }, { 5, -48 }, + + { 6,-2203 }, { 7,-2203 }, { 8,-2203 }, { 9,-2203 }, { 10,-2203 }, + { 11,-2565 }, { 12,-2203 }, { 13,-2203 }, { 14,-2203 }, { 15,-2203 }, + { 16,-2203 }, { 17,-2203 }, { 18,-2203 }, { 19, 730 }, { 20, 730 }, + { 21, 730 }, { 22, 730 }, { 23, 730 }, { 24, 730 }, { 25,-2203 }, + { 26,-2203 }, { 27,-2203 }, { 28,-2203 }, { 29,-2203 }, { 30, 730 }, + { 31, 730 }, { 32, 730 }, { 33,-2203 }, { 34,-2203 }, { 35,-2203 }, + { 36,-2203 }, { 37,-2155 }, { 38,-2203 }, { 39, 730 }, { 40, 730 }, + { 41,-2203 }, { 42,-2203 }, { 43,-2203 }, { 44,-2203 }, { 45,-2203 }, + { 46,-2107 }, { 0, 0 }, { 0,2526 }, { 1, 730 }, { 2, 730 }, + { 3, 730 }, { 4, 730 }, { 5, 730 }, { 6, 730 }, { 7, 730 }, + + { 8, 730 }, { 9, 730 }, { 10, 730 }, { 11, 730 }, { 12, 730 }, + { 13, 778 }, { 14, 730 }, { 15, 730 }, { 16, 730 }, { 17, 730 }, + { 18, 730 }, { 19, 730 }, { 20, 730 }, { 21, 730 }, { 22, 730 }, + { 23, 730 }, { 24, 730 }, { 25, 730 }, { 26, 730 }, { 27, 730 }, + { 28, 730 }, { 29, 730 }, { 30, 730 }, { 31, 730 }, { 32, 730 }, + { 33, 730 }, { 34, 730 }, { 35, 730 }, { 36, 730 }, { 37, 730 }, + { 38, 730 }, { 39, 730 }, { 40, 730 }, { 41, 730 }, { 42, 730 }, + { 43, 730 }, { 44, 730 }, { 45, 730 }, { 46, 730 }, { 0, 20 }, + { 0,2478 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-990 }, { 0, 0 }, { 0, 0 }, { 19,-990 }, + { 20,-990 }, { 21,-990 }, { 22,-990 }, { 23,-990 }, { 24,-990 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30,-990 }, { 31,-990 }, { 32,-990 }, { 33,-990 }, { 34,-990 }, + { 35,-990 }, { 36,-990 }, { 37,-942 }, { 0, 0 }, { 39,-990 }, + { 40,-990 }, { 41,-990 }, { 42,-990 }, { 43,-990 }, { 0, 20 }, + { 0,2433 }, { 46,-990 }, { 2, -45 }, { 3, -45 }, { 4, -45 }, + { 5, 733 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0,2421 }, { 0, 0 }, { 0, 0 }, + + { 3,-324 }, { 16,-1035 }, { 0, 0 }, { 0, 0 }, { 19, 778 }, + { 20, 778 }, { 21, 778 }, { 22, 778 }, { 23, 778 }, { 24, 778 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, 778 }, { 31, 778 }, { 32, 778 }, { 33,-1035 }, { 34,-1035 }, + { 35,-1035 }, { 36,-1035 }, { 37,-987 }, { 0, 0 }, { 39, 778 }, + { 40, 778 }, { 41,-1035 }, { 42,-1035 }, { 43,-1035 }, { 0, 20 }, + { 0,2388 }, { 46,-1035 }, { 35,-1841 }, { 3,-984 }, { 37,-880 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 42,-1841 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-1080 }, { 0, 0 }, { 0, 0 }, { 19,-1080 }, + + { 20,-1080 }, { 21,-1080 }, { 22,-1080 }, { 23,-1080 }, { 24,-1080 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30,-1080 }, { 31,-1080 }, { 32,-1080 }, { 33,-1080 }, { 34,-1080 }, + { 35,-1080 }, { 36,-1080 }, { 37,-1032 }, { 0, 0 }, { 39,-1080 }, + { 40,-1080 }, { 41,-1080 }, { 42,-1080 }, { 43,-1080 }, { 0, 20 }, + { 0,2343 }, { 46,-1080 }, { 2,-1029 }, { 3,-1029 }, { 4,-1029 }, + { 5, -45 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-1125 }, { 0, 0 }, { 0, 0 }, { 19, 733 }, + { 20, 733 }, { 21, 733 }, { 22, 733 }, { 23, 733 }, { 24, 733 }, + + { 0, 0 }, { 0,2317 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, 733 }, { 31, 733 }, { 32, 733 }, { 33,-1125 }, { 34,-1125 }, + { 35,-1125 }, { 36,-1125 }, { 37,-1077 }, { 0, 0 }, { 39, 733 }, + { 40, 733 }, { 41,-1125 }, { 42,-1125 }, { 43,-1125 }, { 0, 0 }, + { 19,-790 }, { 46,-1125 }, { 0, 0 }, { 22,-769 }, { 0, 0 }, + { 24,-721 }, { 0, 0 }, { 0,2291 }, { 0, 0 }, { 2,-454 }, + { 3,-454 }, { 4,-454 }, { 5,-130 }, { 0, 0 }, { 0,2284 }, + { 0, 0 }, { 0,2282 }, { 36,-714 }, { 2,-463 }, { 3,-463 }, + { 4,-463 }, { 5,-139 }, { 0, 0 }, { 0, 0 }, { 43,-714 }, + { 0, 0 }, { 0, 0 }, { 0,2271 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 19, 189 }, { 0, 0 }, + { 0, 0 }, { 22,-802 }, { 0, 0 }, { 24,-754 }, { 0, 17 }, + { 0,2258 }, { 0, 0 }, { 35,-1971 }, { 0, 0 }, { 37,-1010 }, + { 0, 0 }, { 19, 576 }, { 0, 0 }, { 21,-1185 }, { 42,-1971 }, + { 23,-1044 }, { 35,-1980 }, { 0, 0 }, { 37,-1019 }, { 0, 0 }, + { 0,2243 }, { 16,-1018 }, { 0, 0 }, { 42,-1980 }, { 19,-1018 }, + { 20,-1018 }, { 21,-1018 }, { 22,-1018 }, { 23,-1018 }, { 24,-1018 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30,-1018 }, { 31,-1018 }, { 32,-1018 }, { 33,-1018 }, { 34,-1018 }, + { 35,-1018 }, { 36,-1018 }, { 37,-970 }, { 0, 0 }, { 39,-1018 }, + + { 40,-1018 }, { 41,-1018 }, { 42,-1018 }, { 43,-1018 }, { 0, 17 }, + { 0,2213 }, { 46,-1018 }, { 2, -45 }, { 3, -45 }, { 4, -45 }, + { 5, 678 }, { 36,-1487 }, { 37, -74 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 43,-1487 }, { 0, 0 }, + { 0,2198 }, { 16,-1063 }, { 0, 0 }, { 3, -45 }, { 19, 723 }, + { 20, 723 }, { 21, 723 }, { 22, 723 }, { 23, 723 }, { 24, 723 }, + { 0, 0 }, { 0,2187 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, 723 }, { 31, 723 }, { 32, 723 }, { 33,-1063 }, { 34,-1063 }, + { 35,-1063 }, { 36,-1063 }, { 37,-1015 }, { 0, 0 }, { 39, 723 }, + { 40, 723 }, { 41,-1063 }, { 42,-1063 }, { 43,-1063 }, { 0, 17 }, + + { 0,2168 }, { 46,-1063 }, { 21,-1933 }, { 3,-1012 }, { 23,-1792 }, + { 0, 0 }, { 36,-1532 }, { 37,-119 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 43,-1532 }, { 0, 0 }, + { 0, 0 }, { 16,-1108 }, { 0, 0 }, { 0, 0 }, { 19,-1108 }, + { 20,-1108 }, { 21,-1108 }, { 22,-1108 }, { 23,-1108 }, { 24,-1108 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30,-1108 }, { 31,-1108 }, { 32,-1108 }, { 33,-1108 }, { 34,-1108 }, + { 35,-1108 }, { 36,-1108 }, { 37,-1060 }, { 0, 0 }, { 39,-1108 }, + { 40,-1108 }, { 41,-1108 }, { 42,-1108 }, { 43,-1108 }, { 0, 17 }, + { 0,2123 }, { 46,-1108 }, { 2,-1057 }, { 3,-1057 }, { 4,-1057 }, + + { 5, -45 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-1153 }, { 0, 0 }, { 0, 0 }, { 19, 678 }, + { 20, 678 }, { 21, 678 }, { 22, 678 }, { 23, 678 }, { 24, 678 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0,2095 }, { 0, 0 }, + { 30, 678 }, { 31, 678 }, { 32, 678 }, { 33,-1153 }, { 34,-1153 }, + { 35,-1153 }, { 36,-1153 }, { 37,-1105 }, { 0, 0 }, { 39, 678 }, + { 40, 678 }, { 41,-1153 }, { 42,-1153 }, { 43,-1153 }, { 0, 7 }, + { 0,2078 }, { 46,-1153 }, { 19, 533 }, { 3,-1012 }, { 0, 0 }, + { 22,-991 }, { 0, 0 }, { 24,-943 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 12,-2205 }, { 0, 0 }, { 0,2064 }, + { 0, 0 }, { 16,-2056 }, { 0, 0 }, { 0, 0 }, { 19,-2056 }, + { 20,-2056 }, { 21,-2056 }, { 22,-2056 }, { 23,-2056 }, { 24,-2056 }, + { 0, 0 }, { 12,-1106 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30,-2056 }, { 31,-2056 }, { 32,-2056 }, { 33,-2056 }, { 34,-2056 }, + { 35,-2056 }, { 36,-2056 }, { 37,-2008 }, { 0, 0 }, { 39,-2056 }, + { 40,-2056 }, { 41,-2056 }, { 42,-2056 }, { 43,-2056 }, { 0, 7 }, + { 0,2033 }, { 46,-2056 }, { 2,-1057 }, { 3,-1057 }, { 4,-1057 }, + { 5, -45 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 12,-2250 }, { 0, 0 }, { 0,2019 }, + + { 0, 0 }, { 16,-2101 }, { 3, -45 }, { 0, 0 }, { 19, 633 }, + { 20, 633 }, { 21, 633 }, { 22, 633 }, { 23, 633 }, { 24, 633 }, + { 0, 0 }, { 12,-1151 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, 633 }, { 31, 633 }, { 32, 633 }, { 33,-2101 }, { 34,-2101 }, + { 35,-2101 }, { 36,-2101 }, { 37,-2053 }, { 0, 0 }, { 39, 633 }, + { 40, 633 }, { 41,-2101 }, { 42,-2101 }, { 43,-2101 }, { 0, 7 }, + { 0,1988 }, { 46,-2101 }, { 2,-2050 }, { 3,-2050 }, { 4,-2050 }, + { 5,-1012 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 12,-2295 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-2146 }, { 0, 0 }, { 0, 0 }, { 19, 633 }, + + { 20, 633 }, { 21, 633 }, { 22, 633 }, { 23, 633 }, { 24, 633 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, 633 }, { 31, 633 }, { 32, 633 }, { 33,-2146 }, { 34,-2146 }, + { 35,-2146 }, { 36,-2146 }, { 37,-2098 }, { 0, 0 }, { 39, 633 }, + { 40, 633 }, { 41,-2146 }, { 42,-2146 }, { 43,-2146 }, { 0, 0 }, + { 0, 0 }, { 46,-2146 }, { 0, 18 }, { 0,1940 }, { 1,-3077 }, + { 2,-967 }, { 3,-2005 }, { 4,-2005 }, { 5,-919 }, { 6,-3077 }, + { 7,-3199 }, { 8,-3077 }, { 9,-3077 }, { 10,-3077 }, { 11,-3077 }, + { 12,-3077 }, { 13,-3077 }, { 14,-3077 }, { 15,-3077 }, { 16,-3077 }, + { 17,-3077 }, { 18,-3077 }, { 19, 633 }, { 20, 633 }, { 21, 633 }, + + { 22, 633 }, { 23, 633 }, { 24, 633 }, { 25,-3077 }, { 26,-3077 }, + { 27,-3077 }, { 28,-3077 }, { 29,-3077 }, { 30, 633 }, { 31, 633 }, + { 32, 633 }, { 33,-3077 }, { 34,-3077 }, { 35,-3077 }, { 36,-3077 }, + { 37,-3029 }, { 38,-3077 }, { 39, 633 }, { 40, 633 }, { 41,-3077 }, + { 42,-3077 }, { 43,-3077 }, { 44,-3077 }, { 45,-3077 }, { 46,-2981 }, + { 0, 11 }, { 0,1892 }, { 0, 0 }, { 2,-1909 }, { 3,-1909 }, + { 4,-1909 }, { 5,-871 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 16,-2981 }, { 0, 0 }, { 0, 0 }, + { 19, 633 }, { 20, 633 }, { 21, 633 }, { 22, 633 }, { 23, 633 }, + + { 24, 633 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 30, 633 }, { 31, 633 }, { 32, 633 }, { 33,-2981 }, + { 34,-2981 }, { 35,-2981 }, { 36,-2981 }, { 37,-2933 }, { 0, 0 }, + { 39, 633 }, { 40, 633 }, { 41,-2981 }, { 42,-2981 }, { 43,-2981 }, + { 0, 0 }, { 0, 0 }, { 46,-2981 }, { 0, 18 }, { 0,1844 }, + { 1,-2933 }, { 2,-826 }, { 3,-1864 }, { 4,-1864 }, { 5,-778 }, + { 6,-2933 }, { 7,-2933 }, { 8,-2933 }, { 9,-2933 }, { 10,-2933 }, + { 11,-3295 }, { 12,-2933 }, { 13,-2933 }, { 14,-2933 }, { 15,-2933 }, + { 16,-2933 }, { 17,-2933 }, { 18,-2933 }, { 19, 633 }, { 20, 633 }, + { 21, 633 }, { 22, 633 }, { 23, 633 }, { 24, 633 }, { 25,-2933 }, + + { 26,-2933 }, { 27,-2933 }, { 28,-2933 }, { 29,-2933 }, { 30, 633 }, + { 31, 633 }, { 32, 633 }, { 33,-2933 }, { 34,-2933 }, { 35,-2933 }, + { 36,-2933 }, { 37,-2885 }, { 38,-2933 }, { 39, 633 }, { 40, 633 }, + { 41,-2933 }, { 42,-2933 }, { 43,-2933 }, { 44,-2933 }, { 45,-2933 }, + { 46,-2837 }, { 0, 0 }, { 0,1796 }, { 1, 0 }, { 2, 0 }, + { 3, 0 }, { 4, 0 }, { 5, 0 }, { 6, 0 }, { 7, 0 }, + { 8, 0 }, { 9, 0 }, { 10, 0 }, { 11, 0 }, { 12, 0 }, + { 13, 48 }, { 14, 0 }, { 15, 0 }, { 16, 0 }, { 17, 0 }, + { 18, 0 }, { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, + { 23, 0 }, { 24, 0 }, { 25, 0 }, { 26, 0 }, { 27, 0 }, + + { 28, 0 }, { 29, 0 }, { 30, 0 }, { 31, 0 }, { 32, 0 }, + { 33, 0 }, { 34, 0 }, { 35, 0 }, { 36, 0 }, { 37, 0 }, + { 38, 0 }, { 39, 0 }, { 40, 0 }, { 41, 0 }, { 42, 0 }, + { 43, 0 }, { 44, 0 }, { 45, 0 }, { 46, 0 }, { 0, 0 }, + { 0,1748 }, { 1,-778 }, { 2,-778 }, { 3,-778 }, { 4,-778 }, + { 5,-778 }, { 6,-778 }, { 7,-778 }, { 8,-778 }, { 9,-778 }, + { 10,-778 }, { 11,-778 }, { 12,-778 }, { 13, 0 }, { 14,-778 }, + { 15,-778 }, { 16,-778 }, { 17,-778 }, { 18,-1994 }, { 19,-778 }, + { 20,-778 }, { 21,-778 }, { 22,-778 }, { 23,-778 }, { 24,-778 }, + { 25,-778 }, { 26,-778 }, { 27,-778 }, { 28,-778 }, { 29,-778 }, + + { 30,-778 }, { 31,-778 }, { 32,-778 }, { 33,-778 }, { 34,-778 }, + { 35,-778 }, { 36,-778 }, { 37,-778 }, { 38,-778 }, { 39,-778 }, + { 40,-778 }, { 41,-778 }, { 42,-778 }, { 43,-778 }, { 44,-778 }, + { 45,-778 }, { 46,-778 }, { 0, 20 }, { 0,1700 }, { 0, 0 }, + { 0, 0 }, { 3,-778 }, { 0, 0 }, { 0,1695 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1768 }, + { 0, 0 }, { 0, 0 }, { 19,-1768 }, { 20,-1768 }, { 21,-1768 }, + { 22,-1768 }, { 23,-1768 }, { 24,-1768 }, { 0, 0 }, { 21,-1761 }, + { 0, 0 }, { 23,-1620 }, { 0, 0 }, { 30,-1768 }, { 31,-1768 }, + + { 32,-1768 }, { 33,-1768 }, { 34,-1768 }, { 35,-1768 }, { 36,-1768 }, + { 37,-1720 }, { 0, 0 }, { 39,-1768 }, { 40,-1768 }, { 41,-1768 }, + { 42,-1768 }, { 43,-1768 }, { 0, 20 }, { 0,1655 }, { 46,-1768 }, + { 2,-823 }, { 3,-823 }, { 4,-823 }, { 5, -45 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1813 }, + { 0, 0 }, { 0, 0 }, { 19, 492 }, { 20, 492 }, { 21, 492 }, + { 22, 492 }, { 23, 492 }, { 24, 492 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 492 }, { 31, 492 }, + { 32, 492 }, { 33,-1813 }, { 34,-1813 }, { 35,-1813 }, { 36,-1813 }, + + { 37,-1765 }, { 0, 0 }, { 39, 492 }, { 40, 492 }, { 41,-1813 }, + { 42,-1813 }, { 43,-1813 }, { 0, 20 }, { 0,1610 }, { 46,-1813 }, + { 2,-1762 }, { 3,-1762 }, { 4,-1762 }, { 5,-778 }, { 0, 0 }, + { 0, 0 }, { 0,1602 }, { 0, 0 }, { 2,-641 }, { 3,-641 }, + { 4,-641 }, { 5,-596 }, { 0, 0 }, { 0, 0 }, { 16,-1858 }, + { 0, 0 }, { 0, 0 }, { 19, 492 }, { 20, 492 }, { 21, 492 }, + { 22, 492 }, { 23, 492 }, { 24, 492 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 492 }, { 31, 492 }, + { 32, 492 }, { 33,-1858 }, { 34,-1858 }, { 35,-1858 }, { 36,-1858 }, + { 37,-1810 }, { 0, 0 }, { 39, 492 }, { 40, 492 }, { 41,-1858 }, + + { 42,-1858 }, { 43,-1858 }, { 36,-2128 }, { 37,-715 }, { 46,-1858 }, + { 0, 0 }, { 0,1562 }, { 0, 0 }, { 0,1560 }, { 43,-2128 }, + { 2,-683 }, { 3,-683 }, { 4,-683 }, { 5,-638 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 22,-1524 }, { 0, 0 }, + { 24,-1476 }, { 0, 0 }, { 0, 17 }, { 0,1535 }, { 0, 0 }, + { 0, 0 }, { 3,-723 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 36,-2170 }, + { 37,-757 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1741 }, + + { 0, 0 }, { 43,-2170 }, { 19,-1741 }, { 20,-1741 }, { 21,-1741 }, + { 22,-1741 }, { 23,-1741 }, { 24,-1741 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30,-1741 }, { 31,-1741 }, + { 32,-1741 }, { 33,-1741 }, { 34,-1741 }, { 35,-1741 }, { 36,-1741 }, + { 37,-1693 }, { 0, 0 }, { 39,-1741 }, { 40,-1741 }, { 41,-1741 }, + { 42,-1741 }, { 43,-1741 }, { 0, 17 }, { 0,1490 }, { 46,-1741 }, + { 2,-768 }, { 3,-768 }, { 4,-768 }, { 5, -45 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1786 }, + { 0, 0 }, { 0, 0 }, { 19, 428 }, { 20, 428 }, { 21, 428 }, + + { 22, 428 }, { 23, 428 }, { 24, 428 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 428 }, { 31, 428 }, + { 32, 428 }, { 33,-1786 }, { 34,-1786 }, { 35,-1786 }, { 36,-1786 }, + { 37,-1738 }, { 0, 0 }, { 39, 428 }, { 40, 428 }, { 41,-1786 }, + { 42,-1786 }, { 43,-1786 }, { 0, 17 }, { 0,1445 }, { 46,-1786 }, + { 2,-1735 }, { 3,-1735 }, { 4,-1735 }, { 5,-723 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1831 }, + { 0, 0 }, { 0, 0 }, { 19, 428 }, { 20, 428 }, { 21, 428 }, + { 22, 428 }, { 23, 428 }, { 24, 428 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 428 }, { 31, 428 }, + { 32, 428 }, { 33,-1831 }, { 34,-1831 }, { 35,-1831 }, { 36,-1831 }, + { 37,-1783 }, { 0, 0 }, { 39, 428 }, { 40, 428 }, { 41,-1831 }, + { 42,-1831 }, { 43,-1831 }, { 0, 7 }, { 0,1400 }, { 46,-1831 }, + { 2,-1690 }, { 3,-1690 }, { 4,-1690 }, { 5,-678 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 12,-2883 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-2734 }, + { 0, 0 }, { 0, 0 }, { 19, 428 }, { 20, 428 }, { 21, 428 }, + { 22, 428 }, { 23, 428 }, { 24, 428 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 428 }, { 31, 428 }, + + { 32, 428 }, { 33,-2734 }, { 34,-2734 }, { 35,-2734 }, { 36,-2734 }, + { 37,-2686 }, { 0, 0 }, { 39, 428 }, { 40, 428 }, { 41,-2734 }, + { 42,-2734 }, { 43,-2734 }, { 0, 7 }, { 0,1355 }, { 46,-2734 }, + { 2,-2683 }, { 3,-2683 }, { 4,-2683 }, { 5,-1645 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 12,-2928 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-2779 }, + { 0, 0 }, { 0, 0 }, { 19, 428 }, { 20, 428 }, { 21, 428 }, + { 22, 428 }, { 23, 428 }, { 24, 428 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 428 }, { 31, 428 }, + { 32, 428 }, { 33,-2779 }, { 34,-2779 }, { 35,-2779 }, { 36,-2779 }, + + { 37,-2731 }, { 0, 0 }, { 39, 428 }, { 40, 428 }, { 41,-2779 }, + { 42,-2779 }, { 43,-2779 }, { 0, 0 }, { 0, 0 }, { 46,-2779 }, + { 0, 18 }, { 0,1307 }, { 1,-3710 }, { 2,-1600 }, { 3,-2638 }, + { 4,-2638 }, { 5,-1552 }, { 6,-3710 }, { 7,-3832 }, { 8,-3710 }, + { 9,-3710 }, { 10,-3710 }, { 11,-3710 }, { 12,-3710 }, { 13,-3710 }, + { 14,-3710 }, { 15,-3710 }, { 16,-3710 }, { 17,-3710 }, { 18,-3710 }, + { 19, 428 }, { 20, 428 }, { 21, 428 }, { 22, 428 }, { 23, 428 }, + { 24, 428 }, { 25,-3710 }, { 26,-3710 }, { 27,-3710 }, { 28,-3710 }, + { 29,-3710 }, { 30, 428 }, { 31, 428 }, { 32, 428 }, { 33,-3710 }, + { 34,-3710 }, { 35,-3710 }, { 36,-3710 }, { 37,-3662 }, { 38,-3710 }, + + { 39, 428 }, { 40, 428 }, { 41,-3710 }, { 42,-3710 }, { 43,-3710 }, + { 44,-3710 }, { 45,-3710 }, { 46,-3614 }, { 0, 11 }, { 0,1259 }, + { 0, 0 }, { 2,-2542 }, { 3,-2542 }, { 4,-2542 }, { 5,-1504 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 16,-3614 }, { 0, 0 }, { 0, 0 }, { 19, 428 }, { 20, 428 }, + { 21, 428 }, { 22, 428 }, { 23, 428 }, { 24, 428 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 428 }, + { 31, 428 }, { 32, 428 }, { 33,-3614 }, { 34,-3614 }, { 35,-3614 }, + { 36,-3614 }, { 37,-3566 }, { 0, 0 }, { 39, 428 }, { 40, 428 }, + + { 41,-3614 }, { 42,-3614 }, { 43,-3614 }, { 0, 0 }, { 0, 0 }, + { 46,-3614 }, { 0, 18 }, { 0,1211 }, { 1,-3566 }, { 2,-1459 }, + { 3,-2497 }, { 4,-2497 }, { 5,-1411 }, { 6,-3566 }, { 7,-3566 }, + { 8,-3566 }, { 9,-3566 }, { 10,-3566 }, { 11,-3928 }, { 12,-3566 }, + { 13,-3566 }, { 14,-3566 }, { 15,-3566 }, { 16,-3566 }, { 17,-3566 }, + { 18,-3566 }, { 19, 428 }, { 20, 428 }, { 21, 428 }, { 22, 428 }, + { 23, 428 }, { 24, 428 }, { 25,-3566 }, { 26,-3566 }, { 27,-3566 }, + { 28,-3566 }, { 29,-3566 }, { 30, 428 }, { 31, 428 }, { 32, 428 }, + { 33,-3566 }, { 34,-3566 }, { 35,-3566 }, { 36,-3566 }, { 37,-3518 }, + { 38,-3566 }, { 39, 428 }, { 40, 428 }, { 41,-3566 }, { 42,-3566 }, + + { 43,-3566 }, { 44,-3566 }, { 45,-3566 }, { 46,-3470 }, { 0, 20 }, + { 0,1163 }, { 0, 0 }, { 2,-1315 }, { 3,-1315 }, { 4,-1315 }, + { 5,-537 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-2305 }, { 0, 0 }, { 0, 0 }, { 19, 428 }, + { 20, 428 }, { 21, 428 }, { 22, 428 }, { 23, 428 }, { 24, 428 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, 428 }, { 31, 428 }, { 32, 428 }, { 33,-2305 }, { 34,-2305 }, + { 35,-2305 }, { 36,-2305 }, { 37,-2257 }, { 0, 0 }, { 39, 428 }, + { 40, 428 }, { 41,-2305 }, { 42,-2305 }, { 43,-2305 }, { 0, 20 }, + + { 0,1118 }, { 46,-2305 }, { 2,-2254 }, { 3,-2254 }, { 4,-2254 }, + { 5,-1270 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-2350 }, { 0, 0 }, { 0, 0 }, { 19, 428 }, + { 20, 428 }, { 21, 428 }, { 22, 428 }, { 23, 428 }, { 24, 428 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, 428 }, { 31, 428 }, { 32, 428 }, { 33,-2350 }, { 34,-2350 }, + { 35,-2350 }, { 36,-2350 }, { 37,-2302 }, { 0, 0 }, { 39, 428 }, + { 40, 428 }, { 41,-2350 }, { 42,-2350 }, { 43,-2350 }, { 0, 0 }, + { 0,1073 }, { 46,-2350 }, { 2,-991 }, { 3,-991 }, { 4,-991 }, + + { 5,-946 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 17 }, { 0,1062 }, { 12,-2097 }, { 2,-1196 }, { 3,-1196 }, + { 4,-1196 }, { 5,-473 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 16,-2214 }, { 0, 0 }, { 0, 0 }, + { 19, 417 }, { 20, 417 }, { 21, 417 }, { 22, 417 }, { 23, 417 }, + { 24, 417 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 30, 417 }, { 31, 417 }, { 32, 417 }, { 33,-2214 }, + { 34,-2214 }, { 35,-2214 }, { 36,-2214 }, { 37,-2166 }, { 0, 0 }, + { 39, 417 }, { 40, 417 }, { 41,-2214 }, { 42,-2214 }, { 43,-2214 }, + + { 0, 17 }, { 0,1017 }, { 46,-2214 }, { 2,-2163 }, { 3,-2163 }, + { 4,-2163 }, { 5,-1151 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 16,-2259 }, { 0, 0 }, { 0, 0 }, + { 19, 417 }, { 20, 417 }, { 21, 417 }, { 22, 417 }, { 23, 417 }, + { 24, 417 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 30, 417 }, { 31, 417 }, { 32, 417 }, { 33,-2259 }, + { 34,-2259 }, { 35,-2259 }, { 36,-2259 }, { 37,-2211 }, { 0, 0 }, + { 39, 417 }, { 40, 417 }, { 41,-2259 }, { 42,-2259 }, { 43,-2259 }, + { 0, 7 }, { 0, 972 }, { 46,-2259 }, { 2,-2118 }, { 3,-2118 }, + + { 4,-2118 }, { 5,-1106 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 12,-3311 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 16,-3162 }, { 0, 0 }, { 0, 0 }, + { 19, 417 }, { 20, 417 }, { 21, 417 }, { 22, 417 }, { 23, 417 }, + { 24, 417 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 30, 417 }, { 31, 417 }, { 32, 417 }, { 33,-3162 }, + { 34,-3162 }, { 35,-3162 }, { 36,-3162 }, { 37,-3114 }, { 0, 0 }, + { 39, 417 }, { 40, 417 }, { 41,-3162 }, { 42,-3162 }, { 43,-3162 }, + { 0, 7 }, { 0, 927 }, { 46,-3162 }, { 2,-3111 }, { 3,-3111 }, + { 4,-3111 }, { 5,-2073 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 12,-3356 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 16,-3207 }, { 0, 0 }, { 0, 0 }, + { 19, 417 }, { 20, 417 }, { 21, 417 }, { 22, 417 }, { 23, 417 }, + { 24, 417 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 30, 417 }, { 31, 417 }, { 32, 417 }, { 33,-3207 }, + { 34,-3207 }, { 35,-3207 }, { 36,-3207 }, { 37,-3159 }, { 0, 0 }, + { 39, 417 }, { 40, 417 }, { 41,-3207 }, { 42,-3207 }, { 43,-3207 }, + { 0, 0 }, { 0, 0 }, { 46,-3207 }, { 0, 18 }, { 0, 879 }, + { 1,-4138 }, { 2,-2028 }, { 3,-3066 }, { 4,-3066 }, { 5,-1980 }, + { 6,-4138 }, { 7,-4260 }, { 8,-4138 }, { 9,-4138 }, { 10,-4138 }, + + { 11,-4138 }, { 12,-4138 }, { 13,-4138 }, { 14,-4138 }, { 15,-4138 }, + { 16,-4138 }, { 17,-4138 }, { 18,-4138 }, { 19, 417 }, { 20, 417 }, + { 21, 417 }, { 22, 417 }, { 23, 417 }, { 24, 417 }, { 25,-4138 }, + { 26,-4138 }, { 27,-4138 }, { 28,-4138 }, { 29,-4138 }, { 30, 417 }, + { 31, 417 }, { 32, 417 }, { 33,-4138 }, { 34,-4138 }, { 35,-4138 }, + { 36,-4138 }, { 37,-4090 }, { 38,-4138 }, { 39, 417 }, { 40, 417 }, + { 41,-4138 }, { 42,-4138 }, { 43,-4138 }, { 44,-4138 }, { 45,-4138 }, + { 46,-4042 }, { 0, 11 }, { 0, 831 }, { 0, 0 }, { 2,-2970 }, + { 3,-2970 }, { 4,-2970 }, { 5,-1932 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-4042 }, { 0, 0 }, + { 0, 0 }, { 19, 417 }, { 20, 417 }, { 21, 417 }, { 22, 417 }, + { 23, 417 }, { 24, 417 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 30, 417 }, { 31, 417 }, { 32, 417 }, + { 33,-4042 }, { 34,-4042 }, { 35,-4042 }, { 36,-4042 }, { 37,-3994 }, + { 0, 0 }, { 39, 417 }, { 40, 417 }, { 41,-4042 }, { 42,-4042 }, + { 43,-4042 }, { 0, 0 }, { 0, 0 }, { 46,-4042 }, { 0, 18 }, + { 0, 783 }, { 1,-3994 }, { 2,-1887 }, { 3,-2925 }, { 4,-2925 }, + { 5,-1839 }, { 6,-3994 }, { 7,-3994 }, { 8,-3994 }, { 9,-3994 }, + { 10,-3994 }, { 11,-4356 }, { 12,-3994 }, { 13,-3994 }, { 14,-3994 }, + + { 15,-3994 }, { 16,-3994 }, { 17,-3994 }, { 18,-3994 }, { 19, 417 }, + { 20, 417 }, { 21, 417 }, { 22, 417 }, { 23, 417 }, { 24, 417 }, + { 25,-3994 }, { 26,-3994 }, { 27,-3994 }, { 28,-3994 }, { 29,-3994 }, + { 30, 417 }, { 31, 417 }, { 32, 417 }, { 33,-3994 }, { 34,-3994 }, + { 35,-3994 }, { 36,-3994 }, { 37,-3946 }, { 38,-3994 }, { 39, 417 }, + { 40, 417 }, { 41,-3994 }, { 42,-3994 }, { 43,-3994 }, { 44,-3994 }, + { 45,-3994 }, { 46,-3898 }, { 0, 20 }, { 0, 735 }, { 0, 0 }, + { 2,-1743 }, { 3,-1743 }, { 4,-1743 }, { 5,-965 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-2733 }, + + { 0, 0 }, { 0, 0 }, { 19, 417 }, { 20, 417 }, { 21, 417 }, + { 22, 417 }, { 23, 417 }, { 24, 417 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 417 }, { 31, 417 }, + { 32, 417 }, { 33,-2733 }, { 34,-2733 }, { 35,-2733 }, { 36,-2733 }, + { 37,-2685 }, { 0, 0 }, { 39, 417 }, { 40, 417 }, { 41,-2733 }, + { 42,-2733 }, { 43,-2733 }, { 0, 20 }, { 0, 690 }, { 46,-2733 }, + { 2,-2682 }, { 3,-2682 }, { 4,-2682 }, { 5,-1698 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-2778 }, + { 0, 0 }, { 0, 0 }, { 19, 417 }, { 20, 417 }, { 21, 417 }, + + { 22, 417 }, { 23, 417 }, { 24, 417 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 417 }, { 31, 417 }, + { 32, 417 }, { 33,-2778 }, { 34,-2778 }, { 35,-2778 }, { 36,-2778 }, + { 37,-2730 }, { 0, 0 }, { 39, 417 }, { 40, 417 }, { 41,-2778 }, + { 42,-2778 }, { 43,-2778 }, { 0, 17 }, { 0, 645 }, { 46,-2778 }, + { 2,-1613 }, { 3,-1613 }, { 4,-1613 }, { 5,-890 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-2631 }, + { 0, 0 }, { 0, 0 }, { 19, 417 }, { 20, 417 }, { 21, 417 }, + { 22, 417 }, { 23, 417 }, { 24, 417 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 417 }, { 31, 417 }, + { 32, 417 }, { 33,-2631 }, { 34,-2631 }, { 35,-2631 }, { 36,-2631 }, + { 37,-2583 }, { 0, 0 }, { 39, 417 }, { 40, 417 }, { 41,-2631 }, + { 42,-2631 }, { 43,-2631 }, { 0, 17 }, { 0, 600 }, { 46,-2631 }, + { 2,-2580 }, { 3,-2580 }, { 4,-2580 }, { 5,-1568 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-2676 }, + { 0, 0 }, { 0, 0 }, { 19, 417 }, { 20, 417 }, { 21, 417 }, + { 22, 417 }, { 23, 417 }, { 24, 417 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 417 }, { 31, 417 }, + + { 32, 417 }, { 33,-2676 }, { 34,-2676 }, { 35,-2676 }, { 36,-2676 }, + { 37,-2628 }, { 0, 0 }, { 39, 417 }, { 40, 417 }, { 41,-2676 }, + { 42,-2676 }, { 43,-2676 }, { 0, 7 }, { 0, 555 }, { 46,-2676 }, + { 2,-2535 }, { 3,-2535 }, { 4,-2535 }, { 5,-1523 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 12,-3728 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-3579 }, + { 0, 0 }, { 0, 0 }, { 19, 417 }, { 20, 417 }, { 21, 417 }, + { 22, 417 }, { 23, 417 }, { 24, 417 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 417 }, { 31, 417 }, + { 32, 417 }, { 33,-3579 }, { 34,-3579 }, { 35,-3579 }, { 36,-3579 }, + + { 37,-3531 }, { 0, 0 }, { 39, 417 }, { 40, 417 }, { 41,-3579 }, + { 42,-3579 }, { 43,-3579 }, { 0, 7 }, { 0, 510 }, { 46,-3579 }, + { 2,-3528 }, { 3,-3528 }, { 4,-3528 }, { 5,-2490 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 12,-3773 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-3624 }, + { 0, 0 }, { 0, 0 }, { 19,-3624 }, { 20,-3624 }, { 21,-3624 }, + { 22,-3624 }, { 23,-3624 }, { 24,-3624 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30,-3624 }, { 31,-3624 }, + { 32,-3624 }, { 33,-3624 }, { 34,-3624 }, { 35,-3624 }, { 36,-3624 }, + { 37,-3576 }, { 0, 0 }, { 39,-3624 }, { 40,-3624 }, { 41,-3624 }, + + { 42,-3624 }, { 43,-3624 }, { 0, 0 }, { 0, 0 }, { 46,-3624 }, + { 0, 18 }, { 0, 462 }, { 1,-4555 }, { 2,-2445 }, { 3,-3483 }, + { 4,-3483 }, { 5,-2397 }, { 6,-4555 }, { 7,-4677 }, { 8,-4555 }, + { 9,-4555 }, { 10,-4555 }, { 11,-4555 }, { 12,-4555 }, { 13,-4555 }, + { 14,-4555 }, { 15,-4555 }, { 16,-4555 }, { 17,-4555 }, { 18,-4555 }, + { 19,-4555 }, { 20,-4555 }, { 21,-4555 }, { 22,-4555 }, { 23,-4555 }, + { 24,-4555 }, { 25,-4555 }, { 26,-4555 }, { 27,-4555 }, { 28,-4555 }, + { 29,-4555 }, { 30,-4555 }, { 31,-4555 }, { 32,-4555 }, { 33,-4555 }, + { 34,-4555 }, { 35,-4555 }, { 36,-4555 }, { 37,-4507 }, { 38,-4555 }, + { 39,-4555 }, { 40,-4555 }, { 41,-4555 }, { 42,-4555 }, { 43,-4555 }, + + { 44,-4555 }, { 45,-4555 }, { 46,-4459 }, { 0, 11 }, { 0, 414 }, + { 0, 0 }, { 2,-3387 }, { 3,-3387 }, { 4,-3387 }, { 5,-2349 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 16,-4459 }, { 0, 0 }, { 0, 0 }, { 19,-4459 }, { 20,-4459 }, + { 21,-4459 }, { 22,-4459 }, { 23,-4459 }, { 24,-4459 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30,-4459 }, + { 31,-4459 }, { 32,-4459 }, { 33,-4459 }, { 34,-4459 }, { 35,-4459 }, + { 36,-4459 }, { 37,-4411 }, { 0, 0 }, { 39,-4459 }, { 40,-4459 }, + { 41,-4459 }, { 42,-4459 }, { 43,-4459 }, { 0, 0 }, { 0, 0 }, + + { 46,-4459 }, { 0, 18 }, { 0, 366 }, { 1,-4411 }, { 2,-2304 }, + { 3,-3342 }, { 4,-3342 }, { 5,-2256 }, { 6,-4411 }, { 7,-4411 }, + { 8,-4411 }, { 9,-4411 }, { 10,-4411 }, { 11,-4773 }, { 12,-4411 }, + { 13,-4411 }, { 14,-4411 }, { 15,-4411 }, { 16,-4411 }, { 17,-4411 }, + { 18,-4411 }, { 19,-4411 }, { 20,-4411 }, { 21,-4411 }, { 22,-4411 }, + { 23,-4411 }, { 24,-4411 }, { 25,-4411 }, { 26,-4411 }, { 27,-4411 }, + { 28,-4411 }, { 29,-4411 }, { 30,-4411 }, { 31,-4411 }, { 32,-4411 }, + { 33,-4411 }, { 34,-4411 }, { 35,-4411 }, { 36,-4411 }, { 37,-4363 }, + { 38,-4411 }, { 39,-4411 }, { 40,-4411 }, { 41,-4411 }, { 42,-4411 }, + { 43,-4411 }, { 44,-4411 }, { 45,-4411 }, { 46,-4315 }, { 0, 20 }, + + { 0, 318 }, { 0, 0 }, { 2,-2160 }, { 3,-2160 }, { 4,-2160 }, + { 5,-1382 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-3150 }, { 0, 0 }, { 0, 0 }, { 19, 225 }, + { 20, 225 }, { 21, 225 }, { 22, 225 }, { 23, 225 }, { 24, 225 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, 225 }, { 31, 225 }, { 32, 225 }, { 33,-3150 }, { 34,-3150 }, + { 35,-3150 }, { 36,-3150 }, { 37,-3102 }, { 0, 0 }, { 39, 225 }, + { 40, 225 }, { 41,-3150 }, { 42,-3150 }, { 43,-3150 }, { 0, 20 }, + { 0, 273 }, { 46,-3150 }, { 2,-3099 }, { 3,-3099 }, { 4,-3099 }, + + { 5,-2115 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-3195 }, { 0, 0 }, { 0, 0 }, { 19,-3195 }, + { 20,-3195 }, { 21,-3195 }, { 22,-3195 }, { 23,-3195 }, { 24,-3195 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30,-3195 }, { 31,-3195 }, { 32,-3195 }, { 33,-3195 }, { 34,-3195 }, + { 35,-3195 }, { 36,-3195 }, { 37,-3147 }, { 0, 0 }, { 39,-3195 }, + { 40,-3195 }, { 41,-3195 }, { 42,-3195 }, { 43,-3195 }, { 0, 17 }, + { 0, 228 }, { 46,-3195 }, { 2,-2030 }, { 3,-2030 }, { 4,-2030 }, + { 5,-1307 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-3048 }, { 0, 0 }, { 0, 0 }, { 19, 180 }, + { 20, 180 }, { 21, 180 }, { 22, 180 }, { 23, 180 }, { 24, 180 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30, 180 }, { 31, 180 }, { 32, 180 }, { 33,-3048 }, { 34,-3048 }, + { 35,-3048 }, { 36,-3048 }, { 37,-3000 }, { 0, 0 }, { 39, 180 }, + { 40, 180 }, { 41,-3048 }, { 42,-3048 }, { 43,-3048 }, { 0, 17 }, + { 0, 183 }, { 46,-3048 }, { 2,-2997 }, { 3,-2997 }, { 4,-2997 }, + { 5,-1985 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 0, 0 }, { 16,-3093 }, { 0, 0 }, { 0, 0 }, { 19,-3093 }, + { 20,-3093 }, { 21,-3093 }, { 22,-3093 }, { 23,-3093 }, { 24,-3093 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30,-3093 }, { 31,-3093 }, { 32,-3093 }, { 33,-3093 }, { 34,-3093 }, + { 35,-3093 }, { 36,-3093 }, { 37,-3045 }, { 0, 0 }, { 39,-3093 }, + { 40,-3093 }, { 41,-3093 }, { 42,-3093 }, { 43,-3093 }, { 0, 7 }, + { 0, 138 }, { 46,-3093 }, { 2,-2952 }, { 3,-2952 }, { 4,-2952 }, + { 5,-1940 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 12,-4145 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-3996 }, { 0, 0 }, { 0, 0 }, { 19,-3996 }, + + { 20,-3996 }, { 21,-3996 }, { 22,-3996 }, { 23,-3996 }, { 24,-3996 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30,-3996 }, { 31,-3996 }, { 32,-3996 }, { 33,-3996 }, { 34,-3996 }, + { 35,-3996 }, { 36,-3996 }, { 37,-3948 }, { 0, 0 }, { 39,-3996 }, + { 40,-3996 }, { 41,-3996 }, { 42,-3996 }, { 43,-3996 }, { 0, 20 }, + { 0, 93 }, { 46,-3996 }, { 2,-2385 }, { 3,-2385 }, { 4,-2385 }, + { 5,-1607 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-3375 }, { 0, 0 }, { 0, 0 }, { 19,-3375 }, + { 20,-3375 }, { 21,-3375 }, { 22,-3375 }, { 23,-3375 }, { 24,-3375 }, + + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 30,-3375 }, { 31,-3375 }, { 32,-3375 }, { 33,-3375 }, { 34,-3375 }, + { 35,-3375 }, { 36,-3375 }, { 37,-3327 }, { 0, 0 }, { 39,-3375 }, + { 40,-3375 }, { 41,-3375 }, { 42,-3375 }, { 43,-3375 }, { 0, 17 }, + { 0, 48 }, { 46,-3375 }, { 2,-2210 }, { 3,-2210 }, { 4,-2210 }, + { 5,-1487 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 16,-3228 }, { 0, 0 }, { 0, 0 }, { 19,-3228 }, + { 20,-3228 }, { 21,-3228 }, { 22,-3228 }, { 23,-3228 }, { 24,-3228 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + { 30,-3228 }, { 31,-3228 }, { 32,-3228 }, { 33,-3228 }, { 34,-3228 }, + { 35,-3228 }, { 36,-3228 }, { 37,-3180 }, { 0, 0 }, { 39,-3228 }, + { 40,-3228 }, { 41,-3228 }, { 42,-3228 }, { 43,-3228 }, { 0, 0 }, + { 0, 0 }, { 46,-3228 }, { 47, 26 }, { 1, 0 }, }; + +static yyconst struct yy_trans_info *yy_start_state_list[3] = +{ + &yy_transition[1], + &yy_transition[3], + &yy_transition[51], + +} ; + +static yyconst flex_int32_t yy_ec[256] = +{ 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 4, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 6, 7, 8, 9, 10, 1, 11, 12, + 1, 13, 14, 15, 16, 17, 18, 19, 20, 20, + 20, 21, 22, 23, 24, 20, 20, 25, 1, 26, + 27, 28, 1, 29, 30, 30, 30, 30, 31, 32, + 33, 33, 33, 33, 33, 33, 33, 34, 35, 33, + 33, 33, 33, 36, 33, 33, 33, 33, 33, 33, + 1, 37, 1, 38, 33, 1, 30, 30, 30, 30, + + 39, 40, 33, 33, 33, 33, 33, 33, 33, 41, + 42, 33, 33, 33, 33, 43, 33, 33, 33, 33, + 33, 33, 1, 44, 1, 45, 1, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46 +} ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#define YY_NO_INPUT 1 +enum css_token { + SPACE = 1, + INCLUDES, + DASHMATCH, + PREFIXMATCH, + SUFFIXMATCH, + SUBSTRINGMATCH, + IDENT, + STRING, + FUNCTION, + NUMBER, + HASH, + PLUS, + GREATER, + COMMA, + TILDE, + NOT, + ATKEYWORD, + INVALID, + PERCENTAGE, + DIMENSION, + CDO, + CDC +}; + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Holds the entire state of the reentrant scanner. */ +struct yyguts_t +{ + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + yy_size_t yy_n_chars; + yy_size_t yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + + char *yytext_r; + int yy_more_flag; + int yy_more_len; + +}; /* end struct yyguts_t */ + +static int yy_init_globals (yyscan_t yyscanner ); + +int csslex_init (yyscan_t* scanner); + +int csslex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int csslex_destroy (yyscan_t yyscanner ); + +int cssget_debug (yyscan_t yyscanner ); + +void cssset_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE cssget_extra (yyscan_t yyscanner ); + +void cssset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *cssget_in (yyscan_t yyscanner ); + +void cssset_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *cssget_out (yyscan_t yyscanner ); + +void cssset_out (FILE * out_str ,yyscan_t yyscanner ); + +yy_size_t cssget_leng (yyscan_t yyscanner ); + +char *cssget_text (yyscan_t yyscanner ); + +int cssget_lineno (yyscan_t yyscanner ); + +void cssset_lineno (int line_number ,yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int csswrap (yyscan_t yyscanner ); +#else +extern int csswrap (yyscan_t yyscanner ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (yyscan_t yyscanner ); +#else +static int input (yyscan_t yyscanner ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ +errno=0; \ +while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \ +{ \ +if( errno != EINTR) \ +{ \ +YY_FATAL_ERROR( "input in flex scanner failed" ); \ +break; \ +} \ +errno=0; \ +clearerr(yyin); \ +}\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int csslex (yyscan_t yyscanner); + +#define YY_DECL int csslex (yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ +YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( !yyg->yy_init ) + { + yyg->yy_init = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yyg->yy_start ) + yyg->yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + cssensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + css_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + css_load_buffer_state(yyscanner ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yyg->yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yyg->yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start_state_list[yyg->yy_start]; + yy_match: + { + register yyconst struct yy_trans_info *yy_trans_info; + + register YY_CHAR yy_c; + + for ( yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + (yy_trans_info = &yy_current_state[(unsigned int) yy_c])-> + yy_verify == yy_c; + yy_c = yy_ec[YY_SC_TO_UI(*++yy_cp)] ) + { + yy_current_state += yy_trans_info->yy_nxt; + + if ( yy_current_state[-1].yy_nxt ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + } + } + + yy_find_action: + yy_act = yy_current_state[-1].yy_nxt; + + YY_DO_BEFORE_ACTION; + + do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yyg->yy_hold_char; + yy_cp = yyg->yy_last_accepting_cpos + 1; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + + case 1: + /* rule 1 can match eol */ + YY_RULE_SETUP + return SPACE; + YY_BREAK + case 2: + YY_RULE_SETUP + return INCLUDES; + YY_BREAK + case 3: + YY_RULE_SETUP + return DASHMATCH; + YY_BREAK + case 4: + YY_RULE_SETUP + return PREFIXMATCH; + YY_BREAK + case 5: + YY_RULE_SETUP + return SUFFIXMATCH; + YY_BREAK + case 6: + YY_RULE_SETUP + return SUBSTRINGMATCH; + YY_BREAK + case 7: + /* rule 7 can match eol */ + YY_RULE_SETUP + return IDENT; + YY_BREAK + case 8: + /* rule 8 can match eol */ + YY_RULE_SETUP + return STRING; + YY_BREAK + case 9: + /* rule 9 can match eol */ + YY_RULE_SETUP + return FUNCTION; + YY_BREAK + case 10: + YY_RULE_SETUP + return NUMBER; + YY_BREAK + case 11: + /* rule 11 can match eol */ + YY_RULE_SETUP + return HASH; + YY_BREAK + case 12: + /* rule 12 can match eol */ + YY_RULE_SETUP + return PLUS; + YY_BREAK + case 13: + /* rule 13 can match eol */ + YY_RULE_SETUP + return GREATER; + YY_BREAK + case 14: + /* rule 14 can match eol */ + YY_RULE_SETUP + return COMMA; + YY_BREAK + case 15: + /* rule 15 can match eol */ + YY_RULE_SETUP + return TILDE; + YY_BREAK + case 16: + /* rule 16 can match eol */ + YY_RULE_SETUP + return NOT; + YY_BREAK + case 17: + /* rule 17 can match eol */ + YY_RULE_SETUP + return ATKEYWORD; + YY_BREAK + case 18: + /* rule 18 can match eol */ + YY_RULE_SETUP + return INVALID; + YY_BREAK + case 19: + YY_RULE_SETUP + return PERCENTAGE; + YY_BREAK + case 20: + /* rule 20 can match eol */ + YY_RULE_SETUP + return DIMENSION; + YY_BREAK + case 21: + YY_RULE_SETUP + return CDO; + YY_BREAK + case 22: + YY_RULE_SETUP + return CDC; + YY_BREAK + case 23: + /* rule 23 can match eol */ + YY_RULE_SETUP + /* ignore comments */ + YY_BREAK + case 24: + YY_RULE_SETUP + return *yytext; + YY_BREAK + case 25: + YY_RULE_SETUP + YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK + case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yyg->yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * csslex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); + + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yyg->yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yyg->yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_END_OF_FILE: + { + yyg->yy_did_buffer_switch_on_eof = 0; + + if ( csswrap(yyscanner ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = + yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yyg->yy_c_buf_p = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of csslex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = yyg->yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) (yyg->yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + cssrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + yyg->yy_n_chars, num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + if ( yyg->yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + cssrestart(yyin ,yyscanner); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cssrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + yyg->yy_n_chars += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_current_state = yy_start_state_list[yyg->yy_start]; + + for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) + { + yy_current_state += yy_current_state[(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)].yy_nxt; + if ( yy_current_state[-1].yy_nxt ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ +static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) +{ + register int yy_is_jam; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ + register char *yy_cp = yyg->yy_c_buf_p; + + register int yy_c = 1; + register yyconst struct yy_trans_info *yy_trans_info; + + yy_trans_info = &yy_current_state[(unsigned int) yy_c]; + yy_current_state += yy_trans_info->yy_nxt; + yy_is_jam = (yy_trans_info->yy_verify != yy_c); + + if ( ! yy_is_jam ) + { + if ( yy_current_state[-1].yy_nxt ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + } + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput (yyscan_t yyscanner) +#else +static int input (yyscan_t yyscanner) +#endif + +{ + int c; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + *yyg->yy_c_buf_p = yyg->yy_hold_char; + + if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + /* This was really a NUL. */ + *yyg->yy_c_buf_p = '\0'; + + else + { /* need more input */ + yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + ++yyg->yy_c_buf_p; + + switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + cssrestart(yyin ,yyscanner); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( csswrap(yyscanner ) ) + return 0; + + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(yyscanner); +#else + return input(yyscanner); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = yyg->yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ + *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ + yyg->yy_hold_char = *++yyg->yy_c_buf_p; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * @param yyscanner The scanner object. + * @note This function does not reset the start condition to @c INITIAL . + */ +void cssrestart (FILE * input_file , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! YY_CURRENT_BUFFER ){ + cssensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + css_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + css_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); + css_load_buffer_state(yyscanner ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * @param yyscanner The scanner object. + */ +void css_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* TODO. We should be able to replace this entire function body + * with + * csspop_buffer_state(); + * csspush_buffer_state(new_buffer); + */ + cssensure_buffer_stack (yyscanner); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + css_load_buffer_state(yyscanner ); + + /* We don't actually know whether we did this switch during + * EOF (csswrap()) processing, but the only time this flag + * is looked at is after csswrap() is called, so it's safe + * to go ahead and always set it. + */ + yyg->yy_did_buffer_switch_on_eof = 1; +} + +static void css_load_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + yyg->yy_hold_char = *yyg->yy_c_buf_p; +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * @param yyscanner The scanner object. + * @return the allocated buffer state. + */ +YY_BUFFER_STATE css_create_buffer (FILE * file, int size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) cssalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in css_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) cssalloc(b->yy_buf_size + 2 ,yyscanner ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in css_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + css_init_buffer(b,file ,yyscanner); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with css_create_buffer() + * @param yyscanner The scanner object. + */ +void css_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + cssfree((void *) b->yy_ch_buf ,yyscanner ); + + cssfree((void *) b ,yyscanner ); +} + +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a cssrestart() or at EOF. + */ +static void css_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) + +{ + int oerrno = errno; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + css_flush_buffer(b ,yyscanner); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then css_init_buffer was _probably_ + * called from cssrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * @param yyscanner The scanner object. + */ +void css_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + css_load_buffer_state(yyscanner ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * @param yyscanner The scanner object. + */ +void csspush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (new_buffer == NULL) + return; + + cssensure_buffer_stack(yyscanner); + + /* This block is copied from css_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + yyg->yy_buffer_stack_top++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from css_switch_to_buffer. */ + css_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * @param yyscanner The scanner object. + */ +void csspop_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (!YY_CURRENT_BUFFER) + return; + + css_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); + YY_CURRENT_BUFFER_LVALUE = NULL; + if (yyg->yy_buffer_stack_top > 0) + --yyg->yy_buffer_stack_top; + + if (YY_CURRENT_BUFFER) { + css_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void cssensure_buffer_stack (yyscan_t yyscanner) +{ + yy_size_t num_to_alloc; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (!yyg->yy_buffer_stack) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + yyg->yy_buffer_stack = (struct yy_buffer_state**)cssalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in cssensure_buffer_stack()" ); + + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + yyg->yy_buffer_stack_max = num_to_alloc; + yyg->yy_buffer_stack_top = 0; + return; + } + + if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = yyg->yy_buffer_stack_max + grow_size; + yyg->yy_buffer_stack = (struct yy_buffer_state**)cssrealloc + (yyg->yy_buffer_stack, + num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in cssensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); + yyg->yy_buffer_stack_max = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE css_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) cssalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in css_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + css_switch_to_buffer(b ,yyscanner ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to csslex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * css_scan_bytes() instead. + */ +YY_BUFFER_STATE css_scan_string (yyconst char * yystr , yyscan_t yyscanner) +{ + + return css_scan_bytes(yystr,strlen(yystr) ,yyscanner); +} + +/** Setup the input buffer state to scan the given bytes. The next call to csslex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE css_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n, i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) cssalloc(n ,yyscanner ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in css_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = css_scan_buffer(buf,n ,yyscanner); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in css_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ +do \ +{ \ +/* Undo effects of setting up yytext. */ \ +int yyless_macro_arg = (n); \ +YY_LESS_LINENO(yyless_macro_arg);\ +yytext[yyleng] = yyg->yy_hold_char; \ +yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ +yyg->yy_hold_char = *yyg->yy_c_buf_p; \ +*yyg->yy_c_buf_p = '\0'; \ +yyleng = yyless_macro_arg; \ +} \ +while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the user-defined data for this scanner. + * @param yyscanner The scanner object. + */ +YY_EXTRA_TYPE cssget_extra (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyextra; +} + +/** Get the current line number. + * @param yyscanner The scanner object. + */ +int cssget_lineno (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yylineno; +} + +/** Get the current column number. + * @param yyscanner The scanner object. + */ +int cssget_column (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yycolumn; +} + +/** Get the input stream. + * @param yyscanner The scanner object. + */ +FILE *cssget_in (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyin; +} + +/** Get the output stream. + * @param yyscanner The scanner object. + */ +FILE *cssget_out (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyout; +} + +/** Get the length of the current token. + * @param yyscanner The scanner object. + */ +yy_size_t cssget_leng (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyleng; +} + +/** Get the current token. + * @param yyscanner The scanner object. + */ + +char *cssget_text (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yytext; +} + +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * @param yyscanner The scanner object. + */ +void cssset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyextra = user_defined ; +} + +/** Set the current line number. + * @param line_number + * @param yyscanner The scanner object. + */ +void cssset_lineno (int line_number , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "cssset_lineno called with no buffer" , yyscanner); + + yylineno = line_number; +} + +/** Set the current column. + * @param line_number + * @param yyscanner The scanner object. + */ +void cssset_column (int column_no , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "cssset_column called with no buffer" , yyscanner); + + yycolumn = column_no; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * @param yyscanner The scanner object. + * @see css_switch_to_buffer + */ +void cssset_in (FILE * in_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyin = in_str ; +} + +void cssset_out (FILE * out_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyout = out_str ; +} + +int cssget_debug (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yy_flex_debug; +} + +void cssset_debug (int bdebug , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yy_flex_debug = bdebug ; +} + +/* Accessor methods for yylval and yylloc */ + +/* User-visible API */ + +/* csslex_init is special because it creates the scanner itself, so it is + * the ONLY reentrant function that doesn't take the scanner as the last argument. + * That's why we explicitly handle the declaration, instead of using our macros. + */ + +int csslex_init(yyscan_t* ptr_yy_globals) + +{ + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) cssalloc ( sizeof( struct yyguts_t ), NULL ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + return yy_init_globals ( *ptr_yy_globals ); +} + +/* csslex_init_extra has the same functionality as csslex_init, but follows the + * convention of taking the scanner as the last argument. Note however, that + * this is a *pointer* to a scanner, as it will be allocated by this call (and + * is the reason, too, why this function also must handle its own declaration). + * The user defined value in the first argument will be available to cssalloc in + * the yyextra field. + */ + +int csslex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) + +{ + struct yyguts_t dummy_yyguts; + + cssset_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) cssalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in + yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + cssset_extra (yy_user_defined, *ptr_yy_globals); + + return yy_init_globals ( *ptr_yy_globals ); +} + +static int yy_init_globals (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from csslex_destroy(), so don't allocate here. + */ + + yyg->yy_buffer_stack = 0; + yyg->yy_buffer_stack_top = 0; + yyg->yy_buffer_stack_max = 0; + yyg->yy_c_buf_p = (char *) 0; + yyg->yy_init = 0; + yyg->yy_start = 0; + + yyg->yy_start_stack_ptr = 0; + yyg->yy_start_stack_depth = 0; + yyg->yy_start_stack = NULL; + + /* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * csslex_init() + */ + return 0; +} + +/* csslex_destroy is for both reentrant and non-reentrant scanners. */ +int csslex_destroy (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + css_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); + YY_CURRENT_BUFFER_LVALUE = NULL; + csspop_buffer_state(yyscanner); + } + + /* Destroy the stack itself. */ + cssfree(yyg->yy_buffer_stack ,yyscanner); + yyg->yy_buffer_stack = NULL; + + /* Destroy the start condition stack. */ + cssfree(yyg->yy_start_stack ,yyscanner ); + yyg->yy_start_stack = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * csslex() is called, initialization will occur. */ + yy_init_globals( yyscanner); + + /* Destroy the main struct (reentrant only). */ + cssfree ( yyscanner , yyscanner ); + yyscanner = NULL; + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *cssalloc (yy_size_t size , yyscan_t yyscanner) +{ + return (void *) malloc( size ); +} + +void *cssrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void cssfree (void * ptr , yyscan_t yyscanner) +{ + free( (char *) ptr ); /* see cssrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" diff --git a/HTMLKit/CSSLexer.h b/HTMLKit/CSSLexer.h new file mode 100644 index 0000000..7e85d1d --- /dev/null +++ b/HTMLKit/CSSLexer.h @@ -0,0 +1,329 @@ +#ifndef cssHEADER_H +#define cssHEADER_H 1 +#define cssIN_HEADER 1 + +#line 6 "CSSLexer.h" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +typedef uint64_t flex_uint64_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state +{ + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +}; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +void cssrestart (FILE *input_file ,yyscan_t yyscanner ); +void css_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE css_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void css_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void css_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void csspush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void csspop_buffer_state (yyscan_t yyscanner ); + +YY_BUFFER_STATE css_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE css_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE css_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); + +void *cssalloc (yy_size_t ,yyscan_t yyscanner ); +void *cssrealloc (void *,yy_size_t ,yyscan_t yyscanner ); +void cssfree (void * ,yyscan_t yyscanner ); + +#define csswrap(n) 1 +#define YY_SKIP_YYWRAP + +#define yytext_ptr yytext_r + +#ifdef YY_HEADER_EXPORT_START_CONDITIONS +#define INITIAL 0 + +#endif + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +int csslex_init (yyscan_t* scanner); + +int csslex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int csslex_destroy (yyscan_t yyscanner ); + +int cssget_debug (yyscan_t yyscanner ); + +void cssset_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE cssget_extra (yyscan_t yyscanner ); + +void cssset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *cssget_in (yyscan_t yyscanner ); + +void cssset_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *cssget_out (yyscan_t yyscanner ); + +void cssset_out (FILE * out_str ,yyscan_t yyscanner ); + +yy_size_t cssget_leng (yyscan_t yyscanner ); + +char *cssget_text (yyscan_t yyscanner ); + +int cssget_lineno (yyscan_t yyscanner ); + +void cssset_lineno (int line_number ,yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int csswrap (yyscan_t yyscanner ); +#else +extern int csswrap (yyscan_t yyscanner ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int csslex (yyscan_t yyscanner); + +#define YY_DECL int csslex (yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +#line 328 "CSSLexer.h" +#undef cssIN_HEADER +#endif /* cssHEADER_H */ diff --git a/HTMLKit/CSSTokenizer.h b/HTMLKit/CSSTokenizer.h new file mode 100644 index 0000000..2913093 --- /dev/null +++ b/HTMLKit/CSSTokenizer.h @@ -0,0 +1,44 @@ +// +// CSSTokenizer.h +// HTMLKit +// +// Created by Iska on 07/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import + +typedef NS_ENUM(int, CSSToken) +{ + CSSTokenSpace = 1, + CSSTokenIncludes, + CSSTokenDashMatch, + CSSTokenPrefixMatch, + CSSTokenSuffixMatch, + CSSTokenSubstringMatch, + CSSTokenIdent, + CSSTokenString, + CSSTokenFunction, + CSSTokenNumber, + CSSTokenHash, + CSSTokenPlus, + CSSTokenGreater, + CSSTokenComma, + CSSTokenTilde, + CSSTokenNot, + CSSTokenAtKeyword, + CSSTokenInvalid, + CSSTokenPercentage, + CSSTokenDimension, + CSSTokenCDO, + CSSTokenCDC +}; + +@interface CSSTokenizer : NSObject + +- (instancetype)initWithString:(NSString *)string; + +- (CSSToken)nextToken; +- (NSString *)currentTokenText; + +@end diff --git a/HTMLKit/CSSTokenizer.m b/HTMLKit/CSSTokenizer.m new file mode 100644 index 0000000..edb87b6 --- /dev/null +++ b/HTMLKit/CSSTokenizer.m @@ -0,0 +1,56 @@ +// +// CSSTokenizer.m +// HTMLKit +// +// Created by Iska on 07/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "CSSTokenizer.h" +#import "CSSLexer.h" + +@interface CSSTokenizer () +{ + yyscan_t _scanner; + CSSToken _currentToken; + size_t _currentPosition; + size_t _tokenPosition; +} +@end + +@implementation CSSTokenizer + +- (instancetype)initWithString:(NSString *)string +{ + self = [super init]; + if (self) { + csslex_init(&_scanner); + css_scan_string(string.UTF8String, _scanner); + _currentToken = 0; + _currentPosition = 0; + _tokenPosition = 0; + } + return self; +} + +- (CSSToken)nextToken +{ + _currentToken = csslex(_scanner); + _tokenPosition += _currentPosition; + _currentPosition += cssget_leng(_scanner); + + return _currentToken; +} + +- (NSString *)currentTokenText +{ + if (_currentToken == 0) { + return nil; + } + + char *content = NULL; + content = cssget_text(_scanner); + return [NSString stringWithCString:content encoding:NSUTF8StringEncoding]; +} + +@end From 81a20f0333ce233cfaac14224919387a1b5545d4 Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 14 May 2015 16:15:41 +0200 Subject: [PATCH 002/103] Add HTML Node Filter protocol https://dom.spec.whatwg.org/#interface-nodefilter --- HTMLKit.xcodeproj/project.pbxproj | 4 ++++ HTMLKit/HTMLNodeFilter.h | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 HTMLKit/HTMLNodeFilter.h diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 3eed2ab..2eff2b1 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -82,6 +82,7 @@ 624AC90619FBFEA000BD3C4A /* html5lib-tests in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90419FBFE8A00BD3C4A /* html5lib-tests */; }; 624AC90E19FC702E00BD3C4A /* HTML Standard.html in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90D19FC702E00BD3C4A /* HTML Standard.html */; }; 624AC90F19FC702E00BD3C4A /* HTML Standard.html in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90D19FC702E00BD3C4A /* HTML Standard.html */; }; + 624B28BC1B03DAB70048D328 /* HTMLNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28BB1B03DAB70048D328 /* HTMLNodeFilter.h */; }; 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 */; }; @@ -226,6 +227,7 @@ 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitTokenizerTests.m; sourceTree = ""; }; 624AC90419FBFE8A00BD3C4A /* html5lib-tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "html5lib-tests"; sourceTree = ""; }; 624AC90D19FC702E00BD3C4A /* HTML Standard.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "HTML Standard.html"; sourceTree = ""; }; + 624B28BB1B03DAB70048D328 /* HTMLNodeFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNodeFilter.h; 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 = ""; }; @@ -337,6 +339,7 @@ 623719441AA1472B002E03C8 /* Nodes */ = { isa = PBXGroup; children = ( + 624B28BB1B03DAB70048D328 /* HTMLNodeFilter.h */, 623719431AA12EE8002E03C8 /* HTMLQuirksMode.h */, 62362A3F1A9FDE8A00301989 /* HTMLNodes.h */, 6234584C1A9D2FA4009BD491 /* HTMLNode.h */, @@ -564,6 +567,7 @@ 62D89DB11AE7081600B6243D /* HTMLTokenizerStates.h in Headers */, 62D89DB21AE7081600B6243D /* HTMLTokenizerCharacters.h in Headers */, 62D89DB31AE7081600B6243D /* HTMLNamespaces.h in Headers */, + 624B28BC1B03DAB70048D328 /* HTMLNodeFilter.h in Headers */, 62D89DB41AE7081600B6243D /* HTMLElementTypes.h in Headers */, 62D89DB51AE7081600B6243D /* HTMLElementAdjustment.h in Headers */, 62D89DB61AE7081600B6243D /* HTMLParserInsertionModes.h in Headers */, diff --git a/HTMLKit/HTMLNodeFilter.h b/HTMLKit/HTMLNodeFilter.h new file mode 100644 index 0000000..2bf2fc2 --- /dev/null +++ b/HTMLKit/HTMLNodeFilter.h @@ -0,0 +1,17 @@ +// +// HTMLNodeFilter.h +// HTMLKit +// +// Created by Iska on 13/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import + +@class HTMLNode; + +@protocol HTMLNodeFilter + +- (BOOL)acceptNode:(HTMLNode *)node; + +@end From c87076b470caa2833daf770740fd3fa450fe7089 Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 14 May 2015 16:19:31 +0200 Subject: [PATCH 003/103] Add a NSCharacterSet category for HTML Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace --- HTMLKit.xcodeproj/project.pbxproj | 10 ++++++++++ HTMLKit/NSCharacterSet+HTMLKit.h | 15 +++++++++++++++ HTMLKit/NSCharacterSet+HTMLKit.m | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 HTMLKit/NSCharacterSet+HTMLKit.h create mode 100644 HTMLKit/NSCharacterSet+HTMLKit.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 2eff2b1..17435a5 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -83,6 +83,9 @@ 624AC90E19FC702E00BD3C4A /* HTML Standard.html in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90D19FC702E00BD3C4A /* HTML Standard.html */; }; 624AC90F19FC702E00BD3C4A /* HTML Standard.html in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90D19FC702E00BD3C4A /* HTML Standard.html */; }; 624B28BC1B03DAB70048D328 /* HTMLNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28BB1B03DAB70048D328 /* HTMLNodeFilter.h */; }; + 624B28C41B04190D0048D328 /* NSCharacterSet+HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */; }; + 624B28C51B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */; }; + 624B28C61B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.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 */; }; @@ -228,6 +231,8 @@ 624AC90419FBFE8A00BD3C4A /* html5lib-tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "html5lib-tests"; sourceTree = ""; }; 624AC90D19FC702E00BD3C4A /* HTML Standard.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "HTML Standard.html"; sourceTree = ""; }; 624B28BB1B03DAB70048D328 /* HTMLNodeFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNodeFilter.h; sourceTree = ""; }; + 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSCharacterSet+HTMLKit.h"; sourceTree = ""; }; + 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSCharacterSet+HTMLKit.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 = ""; }; @@ -513,6 +518,8 @@ children = ( 6235CE991AA509430026937B /* NSString+HTMLKit.h */, 6235CE9A1AA509430026937B /* NSString+HTMLKit.m */, + 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */, + 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */, ); name = Categories; sourceTree = ""; @@ -587,6 +594,7 @@ 6279F87419E1808D00F12EE5 /* HTMLElement.h in Headers */, 62AE593F19F9907C0043F069 /* HTMLTagToken.h in Headers */, 623857911A9E772B003A45D9 /* HTMLDocument.h in Headers */, + 624B28C41B04190D0048D328 /* NSCharacterSet+HTMLKit.h in Headers */, 624493A619CCC54100BCDDF4 /* HTMLTokenizer.h in Headers */, 62AE593A19F97E1C0043F069 /* HTMLDOCTYPEToken.h in Headers */, 623424881AB467B200726190 /* HTMLOrderedDictionary.h in Headers */, @@ -767,6 +775,7 @@ 6238C9871AB8D6330006512E /* HTMLKitExceptions.m in Sources */, 62F873ED19E088C90062683C /* HTMLParser.m in Sources */, 623803A11AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */, + 624B28C61B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */, 6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */, 625A150A19C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */, 623857931A9E772B003A45D9 /* HTMLDocument.m in Sources */, @@ -821,6 +830,7 @@ 6238C9861AB8D6330006512E /* HTMLKitExceptions.m in Sources */, 62F873EC19E088C90062683C /* HTMLParser.m in Sources */, 623803A01AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */, + 624B28C51B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */, 6279F87519E1808D00F12EE5 /* HTMLElement.m in Sources */, 625A150919C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */, 623857921A9E772B003A45D9 /* HTMLDocument.m in Sources */, diff --git a/HTMLKit/NSCharacterSet+HTMLKit.h b/HTMLKit/NSCharacterSet+HTMLKit.h new file mode 100644 index 0000000..d987429 --- /dev/null +++ b/HTMLKit/NSCharacterSet+HTMLKit.h @@ -0,0 +1,15 @@ +// +// NSCharacterSet+HTMLKit.h +// HTMLKit +// +// Created by Iska on 14/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import + +@interface NSCharacterSet (HTMLKit) + ++ (instancetype)HTMLWhitespaceCharacterSet; + +@end diff --git a/HTMLKit/NSCharacterSet+HTMLKit.m b/HTMLKit/NSCharacterSet+HTMLKit.m new file mode 100644 index 0000000..78d4fb7 --- /dev/null +++ b/HTMLKit/NSCharacterSet+HTMLKit.m @@ -0,0 +1,18 @@ +// +// NSCharacterSet+HTMLKit.m +// HTMLKit +// +// Created by Iska on 14/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "NSCharacterSet+HTMLKit.h" + +@implementation NSCharacterSet (HTMLKit) + ++ (instancetype)HTMLWhitespaceCharacterSet +{ + return [NSCharacterSet characterSetWithCharactersInString:@" \t\n\r\f"]; +} + +@end From 7c58268dfd1dc455f0c930eae4d96ada3055d41e Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 14 May 2015 16:21:26 +0200 Subject: [PATCH 004/103] Add initial implementation for the CSS Selector base class --- HTMLKit.xcodeproj/project.pbxproj | 10 +++++++++ HTMLKit/CSSSelector.h | 20 +++++++++++++++++ HTMLKit/CSSSelector.m | 37 +++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 HTMLKit/CSSSelector.h create mode 100644 HTMLKit/CSSSelector.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 17435a5..868043e 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 62079BE91AF56F1E00D3B402 /* CSSSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62079BE71AF56F1E00D3B402 /* CSSSelector.h */; }; + 62079BEA1AF56F1E00D3B402 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62079BE81AF56F1E00D3B402 /* CSSSelector.m */; }; + 62079BEB1AF56F1E00D3B402 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62079BE81AF56F1E00D3B402 /* CSSSelector.m */; }; 620802021AFD939200F2962F /* CSSTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 623F13A81AFC11D900C90BF4 /* CSSTokenizer.h */; }; 623406E11ADB04F9004677A3 /* HTMLTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 623406DF1ADB04F9004677A3 /* HTMLTemplate.h */; }; 623406E21ADB04F9004677A3 /* HTMLTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E01ADB04F9004677A3 /* HTMLTemplate.m */; }; @@ -177,6 +180,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 62079BE71AF56F1E00D3B402 /* CSSSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelector.h; sourceTree = ""; }; + 62079BE81AF56F1E00D3B402 /* CSSSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelector.m; sourceTree = ""; }; 6223211D1A969B9300BACED5 /* HTMLElementTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLElementTypes.h; sourceTree = ""; }; 623406DF1ADB04F9004677A3 /* HTMLTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLTemplate.h; sourceTree = ""; }; 623406E01ADB04F9004677A3 /* HTMLTemplate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTemplate.m; sourceTree = ""; }; @@ -326,6 +331,8 @@ 623F13A91AFC11D900C90BF4 /* CSSTokenizer.m */, 62491C461AFE51F100ACF9E2 /* CSSLexer.h */, 62491C451AFE51F100ACF9E2 /* CSSLexer.c */, + 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, + 62079BE81AF56F1E00D3B402 /* CSSSelector.m */, ); name = Selectors; sourceTree = ""; @@ -572,6 +579,7 @@ files = ( 6235CE9B1AA509430026937B /* NSString+HTMLKit.h in Headers */, 62D89DB11AE7081600B6243D /* HTMLTokenizerStates.h in Headers */, + 62079BE91AF56F1E00D3B402 /* CSSSelector.h in Headers */, 62D89DB21AE7081600B6243D /* HTMLTokenizerCharacters.h in Headers */, 62D89DB31AE7081600B6243D /* HTMLNamespaces.h in Headers */, 624B28BC1B03DAB70048D328 /* HTMLNodeFilter.h in Headers */, @@ -785,6 +793,7 @@ 62491C481AFE51F100ACF9E2 /* CSSLexer.c in Sources */, 625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */, 623857981A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, + 62079BEB1AF56F1E00D3B402 /* CSSSelector.m in Sources */, 62AE594B19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, 623458501A9D2FA4009BD491 /* HTMLNode.m in Sources */, 62F31FDF19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */, @@ -840,6 +849,7 @@ 62491C471AFE51F100ACF9E2 /* CSSLexer.c in Sources */, 625A150219C783DE00AD0C32 /* HTMLKit.m in Sources */, 623857971A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, + 62079BEA1AF56F1E00D3B402 /* CSSSelector.m in Sources */, 62AE594A19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, 6234584F1A9D2FA4009BD491 /* HTMLNode.m in Sources */, 62F31FDE19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */, diff --git a/HTMLKit/CSSSelector.h b/HTMLKit/CSSSelector.h new file mode 100644 index 0000000..8416102 --- /dev/null +++ b/HTMLKit/CSSSelector.h @@ -0,0 +1,20 @@ +// +// HTMLSelector.h +// HTMLKit +// +// Created by Iska on 02/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import +#import "HTMLNodeFilter.h" + +@class HTMLElement; + +@interface CSSSelector : NSObject + ++ (instancetype)selectorWithSting:(NSString *)string; + +- (BOOL)matchesElement:(HTMLElement *)element; + +@end diff --git a/HTMLKit/CSSSelector.m b/HTMLKit/CSSSelector.m new file mode 100644 index 0000000..797d455 --- /dev/null +++ b/HTMLKit/CSSSelector.m @@ -0,0 +1,37 @@ +// +// HTMLSelector.m +// HTMLKit +// +// Created by Iska on 02/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelector.h" +#import "HTMLNode.h" +#import "HTMLElement.h" + +@interface CSSSelector () +{ + NSString *_string; +} +@end + +@implementation CSSSelector + ++ (instancetype)selectorWithSting:(NSString *)string +{ + return nil; +} + +- (BOOL)acceptNode:(HTMLNode *)node +{ + return node.type == HTMLNodeElement && [self matchesElement:(HTMLElement *)node]; +} + +- (BOOL)matchesElement:(HTMLElement *)element +{ + [self doesNotRecognizeSelector:_cmd]; + return NO; +} + +@end From acec99ffead77b874977bf5ef3062f9675c91387 Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 14 May 2015 16:23:23 +0200 Subject: [PATCH 005/103] Add implementation for a CSS Type Selector Matches an Element with the given tag name or all Elements (universal selector) http://www.w3.org/TR/css3-selectors/#type-selectors --- HTMLKit.xcodeproj/project.pbxproj | 10 +++++++ HTMLKit/CSSTypeSelector.h | 19 +++++++++++++ HTMLKit/CSSTypeSelector.m | 45 +++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 HTMLKit/CSSTypeSelector.h create mode 100644 HTMLKit/CSSTypeSelector.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 868043e..aea30ae 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -85,6 +85,9 @@ 624AC90619FBFEA000BD3C4A /* html5lib-tests in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90419FBFE8A00BD3C4A /* html5lib-tests */; }; 624AC90E19FC702E00BD3C4A /* HTML Standard.html in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90D19FC702E00BD3C4A /* HTML Standard.html */; }; 624AC90F19FC702E00BD3C4A /* HTML Standard.html in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90D19FC702E00BD3C4A /* HTML Standard.html */; }; + 624B28B81B03DA820048D328 /* CSSTypeSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28B61B03DA820048D328 /* CSSTypeSelector.h */; }; + 624B28B91B03DA820048D328 /* CSSTypeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28B71B03DA820048D328 /* CSSTypeSelector.m */; }; + 624B28BA1B03DA820048D328 /* CSSTypeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28B71B03DA820048D328 /* CSSTypeSelector.m */; }; 624B28BC1B03DAB70048D328 /* HTMLNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28BB1B03DAB70048D328 /* HTMLNodeFilter.h */; }; 624B28C41B04190D0048D328 /* NSCharacterSet+HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */; }; 624B28C51B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */; }; @@ -235,6 +238,8 @@ 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitTokenizerTests.m; sourceTree = ""; }; 624AC90419FBFE8A00BD3C4A /* html5lib-tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "html5lib-tests"; sourceTree = ""; }; 624AC90D19FC702E00BD3C4A /* HTML Standard.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "HTML Standard.html"; sourceTree = ""; }; + 624B28B61B03DA820048D328 /* CSSTypeSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSTypeSelector.h; sourceTree = ""; }; + 624B28B71B03DA820048D328 /* CSSTypeSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTypeSelector.m; sourceTree = ""; }; 624B28BB1B03DAB70048D328 /* HTMLNodeFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNodeFilter.h; sourceTree = ""; }; 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSCharacterSet+HTMLKit.h"; sourceTree = ""; }; 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSCharacterSet+HTMLKit.m"; sourceTree = ""; }; @@ -333,6 +338,8 @@ 62491C451AFE51F100ACF9E2 /* CSSLexer.c */, 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, 62079BE81AF56F1E00D3B402 /* CSSSelector.m */, + 624B28B61B03DA820048D328 /* CSSTypeSelector.h */, + 624B28B71B03DA820048D328 /* CSSTypeSelector.m */, ); name = Selectors; sourceTree = ""; @@ -596,6 +603,7 @@ 6235CEA01AA5170A0026937B /* HTMLMarker.h in Headers */, 62F31FDD19E9DCCF007F0657 /* HTMLTokenizerEntities.h in Headers */, 623406E11ADB04F9004677A3 /* HTMLTemplate.h in Headers */, + 624B28B81B03DA820048D328 /* CSSTypeSelector.h in Headers */, 6234BEEE1AABBF1400DEB15F /* HTMLStackOfOpenElements.h in Headers */, 6238C9851AB8D6330006512E /* HTMLKitExceptions.h in Headers */, 6238039F1AB63A8C008A53D0 /* HTMLEOFToken.h in Headers */, @@ -791,6 +799,7 @@ 624493A819CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, 623F13AC1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, 62491C481AFE51F100ACF9E2 /* CSSLexer.c in Sources */, + 624B28BA1B03DA820048D328 /* CSSTypeSelector.m in Sources */, 625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */, 623857981A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, 62079BEB1AF56F1E00D3B402 /* CSSSelector.m in Sources */, @@ -847,6 +856,7 @@ 624493A719CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, 623F13AB1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, 62491C471AFE51F100ACF9E2 /* CSSLexer.c in Sources */, + 624B28B91B03DA820048D328 /* CSSTypeSelector.m in Sources */, 625A150219C783DE00AD0C32 /* HTMLKit.m in Sources */, 623857971A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, 62079BEA1AF56F1E00D3B402 /* CSSSelector.m in Sources */, diff --git a/HTMLKit/CSSTypeSelector.h b/HTMLKit/CSSTypeSelector.h new file mode 100644 index 0000000..6cd2e16 --- /dev/null +++ b/HTMLKit/CSSTypeSelector.h @@ -0,0 +1,19 @@ +// +// CSSTypeSelector.h +// HTMLKit +// +// Created by Iska on 13/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import +#import "CSSSelector.h" + +@interface CSSTypeSelector : CSSSelector + +@property (nonatomic, copy) NSString *type; + ++ (instancetype)universalSelector; +- (instancetype)initWithType:(NSString *)type; + +@end diff --git a/HTMLKit/CSSTypeSelector.m b/HTMLKit/CSSTypeSelector.m new file mode 100644 index 0000000..dd916bb --- /dev/null +++ b/HTMLKit/CSSTypeSelector.m @@ -0,0 +1,45 @@ +// +// CSSTypeSelector.m +// HTMLKit +// +// Created by Iska on 13/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "CSSTypeSelector.h" +#import "HTMLElement.h" +#import "NSString+HTMLKit.h" + +@interface CSSTypeSelector () +{ + NSString *_type; +} +@end + +@implementation CSSTypeSelector + ++ (instancetype)universalSelector +{ + return [[self alloc] initWithType:@"*"]; +} + +- (instancetype)initWithType:(NSString *)type +{ + self = [super init]; + if (self) { + self.type = [type copy]; + } + return self; +} + +- (BOOL)matchesElement:(HTMLElement *)element +{ + return [_type isEqualToString:@"*"] || [_type isEqualToStringIgnoringCase:element.tagName]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.type]; +} + +@end From 3cb5ed9a420d651847bc48af0a6fba0fe07ae6ed Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 14 May 2015 16:32:30 +0200 Subject: [PATCH 006/103] Add implementation for a CSS Attribute Selector http://www.w3.org/TR/css3-selectors/#attribute-selectors --- HTMLKit.xcodeproj/project.pbxproj | 10 ++++ HTMLKit/CSSAttributeSelector.h | 33 ++++++++++++ HTMLKit/CSSAttributeSelector.m | 89 +++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 HTMLKit/CSSAttributeSelector.h create mode 100644 HTMLKit/CSSAttributeSelector.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index aea30ae..42b9967 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -89,6 +89,9 @@ 624B28B91B03DA820048D328 /* CSSTypeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28B71B03DA820048D328 /* CSSTypeSelector.m */; }; 624B28BA1B03DA820048D328 /* CSSTypeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28B71B03DA820048D328 /* CSSTypeSelector.m */; }; 624B28BC1B03DAB70048D328 /* HTMLNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28BB1B03DAB70048D328 /* HTMLNodeFilter.h */; }; + 624B28BF1B0413200048D328 /* CSSAttributeSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28BD1B0413200048D328 /* CSSAttributeSelector.h */; }; + 624B28C01B0413200048D328 /* CSSAttributeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */; }; + 624B28C11B0413200048D328 /* CSSAttributeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */; }; 624B28C41B04190D0048D328 /* NSCharacterSet+HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */; }; 624B28C51B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */; }; 624B28C61B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */; }; @@ -241,6 +244,8 @@ 624B28B61B03DA820048D328 /* CSSTypeSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSTypeSelector.h; sourceTree = ""; }; 624B28B71B03DA820048D328 /* CSSTypeSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTypeSelector.m; sourceTree = ""; }; 624B28BB1B03DAB70048D328 /* HTMLNodeFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNodeFilter.h; sourceTree = ""; }; + 624B28BD1B0413200048D328 /* CSSAttributeSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSAttributeSelector.h; sourceTree = ""; }; + 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSAttributeSelector.m; sourceTree = ""; }; 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSCharacterSet+HTMLKit.h"; sourceTree = ""; }; 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSCharacterSet+HTMLKit.m"; sourceTree = ""; }; 624B9FB11AE0313300646C4C /* HTMLKitStringCategoryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitStringCategoryTests.m; sourceTree = ""; }; @@ -340,6 +345,8 @@ 62079BE81AF56F1E00D3B402 /* CSSSelector.m */, 624B28B61B03DA820048D328 /* CSSTypeSelector.h */, 624B28B71B03DA820048D328 /* CSSTypeSelector.m */, + 624B28BD1B0413200048D328 /* CSSAttributeSelector.h */, + 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */, ); name = Selectors; sourceTree = ""; @@ -590,6 +597,7 @@ 62D89DB21AE7081600B6243D /* HTMLTokenizerCharacters.h in Headers */, 62D89DB31AE7081600B6243D /* HTMLNamespaces.h in Headers */, 624B28BC1B03DAB70048D328 /* HTMLNodeFilter.h in Headers */, + 624B28BF1B0413200048D328 /* CSSAttributeSelector.h in Headers */, 62D89DB41AE7081600B6243D /* HTMLElementTypes.h in Headers */, 62D89DB51AE7081600B6243D /* HTMLElementAdjustment.h in Headers */, 62D89DB61AE7081600B6243D /* HTMLParserInsertionModes.h in Headers */, @@ -805,6 +813,7 @@ 62079BEB1AF56F1E00D3B402 /* CSSSelector.m in Sources */, 62AE594B19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, 623458501A9D2FA4009BD491 /* HTMLNode.m in Sources */, + 624B28C11B0413200048D328 /* CSSAttributeSelector.m in Sources */, 62F31FDF19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */, 62AE593719F97D880043F069 /* HTMLParseErrorToken.m in Sources */, ); @@ -862,6 +871,7 @@ 62079BEA1AF56F1E00D3B402 /* CSSSelector.m in Sources */, 62AE594A19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, 6234584F1A9D2FA4009BD491 /* HTMLNode.m in Sources */, + 624B28C01B0413200048D328 /* CSSAttributeSelector.m in Sources */, 62F31FDE19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */, 62AE593619F97D880043F069 /* HTMLParseErrorToken.m in Sources */, ); diff --git a/HTMLKit/CSSAttributeSelector.h b/HTMLKit/CSSAttributeSelector.h new file mode 100644 index 0000000..26aa258 --- /dev/null +++ b/HTMLKit/CSSAttributeSelector.h @@ -0,0 +1,33 @@ +// +// CSSAttributeSelector.h +// HTMLKit +// +// Created by Iska on 14/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import +#import "CSSSelector.h" + +typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType) +{ + CSSAttributeSelectorExists, + CSSAttributeSelectorExactMatch, + CSSAttributeSelectorIncludes, + CSSAttributeSelectorBegins, + CSSAttributeSelectorEnds, + CSSAttributeSelectorContains, + CSSAttributeSelectorHyphen +}; + +@interface CSSAttributeSelector : CSSSelector + +@property (nonatomic, assign) CSSAttributeSelectorType type; +@property (nonatomic, copy) NSString *name; +@property (nonatomic, copy) NSString *value; + +- (instancetype)initWithType:(CSSAttributeSelectorType)type + attributeName:(NSString *)name + attrbiuteValue:(NSString *)value; + +@end diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m new file mode 100644 index 0000000..c9cc1c0 --- /dev/null +++ b/HTMLKit/CSSAttributeSelector.m @@ -0,0 +1,89 @@ +// +// CSSAttributeSelector.m +// HTMLKit +// +// Created by Iska on 14/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "CSSAttributeSelector.h" +#import "HTMLElement.h" +#import "NSCharacterSet+HTMLKit.h" + +@interface CSSAttributeSelector () +{ + CSSAttributeSelectorType _type; + NSString *_name; + NSString *_value; +} +@end + +@implementation CSSAttributeSelector + +- (instancetype)initWithType:(CSSAttributeSelectorType)type + attributeName:(NSString *)name + attrbiuteValue:(NSString *)value +{ + self = [super init]; + if (self) { + self.type = type; + self.name = [name copy]; + self.value = [value copy]; + } + return self; +} + +- (BOOL)matchesElement:(HTMLElement *)element +{ + switch (_type) { + case CSSAttributeSelectorExists: + { + return !!element[_name]; + } + case CSSAttributeSelectorExactMatch: + { + return [element[_name] isEqualToString:_value]; + } + case CSSAttributeSelectorIncludes: + { + NSArray *components = [element[_name] componentsSeparatedByCharactersInSet:[NSCharacterSet HTMLWhitespaceCharacterSet]]; + return [components containsObject:_value]; + } + case CSSAttributeSelectorBegins: + { + return [element[_name] hasPrefix:_value]; + } + case CSSAttributeSelectorEnds: + { + return [element[_name] hasSuffix:_value]; + } + case CSSAttributeSelectorContains: + { + return [element[_name] containsString:_value]; + } + case CSSAttributeSelectorHyphen: + { + return [element[_name] isEqualToString:_value] || [element[_name] hasSuffix:[_value stringByAppendingString:@"-"]]; + } + default: + return NO; + } +} + +- (NSString *)description +{ + if (self.type == CSSAttributeSelectorExists) { + return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.name]; + } + + NSString *matcher = @{@(CSSAttributeSelectorExactMatch): @"=", + @(CSSAttributeSelectorIncludes): @"~=", + @(CSSAttributeSelectorBegins): @"^=", + @(CSSAttributeSelectorEnds): @"$=", + @(CSSAttributeSelectorContains): @"*=", + @(CSSAttributeSelectorHyphen): @"|="}[@(self.type)]; + + return [NSString stringWithFormat:@"<%@: %p '%@' %@ '%@'>", self.class, self, self.name, matcher, self.value]; +} + +@end From c401c3ca2c757279c31a6b4c261559694f70a92d Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 14 May 2015 17:09:17 +0200 Subject: [PATCH 007/103] Add umbrella header for all CSS Selectors --- HTMLKit.xcodeproj/project.pbxproj | 2 ++ HTMLKit/CSSSelectors.h | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 HTMLKit/CSSSelectors.h diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 42b9967..f1cd70e 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -237,6 +237,7 @@ 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLToken.m; sourceTree = ""; }; 62491C451AFE51F100ACF9E2 /* CSSLexer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CSSLexer.c; sourceTree = ""; }; 62491C461AFE51F100ACF9E2 /* CSSLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSLexer.h; sourceTree = ""; }; + 624AB3151B04EA4200F3830D /* CSSSelectors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSSelectors.h; sourceTree = ""; }; 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokens.h; sourceTree = ""; }; 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitTokenizerTests.m; sourceTree = ""; }; 624AC90419FBFE8A00BD3C4A /* html5lib-tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "html5lib-tests"; sourceTree = ""; }; @@ -337,6 +338,7 @@ 62079BE61AF5656600D3B402 /* Selectors */ = { isa = PBXGroup; children = ( + 624AB3151B04EA4200F3830D /* CSSSelectors.h */, 623F13A81AFC11D900C90BF4 /* CSSTokenizer.h */, 623F13A91AFC11D900C90BF4 /* CSSTokenizer.m */, 62491C461AFE51F100ACF9E2 /* CSSLexer.h */, diff --git a/HTMLKit/CSSSelectors.h b/HTMLKit/CSSSelectors.h new file mode 100644 index 0000000..fd583d6 --- /dev/null +++ b/HTMLKit/CSSSelectors.h @@ -0,0 +1,13 @@ +// +// CSSSelectors.h +// HTMLKit +// +// Created by Iska on 14/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#ifndef HTMLKit_CSSSelectors_h +#define HTMLKit_CSSSelectors_h + + +#endif From 745d0f72a70da66dda1001bd3693715230f779dd Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 14 May 2015 21:15:39 +0200 Subject: [PATCH 008/103] Add convenience methods to create Class & ID Attribute Selectors http://www.w3.org/TR/css3-selectors/#class-html http://www.w3.org/TR/css3-selectors/#id-selectors --- HTMLKit/CSSAttributeSelector.h | 3 +++ HTMLKit/CSSAttributeSelector.m | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/HTMLKit/CSSAttributeSelector.h b/HTMLKit/CSSAttributeSelector.h index 26aa258..812e29e 100644 --- a/HTMLKit/CSSAttributeSelector.h +++ b/HTMLKit/CSSAttributeSelector.h @@ -26,6 +26,9 @@ typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType) @property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSString *value; ++ (instancetype)selectorForClass:(NSString *)className; ++ (instancetype)selectorForId:(NSString *)elementId; + - (instancetype)initWithType:(CSSAttributeSelectorType)type attributeName:(NSString *)name attrbiuteValue:(NSString *)value; diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index c9cc1c0..498f037 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -20,6 +20,16 @@ @implementation CSSAttributeSelector ++ (instancetype)selectorForClass:(NSString *)className +{ + return [[self alloc] initWithType:CSSAttributeSelectorIncludes attributeName:@"class" attrbiuteValue:className]; +} + ++ (instancetype)selectorForId:(NSString *)elementId +{ + return [[self alloc] initWithType:CSSAttributeSelectorExactMatch attributeName:@"id" attrbiuteValue:elementId]; +} + - (instancetype)initWithType:(CSSAttributeSelectorType)type attributeName:(NSString *)name attrbiuteValue:(NSString *)value From a2d9e65f0e04e54f6d2c94ac77d50afacbaab25a Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 14 May 2015 21:16:29 +0200 Subject: [PATCH 009/103] Fix Attribute Selector for the Hyphen-case Check for prefix instead of suffix with "-" --- HTMLKit/CSSAttributeSelector.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index 498f037..ca93b23 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -73,7 +73,7 @@ } case CSSAttributeSelectorHyphen: { - return [element[_name] isEqualToString:_value] || [element[_name] hasSuffix:[_value stringByAppendingString:@"-"]]; + return [element[_name] isEqualToString:_value] || [element[_name] hasPrefix:[_value stringByAppendingString:@"-"]]; } default: return NO; From 221b085fe5bdf31a1bbbbb497ce8da11264477c6 Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 14 May 2015 21:18:55 +0200 Subject: [PATCH 010/103] Add tests for the Type & Attribute selectors --- HTMLKit.xcodeproj/project.pbxproj | 12 ++ HTMLKit/CSSSelectors.h | 8 +- HTMLKitTests/CSSAttributeSelectorTests.m | 210 +++++++++++++++++++++++ HTMLKitTests/CSSTypeSelectorTests.m | 51 ++++++ 4 files changed, 276 insertions(+), 5 deletions(-) create mode 100644 HTMLKitTests/CSSAttributeSelectorTests.m create mode 100644 HTMLKitTests/CSSTypeSelectorTests.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index f1cd70e..f4e0e6f 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -78,6 +78,10 @@ 62491C471AFE51F100ACF9E2 /* CSSLexer.c in Sources */ = {isa = PBXBuildFile; fileRef = 62491C451AFE51F100ACF9E2 /* CSSLexer.c */; }; 62491C481AFE51F100ACF9E2 /* CSSLexer.c in Sources */ = {isa = PBXBuildFile; fileRef = 62491C451AFE51F100ACF9E2 /* CSSLexer.c */; }; 62491C491AFE51F100ACF9E2 /* CSSLexer.h in Headers */ = {isa = PBXBuildFile; fileRef = 62491C461AFE51F100ACF9E2 /* CSSLexer.h */; }; + 624AB3171B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; + 624AB3181B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; + 624AB31A1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; + 624AB31B1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; 624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */; }; 624AC90119FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; 624AC90219FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; @@ -238,6 +242,8 @@ 62491C451AFE51F100ACF9E2 /* CSSLexer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CSSLexer.c; sourceTree = ""; }; 62491C461AFE51F100ACF9E2 /* CSSLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSLexer.h; sourceTree = ""; }; 624AB3151B04EA4200F3830D /* CSSSelectors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSSelectors.h; sourceTree = ""; }; + 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTypeSelectorTests.m; sourceTree = ""; }; + 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSAttributeSelectorTests.m; sourceTree = ""; }; 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokens.h; sourceTree = ""; }; 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitTokenizerTests.m; sourceTree = ""; }; 624AC90419FBFE8A00BD3C4A /* html5lib-tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "html5lib-tests"; sourceTree = ""; }; @@ -501,6 +507,8 @@ 624B9FB71AE072CB00646C4C /* Nodes */, 624B9FB81AE072D500646C4C /* Categories */, 625A14CB19C7829400AD0C32 /* Supporting Files */, + 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */, + 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */, ); name = Tests; path = HTMLKitTests; @@ -828,7 +836,9 @@ 6239755B1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */, 623CAF9E1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */, 62EC7AE71AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */, + 624AB31B1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */, 624B9FB61AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m in Sources */, + 624AB3181B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */, 6236738F1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m in Sources */, 624AC90219FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */, 624B9FB31AE0313300646C4C /* HTMLKitStringCategoryTests.m in Sources */, @@ -886,7 +896,9 @@ 6239755A1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */, 623CAF9D1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */, 62EC7AE61AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */, + 624AB31A1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */, 624B9FB51AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m in Sources */, + 624AB3171B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */, 6236738E1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m in Sources */, 624AC90119FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */, 624B9FB21AE0313300646C4C /* HTMLKitStringCategoryTests.m in Sources */, diff --git a/HTMLKit/CSSSelectors.h b/HTMLKit/CSSSelectors.h index fd583d6..30d21f3 100644 --- a/HTMLKit/CSSSelectors.h +++ b/HTMLKit/CSSSelectors.h @@ -6,8 +6,6 @@ // Copyright (c) 2015 BrainCookie. All rights reserved. // -#ifndef HTMLKit_CSSSelectors_h -#define HTMLKit_CSSSelectors_h - - -#endif +#import "CSSSelector.h" +#import "CSSTypeSelector.h" +#import "CSSAttributeSelector.h" diff --git a/HTMLKitTests/CSSAttributeSelectorTests.m b/HTMLKitTests/CSSAttributeSelectorTests.m new file mode 100644 index 0000000..2b8357e --- /dev/null +++ b/HTMLKitTests/CSSAttributeSelectorTests.m @@ -0,0 +1,210 @@ +// +// CSSAttributeSelectorTests.m +// HTMLKit +// +// Created by Iska on 14/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import +#import "CSSSelectors.h" +#import "HTMLNodes.h" + +@interface CSSAttributeSelectorTests : XCTestCase +{ + HTMLElement *_element; +} +@end + +@implementation CSSAttributeSelectorTests + +- (void)setUp +{ + [super setUp]; + _element = [[HTMLElement alloc] initWithTagName:@"div"]; +} + +- (void)testAttributeExists +{ + CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorExists + attributeName:@"attr" + attrbiuteValue:@""]; + + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"class"] = @"class"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"value"; + XCTAssertTrue([selector acceptNode:_element]); + + _element[@"attr"] = @"value 2"; + XCTAssertTrue([selector acceptNode:_element]); + + _element[@"attr"] = @"value 3"; + XCTAssertTrue([selector acceptNode:_element]); + + [_element.attributes removeObjectForKey:@"attr"]; + XCTAssertFalse([selector acceptNode:_element]); +} + +- (void)testAttributeExactMatch +{ + CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorExactMatch + attributeName:@"attr" + attrbiuteValue:@"value"]; + + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"class"] = @"class"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"value 1"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"value 2"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"value 3"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"value"; + XCTAssertTrue([selector acceptNode:_element]); + + [_element.attributes removeObjectForKey:@"attr"]; + XCTAssertFalse([selector acceptNode:_element]); +} + +- (void)testAttributeIncludes +{ + CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorIncludes + attributeName:@"attr" + attrbiuteValue:@"value"]; + + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"class"] = @"class"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"value"; + XCTAssertTrue([selector acceptNode:_element]); + + _element[@"attr"] = @"a b value"; + XCTAssertTrue([selector acceptNode:_element]); + + _element[@"attr"] = @"a value b"; + XCTAssertTrue([selector acceptNode:_element]); + + [_element.attributes removeObjectForKey:@"attr"]; + XCTAssertFalse([selector acceptNode:_element]); +} + +- (void)testAttributeBegins +{ + CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorBegins + attributeName:@"attr" + attrbiuteValue:@"value"]; + + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"class"] = @"class"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"val"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"a value"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"value"; + XCTAssertTrue([selector acceptNode:_element]); + + _element[@"attr"] = @"values"; + XCTAssertTrue([selector acceptNode:_element]); + + [_element.attributes removeObjectForKey:@"attr"]; + XCTAssertFalse([selector acceptNode:_element]); +} + +- (void)testAttributeEnds +{ + CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorEnds + attributeName:@"attr" + attrbiuteValue:@"value"]; + + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"class"] = @"class"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"val"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"value"; + XCTAssertTrue([selector acceptNode:_element]); + + _element[@"attr"] = @"a value"; + XCTAssertTrue([selector acceptNode:_element]); + + _element[@"attr"] = @"some-value"; + XCTAssertTrue([selector acceptNode:_element]); + + [_element.attributes removeObjectForKey:@"attr"]; + XCTAssertFalse([selector acceptNode:_element]); +} + +- (void)testAttributeContains +{ + CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorContains + attributeName:@"attr" + attrbiuteValue:@"value"]; + + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"class"] = @"class"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"val"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"value"; + XCTAssertTrue([selector acceptNode:_element]); + + _element[@"attr"] = @"a value b"; + XCTAssertTrue([selector acceptNode:_element]); + + _element[@"attr"] = @"some-values"; + XCTAssertTrue([selector acceptNode:_element]); + + [_element.attributes removeObjectForKey:@"attr"]; + XCTAssertFalse([selector acceptNode:_element]); +} + +- (void)testAttributeHyphen +{ + CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorHyphen + attributeName:@"attr" + attrbiuteValue:@"top"]; + + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"class"] = @"class"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"top_text"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"toptext"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"top"; + XCTAssertTrue([selector acceptNode:_element]); + + _element[@"attr"] = @"top-text"; + XCTAssertTrue([selector acceptNode:_element]); + + [_element.attributes removeObjectForKey:@"attr"]; + XCTAssertFalse([selector acceptNode:_element]); +} + +@end diff --git a/HTMLKitTests/CSSTypeSelectorTests.m b/HTMLKitTests/CSSTypeSelectorTests.m new file mode 100644 index 0000000..88f13fd --- /dev/null +++ b/HTMLKitTests/CSSTypeSelectorTests.m @@ -0,0 +1,51 @@ +// +// CSSTypeSelectorTests.m +// HTMLKit +// +// Created by Iska on 14/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import +#import "CSSSelectors.h" +#import "HTMLNodes.h" + +@interface CSSTypeSelectorTests : XCTestCase + +@end + +@implementation CSSTypeSelectorTests + +- (void)testUniversalSelector +{ + CSSTypeSelector *selector = [CSSTypeSelector universalSelector]; + + XCTAssertFalse([selector acceptNode:[HTMLDocumentType new]]); + XCTAssertFalse([selector acceptNode:[HTMLDocumentFragment new]]); + XCTAssertFalse([selector acceptNode:[[HTMLText alloc] initWithData:@"Text"]]); + XCTAssertFalse([selector acceptNode:[[HTMLComment alloc] initWithData:@"Comment"]]); + + XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:nil]]); + XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@""]]); + XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]]); + XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"p"]]); + XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"any other name"]]); +} + +- (void)testTypeSelector +{ + CSSTypeSelector *selector = [[CSSTypeSelector alloc] initWithType:@"div"]; + + XCTAssertFalse([selector acceptNode:[HTMLDocumentType new]]); + XCTAssertFalse([selector acceptNode:[HTMLDocumentFragment new]]); + XCTAssertFalse([selector acceptNode:[[HTMLText alloc] initWithData:@"Text"]]); + XCTAssertFalse([selector acceptNode:[[HTMLComment alloc] initWithData:@"Comment"]]); + XCTAssertFalse([selector acceptNode:[[HTMLElement alloc] initWithTagName:nil]]); + XCTAssertFalse([selector acceptNode:[[HTMLElement alloc] initWithTagName:@""]]); + XCTAssertFalse([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"p"]]); + XCTAssertFalse([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"any other name"]]); + + XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]]); +} + +@end From a7a30a7cbf2b4fb8f22c170b3fa2b7ee5f45e662 Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 14 May 2015 21:27:08 +0200 Subject: [PATCH 011/103] Add convenience initializer for the Type Selector --- HTMLKit/CSSTypeSelector.h | 2 ++ HTMLKit/CSSTypeSelector.m | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/HTMLKit/CSSTypeSelector.h b/HTMLKit/CSSTypeSelector.h index 6cd2e16..acc6b6e 100644 --- a/HTMLKit/CSSTypeSelector.h +++ b/HTMLKit/CSSTypeSelector.h @@ -14,6 +14,8 @@ @property (nonatomic, copy) NSString *type; + (instancetype)universalSelector; ++ (instancetype)selectorForType:(NSString *)type; + - (instancetype)initWithType:(NSString *)type; @end diff --git a/HTMLKit/CSSTypeSelector.m b/HTMLKit/CSSTypeSelector.m index dd916bb..f0a336e 100644 --- a/HTMLKit/CSSTypeSelector.m +++ b/HTMLKit/CSSTypeSelector.m @@ -23,6 +23,11 @@ return [[self alloc] initWithType:@"*"]; } ++ (instancetype)selectorForType:(NSString *)type +{ + return [[self alloc] initWithType:type]; +} + - (instancetype)initWithType:(NSString *)type { self = [super init]; From 62b385d9b4870fe8586a82d226bca9dc64c4aa8c Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 14 May 2015 21:42:53 +0200 Subject: [PATCH 012/103] Add test cases for changing selectors' properties for the Type & Attribute selectors --- HTMLKitTests/CSSAttributeSelectorTests.m | 66 ++++++++++++++++++++++++ HTMLKitTests/CSSTypeSelectorTests.m | 10 ++++ 2 files changed, 76 insertions(+) diff --git a/HTMLKitTests/CSSAttributeSelectorTests.m b/HTMLKitTests/CSSAttributeSelectorTests.m index 2b8357e..25b966a 100644 --- a/HTMLKitTests/CSSAttributeSelectorTests.m +++ b/HTMLKitTests/CSSAttributeSelectorTests.m @@ -207,4 +207,70 @@ XCTAssertFalse([selector acceptNode:_element]); } +- (void)testChangeAttributeName +{ + CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorExists + attributeName:@"attr" + attrbiuteValue:@""]; + + _element[@"attr"] = @"value"; + XCTAssertTrue([selector acceptNode:_element]); + + selector.name = @"new-attr"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"new-attr"] = @"value"; + XCTAssertTrue([selector acceptNode:_element]); +} + +- (void)testChangeAttributeValue +{ + CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorExactMatch + attributeName:@"attr" + attrbiuteValue:@"value"]; + + _element[@"attr"] = @"value"; + XCTAssertTrue([selector acceptNode:_element]); + + selector.value = @"new-value"; + XCTAssertFalse([selector acceptNode:_element]); + + _element[@"attr"] = @"new-value"; + XCTAssertTrue([selector acceptNode:_element]); +} + +- (void)testChangeAttributeType +{ + CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorExists + attributeName:@"attr" + attrbiuteValue:@"value"]; + + _element[@"attr"] = @""; + XCTAssertTrue([selector acceptNode:_element]); + + selector.type = CSSAttributeSelectorExactMatch; + _element[@"attr"] = @"value"; + XCTAssertTrue([selector acceptNode:_element]); + + selector.type = CSSAttributeSelectorIncludes; + _element[@"attr"] = @"first-value value another-value"; + XCTAssertTrue([selector acceptNode:_element]); + + selector.type = CSSAttributeSelectorBegins; + _element[@"attr"] = @"values"; + XCTAssertTrue([selector acceptNode:_element]); + + selector.type = CSSAttributeSelectorEnds; + _element[@"attr"] = @"some-value"; + XCTAssertTrue([selector acceptNode:_element]); + + selector.type = CSSAttributeSelectorContains; + _element[@"attr"] = @"here-is-a-value-"; + XCTAssertTrue([selector acceptNode:_element]); + + selector.type = CSSAttributeSelectorHyphen; + _element[@"attr"] = @"value-"; + XCTAssertTrue([selector acceptNode:_element]); +} + @end diff --git a/HTMLKitTests/CSSTypeSelectorTests.m b/HTMLKitTests/CSSTypeSelectorTests.m index 88f13fd..88e28d3 100644 --- a/HTMLKitTests/CSSTypeSelectorTests.m +++ b/HTMLKitTests/CSSTypeSelectorTests.m @@ -48,4 +48,14 @@ XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]]); } +- (void)testChangeSelectorType +{ + CSSTypeSelector *selector = [[CSSTypeSelector alloc] initWithType:@"div"]; + XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]]); + + selector.type = @"p"; + XCTAssertFalse([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]]); + XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"p"]]); +} + @end From 4f03e00003d80391eee45f6cdc1ebe5db01a69f8 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 15 May 2015 02:28:03 +0200 Subject: [PATCH 013/103] Add a protocol for CSS Simple Selectors Simple Selectors should conform to this protocol in order to be addable to the Simple Selector Sequence. --- HTMLKit.xcodeproj/project.pbxproj | 5 +++++ HTMLKit/CSSSimpleSelector.h | 13 +++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 HTMLKit/CSSSimpleSelector.h diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index f4e0e6f..fce98be 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -82,6 +82,7 @@ 624AB3181B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; 624AB31A1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; 624AB31B1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; + 624AB3221B053A5800F3830D /* CSSSimpleSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */; }; 624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */; }; 624AC90119FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; 624AC90219FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; @@ -244,6 +245,7 @@ 624AB3151B04EA4200F3830D /* CSSSelectors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSSelectors.h; sourceTree = ""; }; 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTypeSelectorTests.m; sourceTree = ""; }; 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSAttributeSelectorTests.m; sourceTree = ""; }; + 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSimpleSelector.h; sourceTree = ""; }; 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokens.h; sourceTree = ""; }; 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitTokenizerTests.m; sourceTree = ""; }; 624AC90419FBFE8A00BD3C4A /* html5lib-tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "html5lib-tests"; sourceTree = ""; }; @@ -351,6 +353,7 @@ 62491C451AFE51F100ACF9E2 /* CSSLexer.c */, 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, 62079BE81AF56F1E00D3B402 /* CSSSelector.m */, + 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */, 624B28B61B03DA820048D328 /* CSSTypeSelector.h */, 624B28B71B03DA820048D328 /* CSSTypeSelector.m */, 624B28BD1B0413200048D328 /* CSSAttributeSelector.h */, @@ -624,6 +627,7 @@ 624B28B81B03DA820048D328 /* CSSTypeSelector.h in Headers */, 6234BEEE1AABBF1400DEB15F /* HTMLStackOfOpenElements.h in Headers */, 6238C9851AB8D6330006512E /* HTMLKitExceptions.h in Headers */, + 624AB3221B053A5800F3830D /* CSSSimpleSelector.h in Headers */, 6238039F1AB63A8C008A53D0 /* HTMLEOFToken.h in Headers */, 6279F87419E1808D00F12EE5 /* HTMLElement.h in Headers */, 62AE593F19F9907C0043F069 /* HTMLTagToken.h in Headers */, @@ -815,6 +819,7 @@ 623857931A9E772B003A45D9 /* HTMLDocument.m in Sources */, 623406E81ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */, 624493A819CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, + 624AB3201B05373600F3830D /* CSSSimpleSequence.m in Sources */, 623F13AC1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, 62491C481AFE51F100ACF9E2 /* CSSLexer.c in Sources */, 624B28BA1B03DA820048D328 /* CSSTypeSelector.m in Sources */, diff --git a/HTMLKit/CSSSimpleSelector.h b/HTMLKit/CSSSimpleSelector.h new file mode 100644 index 0000000..0f9cd28 --- /dev/null +++ b/HTMLKit/CSSSimpleSelector.h @@ -0,0 +1,13 @@ +// +// CSSSimpleSelector.h +// HTMLKit +// +// Created by Iska on 14/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import + +@protocol CSSSimpleSelector + +@end From 0c8fd754c366cfdb4edf7e56e63875b0d1fe15b4 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 15 May 2015 02:29:18 +0200 Subject: [PATCH 014/103] Add CSS Simple Selector protocol to the Type & Attribute selectors --- HTMLKit/CSSAttributeSelector.h | 3 ++- HTMLKit/CSSSelectors.h | 1 + HTMLKit/CSSTypeSelector.h | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/HTMLKit/CSSAttributeSelector.h b/HTMLKit/CSSAttributeSelector.h index 812e29e..b7e6a99 100644 --- a/HTMLKit/CSSAttributeSelector.h +++ b/HTMLKit/CSSAttributeSelector.h @@ -8,6 +8,7 @@ #import #import "CSSSelector.h" +#import "CSSSimpleSelector.h" typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType) { @@ -20,7 +21,7 @@ typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType) CSSAttributeSelectorHyphen }; -@interface CSSAttributeSelector : CSSSelector +@interface CSSAttributeSelector : CSSSelector @property (nonatomic, assign) CSSAttributeSelectorType type; @property (nonatomic, copy) NSString *name; diff --git a/HTMLKit/CSSSelectors.h b/HTMLKit/CSSSelectors.h index 30d21f3..d147704 100644 --- a/HTMLKit/CSSSelectors.h +++ b/HTMLKit/CSSSelectors.h @@ -7,5 +7,6 @@ // #import "CSSSelector.h" +#import "CSSSimpleSelector.h" #import "CSSTypeSelector.h" #import "CSSAttributeSelector.h" diff --git a/HTMLKit/CSSTypeSelector.h b/HTMLKit/CSSTypeSelector.h index acc6b6e..1d5c82e 100644 --- a/HTMLKit/CSSTypeSelector.h +++ b/HTMLKit/CSSTypeSelector.h @@ -8,8 +8,9 @@ #import #import "CSSSelector.h" +#import "CSSSimpleSelector.h" -@interface CSSTypeSelector : CSSSelector +@interface CSSTypeSelector : CSSSelector @property (nonatomic, copy) NSString *type; From f5d970ba875a5201907b9478e6434bde0065370c Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 15 May 2015 02:31:22 +0200 Subject: [PATCH 015/103] Add implementation for a CSS Simple Sequence of Selectors http://www.w3.org/TR/css3-selectors/#sequence --- HTMLKit.xcodeproj/project.pbxproj | 9 +++++ HTMLKit/CSSSelectors.h | 1 + HTMLKit/CSSSimpleSequence.h | 25 ++++++++++++ HTMLKit/CSSSimpleSequence.m | 63 +++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+) create mode 100644 HTMLKit/CSSSimpleSequence.h create mode 100644 HTMLKit/CSSSimpleSequence.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index fce98be..6c20966 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -82,6 +82,9 @@ 624AB3181B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; 624AB31A1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; 624AB31B1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; + 624AB31E1B05373600F3830D /* CSSSimpleSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AB31C1B05373600F3830D /* CSSSimpleSequence.h */; }; + 624AB31F1B05373600F3830D /* CSSSimpleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */; }; + 624AB3201B05373600F3830D /* CSSSimpleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */; }; 624AB3221B053A5800F3830D /* CSSSimpleSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */; }; 624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */; }; 624AC90119FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; @@ -245,6 +248,8 @@ 624AB3151B04EA4200F3830D /* CSSSelectors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSSelectors.h; sourceTree = ""; }; 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTypeSelectorTests.m; sourceTree = ""; }; 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSAttributeSelectorTests.m; sourceTree = ""; }; + 624AB31C1B05373600F3830D /* CSSSimpleSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSimpleSequence.h; sourceTree = ""; }; + 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSimpleSequence.m; sourceTree = ""; }; 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSimpleSelector.h; sourceTree = ""; }; 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokens.h; sourceTree = ""; }; 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitTokenizerTests.m; sourceTree = ""; }; @@ -354,6 +359,8 @@ 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, 62079BE81AF56F1E00D3B402 /* CSSSelector.m */, 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */, + 624AB31C1B05373600F3830D /* CSSSimpleSequence.h */, + 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */, 624B28B61B03DA820048D328 /* CSSTypeSelector.h */, 624B28B71B03DA820048D328 /* CSSTypeSelector.m */, 624B28BD1B0413200048D328 /* CSSAttributeSelector.h */, @@ -622,6 +629,7 @@ 62AE594419F992F30043F069 /* HTMLCommentToken.h in Headers */, 624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */, 6235CEA01AA5170A0026937B /* HTMLMarker.h in Headers */, + 624AB31E1B05373600F3830D /* CSSSimpleSequence.h in Headers */, 62F31FDD19E9DCCF007F0657 /* HTMLTokenizerEntities.h in Headers */, 623406E11ADB04F9004677A3 /* HTMLTemplate.h in Headers */, 624B28B81B03DA820048D328 /* CSSTypeSelector.h in Headers */, @@ -880,6 +888,7 @@ 623857921A9E772B003A45D9 /* HTMLDocument.m in Sources */, 623406E71ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */, 624493A719CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, + 624AB31F1B05373600F3830D /* CSSSimpleSequence.m in Sources */, 623F13AB1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, 62491C471AFE51F100ACF9E2 /* CSSLexer.c in Sources */, 624B28B91B03DA820048D328 /* CSSTypeSelector.m in Sources */, diff --git a/HTMLKit/CSSSelectors.h b/HTMLKit/CSSSelectors.h index d147704..1698518 100644 --- a/HTMLKit/CSSSelectors.h +++ b/HTMLKit/CSSSelectors.h @@ -8,5 +8,6 @@ #import "CSSSelector.h" #import "CSSSimpleSelector.h" +#import "CSSSimpleSequence.h" #import "CSSTypeSelector.h" #import "CSSAttributeSelector.h" diff --git a/HTMLKit/CSSSimpleSequence.h b/HTMLKit/CSSSimpleSequence.h new file mode 100644 index 0000000..667856d --- /dev/null +++ b/HTMLKit/CSSSimpleSequence.h @@ -0,0 +1,25 @@ +// +// CSSSimpleSequence.h +// HTMLKit +// +// Created by Iska on 14/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import +#import "CSSSelector.h" +#import "CSSSimpleSelector.h" + +@class CSSTypeSelector; + +@interface CSSSimpleSequence : CSSSelector + ++ (instancetype)sequenceForType:(CSSTypeSelector *)typeSelector; ++ (instancetype)sequenceWithSelectors:(NSArray *)selectors; + +- (instancetype)initWithType:(CSSTypeSelector *)selector; +- (instancetype)initWithSelectors:(NSArray *)selectors; + +- (void)addSelector:(id)selector; + +@end diff --git a/HTMLKit/CSSSimpleSequence.m b/HTMLKit/CSSSimpleSequence.m new file mode 100644 index 0000000..76aa397 --- /dev/null +++ b/HTMLKit/CSSSimpleSequence.m @@ -0,0 +1,63 @@ +// +// CSSSimpleSequence.m +// HTMLKit +// +// Created by Iska on 14/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "CSSSimpleSequence.h" + +@interface CSSSimpleSequence () +{ + NSMutableArray *_selectors; +} +@end + +@implementation CSSSimpleSequence + ++ (instancetype)sequenceForType:(CSSTypeSelector *)typeSelector +{ + return [[self alloc] initWithType:typeSelector]; +} + ++ (instancetype)sequenceWithSelectors:(NSArray *)selectors +{ + return [[self alloc] initWithSelectors:selectors]; +} + +- (instancetype)init +{ + return [self initWithSelectors:nil]; +} + +- (instancetype)initWithType:(CSSTypeSelector *)selector +{ + return [self initWithSelectors:@[selector]]; +} + +- (instancetype)initWithSelectors:(NSArray *)selectors +{ + self = [super init]; + if (self) { + _selectors = [[NSMutableArray alloc] initWithArray:selectors]; + } + return self; +} + +- (void)addSelector:(id)selector +{ + [_selectors addObject:selector]; +} + +- (BOOL)matchesElement:(HTMLElement *)element +{ + for (CSSSelector *selector in _selectors) { + if (![selector matchesElement:element]) { + return NO; + } + } + return YES; +} + +@end From 52b850317e82a9d47b73fddf477d629ffa563a80 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 15 May 2015 22:37:56 +0200 Subject: [PATCH 016/103] Remove selector method to match a HTML Element used in the simple selectors Selectors have only one method to implement, the Node Filter's acceptNode --- HTMLKit/CSSAttributeSelector.m | 8 +++++++- HTMLKit/CSSSelector.h | 2 -- HTMLKit/CSSSelector.m | 5 ----- HTMLKit/CSSSimpleSequence.m | 4 ++-- HTMLKit/CSSTypeSelector.m | 8 ++++++-- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index ca93b23..96d0247 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -43,8 +43,14 @@ return self; } -- (BOOL)matchesElement:(HTMLElement *)element +- (BOOL)acceptNode:(HTMLNode *)node { + if (node.type != HTMLNodeElement) { + return NO; + } + + HTMLElement *element = (HTMLElement *)node; + switch (_type) { case CSSAttributeSelectorExists: { diff --git a/HTMLKit/CSSSelector.h b/HTMLKit/CSSSelector.h index 8416102..b1e5c43 100644 --- a/HTMLKit/CSSSelector.h +++ b/HTMLKit/CSSSelector.h @@ -15,6 +15,4 @@ + (instancetype)selectorWithSting:(NSString *)string; -- (BOOL)matchesElement:(HTMLElement *)element; - @end diff --git a/HTMLKit/CSSSelector.m b/HTMLKit/CSSSelector.m index 797d455..dfd73f3 100644 --- a/HTMLKit/CSSSelector.m +++ b/HTMLKit/CSSSelector.m @@ -24,11 +24,6 @@ } - (BOOL)acceptNode:(HTMLNode *)node -{ - return node.type == HTMLNodeElement && [self matchesElement:(HTMLElement *)node]; -} - -- (BOOL)matchesElement:(HTMLElement *)element { [self doesNotRecognizeSelector:_cmd]; return NO; diff --git a/HTMLKit/CSSSimpleSequence.m b/HTMLKit/CSSSimpleSequence.m index 76aa397..5168e46 100644 --- a/HTMLKit/CSSSimpleSequence.m +++ b/HTMLKit/CSSSimpleSequence.m @@ -50,10 +50,10 @@ [_selectors addObject:selector]; } -- (BOOL)matchesElement:(HTMLElement *)element +- (BOOL)acceptNode:(HTMLNode *)node { for (CSSSelector *selector in _selectors) { - if (![selector matchesElement:element]) { + if (![selector acceptNode:node]) { return NO; } } diff --git a/HTMLKit/CSSTypeSelector.m b/HTMLKit/CSSTypeSelector.m index f0a336e..2c06df8 100644 --- a/HTMLKit/CSSTypeSelector.m +++ b/HTMLKit/CSSTypeSelector.m @@ -37,9 +37,13 @@ return self; } -- (BOOL)matchesElement:(HTMLElement *)element +- (BOOL)acceptNode:(HTMLNode *)node { - return [_type isEqualToString:@"*"] || [_type isEqualToStringIgnoringCase:element.tagName]; + if (node.type != HTMLNodeElement) { + return NO; + } + + return [_type isEqualToString:@"*"] || [_type isEqualToStringIgnoringCase:[(HTMLElement *)node tagName]]; } - (NSString *)description From 8490d4d2cae2e73f5bc928e713be59b052d82208 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 16 May 2015 14:22:44 +0200 Subject: [PATCH 017/103] Add tokenizer method to get next-non-space token --- HTMLKit/CSSTokenizer.h | 1 + HTMLKit/CSSTokenizer.m | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/HTMLKit/CSSTokenizer.h b/HTMLKit/CSSTokenizer.h index 2913093..03a78f0 100644 --- a/HTMLKit/CSSTokenizer.h +++ b/HTMLKit/CSSTokenizer.h @@ -39,6 +39,7 @@ typedef NS_ENUM(int, CSSToken) - (instancetype)initWithString:(NSString *)string; - (CSSToken)nextToken; +- (CSSToken)nextNonSpaceToken; - (NSString *)currentTokenText; @end diff --git a/HTMLKit/CSSTokenizer.m b/HTMLKit/CSSTokenizer.m index edb87b6..ada62c6 100644 --- a/HTMLKit/CSSTokenizer.m +++ b/HTMLKit/CSSTokenizer.m @@ -42,6 +42,15 @@ return _currentToken; } +- (CSSToken)nextNonSpaceToken +{ + CSSToken token; + do { + token = self.nextToken; + } while (token == CSSTokenSpace); + return token; +} + - (NSString *)currentTokenText { if (_currentToken == 0) { From 05e224283a5801dbc3dc653dd7a138cc16aeea72 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 16 May 2015 14:23:06 +0200 Subject: [PATCH 018/103] Expose tokenizer's position variables for better error reporting --- HTMLKit/CSSTokenizer.h | 3 +++ HTMLKit/CSSTokenizer.m | 2 ++ 2 files changed, 5 insertions(+) diff --git a/HTMLKit/CSSTokenizer.h b/HTMLKit/CSSTokenizer.h index 03a78f0..32ab165 100644 --- a/HTMLKit/CSSTokenizer.h +++ b/HTMLKit/CSSTokenizer.h @@ -36,6 +36,9 @@ typedef NS_ENUM(int, CSSToken) @interface CSSTokenizer : NSObject +@property (nonatomic, readonly) size_t currentPosition; +@property (nonatomic, readonly) size_t tokenPosition; + - (instancetype)initWithString:(NSString *)string; - (CSSToken)nextToken; diff --git a/HTMLKit/CSSTokenizer.m b/HTMLKit/CSSTokenizer.m index ada62c6..cb833e0 100644 --- a/HTMLKit/CSSTokenizer.m +++ b/HTMLKit/CSSTokenizer.m @@ -19,6 +19,8 @@ @end @implementation CSSTokenizer +@synthesize currentPosition = _currentPosition; +@synthesize tokenPosition = _tokenPosition; - (instancetype)initWithString:(NSString *)string { From 5e5b903c52fb1f0ebc1aa1fb6ded6375f164b5cc Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 6 Jun 2015 23:29:04 +0200 Subject: [PATCH 019/103] Fix import in CSS Selector test classes --- HTMLKitTests/CSSAttributeSelectorTests.m | 2 +- HTMLKitTests/CSSTypeSelectorTests.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HTMLKitTests/CSSAttributeSelectorTests.m b/HTMLKitTests/CSSAttributeSelectorTests.m index 25b966a..adee0bf 100644 --- a/HTMLKitTests/CSSAttributeSelectorTests.m +++ b/HTMLKitTests/CSSAttributeSelectorTests.m @@ -8,7 +8,7 @@ #import #import "CSSSelectors.h" -#import "HTMLNodes.h" +#import "HTMLDOM.h" @interface CSSAttributeSelectorTests : XCTestCase { diff --git a/HTMLKitTests/CSSTypeSelectorTests.m b/HTMLKitTests/CSSTypeSelectorTests.m index 88e28d3..c855df4 100644 --- a/HTMLKitTests/CSSTypeSelectorTests.m +++ b/HTMLKitTests/CSSTypeSelectorTests.m @@ -8,7 +8,7 @@ #import #import "CSSSelectors.h" -#import "HTMLNodes.h" +#import "HTMLDOM.h" @interface CSSTypeSelectorTests : XCTestCase From a5d53b3eef5e8c8c379d24a94b9bd331bb5c58ef Mon Sep 17 00:00:00 2001 From: iska Date: Sun, 7 Jun 2015 00:08:40 +0200 Subject: [PATCH 020/103] Fix acceptNode method in the selector's implementation after merge with new DOM --- HTMLKit/CSSAttributeSelector.m | 6 +++--- HTMLKit/CSSSelector.m | 4 ++-- HTMLKit/CSSSimpleSequence.m | 6 +++--- HTMLKit/CSSTypeSelector.m | 6 +++--- HTMLKit/HTMLDocumentFragment.m | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index 96d0247..3cf8a80 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -43,10 +43,10 @@ return self; } -- (BOOL)acceptNode:(HTMLNode *)node +- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node { - if (node.type != HTMLNodeElement) { - return NO; + if (node.nodeType != HTMLNodeElement) { + return HTMLNodeFilterSkip; } HTMLElement *element = (HTMLElement *)node; diff --git a/HTMLKit/CSSSelector.m b/HTMLKit/CSSSelector.m index dfd73f3..7f624ec 100644 --- a/HTMLKit/CSSSelector.m +++ b/HTMLKit/CSSSelector.m @@ -23,10 +23,10 @@ return nil; } -- (BOOL)acceptNode:(HTMLNode *)node +- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node { [self doesNotRecognizeSelector:_cmd]; - return NO; + return HTMLNodeFilterSkip; } @end diff --git a/HTMLKit/CSSSimpleSequence.m b/HTMLKit/CSSSimpleSequence.m index 5168e46..e651bb6 100644 --- a/HTMLKit/CSSSimpleSequence.m +++ b/HTMLKit/CSSSimpleSequence.m @@ -50,14 +50,14 @@ [_selectors addObject:selector]; } -- (BOOL)acceptNode:(HTMLNode *)node +- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node { for (CSSSelector *selector in _selectors) { if (![selector acceptNode:node]) { - return NO; + return HTMLNodeFilterSkip; } } - return YES; + return HTMLNodeFilterAccept; } @end diff --git a/HTMLKit/CSSTypeSelector.m b/HTMLKit/CSSTypeSelector.m index 2c06df8..72e0741 100644 --- a/HTMLKit/CSSTypeSelector.m +++ b/HTMLKit/CSSTypeSelector.m @@ -37,10 +37,10 @@ return self; } -- (BOOL)acceptNode:(HTMLNode *)node +- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node { - if (node.type != HTMLNodeElement) { - return NO; + if (node.nodeType != HTMLNodeElement) { + return HTMLNodeFilterSkip; } return [_type isEqualToString:@"*"] || [_type isEqualToStringIgnoringCase:[(HTMLElement *)node tagName]]; diff --git a/HTMLKit/HTMLDocumentFragment.m b/HTMLKit/HTMLDocumentFragment.m index adcde5e..2f2d5a2 100644 --- a/HTMLKit/HTMLDocumentFragment.m +++ b/HTMLKit/HTMLDocumentFragment.m @@ -32,7 +32,7 @@ - (NSString *)textContent { NSMutableString *content = [NSMutableString string]; - for (HTMLNode *node in self.treeEnumerator) { + for (HTMLNode *node in self.nodeIterator) { if (node.nodeType == HTMLNodeText) { [content appendString:[(HTMLText *)node data]]; } From 852dfad19cbe35f6e34ca62fe8852effa4b18b46 Mon Sep 17 00:00:00 2001 From: iska Date: Sun, 7 Jun 2015 20:52:42 +0200 Subject: [PATCH 021/103] Add enum values for the other different tokens in a CSS Selector --- HTMLKit/CSSTokenizer.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/HTMLKit/CSSTokenizer.h b/HTMLKit/CSSTokenizer.h index 32ab165..b72db7a 100644 --- a/HTMLKit/CSSTokenizer.h +++ b/HTMLKit/CSSTokenizer.h @@ -31,7 +31,15 @@ typedef NS_ENUM(int, CSSToken) CSSTokenPercentage, CSSTokenDimension, CSSTokenCDO, - CSSTokenCDC + CSSTokenCDC, + CSSTokenRightParenthesis = 41, + CSSTokenWildcard = 42, + CSSTokenMinus = 45, + CSSTokenDot = 46, + CSSTokenColon = 58, + CSSTokenEqual = 61, + CSSTokenLeftSquareBracket = 91, + CSSTokenRightSquareBracket = 93 }; @interface CSSTokenizer : NSObject From a54cae882967c32044ed19899dad2ae543e6e788 Mon Sep 17 00:00:00 2001 From: iska Date: Sun, 7 Jun 2015 22:34:50 +0200 Subject: [PATCH 022/103] Fix type & attribute selectors and their tests after merge with new DOM --- HTMLKit/CSSAttributeSelector.m | 9 +- HTMLKit/CSSTypeSelector.m | 6 +- HTMLKitTests/CSSAttributeSelectorTests.m | 120 +++++++++++------------ HTMLKitTests/CSSTypeSelectorTests.m | 42 ++++---- 4 files changed, 94 insertions(+), 83 deletions(-) diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index 3cf8a80..6be673d 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -49,8 +49,15 @@ return HTMLNodeFilterSkip; } - HTMLElement *element = (HTMLElement *)node; + if ([self acceptElement:node.asElement]) { + return HTMLNodeFilterAccept; + } + return HTMLNodeFilterSkip; +} + +- (BOOL)acceptElement:(HTMLElement *)element +{ switch (_type) { case CSSAttributeSelectorExists: { diff --git a/HTMLKit/CSSTypeSelector.m b/HTMLKit/CSSTypeSelector.m index 72e0741..d1e9321 100644 --- a/HTMLKit/CSSTypeSelector.m +++ b/HTMLKit/CSSTypeSelector.m @@ -43,7 +43,11 @@ return HTMLNodeFilterSkip; } - return [_type isEqualToString:@"*"] || [_type isEqualToStringIgnoringCase:[(HTMLElement *)node tagName]]; + if ([_type isEqualToString:@"*"] || [_type isEqualToStringIgnoringCase:[node.asElement tagName]]) { + return HTMLNodeFilterAccept; + } + + return HTMLNodeFilterSkip; } - (NSString *)description diff --git a/HTMLKitTests/CSSAttributeSelectorTests.m b/HTMLKitTests/CSSAttributeSelectorTests.m index adee0bf..8bb9b8c 100644 --- a/HTMLKitTests/CSSAttributeSelectorTests.m +++ b/HTMLKitTests/CSSAttributeSelectorTests.m @@ -30,22 +30,22 @@ attributeName:@"attr" attrbiuteValue:@""]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"class"] = @"class"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); _element[@"attr"] = @"value 2"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); _element[@"attr"] = @"value 3"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); } - (void)testAttributeExactMatch @@ -54,25 +54,25 @@ attributeName:@"attr" attrbiuteValue:@"value"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"class"] = @"class"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"value 1"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"value 2"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"value 3"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); } - (void)testAttributeIncludes @@ -81,22 +81,22 @@ attributeName:@"attr" attrbiuteValue:@"value"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"class"] = @"class"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); _element[@"attr"] = @"a b value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); _element[@"attr"] = @"a value b"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); } - (void)testAttributeBegins @@ -105,25 +105,25 @@ attributeName:@"attr" attrbiuteValue:@"value"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"class"] = @"class"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"val"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"a value"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); _element[@"attr"] = @"values"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); } - (void)testAttributeEnds @@ -132,25 +132,25 @@ attributeName:@"attr" attrbiuteValue:@"value"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"class"] = @"class"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"val"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); _element[@"attr"] = @"a value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); _element[@"attr"] = @"some-value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); } - (void)testAttributeContains @@ -159,25 +159,25 @@ attributeName:@"attr" attrbiuteValue:@"value"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"class"] = @"class"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"val"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); _element[@"attr"] = @"a value b"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); _element[@"attr"] = @"some-values"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); } - (void)testAttributeHyphen @@ -186,25 +186,25 @@ attributeName:@"attr" attrbiuteValue:@"top"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"class"] = @"class"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"top_text"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"toptext"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"top"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); _element[@"attr"] = @"top-text"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); } - (void)testChangeAttributeName @@ -214,13 +214,13 @@ attrbiuteValue:@""]; _element[@"attr"] = @"value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); selector.name = @"new-attr"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"new-attr"] = @"value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); } - (void)testChangeAttributeValue @@ -230,13 +230,13 @@ attrbiuteValue:@"value"]; _element[@"attr"] = @"value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); selector.value = @"new-value"; - XCTAssertFalse([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); _element[@"attr"] = @"new-value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); } - (void)testChangeAttributeType @@ -246,31 +246,31 @@ attrbiuteValue:@"value"]; _element[@"attr"] = @""; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); selector.type = CSSAttributeSelectorExactMatch; _element[@"attr"] = @"value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); selector.type = CSSAttributeSelectorIncludes; _element[@"attr"] = @"first-value value another-value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); selector.type = CSSAttributeSelectorBegins; _element[@"attr"] = @"values"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); selector.type = CSSAttributeSelectorEnds; _element[@"attr"] = @"some-value"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); selector.type = CSSAttributeSelectorContains; _element[@"attr"] = @"here-is-a-value-"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); selector.type = CSSAttributeSelectorHyphen; _element[@"attr"] = @"value-"; - XCTAssertTrue([selector acceptNode:_element]); + XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); } @end diff --git a/HTMLKitTests/CSSTypeSelectorTests.m b/HTMLKitTests/CSSTypeSelectorTests.m index c855df4..490619e 100644 --- a/HTMLKitTests/CSSTypeSelectorTests.m +++ b/HTMLKitTests/CSSTypeSelectorTests.m @@ -20,42 +20,42 @@ { CSSTypeSelector *selector = [CSSTypeSelector universalSelector]; - XCTAssertFalse([selector acceptNode:[HTMLDocumentType new]]); - XCTAssertFalse([selector acceptNode:[HTMLDocumentFragment new]]); - XCTAssertFalse([selector acceptNode:[[HTMLText alloc] initWithData:@"Text"]]); - XCTAssertFalse([selector acceptNode:[[HTMLComment alloc] initWithData:@"Comment"]]); + XCTAssertEqual([selector acceptNode:[HTMLDocumentType new]], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptNode:[HTMLDocumentFragment new]], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptNode:[[HTMLText alloc] initWithData:@"Text"]], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptNode:[[HTMLComment alloc] initWithData:@"Comment"]], HTMLNodeFilterSkip); - XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:nil]]); - XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@""]]); - XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]]); - XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"p"]]); - XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"any other name"]]); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:nil]], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@""]], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"p"]], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"any other name"]], HTMLNodeFilterAccept); } - (void)testTypeSelector { CSSTypeSelector *selector = [[CSSTypeSelector alloc] initWithType:@"div"]; - XCTAssertFalse([selector acceptNode:[HTMLDocumentType new]]); - XCTAssertFalse([selector acceptNode:[HTMLDocumentFragment new]]); - XCTAssertFalse([selector acceptNode:[[HTMLText alloc] initWithData:@"Text"]]); - XCTAssertFalse([selector acceptNode:[[HTMLComment alloc] initWithData:@"Comment"]]); - XCTAssertFalse([selector acceptNode:[[HTMLElement alloc] initWithTagName:nil]]); - XCTAssertFalse([selector acceptNode:[[HTMLElement alloc] initWithTagName:@""]]); - XCTAssertFalse([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"p"]]); - XCTAssertFalse([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"any other name"]]); + XCTAssertEqual([selector acceptNode:[HTMLDocumentType new]], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptNode:[HTMLDocumentFragment new]], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptNode:[[HTMLText alloc] initWithData:@"Text"]], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptNode:[[HTMLComment alloc] initWithData:@"Comment"]], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:nil]], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@""]], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"p"]], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"any other name"]], HTMLNodeFilterSkip); - XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]]); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]], HTMLNodeFilterAccept); } - (void)testChangeSelectorType { CSSTypeSelector *selector = [[CSSTypeSelector alloc] initWithType:@"div"]; - XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]]); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]], HTMLNodeFilterAccept); selector.type = @"p"; - XCTAssertFalse([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]]); - XCTAssertTrue([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"p"]]); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"p"]], HTMLNodeFilterAccept); } @end From c4aacfae2b0d4391640686fa69d9b9b6fe9b4404 Mon Sep 17 00:00:00 2001 From: iska Date: Sun, 14 Jun 2015 20:16:29 +0200 Subject: [PATCH 023/103] Add CSS Input Stream class http://www.w3.org/TR/2013/WD-css-syntax-3-20131105/#tokenizing-and-parsing --- HTMLKit.xcodeproj/project.pbxproj | 10 +++++ HTMLKit/CSSInputStream.h | 23 +++++++++++ HTMLKit/CSSInputStream.m | 65 +++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 HTMLKit/CSSInputStream.h create mode 100644 HTMLKit/CSSInputStream.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 54c22ab..2fb0750 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -114,6 +114,9 @@ 624B28C41B04190D0048D328 /* NSCharacterSet+HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */; }; 624B28C51B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */; }; 624B28C61B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */; }; + 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 */; }; 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 */; }; @@ -280,6 +283,8 @@ 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSAttributeSelector.m; sourceTree = ""; }; 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSCharacterSet+HTMLKit.h"; sourceTree = ""; }; 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSCharacterSet+HTMLKit.m"; sourceTree = ""; }; + 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 = ""; }; 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 = ""; }; @@ -370,6 +375,8 @@ isa = PBXGroup; children = ( 624AB3151B04EA4200F3830D /* CSSSelectors.h */, + 624B371C1B24E9BA0010BDDF /* CSSInputStream.h */, + 624B371D1B24E9BA0010BDDF /* CSSInputStream.m */, 623F13A81AFC11D900C90BF4 /* CSSTokenizer.h */, 623F13A91AFC11D900C90BF4 /* CSSTokenizer.m */, 62491C461AFE51F100ACF9E2 /* CSSLexer.h */, @@ -660,6 +667,7 @@ 624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */, 62AE594419F992F30043F069 /* HTMLCommentToken.h in Headers */, 624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */, + 624B371E1B24E9BA0010BDDF /* CSSInputStream.h in Headers */, 6235CEA01AA5170A0026937B /* HTMLMarker.h in Headers */, 624AB31E1B05373600F3830D /* CSSSimpleSequence.h in Headers */, 62F31FDD19E9DCCF007F0657 /* HTMLTokenizerEntities.h in Headers */, @@ -850,6 +858,7 @@ 6234248A1AB467B200726190 /* HTMLOrderedDictionary.m in Sources */, 624717BE1B22009200B38302 /* HTMLTreeWalker.m in Sources */, 62AE594119F9907C0043F069 /* HTMLTagToken.m in Sources */, + 624B37201B24E9BA0010BDDF /* CSSInputStream.m in Sources */, 62AE594619F992F30043F069 /* HTMLCommentToken.m in Sources */, 62363C3F1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m in Sources */, 62AE593C19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */, @@ -915,6 +924,7 @@ 623424891AB467B200726190 /* HTMLOrderedDictionary.m in Sources */, 624717BD1B22009200B38302 /* HTMLTreeWalker.m in Sources */, 62AE594019F9907C0043F069 /* HTMLTagToken.m in Sources */, + 624B371F1B24E9BA0010BDDF /* CSSInputStream.m in Sources */, 62AE594519F992F30043F069 /* HTMLCommentToken.m in Sources */, 62363C3E1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m in Sources */, 62AE593B19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */, diff --git a/HTMLKit/CSSInputStream.h b/HTMLKit/CSSInputStream.h new file mode 100644 index 0000000..3a6699f --- /dev/null +++ b/HTMLKit/CSSInputStream.h @@ -0,0 +1,23 @@ +// +// CSSInputStream.h +// HTMLKit +// +// Created by Iska on 07/06/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import + +@interface CSSInputStream : NSObject + +@property (nonatomic, readonly) NSUInteger location; + +- (instancetype)initWithString:(NSString *)string; + +- (UTF32Char)currentCodePoint; +- (UTF32Char)nextCodePoint; +- (UTF32Char)nextCodePointAtOffset:(NSUInteger)offset; +- (UTF32Char)consumeNextCodePoint; +- (void)reconsumeCurrentCodePoint; + +@end diff --git a/HTMLKit/CSSInputStream.m b/HTMLKit/CSSInputStream.m new file mode 100644 index 0000000..a3a3053 --- /dev/null +++ b/HTMLKit/CSSInputStream.m @@ -0,0 +1,65 @@ +// +// CSSInputStream.m +// HTMLKit +// +// Created by Iska on 07/06/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "CSSInputStream.h" + +@interface CSSInputStream () +{ + CFStringInlineBuffer _buffer; + NSUInteger _location; + UTF32Char _currentCodePoint; +} +@end + +@implementation CSSInputStream +@synthesize location = _location; + +- (instancetype)initWithString:(NSString *)string +{ + self = [super init]; + if (self) { + CFStringInitInlineBuffer((CFStringRef)string, &_buffer, CFRangeMake(0, string.length)); + _location = 0; + _currentCodePoint = 0; + } + return self; +} + +- (UTF32Char)currentCodePoint +{ + return _currentCodePoint; +} + +- (UTF32Char)nextCodePointAtOffset:(NSUInteger)offset; +{ + UTF32Char codePoint = CFStringGetCharacterFromInlineBuffer(&_buffer, _location + offset); + return codePoint; +} + +- (UTF32Char)nextCodePoint +{ + return [self nextCodePointAtOffset:0]; +} + +- (UTF32Char)consumeNextCodePoint +{ + UTF32Char codePoint = [self nextCodePoint]; + _currentCodePoint = codePoint; + if (codePoint != 0) { + _location++; + } + + return codePoint; +} + +- (void)reconsumeCurrentCodePoint +{ + _location = _location - 1; +} + +@end From 576dc4dfb2241c7848b756a044ae464f38c53b65 Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 22 Jun 2015 00:42:34 +0200 Subject: [PATCH 024/103] Add CSS Token classes --- HTMLKit.xcodeproj/project.pbxproj | 10 ++++ HTMLKit/CSSToken.h | 80 +++++++++++++++++++++++++++++++ HTMLKit/CSSToken.m | 62 ++++++++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 HTMLKit/CSSToken.h create mode 100644 HTMLKit/CSSToken.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 2fb0750..0da4ce7 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -117,6 +117,9 @@ 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 */; }; @@ -285,6 +288,8 @@ 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSCharacterSet+HTMLKit.m"; sourceTree = ""; }; 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 = ""; }; + 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 = ""; }; @@ -379,6 +384,8 @@ 624B371D1B24E9BA0010BDDF /* CSSInputStream.m */, 623F13A81AFC11D900C90BF4 /* CSSTokenizer.h */, 623F13A91AFC11D900C90BF4 /* CSSTokenizer.m */, + 624B7DDA1B2E3AAB00A4BD61 /* CSSToken.h */, + 624B7DDB1B2E3AAB00A4BD61 /* CSSToken.m */, 62491C461AFE51F100ACF9E2 /* CSSLexer.h */, 62491C451AFE51F100ACF9E2 /* CSSLexer.c */, 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, @@ -657,6 +664,7 @@ 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 */, 62D89DB51AE7081600B6243D /* HTMLElementAdjustment.h in Headers */, @@ -871,6 +879,7 @@ 6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */, 625A150A19C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */, 623857931A9E772B003A45D9 /* HTMLDocument.m in Sources */, + 624B7DDE1B2E3AAB00A4BD61 /* CSSToken.m in Sources */, 623406E81ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */, 624717B91B21FE5400B38302 /* HTMLNodeFilter.m in Sources */, 624493A819CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, @@ -937,6 +946,7 @@ 6279F87519E1808D00F12EE5 /* HTMLElement.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 */, 624493A719CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, diff --git a/HTMLKit/CSSToken.h b/HTMLKit/CSSToken.h new file mode 100644 index 0000000..cc06fdb --- /dev/null +++ b/HTMLKit/CSSToken.h @@ -0,0 +1,80 @@ +// +// 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 start; +@property (nonatomic, assign) NSUInteger end; +@property (nonatomic, copy) NSString *text; + ++ (instancetype)tokenWithType:(CSSTokenType)type; + +@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 new file mode 100644 index 0000000..22bf324 --- /dev/null +++ b/HTMLKit/CSSToken.m @@ -0,0 +1,62 @@ +// +// 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 + +@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 From b1ddbc5f751b8da6254b11134490668a6e29d599 Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 22 Jun 2015 00:43:32 +0200 Subject: [PATCH 025/103] Add CSS Tokenizer related helper function for dealing with code points --- HTMLKit.xcodeproj/project.pbxproj | 2 + HTMLKit/CSSTokenizerCodePoints.h | 168 ++++++++++++++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 HTMLKit/CSSTokenizerCodePoints.h diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 0da4ce7..0c84315 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -288,6 +288,7 @@ 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSCharacterSet+HTMLKit.m"; sourceTree = ""; }; 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 /* CSSTokenizerCodePoints.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSTokenizerCodePoints.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 = ""; }; @@ -386,6 +387,7 @@ 623F13A91AFC11D900C90BF4 /* CSSTokenizer.m */, 624B7DDA1B2E3AAB00A4BD61 /* CSSToken.h */, 624B7DDB1B2E3AAB00A4BD61 /* CSSToken.m */, + 624B37211B250BB50010BDDF /* CSSTokenizerCodePoints.h */, 62491C461AFE51F100ACF9E2 /* CSSLexer.h */, 62491C451AFE51F100ACF9E2 /* CSSLexer.c */, 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, diff --git a/HTMLKit/CSSTokenizerCodePoints.h b/HTMLKit/CSSTokenizerCodePoints.h new file mode 100644 index 0000000..1ff909a --- /dev/null +++ b/HTMLKit/CSSTokenizerCodePoints.h @@ -0,0 +1,168 @@ +// +// CSSTokenizer CODEPOINTs.h +// HTMLKit +// +// Created by Iska on 08/06/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#define CODEPOINTS \ + CODEPOINT( EOF_CHARACTER, 0x0000 ) \ + CODEPOINT( BACK_SPACE, 0x0008 ) \ + CODEPOINT( CHARACTER_TABULATION, 0x0009 ) \ + CODEPOINT( LINE_FEED, 0x000A ) \ + CODEPOINT( LINE_TABULATION, 0x000B ) \ + CODEPOINT( SHIFT_OUT, 0x000E ) \ + CODEPOINT( INFORMATION_SEPARATOR_ONE, 0x001F ) \ + CODEPOINT( DELETE, 0x007F ) \ + CODEPOINT( SPACE, 0x0020 ) \ + CODEPOINT( EXCLAMATION_MARK, 0x0021 ) \ + CODEPOINT( QUOTATION_MARK, 0x0022 ) \ + CODEPOINT( NUMBER_SIGN, 0x0023 ) \ + CODEPOINT( DOLLAR_SIGN, 0x0024 ) \ + CODEPOINT( PERCENTAGE_SIGN, 0x0025 ) \ + CODEPOINT( APOSTROPHE, 0x0027 ) \ + CODEPOINT( LEFT_PARENTHESIS, 0x0028 ) \ + CODEPOINT( RIGHT_PARENTHESIS, 0x0029 ) \ + CODEPOINT( ASTERIX, 0x002A ) \ + CODEPOINT( PLUS_SIGN, 0x002B ) \ + CODEPOINT( COMMA, 0x002C ) \ + CODEPOINT( HYPHEN_MINUS, 0x002D ) \ + CODEPOINT( FULL_STOP, 0x002E ) \ + CODEPOINT( SOLIDUS, 0x002F ) \ + CODEPOINT( DIGIT_ZERO, 0x0030 ) \ + CODEPOINT( DIGIT_NINE, 0x0039 ) \ + CODEPOINT( COLON, 0x003A ) \ + CODEPOINT( SEMICOLON, 0x003B ) \ + CODEPOINT( LESS_THAN_SIGN, 0x003C ) \ + CODEPOINT( EQUALS_SIGN, 0x003D ) \ + CODEPOINT( QUESTION_MARK, 0x003F ) \ + CODEPOINT( COMMERCIAL_AT, 0x0040) \ + CODEPOINT( LATIN_CAPITAL_LETTER_A, 0x0041 ) \ + CODEPOINT( LATIN_CAPITAL_LETTER_E, 0x0045 ) \ + CODEPOINT( LATIN_CAPITAL_LETTER_F, 0x0046 ) \ + CODEPOINT( LATIN_CAPITAL_LETTER_U, 0x0055 ) \ + CODEPOINT( LATIN_CAPITAL_LETTER_Z, 0x005A ) \ + CODEPOINT( LEFT_SQUARE_BRACKET, 0x005B ) \ + CODEPOINT( REVERSE_SOLIDUS, 0x005C ) \ + CODEPOINT( RIGHT_SQUARE_BRACKET, 0x005D ) \ + CODEPOINT( CIRCUMFLEX_ACCENT, 0x005E ) \ + CODEPOINT( LOW_LINE, 0x005F ) \ + CODEPOINT( LATIN_SMALL_LETTER_A, 0x0061 ) \ + CODEPOINT( LATIN_SMALL_LETTER_E, 0x0065 ) \ + CODEPOINT( LATIN_SMALL_LETTER_F, 0x0066 ) \ + CODEPOINT( LATIN_SMALL_LETTER_U, 0x0075 ) \ + CODEPOINT( LATIN_SMALL_LETTER_Z, 0x007A ) \ + CODEPOINT( LEFT_CURLY_BRACKET, 0x007B ) \ + CODEPOINT( RIGHT_CURLY_BRACKET, 0x007D ) \ + CODEPOINT( VERTICAL_LINE, 0x007A ) \ + CODEPOINT( TILDE, 0x007E ) \ + CODEPOINT( CONTROL, 0x0080 ) \ + CODEPOINT( REPLACEMENT_CHARACTER, 0xFFFD ) + +#define CODEPOINT( name, value ) static UniChar const name = value; +CODEPOINTS +#undef CODEPOINT + +NS_INLINE BOOL isWhitespace(UTF32Char codePoint) +{ + return codePoint == CHARACTER_TABULATION || codePoint == LINE_FEED || codePoint == SPACE; +} + +NS_INLINE BOOL isDigit(UTF32Char codePoint) +{ + return codePoint >= DIGIT_ZERO && codePoint <= DIGIT_NINE; +} + +NS_INLINE BOOL isHexDigit(UTF32Char codePoint) +{ + return ((codePoint >= DIGIT_ZERO && codePoint <= DIGIT_NINE) || + (codePoint >= LATIN_CAPITAL_LETTER_A && codePoint <= LATIN_CAPITAL_LETTER_F) || + (codePoint >= LATIN_SMALL_LETTER_A && codePoint <= LATIN_SMALL_LETTER_F)); +} + +NS_INLINE BOOL isQuote(UTF32Char codePoint) +{ + return codePoint == QUOTATION_MARK || codePoint == APOSTROPHE; +} + +NS_INLINE BOOL isNewLine(UTF32Char codePoint) +{ + return codePoint == LINE_FEED; +} + +NS_INLINE BOOL isNameStart(UTF32Char codePoint) +{ + return ((codePoint >= LATIN_CAPITAL_LETTER_A && codePoint <= LATIN_CAPITAL_LETTER_Z) || + (codePoint >= LATIN_SMALL_LETTER_A && codePoint <= LATIN_SMALL_LETTER_Z) || + codePoint >= CONTROL || + codePoint == LOW_LINE); +} + +NS_INLINE BOOL isName(UTF32Char codePoint) +{ + return isNameStart(codePoint) || isDigit(codePoint) || codePoint == HYPHEN_MINUS; +} + +NS_INLINE BOOL isValidEscape(UTF32Char first, UTF32Char second) +{ + if (first != REVERSE_SOLIDUS || isNewLine(second)) { + return false; + } + + return YES; +} + +NS_INLINE BOOL isValidEscapedCodePoint(UTF32Char codePoint) +{ + return (codePoint != 0 && + !(codePoint >= 0xD800 && codePoint <= 0x0DFFF) && + codePoint <= 0x10FFFF); +} + +NS_INLINE BOOL isNumberStart(UTF32Char first, UTF32Char second, UTF32Char third) +{ + if (first == PLUS_SIGN || first == HYPHEN_MINUS) { + if (isDigit(second)) { + return YES; + } else if (second == FULL_STOP || isDigit(third)) { + return YES; + } else { + return NO; + } + } else if (first == FULL_STOP) { + return isDigit(second); + } else if (isDigit(first)) { + return YES; + } + + return NO; +} + +NS_INLINE BOOL isIdentifierStart(UTF32Char first, UTF32Char second, UTF32Char third) +{ + if (first == HYPHEN_MINUS) { + return isNameStart(second) || isValidEscape(second, third); + } else if (isNameStart(first)) { + return YES; + } else if (first == REVERSE_SOLIDUS) { + return isValidEscape(second, third); + } + + return NO; +} + +NS_INLINE BOOL isNonPrintable(UTF32Char codePoint) +{ + return ((codePoint >= EOF_CHARACTER && codePoint <= BACK_SPACE) || + codePoint == LINE_TABULATION || + (codePoint >= SHIFT_OUT && codePoint <= INFORMATION_SEPARATOR_ONE) || + codePoint == DELETE); +} + +NS_INLINE void AppendCodePoint(CFMutableStringRef string, UTF32Char codePoint) +{ + UniChar pair[2]; + Boolean isPair = CFStringGetSurrogatePairForLongCharacter(codePoint, pair); + CFStringAppendCharacters(string, pair, isPair ? 2 : 1); +} From 1544f71c50bcc61d16eba9b9c5e47dae0846fbc2 Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 22 Jun 2015 00:44:09 +0200 Subject: [PATCH 026/103] Add initial implementation for a CSS Tokenizer http://www.w3.org/TR/2013/WD-css-syntax-3-20131105/#tokenization --- HTMLKit/CSSTokenizer.h | 44 +-- HTMLKit/CSSTokenizer.m | 616 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 588 insertions(+), 72 deletions(-) diff --git a/HTMLKit/CSSTokenizer.h b/HTMLKit/CSSTokenizer.h index b72db7a..31397fd 100644 --- a/HTMLKit/CSSTokenizer.h +++ b/HTMLKit/CSSTokenizer.h @@ -7,50 +7,10 @@ // #import +#import "CSSToken.h" -typedef NS_ENUM(int, CSSToken) -{ - CSSTokenSpace = 1, - CSSTokenIncludes, - CSSTokenDashMatch, - CSSTokenPrefixMatch, - CSSTokenSuffixMatch, - CSSTokenSubstringMatch, - CSSTokenIdent, - CSSTokenString, - CSSTokenFunction, - CSSTokenNumber, - CSSTokenHash, - CSSTokenPlus, - CSSTokenGreater, - CSSTokenComma, - CSSTokenTilde, - CSSTokenNot, - CSSTokenAtKeyword, - CSSTokenInvalid, - CSSTokenPercentage, - CSSTokenDimension, - CSSTokenCDO, - CSSTokenCDC, - CSSTokenRightParenthesis = 41, - CSSTokenWildcard = 42, - CSSTokenMinus = 45, - CSSTokenDot = 46, - CSSTokenColon = 58, - CSSTokenEqual = 61, - CSSTokenLeftSquareBracket = 91, - CSSTokenRightSquareBracket = 93 -}; - -@interface CSSTokenizer : NSObject - -@property (nonatomic, readonly) size_t currentPosition; -@property (nonatomic, readonly) size_t tokenPosition; +@interface CSSTokenizer : NSEnumerator - (instancetype)initWithString:(NSString *)string; -- (CSSToken)nextToken; -- (CSSToken)nextNonSpaceToken; -- (NSString *)currentTokenText; - @end diff --git a/HTMLKit/CSSTokenizer.m b/HTMLKit/CSSTokenizer.m index cb833e0..a0c73a3 100644 --- a/HTMLKit/CSSTokenizer.m +++ b/HTMLKit/CSSTokenizer.m @@ -1,4 +1,4 @@ -// + // // CSSTokenizer.m // HTMLKit // @@ -7,61 +7,617 @@ // #import "CSSTokenizer.h" -#import "CSSLexer.h" +#import "CSSInputStream.h" +#import "CSSTokenizerCodePoints.h" +#import "NSString+HTMLKit.h" @interface CSSTokenizer () { - yyscan_t _scanner; - CSSToken _currentToken; - size_t _currentPosition; - size_t _tokenPosition; + NSString *_string; + CSSInputStream *_inputStream; } @end @implementation CSSTokenizer -@synthesize currentPosition = _currentPosition; -@synthesize tokenPosition = _tokenPosition; + +#pragma mark - Lifecycle - (instancetype)initWithString:(NSString *)string { self = [super init]; if (self) { - csslex_init(&_scanner); - css_scan_string(string.UTF8String, _scanner); - _currentToken = 0; - _currentPosition = 0; - _tokenPosition = 0; + _string = [self preprocessInput:string]; + _inputStream = [[CSSInputStream alloc] initWithString:_string]; } return self; } -- (CSSToken)nextToken -{ - _currentToken = csslex(_scanner); - _tokenPosition += _currentPosition; - _currentPosition += cssget_leng(_scanner); +#pragma mark - Preprocess - return _currentToken; +- (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; } -- (CSSToken)nextNonSpaceToken +#pragma mark - Enumerator + +- (id)nextObject { - CSSToken token; - do { - token = self.nextToken; - } while (token == CSSTokenSpace); + CSSToken *token = [self consumeToken]; + if (token.type == CSSTokenTypeEOF) { + return nil; + } return token; } -- (NSString *)currentTokenText +#pragma mark - Tokenize + +- (void)parseError { - if (_currentToken == 0) { - return nil; + +} + +- (CSSToken *)consumeToken +{ + [self consumeComments]; + + NSUInteger start = _inputStream.location; + UTF32Char 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]; } - char *content = NULL; - content = cssget_text(_scanner); - return [NSString stringWithCString:content encoding:NSUTF8StringEncoding]; + token.start = start; + token.end = _inputStream.location; + token.text = [_string substringWithRange:NSMakeRange(token.start, token.end - token.start)]; + + return token; +} + +- (void)consumeComments +{ + while ([_inputStream nextCodePointAtOffset:0] == SOLIDUS && + [_inputStream nextCodePointAtOffset:1] == ASTERIX) { + [_inputStream consumeNextCodePoint]; + [_inputStream consumeNextCodePoint]; + while (YES) { + UTF32Char 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:(UTF32Char)endingCodePoint +{ + CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); + CSSToken *token = [CSSToken tokenWithType:CSSTokenTypeWhitespace]; + + while (YES) { + UTF32Char 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 { + AppendCodePoint(value, codePoint); + } + } + + 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; + } + + UTF32Char 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) { + UTF32Char 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])) { + AppendCodePoint(value, [self consumeEscapedCodePoint]); + } else { + [self parseError]; + [self consumeRemnantsOfBadURL]; + return [CSSToken tokenWithType:CSSTokenTypeBadURL]; + } + } + + AppendCodePoint(value, codePoint); + } + + return token; +} + +- (CSSToken *)consumeUnicodeRange +{ + CFMutableStringRef hexDigits = CFStringCreateMutable(kCFAllocatorDefault, 6); + while (isHexDigit([_inputStream nextCodePoint]) && CFStringGetLength(hexDigits) < 6) { + UniChar codePoint = [_inputStream consumeNextCodePoint]; + CFStringAppendCharacters(hexDigits, &codePoint, 1); + } + + if (CFStringGetLength(hexDigits) < 6) { + while ([_inputStream nextCodePoint] == QUESTION_MARK && CFStringGetLength(hexDigits) < 6) { + UniChar codePoint = [_inputStream consumeNextCodePoint]; + CFStringAppendCharacters(hexDigits, &codePoint, 1); + } + + NSScanner *scanner = [NSScanner scannerWithString:(__bridge NSString *)(hexDigits)]; + UTF32Char number; + [scanner scanHexInt:&number]; + } + + return nil; +} + +- (UTF32Char)consumeEscapedCodePoint +{ + UTF32Char codePoint = [_inputStream consumeNextCodePoint]; + + if (isHexDigit(codePoint)) { + CFMutableStringRef hexString = CFStringCreateMutable(kCFAllocatorDefault, 6); + AppendCodePoint(hexString, codePoint); + + 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) { + UTF32Char codePoint = [_inputStream consumeNextCodePoint]; + if (isName(codePoint)) { + AppendCodePoint(value, codePoint); + } else if (isValidEscape([_inputStream nextCodePoint], [_inputStream nextCodePointAtOffset:1])) { + AppendCodePoint(value, [self consumeEscapedCodePoint]); + } 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(); + } + + UTF32Char first = [_inputStream nextCodePoint]; + UTF32Char second = [_inputStream nextCodePointAtOffset:1]; + UTF32Char 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) { + UTF32Char codePoint = [_inputStream consumeNextCodePoint]; + if (codePoint == RIGHT_PARENTHESIS || codePoint == EOF_CHARACTER) { + return; + } + + if (isValidEscape([_inputStream currentCodePoint], [_inputStream nextCodePoint])) { + [self consumeEscapedCodePoint]; + } + } } @end From aa95bbd9f2efbbc2c839b5c753d3525a7c0ce684 Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 22 Jun 2015 20:55:33 +0200 Subject: [PATCH 027/103] Add Unicode Range CSS Token parsing --- HTMLKit/CSSToken.h | 12 ++++++-- HTMLKit/CSSToken.m | 7 +++++ HTMLKit/CSSTokenizer.m | 62 +++++++++++++++++++++++++++++++++--------- 3 files changed, 65 insertions(+), 16 deletions(-) diff --git a/HTMLKit/CSSToken.h b/HTMLKit/CSSToken.h index cc06fdb..bc3383e 100644 --- a/HTMLKit/CSSToken.h +++ b/HTMLKit/CSSToken.h @@ -47,14 +47,21 @@ typedef NS_ENUM(NSUInteger, CSSTokenType) @interface CSSToken : NSObject @property (nonatomic, assign) CSSTokenType type; -@property (nonatomic, assign) NSUInteger start; -@property (nonatomic, assign) NSUInteger end; +@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) @@ -63,7 +70,6 @@ typedef NS_ENUM(NSUInteger, CSSNumericTokenType) CSSNumericTokenTypeNumber }; - @interface CSSNumericToken : CSSToken @property (nonatomic, assign) CSSNumericTokenType numericType; @property (nonatomic, strong) NSNumber *value; diff --git a/HTMLKit/CSSToken.m b/HTMLKit/CSSToken.m index 22bf324..c91fb0a 100644 --- a/HTMLKit/CSSToken.m +++ b/HTMLKit/CSSToken.m @@ -28,6 +28,13 @@ @end +#pragma mark - Unicode Range + +@implementation CSSUnicodeRangeToken +@end + +#pragma mark - Numeric + @implementation CSSNumericToken @end diff --git a/HTMLKit/CSSTokenizer.m b/HTMLKit/CSSTokenizer.m index a0c73a3..1cb1275 100644 --- a/HTMLKit/CSSTokenizer.m +++ b/HTMLKit/CSSTokenizer.m @@ -231,9 +231,9 @@ token = [CSSToken tokenWithType:CSSTokenTypeDelim]; } - token.start = start; - token.end = _inputStream.location; - token.text = [_string substringWithRange:NSMakeRange(token.start, token.end - token.start)]; + token.location = start; + token.length = _inputStream.location - start; + token.text = [_string substringWithRange:NSMakeRange(token.location, token.length)]; return token; } @@ -434,24 +434,60 @@ - (CSSToken *)consumeUnicodeRange { - CFMutableStringRef hexDigits = CFStringCreateMutable(kCFAllocatorDefault, 6); - while (isHexDigit([_inputStream nextCodePoint]) && CFStringGetLength(hexDigits) < 6) { - UniChar codePoint = [_inputStream consumeNextCodePoint]; - CFStringAppendCharacters(hexDigits, &codePoint, 1); - } + unsigned int (^ parseHexInt) (NSString *) = ^ unsigned int (NSString *string) { + NSScanner *scanner = [NSScanner scannerWithString:string]; + unsigned int num; + [scanner scanHexInt:&num]; + return num; + }; - if (CFStringGetLength(hexDigits) < 6) { + 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); } - NSScanner *scanner = [NSScanner scannerWithString:(__bridge NSString *)(hexDigits)]; - UTF32Char number; - [scanner scanHexInt:&number]; + 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); + } } - return nil; + 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 From b0668e121eb2f7e04d0b6a0fe3acc6ea08f1e207 Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 22 Jun 2015 23:40:16 +0200 Subject: [PATCH 028/103] Remove obsolete CSS lexer --- HTMLKit.xcodeproj/project.pbxproj | 10 - HTMLKit/CSSLexer.c | 3156 ----------------------------- HTMLKit/CSSLexer.h | 329 --- 3 files changed, 3495 deletions(-) delete mode 100644 HTMLKit/CSSLexer.c delete mode 100644 HTMLKit/CSSLexer.h diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 0c84315..9c55ebf 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -72,9 +72,6 @@ 624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */; }; 624493AD19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; }; 624493AE19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; }; - 62491C471AFE51F100ACF9E2 /* CSSLexer.c in Sources */ = {isa = PBXBuildFile; fileRef = 62491C451AFE51F100ACF9E2 /* CSSLexer.c */; }; - 62491C481AFE51F100ACF9E2 /* CSSLexer.c in Sources */ = {isa = PBXBuildFile; fileRef = 62491C451AFE51F100ACF9E2 /* CSSLexer.c */; }; - 62491C491AFE51F100ACF9E2 /* CSSLexer.h in Headers */ = {isa = PBXBuildFile; fileRef = 62491C461AFE51F100ACF9E2 /* CSSLexer.h */; }; 624AB3171B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; 624AB3181B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; 624AB31A1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; @@ -258,8 +255,6 @@ 624493A919CCE84A00BCDDF4 /* HTMLTokenizerStates.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokenizerStates.h; sourceTree = ""; }; 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLToken.h; sourceTree = ""; }; 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLToken.m; sourceTree = ""; }; - 62491C451AFE51F100ACF9E2 /* CSSLexer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CSSLexer.c; sourceTree = ""; }; - 62491C461AFE51F100ACF9E2 /* CSSLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSLexer.h; sourceTree = ""; }; 624AB3151B04EA4200F3830D /* CSSSelectors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSSelectors.h; sourceTree = ""; }; 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTypeSelectorTests.m; sourceTree = ""; }; 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSAttributeSelectorTests.m; sourceTree = ""; }; @@ -388,8 +383,6 @@ 624B7DDA1B2E3AAB00A4BD61 /* CSSToken.h */, 624B7DDB1B2E3AAB00A4BD61 /* CSSToken.m */, 624B37211B250BB50010BDDF /* CSSTokenizerCodePoints.h */, - 62491C461AFE51F100ACF9E2 /* CSSLexer.h */, - 62491C451AFE51F100ACF9E2 /* CSSLexer.c */, 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, 62079BE81AF56F1E00D3B402 /* CSSSelector.m */, 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */, @@ -701,7 +694,6 @@ 6238579B1A9E8934003A45D9 /* HTMLComment.h in Headers */, 620802021AFD939200F2962F /* CSSTokenizer.h in Headers */, 62AE593519F97D880043F069 /* HTMLParseErrorToken.h in Headers */, - 62491C491AFE51F100ACF9E2 /* CSSLexer.h in Headers */, 62AE594919F9948A0043F069 /* HTMLCharacterToken.h in Headers */, 623857961A9E8606003A45D9 /* HTMLDocumentType.h in Headers */, 623406E61ADB05AD004677A3 /* HTMLDocumentFragment.h in Headers */, @@ -887,7 +879,6 @@ 624493A819CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, 624AB3201B05373600F3830D /* CSSSimpleSequence.m in Sources */, 623F13AC1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, - 62491C481AFE51F100ACF9E2 /* CSSLexer.c in Sources */, 624B28BA1B03DA820048D328 /* CSSTypeSelector.m in Sources */, 625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */, 623857981A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, @@ -954,7 +945,6 @@ 624493A719CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, 624AB31F1B05373600F3830D /* CSSSimpleSequence.m in Sources */, 623F13AB1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, - 62491C471AFE51F100ACF9E2 /* CSSLexer.c in Sources */, 624B28B91B03DA820048D328 /* CSSTypeSelector.m in Sources */, 625A150219C783DE00AD0C32 /* HTMLKit.m in Sources */, 623857971A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, diff --git a/HTMLKit/CSSLexer.c b/HTMLKit/CSSLexer.c deleted file mode 100644 index 219d14c..0000000 --- a/HTMLKit/CSSLexer.c +++ /dev/null @@ -1,3156 +0,0 @@ - -#line 3 "CSSLexer.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -typedef uint64_t flex_uint64_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yyg->yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yyg->yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE cssrestart(yyin ,yyscanner ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -#define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ -do \ -{ \ -/* Undo effects of setting up yytext. */ \ -int yyless_macro_arg = (n); \ -YY_LESS_LINENO(yyless_macro_arg);\ -*yy_cp = yyg->yy_hold_char; \ -YY_RESTORE_YY_MORE_OFFSET \ -yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ -YY_DO_BEFORE_ACTION; /* set up yytext again */ \ -} \ -while ( 0 ) - -#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state -{ - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - yy_size_t yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via cssrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - -}; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ -? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ -: NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] - -void cssrestart (FILE *input_file ,yyscan_t yyscanner ); -void css_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE css_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void css_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void css_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void csspush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void csspop_buffer_state (yyscan_t yyscanner ); - -static void cssensure_buffer_stack (yyscan_t yyscanner ); -static void css_load_buffer_state (yyscan_t yyscanner ); -static void css_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); - -#define YY_FLUSH_BUFFER css_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) - -YY_BUFFER_STATE css_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE css_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE css_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); - -void *cssalloc (yy_size_t ,yyscan_t yyscanner ); -void *cssrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void cssfree (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer css_create_buffer - -#define yy_set_interactive(is_interactive) \ -{ \ -if ( ! YY_CURRENT_BUFFER ){ \ -cssensure_buffer_stack (yyscanner); \ -YY_CURRENT_BUFFER_LVALUE = \ -css_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ -} \ -YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ -} - -#define yy_set_bol(at_bol) \ -{ \ -if ( ! YY_CURRENT_BUFFER ){\ -cssensure_buffer_stack (yyscanner); \ -YY_CURRENT_BUFFER_LVALUE = \ -css_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ -} \ -YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ -} - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -#define csswrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -typedef yyconst struct yy_trans_info *yy_state_type; - -#define yytext_ptr yytext_r - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ -yyg->yytext_ptr = yy_bp; \ -yyleng = (yy_size_t) (yy_cp - yy_bp); \ -yyg->yy_hold_char = *yy_cp; \ -*yy_cp = '\0'; \ -yyg->yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 25 -#define YY_END_OF_BUFFER 26 -struct yy_trans_info -{ - flex_int16_t yy_verify; - flex_int16_t yy_nxt; -}; -static yyconst struct yy_trans_info yy_transition[5613] = -{ - { 0, 0 }, { 0,5567 }, { 0, 0 }, { 0,5565 }, { 1, 96 }, - { 2, 98 }, { 3, 105 }, { 4, 98 }, { 5, 98 }, { 6, 96 }, - { 7, 145 }, { 8, 193 }, { 9, 115 }, { 10, 96 }, { 11, 241 }, - { 12, 96 }, { 13, 122 }, { 14, 124 }, { 15, 128 }, { 16, 289 }, - { 17, 291 }, { 18, 135 }, { 19, 317 }, { 20, 317 }, { 21, 317 }, - { 22, 317 }, { 23, 317 }, { 24, 317 }, { 25, 343 }, { 26, 362 }, - { 27, 96 }, { 28, 365 }, { 29, 367 }, { 30, 412 }, { 31, 412 }, - { 32, 412 }, { 33, 412 }, { 34, 412 }, { 35, 412 }, { 36, 412 }, - { 37, 460 }, { 38, 387 }, { 39, 412 }, { 40, 412 }, { 41, 412 }, - { 42, 412 }, { 43, 412 }, { 44, 389 }, { 45, 391 }, { 46, 412 }, - - { 0, 0 }, { 0,5517 }, { 1, 48 }, { 2, 50 }, { 3, 57 }, - { 4, 50 }, { 5, 50 }, { 6, 48 }, { 7, 97 }, { 8, 145 }, - { 9, 67 }, { 10, 48 }, { 11, 193 }, { 12, 48 }, { 13, 74 }, - { 14, 76 }, { 15, 80 }, { 16, 241 }, { 17, 243 }, { 18, 87 }, - { 19, 269 }, { 20, 269 }, { 21, 269 }, { 22, 269 }, { 23, 269 }, - { 24, 269 }, { 25, 295 }, { 26, 314 }, { 27, 48 }, { 28, 317 }, - { 29, 319 }, { 30, 364 }, { 31, 364 }, { 32, 364 }, { 33, 364 }, - { 34, 364 }, { 35, 364 }, { 36, 364 }, { 37, 412 }, { 38, 339 }, - { 39, 364 }, { 40, 364 }, { 41, 364 }, { 42, 364 }, { 43, 364 }, - { 44, 341 }, { 45, 343 }, { 46, 364 }, { 0, 24 }, { 0,5469 }, - - { 0, 1 }, { 0,5467 }, { 0, 0 }, { 2, 410 }, { 3, 410 }, - { 4, 410 }, { 5, 410 }, { 0, 1 }, { 0,5460 }, { 0, 0 }, - { 2, 403 }, { 3, 403 }, { 4, 403 }, { 5, 403 }, { 0, 0 }, - { 14, 295 }, { 15, 297 }, { 0, 24 }, { 0,5450 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 14, 288 }, { 15, 290 }, { 0, 24 }, - { 0,5443 }, { 0, 12 }, { 0,5441 }, { 0, 0 }, { 28, 322 }, - { 0, 14 }, { 0,5437 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 28, 315 }, { 0, 24 }, { 0,5430 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 27, 315 }, { 45, 324 }, { 0, 18 }, { 0,5420 }, { 1, 403 }, - - { 2, 403 }, { 13, 941 }, { 27, 316 }, { 45, 317 }, { 6, 403 }, - { 7, 281 }, { 8, 403 }, { 9, 403 }, { 10, 403 }, { 11, 403 }, - { 12, 403 }, { 13, 403 }, { 14, 403 }, { 15, 403 }, { 16, 403 }, - { 17, 403 }, { 18, 403 }, { 19, 403 }, { 20, 403 }, { 21, 403 }, - { 22, 403 }, { 23, 403 }, { 24, 403 }, { 25, 403 }, { 26, 403 }, - { 27, 403 }, { 28, 403 }, { 29, 403 }, { 30, 403 }, { 31, 403 }, - { 32, 403 }, { 33, 403 }, { 34, 403 }, { 35, 403 }, { 36, 403 }, - { 37, 451 }, { 38, 403 }, { 39, 403 }, { 40, 403 }, { 41, 403 }, - { 42, 403 }, { 43, 403 }, { 44, 403 }, { 45, 403 }, { 46, 499 }, - { 0, 24 }, { 0,5372 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 16, 499 }, { 0, 0 }, { 0, 0 }, - { 19, 499 }, { 20, 499 }, { 21, 499 }, { 22, 499 }, { 23, 499 }, - { 24, 499 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 30, 499 }, { 31, 499 }, { 32, 499 }, { 33, 499 }, - { 34, 499 }, { 35, 499 }, { 36, 499 }, { 37, 547 }, { 0, 0 }, - { 39, 499 }, { 40, 499 }, { 41, 499 }, { 42, 499 }, { 43, 499 }, - { 0, 0 }, { 0, 0 }, { 46, 499 }, { 0, 18 }, { 0,5324 }, - { 1, 547 }, { 2, 547 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 6, 547 }, { 7, 547 }, { 8, 547 }, { 9, 547 }, { 10, 547 }, - { 11, 185 }, { 12, 547 }, { 13, 547 }, { 14, 547 }, { 15, 547 }, - { 16, 547 }, { 17, 547 }, { 18, 547 }, { 19, 547 }, { 20, 547 }, - { 21, 547 }, { 22, 547 }, { 23, 547 }, { 24, 547 }, { 25, 547 }, - { 26, 547 }, { 27, 547 }, { 28, 547 }, { 29, 547 }, { 30, 547 }, - { 31, 547 }, { 32, 547 }, { 33, 547 }, { 34, 547 }, { 35, 547 }, - { 36, 547 }, { 37, 595 }, { 38, 547 }, { 39, 547 }, { 40, 547 }, - { 41, 547 }, { 42, 547 }, { 43, 547 }, { 44, 547 }, { 45, 547 }, - { 46, 643 }, { 0, 24 }, { 0,5276 }, { 0, 24 }, { 0,5274 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16, 226 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 19, 737 }, { 20, 737 }, - { 21, 737 }, { 22, 737 }, { 23, 737 }, { 24, 737 }, { 0, 10 }, - { 0,5248 }, { 0, 0 }, { 30, 643 }, { 31, 643 }, { 32, 643 }, - { 33, 643 }, { 34, 643 }, { 35, 643 }, { 36, 643 }, { 37, 691 }, - { 10, 200 }, { 39, 643 }, { 40, 643 }, { 41, 643 }, { 42, 643 }, - { 43, 643 }, { 16, 807 }, { 17, 809 }, { 46, 643 }, { 19, 835 }, - { 20, 835 }, { 21, 835 }, { 22, 835 }, { 23, 835 }, { 24, 835 }, - { 0, 24 }, { 0,5222 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 30, 863 }, { 31, 863 }, { 32, 863 }, { 33, 863 }, { 34, 863 }, - { 35, 863 }, { 36, 863 }, { 37, 911 }, { 0, 0 }, { 39, 863 }, - { 40, 863 }, { 41, 863 }, { 42, 863 }, { 43, 863 }, { 0, 24 }, - { 0,5203 }, { 46, 863 }, { 0, 13 }, { 0,5200 }, { 0, 24 }, - { 0,5198 }, { 6, 918 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 34, 933 }, { 0, 0 }, { 0, 0 }, { 37, 935 }, { 0, 0 }, - { 0, 0 }, { 16, 923 }, { 41, 933 }, { 0, 0 }, { 0, 24 }, - { 0,5178 }, { 0, 24 }, { 0,5176 }, { 0, 15 }, { 0,5174 }, - { 0, 12 }, { 0,5172 }, { 0, 14 }, { 0,5170 }, { 0, 0 }, - - { 30, 968 }, { 31, 968 }, { 32, 968 }, { 33, 968 }, { 34, 968 }, - { 35, 968 }, { 36, 968 }, { 37,1016 }, { 0, 0 }, { 39, 968 }, - { 40, 968 }, { 41, 968 }, { 42, 968 }, { 43, 968 }, { 0, 7 }, - { 0,5153 }, { 46, 968 }, { 27, 897 }, { 0, 0 }, { 27, 897 }, - { 0, 0 }, { 27, 897 }, { 0, 13 }, { 0,5145 }, { 0, 15 }, - { 0,5143 }, { 0, 0 }, { 12, 870 }, { 0, 8 }, { 0,5139 }, - { 0, 0 }, { 16,1019 }, { 0, 5 }, { 0,5135 }, { 19,1019 }, - { 20,1019 }, { 21,1019 }, { 22,1019 }, { 23,1019 }, { 24,1019 }, - { 0, 6 }, { 0,5127 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30,1019 }, { 31,1019 }, { 32,1019 }, { 33,1019 }, { 34,1019 }, - - { 35,1019 }, { 36,1019 }, { 37,1067 }, { 0, 0 }, { 39,1019 }, - { 40,1019 }, { 41,1019 }, { 42,1019 }, { 43,1019 }, { 0, 0 }, - { 0, 0 }, { 46,1019 }, { 0, 24 }, { 0,5105 }, { 1,1067 }, - { 2,1067 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6,1067 }, - { 7,1067 }, { 8,1067 }, { 9,1067 }, { 10,1067 }, { 11,1067 }, - { 12,1067 }, { 13,1067 }, { 14,1067 }, { 15,1067 }, { 16,1067 }, - { 17,1067 }, { 18,1067 }, { 19,1112 }, { 20,1112 }, { 21,1112 }, - { 22,1112 }, { 23,1112 }, { 24,1112 }, { 25,1067 }, { 26,1067 }, - { 27,1067 }, { 28,1067 }, { 29,1067 }, { 30,1112 }, { 31,1112 }, - { 32,1112 }, { 33,1067 }, { 34,1067 }, { 35,1067 }, { 36,1067 }, - - { 37,1067 }, { 38,1067 }, { 39,1112 }, { 40,1112 }, { 41,1067 }, - { 42,1067 }, { 43,1067 }, { 44,1067 }, { 45,1067 }, { 46,1067 }, - { 0, 1 }, { 0,5057 }, { 0, 0 }, { 2, 0 }, { 3, 0 }, - { 4, 0 }, { 5, 0 }, { 0, 0 }, { 0,5050 }, { 0, 19 }, - { 0,5048 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 14,-115 }, { 15,-113 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 28, -88 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 28, 777 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 0, 18 }, { 0,5017 }, { 1, 0 }, { 2, 0 }, { 0, 0 }, - { 0, 0 }, { 45, -86 }, { 6, 0 }, { 7,-122 }, { 8, 0 }, - { 9, 0 }, { 10, 0 }, { 11, 0 }, { 12, 0 }, { 13, 0 }, - { 14, 0 }, { 15, 0 }, { 16, 0 }, { 17, 0 }, { 18, 0 }, - { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, { 23, 0 }, - { 24, 0 }, { 25, 0 }, { 26, 0 }, { 27, 0 }, { 28, 0 }, - { 29, 0 }, { 30, 0 }, { 31, 0 }, { 32, 0 }, { 33, 0 }, - { 34, 0 }, { 35, 0 }, { 36, 0 }, { 37, 48 }, { 38, 0 }, - { 39, 0 }, { 40, 0 }, { 41, 0 }, { 42, 0 }, { 43, 0 }, - { 44, 0 }, { 45, 0 }, { 46, 96 }, { 0, 0 }, { 0,4969 }, - - { 1,1024 }, { 2,1024 }, { 3, -48 }, { 4, -48 }, { 5,1072 }, - { 6,1024 }, { 7,1024 }, { 8,1024 }, { 9,1024 }, { 10,1024 }, - { 11,1024 }, { 12,1024 }, { 13,1024 }, { 14,1024 }, { 15,1024 }, - { 16,1024 }, { 17,1024 }, { 18,1024 }, { 19,1120 }, { 20,1120 }, - { 21,1120 }, { 22,1120 }, { 23,1120 }, { 24,1120 }, { 25,1024 }, - { 26,1024 }, { 27,1024 }, { 28,1024 }, { 29,1024 }, { 30,1120 }, - { 31,1120 }, { 32,1120 }, { 33,1024 }, { 34,1024 }, { 35,1024 }, - { 36,1024 }, { 37,1024 }, { 38,1024 }, { 39,1120 }, { 40,1120 }, - { 41,1024 }, { 42,1024 }, { 43,1024 }, { 44,1024 }, { 45,1024 }, - { 46,1024 }, { 0, 18 }, { 0,4921 }, { 1, -96 }, { 2, -96 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, -96 }, { 7,-218 }, - { 8, -96 }, { 9, -96 }, { 10, -96 }, { 11, -96 }, { 12, -96 }, - { 13, -96 }, { 14, -96 }, { 15, -96 }, { 16, -96 }, { 17, -96 }, - { 18, -96 }, { 19, -96 }, { 20, -96 }, { 21, -96 }, { 22, -96 }, - { 23, -96 }, { 24, -96 }, { 25, -96 }, { 26, -96 }, { 27, -96 }, - { 28, -96 }, { 29, -96 }, { 30, -96 }, { 31, -96 }, { 32, -96 }, - { 33, -96 }, { 34, -96 }, { 35, -96 }, { 36, -96 }, { 37, -48 }, - { 38, -96 }, { 39, -96 }, { 40, -96 }, { 41, -96 }, { 42, -96 }, - { 43, -96 }, { 44, -96 }, { 45, -96 }, { 46, 0 }, { 0, 11 }, - { 0,4873 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16, 0 }, { 0, 0 }, { 0, 0 }, { 19, 0 }, - { 20, 0 }, { 21, 0 }, { 22, 0 }, { 23, 0 }, { 24, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, 0 }, { 31, 0 }, { 32, 0 }, { 33, 0 }, { 34, 0 }, - { 35, 0 }, { 36, 0 }, { 37, 48 }, { 0, 0 }, { 39, 0 }, - { 40, 0 }, { 41, 0 }, { 42, 0 }, { 43, 0 }, { 0, 0 }, - { 0, 0 }, { 46, 0 }, { 0, 0 }, { 0,4825 }, { 1,1024 }, - { 2,1024 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6,1024 }, - - { 7,1024 }, { 8,1024 }, { 9,1024 }, { 10,1024 }, { 11,1024 }, - { 12,1024 }, { 13,1024 }, { 14,1024 }, { 15,1024 }, { 16,1024 }, - { 17,1024 }, { 18,1024 }, { 19,1069 }, { 20,1069 }, { 21,1069 }, - { 22,1069 }, { 23,1069 }, { 24,1069 }, { 25,1024 }, { 26,1024 }, - { 27,1024 }, { 28,1024 }, { 29,1024 }, { 30,1069 }, { 31,1069 }, - { 32,1069 }, { 33,1024 }, { 34,1024 }, { 35,1024 }, { 36,1024 }, - { 37,1024 }, { 38,1024 }, { 39,1069 }, { 40,1069 }, { 41,1024 }, - { 42,1024 }, { 43,1024 }, { 44,1024 }, { 45,1024 }, { 46,1024 }, - { 0, 18 }, { 0,4777 }, { 1, 0 }, { 2, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 6, 0 }, { 7, 0 }, { 8, 0 }, - - { 9, 0 }, { 10, 0 }, { 11,-362 }, { 12, 0 }, { 13, 0 }, - { 14, 0 }, { 15, 0 }, { 16, 0 }, { 17, 0 }, { 18, 0 }, - { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, { 23, 0 }, - { 24, 0 }, { 25, 0 }, { 26, 0 }, { 27, 0 }, { 28, 0 }, - { 29, 0 }, { 30, 0 }, { 31, 0 }, { 32, 0 }, { 33, 0 }, - { 34, 0 }, { 35, 0 }, { 36, 0 }, { 37, 48 }, { 38, 0 }, - { 39, 0 }, { 40, 0 }, { 41, 0 }, { 42, 0 }, { 43, 0 }, - { 44, 0 }, { 45, 0 }, { 46, 96 }, { 0, 0 }, { 0,4729 }, - { 1,1021 }, { 2,1021 }, { 3, -48 }, { 4, -48 }, { 5,1069 }, - { 6,1021 }, { 7,1021 }, { 8,1021 }, { 9,1021 }, { 10,1021 }, - - { 11,1021 }, { 12,1021 }, { 13,1021 }, { 14,1021 }, { 15,1021 }, - { 16,1021 }, { 17,1021 }, { 18,1021 }, { 19,1117 }, { 20,1117 }, - { 21,1117 }, { 22,1117 }, { 23,1117 }, { 24,1117 }, { 25,1021 }, - { 26,1021 }, { 27,1021 }, { 28,1021 }, { 29,1021 }, { 30,1117 }, - { 31,1117 }, { 32,1117 }, { 33,1021 }, { 34,1021 }, { 35,1021 }, - { 36,1021 }, { 37,1021 }, { 38,1021 }, { 39,1117 }, { 40,1117 }, - { 41,1021 }, { 42,1021 }, { 43,1021 }, { 44,1021 }, { 45,1021 }, - { 46,1021 }, { 0, 18 }, { 0,4681 }, { 1, -96 }, { 2, -96 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, -96 }, { 7, -96 }, - { 8, -96 }, { 9, -96 }, { 10, -96 }, { 11,-458 }, { 12, -96 }, - - { 13, -96 }, { 14, -96 }, { 15, -96 }, { 16, -96 }, { 17, -96 }, - { 18, -96 }, { 19, -96 }, { 20, -96 }, { 21, -96 }, { 22, -96 }, - { 23, -96 }, { 24, -96 }, { 25, -96 }, { 26, -96 }, { 27, -96 }, - { 28, -96 }, { 29, -96 }, { 30, -96 }, { 31, -96 }, { 32, -96 }, - { 33, -96 }, { 34, -96 }, { 35, -96 }, { 36, -96 }, { 37, -48 }, - { 38, -96 }, { 39, -96 }, { 40, -96 }, { 41, -96 }, { 42, -96 }, - { 43, -96 }, { 44, -96 }, { 45, -96 }, { 46, 0 }, { 0, 7 }, - { 0,4633 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 12, 350 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 16, 499 }, { 0, 0 }, { 0, 0 }, { 19, 499 }, - { 20, 499 }, { 21, 499 }, { 22, 499 }, { 23, 499 }, { 24, 499 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, 499 }, { 31, 499 }, { 32, 499 }, { 33, 499 }, { 34, 499 }, - { 35, 499 }, { 36, 499 }, { 37, 547 }, { 0, 0 }, { 39, 499 }, - { 40, 499 }, { 41, 499 }, { 42, 499 }, { 43, 499 }, { 0, 0 }, - { 0, 0 }, { 46, 499 }, { 0, 0 }, { 0,4585 }, { 1, 547 }, - { 2, 547 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, 547 }, - { 7, 547 }, { 8, 547 }, { 9, 547 }, { 10, 547 }, { 11, 547 }, - { 12, 547 }, { 13, 547 }, { 14, 547 }, { 15, 547 }, { 16, 547 }, - - { 17, 547 }, { 18, 547 }, { 19, 592 }, { 20, 592 }, { 21, 592 }, - { 22, 592 }, { 23, 592 }, { 24, 592 }, { 25, 547 }, { 26, 547 }, - { 27, 547 }, { 28, 547 }, { 29, 547 }, { 30, 592 }, { 31, 592 }, - { 32, 592 }, { 33, 547 }, { 34, 547 }, { 35, 547 }, { 36, 547 }, - { 37, 547 }, { 38, 547 }, { 39, 592 }, { 40, 592 }, { 41, 547 }, - { 42, 547 }, { 43, 547 }, { 44, 547 }, { 45, 547 }, { 46, 547 }, - { 0, 10 }, { 0,4537 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 10,-511 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 16, 96 }, { 0, 0 }, { 0, 0 }, - - { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, { 23, 0 }, - { 24, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 30, 152 }, { 31, 152 }, { 32, 152 }, { 33, 152 }, - { 34, 152 }, { 35, 152 }, { 36, 152 }, { 37, 200 }, { 0, 0 }, - { 39, 152 }, { 40, 152 }, { 41, 152 }, { 42, 152 }, { 43, 152 }, - { 0, 0 }, { 0, 0 }, { 46, 152 }, { 0, 0 }, { 0,4489 }, - { 1, 925 }, { 2, 925 }, { 3, 925 }, { 4, 925 }, { 5, 925 }, - { 6, 925 }, { 7, 925 }, { 8, 925 }, { 9, 925 }, { 10, 925 }, - { 11, 925 }, { 12, 925 }, { 13, 973 }, { 14, 925 }, { 15, 925 }, - { 16, 925 }, { 17, 925 }, { 18, 925 }, { 19, 925 }, { 20, 925 }, - - { 21, 925 }, { 22, 925 }, { 23, 925 }, { 24, 925 }, { 25, 925 }, - { 26, 925 }, { 27, 925 }, { 28, 925 }, { 29, 925 }, { 30, 925 }, - { 31, 925 }, { 32, 925 }, { 33, 925 }, { 34, 925 }, { 35, 925 }, - { 36, 925 }, { 37, 925 }, { 38, 925 }, { 39, 925 }, { 40, 925 }, - { 41, 925 }, { 42, 925 }, { 43, 925 }, { 44, 925 }, { 45, 925 }, - { 46, 925 }, { 0, 0 }, { 0,4441 }, { 0, 0 }, { 0,4439 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 19, -98 }, { 20, -98 }, - - { 21, -98 }, { 22, -98 }, { 23, -98 }, { 24, -98 }, { 0, 10 }, - { 0,4413 }, { 0, 0 }, { 30, 56 }, { 31, 56 }, { 32, 56 }, - { 33, 56 }, { 34, 56 }, { 35, 56 }, { 36, 56 }, { 37, 104 }, - { 10,-635 }, { 39, 56 }, { 40, 56 }, { 41, 56 }, { 42, 56 }, - { 43, 56 }, { 16, -28 }, { 17, -26 }, { 46, 56 }, { 19, 0 }, - { 20, 0 }, { 21, 0 }, { 22, 0 }, { 23, 0 }, { 24, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 20 }, { 0,4385 }, { 0, 0 }, - { 30, 28 }, { 31, 28 }, { 32, 28 }, { 33, 28 }, { 34, 28 }, - { 35, 28 }, { 36, 28 }, { 37, 76 }, { 0, 0 }, { 39, 28 }, - { 40, 28 }, { 41, 28 }, { 42, 28 }, { 43, 28 }, { 16, 917 }, - - { 0, 0 }, { 46, 28 }, { 19, 917 }, { 20, 917 }, { 21, 917 }, - { 22, 917 }, { 23, 917 }, { 24, 917 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 917 }, { 31, 917 }, - { 32, 917 }, { 33, 917 }, { 34, 917 }, { 35, 917 }, { 36, 917 }, - { 37, 965 }, { 0, 0 }, { 39, 917 }, { 40, 917 }, { 41, 917 }, - { 42, 917 }, { 43, 917 }, { 0, 0 }, { 0, 0 }, { 46, 917 }, - { 0, 0 }, { 0,4337 }, { 1, 965 }, { 2, 965 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 6, 965 }, { 7, 965 }, { 8, 965 }, - { 9, 965 }, { 10, 965 }, { 11, 965 }, { 12, 965 }, { 13, 965 }, - { 14, 965 }, { 15, 965 }, { 16, 965 }, { 17, 965 }, { 18, 965 }, - - { 19,1010 }, { 20,1010 }, { 21,1010 }, { 22,1010 }, { 23,1010 }, - { 24,1010 }, { 25, 965 }, { 26, 965 }, { 27, 965 }, { 28, 965 }, - { 29, 965 }, { 30,1010 }, { 31,1010 }, { 32,1010 }, { 33, 965 }, - { 34, 965 }, { 35, 965 }, { 36, 965 }, { 37, 965 }, { 38, 965 }, - { 39,1010 }, { 40,1010 }, { 41, 965 }, { 42, 965 }, { 43, 965 }, - { 44, 965 }, { 45, 965 }, { 46, 965 }, { 0, 0 }, { 0,4289 }, - { 0, 0 }, { 0,4287 }, { 0, 0 }, { 0,4285 }, { 0, 9 }, - { 0,4283 }, { 0, 4 }, { 0,4281 }, { 0, 3 }, { 0,4279 }, - { 0, 2 }, { 0,4277 }, { 0, 0 }, { 0,4275 }, { 0, 22 }, - { 0,4273 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16, 541 }, - - { 19, 159 }, { 0, 0 }, { 21, 167 }, { 0, 0 }, { 23, 308 }, - { 0, 0 }, { 0,4262 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 35, 27 }, - { 34, 504 }, { 37, 988 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 42, 27 }, { 41, 504 }, { 30, 45 }, { 31, 45 }, - { 32, 45 }, { 33, 45 }, { 34, 45 }, { 35, 45 }, { 36, 45 }, - { 37, 93 }, { 0, 0 }, { 39, 45 }, { 40, 45 }, { 41, 45 }, - { 42, 45 }, { 43, 45 }, { 0, 17 }, { 0,4230 }, { 46, 45 }, - { 0, 0 }, { 0, 0 }, { 36, 532 }, { 37,1945 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 43, 532 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16, 954 }, - { 0, 0 }, { 0, 0 }, { 19, 954 }, { 20, 954 }, { 21, 954 }, - { 22, 954 }, { 23, 954 }, { 24, 954 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 954 }, { 31, 954 }, - { 32, 954 }, { 33, 954 }, { 34, 954 }, { 35, 954 }, { 36, 954 }, - { 37,1002 }, { 0, 0 }, { 39, 954 }, { 40, 954 }, { 41, 954 }, - { 42, 954 }, { 43, 954 }, { 0, 0 }, { 0, 0 }, { 46, 954 }, - { 0, 0 }, { 0,4182 }, { 1,1002 }, { 2,1002 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 6,1002 }, { 7,1002 }, { 8,1002 }, - { 9,1002 }, { 10,1002 }, { 11,1002 }, { 12,1002 }, { 13,1002 }, - - { 14,1002 }, { 15,1002 }, { 16,1002 }, { 17,1002 }, { 18,1002 }, - { 19,1047 }, { 20,1047 }, { 21,1047 }, { 22,1047 }, { 23,1047 }, - { 24,1047 }, { 25,1002 }, { 26,1002 }, { 27,1002 }, { 28,1002 }, - { 29,1002 }, { 30,1047 }, { 31,1047 }, { 32,1047 }, { 33,1002 }, - { 34,1002 }, { 35,1002 }, { 36,1002 }, { 37,1002 }, { 38,1002 }, - { 39,1047 }, { 40,1047 }, { 41,1002 }, { 42,1002 }, { 43,1002 }, - { 44,1002 }, { 45,1002 }, { 46,1002 }, { 0, 7 }, { 0,4134 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0,4128 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 12,-149 }, { 0, 0 }, { 0,4120 }, { 0, 0 }, - - { 16, 0 }, { 0, 0 }, { 0, 0 }, { 19, 0 }, { 20, 0 }, - { 21, 0 }, { 22, 0 }, { 23, 0 }, { 24, 0 }, { 19, 954 }, - { 0, 0 }, { 21, 8 }, { 0, 0 }, { 23, 149 }, { 30, 0 }, - { 31, 0 }, { 32, 0 }, { 33, 0 }, { 34, 0 }, { 35, 0 }, - { 36, 0 }, { 37, 48 }, { 0, 0 }, { 39, 0 }, { 40, 0 }, - { 41, 0 }, { 42, 0 }, { 43, 0 }, { 0, 0 }, { 31,1829 }, - { 46, 0 }, { 0, 0 }, { 0,4086 }, { 1, 996 }, { 2, 996 }, - { 0, 0 }, { 0, 0 }, { 39,1829 }, { 6, 996 }, { 7, 996 }, - { 8, 996 }, { 9, 996 }, { 10, 996 }, { 11, 996 }, { 12, 996 }, - { 13, 996 }, { 14, 996 }, { 15, 996 }, { 16, 996 }, { 17, 996 }, - - { 18, 996 }, { 19,1041 }, { 20,1041 }, { 21,1041 }, { 22,1041 }, - { 23,1041 }, { 24,1041 }, { 25, 996 }, { 26, 996 }, { 27, 996 }, - { 28, 996 }, { 29, 996 }, { 30,1041 }, { 31,1041 }, { 32,1041 }, - { 33, 996 }, { 34, 996 }, { 35, 996 }, { 36, 996 }, { 37, 996 }, - { 38, 996 }, { 39,1041 }, { 40,1041 }, { 41, 996 }, { 42, 996 }, - { 43, 996 }, { 44, 996 }, { 45, 996 }, { 46, 996 }, { 0, 7 }, - { 0,4038 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 12,-245 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16, -96 }, { 0, 0 }, { 0, 0 }, { 19, -96 }, - - { 20, -96 }, { 21, -96 }, { 22, -96 }, { 23, -96 }, { 24, -96 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, -96 }, { 31, -96 }, { 32, -96 }, { 33, -96 }, { 34, -96 }, - { 35, -96 }, { 36, -96 }, { 37, -48 }, { 0, 0 }, { 39, -96 }, - { 40, -96 }, { 41, -96 }, { 42, -96 }, { 43, -96 }, { 0, 7 }, - { 0,3993 }, { 46, -96 }, { 2, -45 }, { 3, -45 }, { 4, -45 }, - { 5, 993 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 12,-290 }, { 0, 0 }, { 0,3979 }, - { 0, 0 }, { 16,-141 }, { 0, 0 }, { 0, 0 }, { 19,1038 }, - { 20,1038 }, { 21,1038 }, { 22,1038 }, { 23,1038 }, { 24,1038 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30,1038 }, { 31,1038 }, { 32,1038 }, { 33,-141 }, { 34,-141 }, - { 35,-141 }, { 36,-141 }, { 37, -93 }, { 0, 0 }, { 39,1038 }, - { 40,1038 }, { 41,-141 }, { 42,-141 }, { 43,-141 }, { 0, 0 }, - { 31,1697 }, { 46,-141 }, { 0, 18 }, { 0,3945 }, { 1,-1072 }, - { 2,-1072 }, { 0, 0 }, { 0, 0 }, { 39,1697 }, { 6,-1072 }, - { 7,-1194 }, { 8,-1072 }, { 9,-1072 }, { 10,-1072 }, { 11,-1072 }, - { 12,-1072 }, { 13,-1072 }, { 14,-1072 }, { 15,-1072 }, { 16,-1072 }, - { 17,-1072 }, { 18,-1072 }, { 19,-1072 }, { 20,-1072 }, { 21,-1072 }, - { 22,-1072 }, { 23,-1072 }, { 24,-1072 }, { 25,-1072 }, { 26,-1072 }, - - { 27,-1072 }, { 28,-1072 }, { 29,-1072 }, { 30,-1072 }, { 31,-1072 }, - { 32,-1072 }, { 33,-1072 }, { 34,-1072 }, { 35,-1072 }, { 36,-1072 }, - { 37,-1024 }, { 38,-1072 }, { 39,-1072 }, { 40,-1072 }, { 41,-1072 }, - { 42,-1072 }, { 43,-1072 }, { 44,-1072 }, { 45,-1072 }, { 46,-976 }, - { 0, 18 }, { 0,3897 }, { 1,-1120 }, { 2,-1120 }, { 3,-1120 }, - { 0, 0 }, { 0, 0 }, { 6,-1120 }, { 7,-1242 }, { 8,-1120 }, - { 9,-1120 }, { 10,-1120 }, { 11,-1120 }, { 12,-1120 }, { 13,-1120 }, - { 14,-1120 }, { 15,-1120 }, { 16,-1120 }, { 17,-1120 }, { 18,-1120 }, - { 19,-1120 }, { 20,-1120 }, { 21,-1120 }, { 22,-1120 }, { 23,-1120 }, - { 24,-1120 }, { 25,-1120 }, { 26,-1120 }, { 27,-1120 }, { 28,-1120 }, - - { 29,-1120 }, { 30,-1120 }, { 31,-1120 }, { 32,-1120 }, { 33,-1120 }, - { 34,-1120 }, { 35,-1120 }, { 36,-1120 }, { 37,-1072 }, { 38,-1120 }, - { 39,-1120 }, { 40,-1120 }, { 41,-1120 }, { 42,-1120 }, { 43,-1120 }, - { 44,-1120 }, { 45,-1120 }, { 46,-1024 }, { 0, 18 }, { 0,3849 }, - { 1,-1168 }, { 2, 942 }, { 3, -96 }, { 4, -96 }, { 5, 990 }, - { 6,-1168 }, { 7,-1290 }, { 8,-1168 }, { 9,-1168 }, { 10,-1168 }, - { 11,-1168 }, { 12,-1168 }, { 13,-1168 }, { 14,-1168 }, { 15,-1168 }, - { 16,-1168 }, { 17,-1168 }, { 18,-1168 }, { 19,1038 }, { 20,1038 }, - { 21,1038 }, { 22,1038 }, { 23,1038 }, { 24,1038 }, { 25,-1168 }, - { 26,-1168 }, { 27,-1168 }, { 28,-1168 }, { 29,-1168 }, { 30,1038 }, - - { 31,1038 }, { 32,1038 }, { 33,-1168 }, { 34,-1168 }, { 35,-1168 }, - { 36,-1168 }, { 37,-1120 }, { 38,-1168 }, { 39,1038 }, { 40,1038 }, - { 41,-1168 }, { 42,-1168 }, { 43,-1168 }, { 44,-1168 }, { 45,-1168 }, - { 46,-1072 }, { 0, 11 }, { 0,3801 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1072 }, { 0, 0 }, - { 0,3783 }, { 19,-1072 }, { 20,-1072 }, { 21,-1072 }, { 22,-1072 }, - { 23,-1072 }, { 24,-1072 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 30,-1072 }, { 31,-1072 }, { 32,-1072 }, - - { 33,-1072 }, { 34,-1072 }, { 35,-1072 }, { 36,-1072 }, { 37,-1024 }, - { 0, 0 }, { 39,-1072 }, { 40,-1072 }, { 41,-1072 }, { 42,-1072 }, - { 43,-1072 }, { 0, 11 }, { 0,3756 }, { 46,-1072 }, { 2, -45 }, - { 3, -45 }, { 4, -45 }, { 5, 993 }, { 0, 0 }, { 0, 0 }, - { 35,-479 }, { 0, 0 }, { 37, 482 }, { 0, 0 }, { 0,3744 }, - { 0, 23 }, { 0,3742 }, { 42,-479 }, { 16,-1117 }, { 0, 0 }, - { 0, 0 }, { 19,1038 }, { 20,1038 }, { 21,1038 }, { 22,1038 }, - { 23,1038 }, { 24,1038 }, { 0, 0 }, { 0,3730 }, { 0, 0 }, - { 16, 572 }, { 0, 0 }, { 30,1038 }, { 31,1038 }, { 32,1038 }, - { 33,-1117 }, { 34,-1117 }, { 35,-1117 }, { 36,-1117 }, { 37,-1069 }, - - { 12, 560 }, { 39,1038 }, { 40,1038 }, { 41,-1117 }, { 42,-1117 }, - { 43,-1117 }, { 0, 0 }, { 0, 0 }, { 46,-1117 }, { 0, 18 }, - { 0,3708 }, { 1,-1069 }, { 2,-1069 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 6,-1069 }, { 7,-1069 }, { 8,-1069 }, { 9,-1069 }, - { 10,-1069 }, { 11,-1431 }, { 12,-1069 }, { 13,-1069 }, { 14,-1069 }, - { 15,-1069 }, { 16,-1069 }, { 17,-1069 }, { 18,-1069 }, { 19,-1069 }, - { 20,-1069 }, { 21,-1069 }, { 22,-1069 }, { 23,-1069 }, { 24,-1069 }, - { 25,-1069 }, { 26,-1069 }, { 27,-1069 }, { 28,-1069 }, { 29,-1069 }, - { 30,-1069 }, { 31,-1069 }, { 32,-1069 }, { 33,-1069 }, { 34,-1069 }, - { 35,-1069 }, { 36,-1069 }, { 37,-1021 }, { 38,-1069 }, { 39,-1069 }, - - { 40,-1069 }, { 41,-1069 }, { 42,-1069 }, { 43,-1069 }, { 44,-1069 }, - { 45,-1069 }, { 46,-973 }, { 0, 18 }, { 0,3660 }, { 1,-1117 }, - { 2,-1117 }, { 3,-1117 }, { 0, 0 }, { 0, 0 }, { 6,-1117 }, - { 7,-1117 }, { 8,-1117 }, { 9,-1117 }, { 10,-1117 }, { 11,-1479 }, - { 12,-1117 }, { 13,-1117 }, { 14,-1117 }, { 15,-1117 }, { 16,-1117 }, - { 17,-1117 }, { 18,-1117 }, { 19,-1117 }, { 20,-1117 }, { 21,-1117 }, - { 22,-1117 }, { 23,-1117 }, { 24,-1117 }, { 25,-1117 }, { 26,-1117 }, - { 27,-1117 }, { 28,-1117 }, { 29,-1117 }, { 30,-1117 }, { 31,-1117 }, - { 32,-1117 }, { 33,-1117 }, { 34,-1117 }, { 35,-1117 }, { 36,-1117 }, - { 37,-1069 }, { 38,-1117 }, { 39,-1117 }, { 40,-1117 }, { 41,-1117 }, - - { 42,-1117 }, { 43,-1117 }, { 44,-1117 }, { 45,-1117 }, { 46,-1021 }, - { 0, 18 }, { 0,3612 }, { 1,-1165 }, { 2, 942 }, { 3, -96 }, - { 4, -96 }, { 5, 990 }, { 6,-1165 }, { 7,-1165 }, { 8,-1165 }, - { 9,-1165 }, { 10,-1165 }, { 11,-1527 }, { 12,-1165 }, { 13,-1165 }, - { 14,-1165 }, { 15,-1165 }, { 16,-1165 }, { 17,-1165 }, { 18,-1165 }, - { 19,1038 }, { 20,1038 }, { 21,1038 }, { 22,1038 }, { 23,1038 }, - { 24,1038 }, { 25,-1165 }, { 26,-1165 }, { 27,-1165 }, { 28,-1165 }, - { 29,-1165 }, { 30,1038 }, { 31,1038 }, { 32,1038 }, { 33,-1165 }, - { 34,-1165 }, { 35,-1165 }, { 36,-1165 }, { 37,-1117 }, { 38,-1165 }, - { 39,1038 }, { 40,1038 }, { 41,-1165 }, { 42,-1165 }, { 43,-1165 }, - - { 44,-1165 }, { 45,-1165 }, { 46,-1069 }, { 0, 0 }, { 0,3564 }, - { 1, 0 }, { 2, 0 }, { 3, 0 }, { 4, 0 }, { 5, 0 }, - { 6, 0 }, { 7, 0 }, { 8, 0 }, { 9, 0 }, { 10, 0 }, - { 11, 0 }, { 12, 0 }, { 13, 48 }, { 14, 0 }, { 15, 0 }, - { 16, 0 }, { 17, 0 }, { 18, 0 }, { 19, 0 }, { 20, 0 }, - { 21, 0 }, { 22, 0 }, { 23, 0 }, { 24, 0 }, { 25, 0 }, - { 26, 0 }, { 27, 0 }, { 28, 0 }, { 29, 0 }, { 30, 0 }, - { 31, 0 }, { 32, 0 }, { 33, 0 }, { 34, 0 }, { 35, 0 }, - { 36, 0 }, { 37, 0 }, { 38, 0 }, { 39, 0 }, { 40, 0 }, - { 41, 0 }, { 42, 0 }, { 43, 0 }, { 44, 0 }, { 45, 0 }, - - { 46, 0 }, { 0, 0 }, { 0,3516 }, { 1, 990 }, { 2, 990 }, - { 3, 990 }, { 4, 990 }, { 5, 990 }, { 6, 990 }, { 7, 990 }, - { 8, 990 }, { 9, 990 }, { 10, 990 }, { 11, 990 }, { 12, 990 }, - { 13, 0 }, { 14, 990 }, { 15, 990 }, { 16, 990 }, { 17, 990 }, - { 18,-226 }, { 19, 990 }, { 20, 990 }, { 21, 990 }, { 22, 990 }, - { 23, 990 }, { 24, 990 }, { 25, 990 }, { 26, 990 }, { 27, 990 }, - { 28, 990 }, { 29, 990 }, { 30, 990 }, { 31, 990 }, { 32, 990 }, - { 33, 990 }, { 34, 990 }, { 35, 990 }, { 36, 990 }, { 37, 990 }, - { 38, 990 }, { 39, 990 }, { 40, 990 }, { 41, 990 }, { 42, 990 }, - { 43, 990 }, { 44, 990 }, { 45, 990 }, { 46, 990 }, { 0, 20 }, - - { 0,3468 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0,3462 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0,3456 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16, 0 }, { 0, 0 }, { 0, 0 }, { 19, 0 }, - { 20, 0 }, { 21, 0 }, { 22, 0 }, { 23, 0 }, { 24, 0 }, - { 19, 468 }, { 0, 0 }, { 21, 6 }, { 0, 0 }, { 23, 147 }, - { 30, 0 }, { 31, 0 }, { 32, 0 }, { 33, 0 }, { 34, 0 }, - { 35, 0 }, { 36, 0 }, { 37, 48 }, { 0, 0 }, { 39, 0 }, - { 40, 0 }, { 41, 0 }, { 42, 0 }, { 43, 0 }, { 32,1854 }, - { 0, 0 }, { 46, 0 }, { 0, 0 }, { 0,3420 }, { 1, 942 }, - - { 2, 942 }, { 0, 0 }, { 40,1854 }, { 0, 0 }, { 6, 942 }, - { 7, 942 }, { 8, 942 }, { 9, 942 }, { 10, 942 }, { 11, 942 }, - { 12, 942 }, { 13, 942 }, { 14, 942 }, { 15, 942 }, { 16, 942 }, - { 17, 942 }, { 18, 942 }, { 19, 987 }, { 20, 987 }, { 21, 987 }, - { 22, 987 }, { 23, 987 }, { 24, 987 }, { 25, 942 }, { 26, 942 }, - { 27, 942 }, { 28, 942 }, { 29, 942 }, { 30, 987 }, { 31, 987 }, - { 32, 987 }, { 33, 942 }, { 34, 942 }, { 35, 942 }, { 36, 942 }, - { 37, 942 }, { 38, 942 }, { 39, 987 }, { 40, 987 }, { 41, 942 }, - { 42, 942 }, { 43, 942 }, { 44, 942 }, { 45, 942 }, { 46, 942 }, - { 0, 20 }, { 0,3372 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 16, -96 }, { 0, 0 }, { 0, 0 }, - { 19, -96 }, { 20, -96 }, { 21, -96 }, { 22, -96 }, { 23, -96 }, - { 24, -96 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 30, -96 }, { 31, -96 }, { 32, -96 }, { 33, -96 }, - { 34, -96 }, { 35, -96 }, { 36, -96 }, { 37, -48 }, { 0, 0 }, - { 39, -96 }, { 40, -96 }, { 41, -96 }, { 42, -96 }, { 43, -96 }, - { 0, 20 }, { 0,3327 }, { 46, -96 }, { 2, -45 }, { 3, -45 }, - { 4, -45 }, { 5, 939 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0,3315 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 16,-141 }, { 0, 0 }, { 0, 0 }, - { 19, 984 }, { 20, 984 }, { 21, 984 }, { 22, 984 }, { 23, 984 }, - { 24, 984 }, { 0, 0 }, { 0,3301 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 30, 984 }, { 31, 984 }, { 32, 984 }, { 33,-141 }, - { 34,-141 }, { 35,-141 }, { 36,-141 }, { 37, -93 }, { 0, 0 }, - { 39, 984 }, { 40, 984 }, { 41,-141 }, { 42,-141 }, { 43,-141 }, - { 32,1755 }, { 19,-161 }, { 46,-141 }, { 21,-155 }, { 0, 0 }, - { 23, -14 }, { 0, 17 }, { 0,3276 }, { 40,1755 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 0,3268 }, { 0, 0 }, { 35, 33 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16, 0 }, { 42, 33 }, - { 0, 0 }, { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, - { 23, 0 }, { 24, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 30, 0 }, { 31, 0 }, { 32, 0 }, - { 33, 0 }, { 34, 0 }, { 35, 0 }, { 36, 0 }, { 37, 48 }, - { 0, 0 }, { 39, 0 }, { 40, 0 }, { 41, 0 }, { 42, 0 }, - { 43, 0 }, { 36,-462 }, { 37, 951 }, { 46, 0 }, { 0, 0 }, - { 0,3228 }, { 1, 970 }, { 2, 970 }, { 43,-462 }, { 0, 0 }, - { 0, 0 }, { 6, 970 }, { 7, 970 }, { 8, 970 }, { 9, 970 }, - - { 10, 970 }, { 11, 970 }, { 12, 970 }, { 13, 970 }, { 14, 970 }, - { 15, 970 }, { 16, 970 }, { 17, 970 }, { 18, 970 }, { 19,1015 }, - { 20,1015 }, { 21,1015 }, { 22,1015 }, { 23,1015 }, { 24,1015 }, - { 25, 970 }, { 26, 970 }, { 27, 970 }, { 28, 970 }, { 29, 970 }, - { 30,1015 }, { 31,1015 }, { 32,1015 }, { 33, 970 }, { 34, 970 }, - { 35, 970 }, { 36, 970 }, { 37, 970 }, { 38, 970 }, { 39,1015 }, - { 40,1015 }, { 41, 970 }, { 42, 970 }, { 43, 970 }, { 44, 970 }, - { 45, 970 }, { 46, 970 }, { 0, 17 }, { 0,3180 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0,3174 }, - { 0, 21 }, { 0,3172 }, { 0, 16 }, { 0,3170 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16, -96 }, - { 0, 0 }, { 0, 0 }, { 19, -96 }, { 20, -96 }, { 21, -96 }, - { 22, -96 }, { 23, -96 }, { 24, -96 }, { 19, 417 }, { 0, 0 }, - { 21,-946 }, { 0, 0 }, { 23,-805 }, { 30, -96 }, { 31, -96 }, - { 32, -96 }, { 33, -96 }, { 34, -96 }, { 35, -96 }, { 36, -96 }, - { 37, -48 }, { 0, 0 }, { 39, -96 }, { 40, -96 }, { 41, -96 }, - { 42, -96 }, { 43, -96 }, { 0, 17 }, { 0,3135 }, { 46, -96 }, - { 2, -45 }, { 3, -45 }, { 4, -45 }, { 5, 967 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-141 }, - - { 0, 0 }, { 0, 0 }, { 19,1012 }, { 20,1012 }, { 21,1012 }, - { 22,1012 }, { 23,1012 }, { 24,1012 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0,3107 }, { 0, 0 }, { 30,1012 }, { 31,1012 }, - { 32,1012 }, { 33,-141 }, { 34,-141 }, { 35,-141 }, { 36,-141 }, - { 37, -93 }, { 0, 0 }, { 39,1012 }, { 40,1012 }, { 41,-141 }, - { 42,-141 }, { 43,-141 }, { 0, 7 }, { 0,3090 }, { 46,-141 }, - { 19, 823 }, { 0, 0 }, { 0,3086 }, { 22, 21 }, { 0, 0 }, - { 24, 69 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 12,-1193 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1044 }, - { 0, 0 }, { 0, 0 }, { 19,-1044 }, { 20,-1044 }, { 21,-1044 }, - - { 22,-1044 }, { 23,-1044 }, { 24,-1044 }, { 21,2013 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30,-1044 }, { 31,-1044 }, - { 32,-1044 }, { 33,-1044 }, { 34,-1044 }, { 35,-1044 }, { 36,-1044 }, - { 37,-996 }, { 0, 0 }, { 39,-1044 }, { 40,-1044 }, { 41,-1044 }, - { 42,-1044 }, { 43,-1044 }, { 0, 7 }, { 0,3045 }, { 46,-1044 }, - { 2, -45 }, { 3, -45 }, { 4, -45 }, { 5, 967 }, { 0, 0 }, - { 0,3038 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 12,-1238 }, { 0, 0 }, { 0,3031 }, { 0, 0 }, { 16,-1089 }, - { 0, 0 }, { 0, 0 }, { 19,1012 }, { 20,1012 }, { 21,1012 }, - { 22,1012 }, { 23,1012 }, { 24,1012 }, { 0, 0 }, { 12,-139 }, - - { 0, 0 }, { 21,1965 }, { 0, 0 }, { 30,1012 }, { 31,1012 }, - { 32,1012 }, { 33,-1089 }, { 34,-1089 }, { 35,-1089 }, { 36,-1089 }, - { 37,-1041 }, { 0, 0 }, { 39,1012 }, { 40,1012 }, { 41,-1089 }, - { 42,-1089 }, { 43,-1089 }, { 0, 7 }, { 0,3000 }, { 46,-1089 }, - { 0, 0 }, { 3,-1038 }, { 0, 0 }, { 0, 0 }, { 0,2994 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 12,-1283 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1134 }, - { 0, 0 }, { 0, 0 }, { 19,-1134 }, { 20,-1134 }, { 21,-1134 }, - { 22,-1134 }, { 23,-1134 }, { 24,-1134 }, { 19, 723 }, { 0, 0 }, - { 21,-462 }, { 0, 0 }, { 23,-321 }, { 30,-1134 }, { 31,-1134 }, - - { 32,-1134 }, { 33,-1134 }, { 34,-1134 }, { 35,-1134 }, { 36,-1134 }, - { 37,-1086 }, { 0, 0 }, { 39,-1134 }, { 40,-1134 }, { 41,-1134 }, - { 42,-1134 }, { 43,-1134 }, { 0, 7 }, { 0,2955 }, { 46,-1134 }, - { 2,-1083 }, { 3,-1083 }, { 4,-1083 }, { 5, -45 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 12,-1328 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1179 }, - { 0, 0 }, { 0, 0 }, { 19, 967 }, { 20, 967 }, { 21, 967 }, - { 22, 967 }, { 23, 967 }, { 24, 967 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 967 }, { 31, 967 }, - { 32, 967 }, { 33,-1179 }, { 34,-1179 }, { 35,-1179 }, { 36,-1179 }, - - { 37,-1131 }, { 0, 0 }, { 39, 967 }, { 40, 967 }, { 41,-1179 }, - { 42,-1179 }, { 43,-1179 }, { 0, 0 }, { 0, 0 }, { 46,-1179 }, - { 0, 18 }, { 0,2907 }, { 1,-2110 }, { 2,-2110 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 6,-2110 }, { 7,-2232 }, { 8,-2110 }, - { 9,-2110 }, { 10,-2110 }, { 11,-2110 }, { 12,-2110 }, { 13,-2110 }, - { 14,-2110 }, { 15,-2110 }, { 16,-2110 }, { 17,-2110 }, { 18,-2110 }, - { 19,-2110 }, { 20,-2110 }, { 21,-2110 }, { 22,-2110 }, { 23,-2110 }, - { 24,-2110 }, { 25,-2110 }, { 26,-2110 }, { 27,-2110 }, { 28,-2110 }, - { 29,-2110 }, { 30,-2110 }, { 31,-2110 }, { 32,-2110 }, { 33,-2110 }, - { 34,-2110 }, { 35,-2110 }, { 36,-2110 }, { 37,-2062 }, { 38,-2110 }, - - { 39,-2110 }, { 40,-2110 }, { 41,-2110 }, { 42,-2110 }, { 43,-2110 }, - { 44,-2110 }, { 45,-2110 }, { 46,-2014 }, { 0, 18 }, { 0,2859 }, - { 1,-2158 }, { 2,-2158 }, { 3,-1086 }, { 0, 0 }, { 0, 0 }, - { 6,-2158 }, { 7,-2280 }, { 8,-2158 }, { 9,-2158 }, { 10,-2158 }, - { 11,-2158 }, { 12,-2158 }, { 13,-2158 }, { 14,-2158 }, { 15,-2158 }, - { 16,-2158 }, { 17,-2158 }, { 18,-2158 }, { 19,-2158 }, { 20,-2158 }, - { 21,-2158 }, { 22,-2158 }, { 23,-2158 }, { 24,-2158 }, { 25,-2158 }, - { 26,-2158 }, { 27,-2158 }, { 28,-2158 }, { 29,-2158 }, { 30,-2158 }, - { 31,-2158 }, { 32,-2158 }, { 33,-2158 }, { 34,-2158 }, { 35,-2158 }, - { 36,-2158 }, { 37,-2110 }, { 38,-2158 }, { 39,-2158 }, { 40,-2158 }, - - { 41,-2158 }, { 42,-2158 }, { 43,-2158 }, { 44,-2158 }, { 45,-2158 }, - { 46,-2062 }, { 0, 18 }, { 0,2811 }, { 1,-2206 }, { 2, -96 }, - { 3,-1134 }, { 4,-1134 }, { 5, -48 }, { 6,-2206 }, { 7,-2328 }, - { 8,-2206 }, { 9,-2206 }, { 10,-2206 }, { 11,-2206 }, { 12,-2206 }, - { 13,-2206 }, { 14,-2206 }, { 15,-2206 }, { 16,-2206 }, { 17,-2206 }, - { 18,-2206 }, { 19, 871 }, { 20, 871 }, { 21, 871 }, { 22, 871 }, - { 23, 871 }, { 24, 871 }, { 25,-2206 }, { 26,-2206 }, { 27,-2206 }, - { 28,-2206 }, { 29,-2206 }, { 30, 871 }, { 31, 871 }, { 32, 871 }, - { 33,-2206 }, { 34,-2206 }, { 35,-2206 }, { 36,-2206 }, { 37,-2158 }, - { 38,-2206 }, { 39, 871 }, { 40, 871 }, { 41,-2206 }, { 42,-2206 }, - - { 43,-2206 }, { 44,-2206 }, { 45,-2206 }, { 46,-2110 }, { 0, 11 }, - { 0,2763 }, { 0, 0 }, { 0, 0 }, { 3,-1038 }, { 0, 0 }, - { 0, 0 }, { 0,2757 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-2110 }, { 0, 0 }, { 0,2745 }, { 19,-2110 }, - { 20,-2110 }, { 21,-2110 }, { 22,-2110 }, { 23,-2110 }, { 24,-2110 }, - { 19, 570 }, { 0, 0 }, { 21,-1363 }, { 0, 0 }, { 23,-1222 }, - { 30,-2110 }, { 31,-2110 }, { 32,-2110 }, { 33,-2110 }, { 34,-2110 }, - { 35,-2110 }, { 36,-2110 }, { 37,-2062 }, { 0, 0 }, { 39,-2110 }, - { 40,-2110 }, { 41,-2110 }, { 42,-2110 }, { 43,-2110 }, { 0, 11 }, - - { 0,2718 }, { 46,-2110 }, { 2,-1083 }, { 3,-1083 }, { 4,-1083 }, - { 5, -45 }, { 0, 0 }, { 0, 0 }, { 35,-1517 }, { 0, 0 }, - { 37,-556 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 42,-1517 }, { 16,-2155 }, { 0, 0 }, { 0, 0 }, { 19, 826 }, - { 20, 826 }, { 21, 826 }, { 22, 826 }, { 23, 826 }, { 24, 826 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, 826 }, { 31, 826 }, { 32, 826 }, { 33,-2155 }, { 34,-2155 }, - { 35,-2155 }, { 36,-2155 }, { 37,-2107 }, { 0, 0 }, { 39, 826 }, - { 40, 826 }, { 41,-2155 }, { 42,-2155 }, { 43,-2155 }, { 0, 0 }, - { 0, 0 }, { 46,-2155 }, { 0, 18 }, { 0,2670 }, { 1,-2107 }, - - { 2,-2107 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6,-2107 }, - { 7,-2107 }, { 8,-2107 }, { 9,-2107 }, { 10,-2107 }, { 11,-2469 }, - { 12,-2107 }, { 13,-2107 }, { 14,-2107 }, { 15,-2107 }, { 16,-2107 }, - { 17,-2107 }, { 18,-2107 }, { 19,-2107 }, { 20,-2107 }, { 21,-2107 }, - { 22,-2107 }, { 23,-2107 }, { 24,-2107 }, { 25,-2107 }, { 26,-2107 }, - { 27,-2107 }, { 28,-2107 }, { 29,-2107 }, { 30,-2107 }, { 31,-2107 }, - { 32,-2107 }, { 33,-2107 }, { 34,-2107 }, { 35,-2107 }, { 36,-2107 }, - { 37,-2059 }, { 38,-2107 }, { 39,-2107 }, { 40,-2107 }, { 41,-2107 }, - { 42,-2107 }, { 43,-2107 }, { 44,-2107 }, { 45,-2107 }, { 46,-2011 }, - { 0, 18 }, { 0,2622 }, { 1,-2155 }, { 2,-2155 }, { 3,-1086 }, - - { 0, 0 }, { 0, 0 }, { 6,-2155 }, { 7,-2155 }, { 8,-2155 }, - { 9,-2155 }, { 10,-2155 }, { 11,-2517 }, { 12,-2155 }, { 13,-2155 }, - { 14,-2155 }, { 15,-2155 }, { 16,-2155 }, { 17,-2155 }, { 18,-2155 }, - { 19,-2155 }, { 20,-2155 }, { 21,-2155 }, { 22,-2155 }, { 23,-2155 }, - { 24,-2155 }, { 25,-2155 }, { 26,-2155 }, { 27,-2155 }, { 28,-2155 }, - { 29,-2155 }, { 30,-2155 }, { 31,-2155 }, { 32,-2155 }, { 33,-2155 }, - { 34,-2155 }, { 35,-2155 }, { 36,-2155 }, { 37,-2107 }, { 38,-2155 }, - { 39,-2155 }, { 40,-2155 }, { 41,-2155 }, { 42,-2155 }, { 43,-2155 }, - { 44,-2155 }, { 45,-2155 }, { 46,-2059 }, { 0, 18 }, { 0,2574 }, - { 1,-2203 }, { 2, -96 }, { 3,-1134 }, { 4,-1134 }, { 5, -48 }, - - { 6,-2203 }, { 7,-2203 }, { 8,-2203 }, { 9,-2203 }, { 10,-2203 }, - { 11,-2565 }, { 12,-2203 }, { 13,-2203 }, { 14,-2203 }, { 15,-2203 }, - { 16,-2203 }, { 17,-2203 }, { 18,-2203 }, { 19, 730 }, { 20, 730 }, - { 21, 730 }, { 22, 730 }, { 23, 730 }, { 24, 730 }, { 25,-2203 }, - { 26,-2203 }, { 27,-2203 }, { 28,-2203 }, { 29,-2203 }, { 30, 730 }, - { 31, 730 }, { 32, 730 }, { 33,-2203 }, { 34,-2203 }, { 35,-2203 }, - { 36,-2203 }, { 37,-2155 }, { 38,-2203 }, { 39, 730 }, { 40, 730 }, - { 41,-2203 }, { 42,-2203 }, { 43,-2203 }, { 44,-2203 }, { 45,-2203 }, - { 46,-2107 }, { 0, 0 }, { 0,2526 }, { 1, 730 }, { 2, 730 }, - { 3, 730 }, { 4, 730 }, { 5, 730 }, { 6, 730 }, { 7, 730 }, - - { 8, 730 }, { 9, 730 }, { 10, 730 }, { 11, 730 }, { 12, 730 }, - { 13, 778 }, { 14, 730 }, { 15, 730 }, { 16, 730 }, { 17, 730 }, - { 18, 730 }, { 19, 730 }, { 20, 730 }, { 21, 730 }, { 22, 730 }, - { 23, 730 }, { 24, 730 }, { 25, 730 }, { 26, 730 }, { 27, 730 }, - { 28, 730 }, { 29, 730 }, { 30, 730 }, { 31, 730 }, { 32, 730 }, - { 33, 730 }, { 34, 730 }, { 35, 730 }, { 36, 730 }, { 37, 730 }, - { 38, 730 }, { 39, 730 }, { 40, 730 }, { 41, 730 }, { 42, 730 }, - { 43, 730 }, { 44, 730 }, { 45, 730 }, { 46, 730 }, { 0, 20 }, - { 0,2478 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-990 }, { 0, 0 }, { 0, 0 }, { 19,-990 }, - { 20,-990 }, { 21,-990 }, { 22,-990 }, { 23,-990 }, { 24,-990 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30,-990 }, { 31,-990 }, { 32,-990 }, { 33,-990 }, { 34,-990 }, - { 35,-990 }, { 36,-990 }, { 37,-942 }, { 0, 0 }, { 39,-990 }, - { 40,-990 }, { 41,-990 }, { 42,-990 }, { 43,-990 }, { 0, 20 }, - { 0,2433 }, { 46,-990 }, { 2, -45 }, { 3, -45 }, { 4, -45 }, - { 5, 733 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0,2421 }, { 0, 0 }, { 0, 0 }, - - { 3,-324 }, { 16,-1035 }, { 0, 0 }, { 0, 0 }, { 19, 778 }, - { 20, 778 }, { 21, 778 }, { 22, 778 }, { 23, 778 }, { 24, 778 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, 778 }, { 31, 778 }, { 32, 778 }, { 33,-1035 }, { 34,-1035 }, - { 35,-1035 }, { 36,-1035 }, { 37,-987 }, { 0, 0 }, { 39, 778 }, - { 40, 778 }, { 41,-1035 }, { 42,-1035 }, { 43,-1035 }, { 0, 20 }, - { 0,2388 }, { 46,-1035 }, { 35,-1841 }, { 3,-984 }, { 37,-880 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 42,-1841 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-1080 }, { 0, 0 }, { 0, 0 }, { 19,-1080 }, - - { 20,-1080 }, { 21,-1080 }, { 22,-1080 }, { 23,-1080 }, { 24,-1080 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30,-1080 }, { 31,-1080 }, { 32,-1080 }, { 33,-1080 }, { 34,-1080 }, - { 35,-1080 }, { 36,-1080 }, { 37,-1032 }, { 0, 0 }, { 39,-1080 }, - { 40,-1080 }, { 41,-1080 }, { 42,-1080 }, { 43,-1080 }, { 0, 20 }, - { 0,2343 }, { 46,-1080 }, { 2,-1029 }, { 3,-1029 }, { 4,-1029 }, - { 5, -45 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-1125 }, { 0, 0 }, { 0, 0 }, { 19, 733 }, - { 20, 733 }, { 21, 733 }, { 22, 733 }, { 23, 733 }, { 24, 733 }, - - { 0, 0 }, { 0,2317 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, 733 }, { 31, 733 }, { 32, 733 }, { 33,-1125 }, { 34,-1125 }, - { 35,-1125 }, { 36,-1125 }, { 37,-1077 }, { 0, 0 }, { 39, 733 }, - { 40, 733 }, { 41,-1125 }, { 42,-1125 }, { 43,-1125 }, { 0, 0 }, - { 19,-790 }, { 46,-1125 }, { 0, 0 }, { 22,-769 }, { 0, 0 }, - { 24,-721 }, { 0, 0 }, { 0,2291 }, { 0, 0 }, { 2,-454 }, - { 3,-454 }, { 4,-454 }, { 5,-130 }, { 0, 0 }, { 0,2284 }, - { 0, 0 }, { 0,2282 }, { 36,-714 }, { 2,-463 }, { 3,-463 }, - { 4,-463 }, { 5,-139 }, { 0, 0 }, { 0, 0 }, { 43,-714 }, - { 0, 0 }, { 0, 0 }, { 0,2271 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 19, 189 }, { 0, 0 }, - { 0, 0 }, { 22,-802 }, { 0, 0 }, { 24,-754 }, { 0, 17 }, - { 0,2258 }, { 0, 0 }, { 35,-1971 }, { 0, 0 }, { 37,-1010 }, - { 0, 0 }, { 19, 576 }, { 0, 0 }, { 21,-1185 }, { 42,-1971 }, - { 23,-1044 }, { 35,-1980 }, { 0, 0 }, { 37,-1019 }, { 0, 0 }, - { 0,2243 }, { 16,-1018 }, { 0, 0 }, { 42,-1980 }, { 19,-1018 }, - { 20,-1018 }, { 21,-1018 }, { 22,-1018 }, { 23,-1018 }, { 24,-1018 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30,-1018 }, { 31,-1018 }, { 32,-1018 }, { 33,-1018 }, { 34,-1018 }, - { 35,-1018 }, { 36,-1018 }, { 37,-970 }, { 0, 0 }, { 39,-1018 }, - - { 40,-1018 }, { 41,-1018 }, { 42,-1018 }, { 43,-1018 }, { 0, 17 }, - { 0,2213 }, { 46,-1018 }, { 2, -45 }, { 3, -45 }, { 4, -45 }, - { 5, 678 }, { 36,-1487 }, { 37, -74 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 43,-1487 }, { 0, 0 }, - { 0,2198 }, { 16,-1063 }, { 0, 0 }, { 3, -45 }, { 19, 723 }, - { 20, 723 }, { 21, 723 }, { 22, 723 }, { 23, 723 }, { 24, 723 }, - { 0, 0 }, { 0,2187 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, 723 }, { 31, 723 }, { 32, 723 }, { 33,-1063 }, { 34,-1063 }, - { 35,-1063 }, { 36,-1063 }, { 37,-1015 }, { 0, 0 }, { 39, 723 }, - { 40, 723 }, { 41,-1063 }, { 42,-1063 }, { 43,-1063 }, { 0, 17 }, - - { 0,2168 }, { 46,-1063 }, { 21,-1933 }, { 3,-1012 }, { 23,-1792 }, - { 0, 0 }, { 36,-1532 }, { 37,-119 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 43,-1532 }, { 0, 0 }, - { 0, 0 }, { 16,-1108 }, { 0, 0 }, { 0, 0 }, { 19,-1108 }, - { 20,-1108 }, { 21,-1108 }, { 22,-1108 }, { 23,-1108 }, { 24,-1108 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30,-1108 }, { 31,-1108 }, { 32,-1108 }, { 33,-1108 }, { 34,-1108 }, - { 35,-1108 }, { 36,-1108 }, { 37,-1060 }, { 0, 0 }, { 39,-1108 }, - { 40,-1108 }, { 41,-1108 }, { 42,-1108 }, { 43,-1108 }, { 0, 17 }, - { 0,2123 }, { 46,-1108 }, { 2,-1057 }, { 3,-1057 }, { 4,-1057 }, - - { 5, -45 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-1153 }, { 0, 0 }, { 0, 0 }, { 19, 678 }, - { 20, 678 }, { 21, 678 }, { 22, 678 }, { 23, 678 }, { 24, 678 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0,2095 }, { 0, 0 }, - { 30, 678 }, { 31, 678 }, { 32, 678 }, { 33,-1153 }, { 34,-1153 }, - { 35,-1153 }, { 36,-1153 }, { 37,-1105 }, { 0, 0 }, { 39, 678 }, - { 40, 678 }, { 41,-1153 }, { 42,-1153 }, { 43,-1153 }, { 0, 7 }, - { 0,2078 }, { 46,-1153 }, { 19, 533 }, { 3,-1012 }, { 0, 0 }, - { 22,-991 }, { 0, 0 }, { 24,-943 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 12,-2205 }, { 0, 0 }, { 0,2064 }, - { 0, 0 }, { 16,-2056 }, { 0, 0 }, { 0, 0 }, { 19,-2056 }, - { 20,-2056 }, { 21,-2056 }, { 22,-2056 }, { 23,-2056 }, { 24,-2056 }, - { 0, 0 }, { 12,-1106 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30,-2056 }, { 31,-2056 }, { 32,-2056 }, { 33,-2056 }, { 34,-2056 }, - { 35,-2056 }, { 36,-2056 }, { 37,-2008 }, { 0, 0 }, { 39,-2056 }, - { 40,-2056 }, { 41,-2056 }, { 42,-2056 }, { 43,-2056 }, { 0, 7 }, - { 0,2033 }, { 46,-2056 }, { 2,-1057 }, { 3,-1057 }, { 4,-1057 }, - { 5, -45 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 12,-2250 }, { 0, 0 }, { 0,2019 }, - - { 0, 0 }, { 16,-2101 }, { 3, -45 }, { 0, 0 }, { 19, 633 }, - { 20, 633 }, { 21, 633 }, { 22, 633 }, { 23, 633 }, { 24, 633 }, - { 0, 0 }, { 12,-1151 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, 633 }, { 31, 633 }, { 32, 633 }, { 33,-2101 }, { 34,-2101 }, - { 35,-2101 }, { 36,-2101 }, { 37,-2053 }, { 0, 0 }, { 39, 633 }, - { 40, 633 }, { 41,-2101 }, { 42,-2101 }, { 43,-2101 }, { 0, 7 }, - { 0,1988 }, { 46,-2101 }, { 2,-2050 }, { 3,-2050 }, { 4,-2050 }, - { 5,-1012 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 12,-2295 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-2146 }, { 0, 0 }, { 0, 0 }, { 19, 633 }, - - { 20, 633 }, { 21, 633 }, { 22, 633 }, { 23, 633 }, { 24, 633 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, 633 }, { 31, 633 }, { 32, 633 }, { 33,-2146 }, { 34,-2146 }, - { 35,-2146 }, { 36,-2146 }, { 37,-2098 }, { 0, 0 }, { 39, 633 }, - { 40, 633 }, { 41,-2146 }, { 42,-2146 }, { 43,-2146 }, { 0, 0 }, - { 0, 0 }, { 46,-2146 }, { 0, 18 }, { 0,1940 }, { 1,-3077 }, - { 2,-967 }, { 3,-2005 }, { 4,-2005 }, { 5,-919 }, { 6,-3077 }, - { 7,-3199 }, { 8,-3077 }, { 9,-3077 }, { 10,-3077 }, { 11,-3077 }, - { 12,-3077 }, { 13,-3077 }, { 14,-3077 }, { 15,-3077 }, { 16,-3077 }, - { 17,-3077 }, { 18,-3077 }, { 19, 633 }, { 20, 633 }, { 21, 633 }, - - { 22, 633 }, { 23, 633 }, { 24, 633 }, { 25,-3077 }, { 26,-3077 }, - { 27,-3077 }, { 28,-3077 }, { 29,-3077 }, { 30, 633 }, { 31, 633 }, - { 32, 633 }, { 33,-3077 }, { 34,-3077 }, { 35,-3077 }, { 36,-3077 }, - { 37,-3029 }, { 38,-3077 }, { 39, 633 }, { 40, 633 }, { 41,-3077 }, - { 42,-3077 }, { 43,-3077 }, { 44,-3077 }, { 45,-3077 }, { 46,-2981 }, - { 0, 11 }, { 0,1892 }, { 0, 0 }, { 2,-1909 }, { 3,-1909 }, - { 4,-1909 }, { 5,-871 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 16,-2981 }, { 0, 0 }, { 0, 0 }, - { 19, 633 }, { 20, 633 }, { 21, 633 }, { 22, 633 }, { 23, 633 }, - - { 24, 633 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 30, 633 }, { 31, 633 }, { 32, 633 }, { 33,-2981 }, - { 34,-2981 }, { 35,-2981 }, { 36,-2981 }, { 37,-2933 }, { 0, 0 }, - { 39, 633 }, { 40, 633 }, { 41,-2981 }, { 42,-2981 }, { 43,-2981 }, - { 0, 0 }, { 0, 0 }, { 46,-2981 }, { 0, 18 }, { 0,1844 }, - { 1,-2933 }, { 2,-826 }, { 3,-1864 }, { 4,-1864 }, { 5,-778 }, - { 6,-2933 }, { 7,-2933 }, { 8,-2933 }, { 9,-2933 }, { 10,-2933 }, - { 11,-3295 }, { 12,-2933 }, { 13,-2933 }, { 14,-2933 }, { 15,-2933 }, - { 16,-2933 }, { 17,-2933 }, { 18,-2933 }, { 19, 633 }, { 20, 633 }, - { 21, 633 }, { 22, 633 }, { 23, 633 }, { 24, 633 }, { 25,-2933 }, - - { 26,-2933 }, { 27,-2933 }, { 28,-2933 }, { 29,-2933 }, { 30, 633 }, - { 31, 633 }, { 32, 633 }, { 33,-2933 }, { 34,-2933 }, { 35,-2933 }, - { 36,-2933 }, { 37,-2885 }, { 38,-2933 }, { 39, 633 }, { 40, 633 }, - { 41,-2933 }, { 42,-2933 }, { 43,-2933 }, { 44,-2933 }, { 45,-2933 }, - { 46,-2837 }, { 0, 0 }, { 0,1796 }, { 1, 0 }, { 2, 0 }, - { 3, 0 }, { 4, 0 }, { 5, 0 }, { 6, 0 }, { 7, 0 }, - { 8, 0 }, { 9, 0 }, { 10, 0 }, { 11, 0 }, { 12, 0 }, - { 13, 48 }, { 14, 0 }, { 15, 0 }, { 16, 0 }, { 17, 0 }, - { 18, 0 }, { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, - { 23, 0 }, { 24, 0 }, { 25, 0 }, { 26, 0 }, { 27, 0 }, - - { 28, 0 }, { 29, 0 }, { 30, 0 }, { 31, 0 }, { 32, 0 }, - { 33, 0 }, { 34, 0 }, { 35, 0 }, { 36, 0 }, { 37, 0 }, - { 38, 0 }, { 39, 0 }, { 40, 0 }, { 41, 0 }, { 42, 0 }, - { 43, 0 }, { 44, 0 }, { 45, 0 }, { 46, 0 }, { 0, 0 }, - { 0,1748 }, { 1,-778 }, { 2,-778 }, { 3,-778 }, { 4,-778 }, - { 5,-778 }, { 6,-778 }, { 7,-778 }, { 8,-778 }, { 9,-778 }, - { 10,-778 }, { 11,-778 }, { 12,-778 }, { 13, 0 }, { 14,-778 }, - { 15,-778 }, { 16,-778 }, { 17,-778 }, { 18,-1994 }, { 19,-778 }, - { 20,-778 }, { 21,-778 }, { 22,-778 }, { 23,-778 }, { 24,-778 }, - { 25,-778 }, { 26,-778 }, { 27,-778 }, { 28,-778 }, { 29,-778 }, - - { 30,-778 }, { 31,-778 }, { 32,-778 }, { 33,-778 }, { 34,-778 }, - { 35,-778 }, { 36,-778 }, { 37,-778 }, { 38,-778 }, { 39,-778 }, - { 40,-778 }, { 41,-778 }, { 42,-778 }, { 43,-778 }, { 44,-778 }, - { 45,-778 }, { 46,-778 }, { 0, 20 }, { 0,1700 }, { 0, 0 }, - { 0, 0 }, { 3,-778 }, { 0, 0 }, { 0,1695 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1768 }, - { 0, 0 }, { 0, 0 }, { 19,-1768 }, { 20,-1768 }, { 21,-1768 }, - { 22,-1768 }, { 23,-1768 }, { 24,-1768 }, { 0, 0 }, { 21,-1761 }, - { 0, 0 }, { 23,-1620 }, { 0, 0 }, { 30,-1768 }, { 31,-1768 }, - - { 32,-1768 }, { 33,-1768 }, { 34,-1768 }, { 35,-1768 }, { 36,-1768 }, - { 37,-1720 }, { 0, 0 }, { 39,-1768 }, { 40,-1768 }, { 41,-1768 }, - { 42,-1768 }, { 43,-1768 }, { 0, 20 }, { 0,1655 }, { 46,-1768 }, - { 2,-823 }, { 3,-823 }, { 4,-823 }, { 5, -45 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1813 }, - { 0, 0 }, { 0, 0 }, { 19, 492 }, { 20, 492 }, { 21, 492 }, - { 22, 492 }, { 23, 492 }, { 24, 492 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 492 }, { 31, 492 }, - { 32, 492 }, { 33,-1813 }, { 34,-1813 }, { 35,-1813 }, { 36,-1813 }, - - { 37,-1765 }, { 0, 0 }, { 39, 492 }, { 40, 492 }, { 41,-1813 }, - { 42,-1813 }, { 43,-1813 }, { 0, 20 }, { 0,1610 }, { 46,-1813 }, - { 2,-1762 }, { 3,-1762 }, { 4,-1762 }, { 5,-778 }, { 0, 0 }, - { 0, 0 }, { 0,1602 }, { 0, 0 }, { 2,-641 }, { 3,-641 }, - { 4,-641 }, { 5,-596 }, { 0, 0 }, { 0, 0 }, { 16,-1858 }, - { 0, 0 }, { 0, 0 }, { 19, 492 }, { 20, 492 }, { 21, 492 }, - { 22, 492 }, { 23, 492 }, { 24, 492 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 492 }, { 31, 492 }, - { 32, 492 }, { 33,-1858 }, { 34,-1858 }, { 35,-1858 }, { 36,-1858 }, - { 37,-1810 }, { 0, 0 }, { 39, 492 }, { 40, 492 }, { 41,-1858 }, - - { 42,-1858 }, { 43,-1858 }, { 36,-2128 }, { 37,-715 }, { 46,-1858 }, - { 0, 0 }, { 0,1562 }, { 0, 0 }, { 0,1560 }, { 43,-2128 }, - { 2,-683 }, { 3,-683 }, { 4,-683 }, { 5,-638 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 22,-1524 }, { 0, 0 }, - { 24,-1476 }, { 0, 0 }, { 0, 17 }, { 0,1535 }, { 0, 0 }, - { 0, 0 }, { 3,-723 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 36,-2170 }, - { 37,-757 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1741 }, - - { 0, 0 }, { 43,-2170 }, { 19,-1741 }, { 20,-1741 }, { 21,-1741 }, - { 22,-1741 }, { 23,-1741 }, { 24,-1741 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30,-1741 }, { 31,-1741 }, - { 32,-1741 }, { 33,-1741 }, { 34,-1741 }, { 35,-1741 }, { 36,-1741 }, - { 37,-1693 }, { 0, 0 }, { 39,-1741 }, { 40,-1741 }, { 41,-1741 }, - { 42,-1741 }, { 43,-1741 }, { 0, 17 }, { 0,1490 }, { 46,-1741 }, - { 2,-768 }, { 3,-768 }, { 4,-768 }, { 5, -45 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1786 }, - { 0, 0 }, { 0, 0 }, { 19, 428 }, { 20, 428 }, { 21, 428 }, - - { 22, 428 }, { 23, 428 }, { 24, 428 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 428 }, { 31, 428 }, - { 32, 428 }, { 33,-1786 }, { 34,-1786 }, { 35,-1786 }, { 36,-1786 }, - { 37,-1738 }, { 0, 0 }, { 39, 428 }, { 40, 428 }, { 41,-1786 }, - { 42,-1786 }, { 43,-1786 }, { 0, 17 }, { 0,1445 }, { 46,-1786 }, - { 2,-1735 }, { 3,-1735 }, { 4,-1735 }, { 5,-723 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-1831 }, - { 0, 0 }, { 0, 0 }, { 19, 428 }, { 20, 428 }, { 21, 428 }, - { 22, 428 }, { 23, 428 }, { 24, 428 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 428 }, { 31, 428 }, - { 32, 428 }, { 33,-1831 }, { 34,-1831 }, { 35,-1831 }, { 36,-1831 }, - { 37,-1783 }, { 0, 0 }, { 39, 428 }, { 40, 428 }, { 41,-1831 }, - { 42,-1831 }, { 43,-1831 }, { 0, 7 }, { 0,1400 }, { 46,-1831 }, - { 2,-1690 }, { 3,-1690 }, { 4,-1690 }, { 5,-678 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 12,-2883 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-2734 }, - { 0, 0 }, { 0, 0 }, { 19, 428 }, { 20, 428 }, { 21, 428 }, - { 22, 428 }, { 23, 428 }, { 24, 428 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 428 }, { 31, 428 }, - - { 32, 428 }, { 33,-2734 }, { 34,-2734 }, { 35,-2734 }, { 36,-2734 }, - { 37,-2686 }, { 0, 0 }, { 39, 428 }, { 40, 428 }, { 41,-2734 }, - { 42,-2734 }, { 43,-2734 }, { 0, 7 }, { 0,1355 }, { 46,-2734 }, - { 2,-2683 }, { 3,-2683 }, { 4,-2683 }, { 5,-1645 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 12,-2928 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-2779 }, - { 0, 0 }, { 0, 0 }, { 19, 428 }, { 20, 428 }, { 21, 428 }, - { 22, 428 }, { 23, 428 }, { 24, 428 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 428 }, { 31, 428 }, - { 32, 428 }, { 33,-2779 }, { 34,-2779 }, { 35,-2779 }, { 36,-2779 }, - - { 37,-2731 }, { 0, 0 }, { 39, 428 }, { 40, 428 }, { 41,-2779 }, - { 42,-2779 }, { 43,-2779 }, { 0, 0 }, { 0, 0 }, { 46,-2779 }, - { 0, 18 }, { 0,1307 }, { 1,-3710 }, { 2,-1600 }, { 3,-2638 }, - { 4,-2638 }, { 5,-1552 }, { 6,-3710 }, { 7,-3832 }, { 8,-3710 }, - { 9,-3710 }, { 10,-3710 }, { 11,-3710 }, { 12,-3710 }, { 13,-3710 }, - { 14,-3710 }, { 15,-3710 }, { 16,-3710 }, { 17,-3710 }, { 18,-3710 }, - { 19, 428 }, { 20, 428 }, { 21, 428 }, { 22, 428 }, { 23, 428 }, - { 24, 428 }, { 25,-3710 }, { 26,-3710 }, { 27,-3710 }, { 28,-3710 }, - { 29,-3710 }, { 30, 428 }, { 31, 428 }, { 32, 428 }, { 33,-3710 }, - { 34,-3710 }, { 35,-3710 }, { 36,-3710 }, { 37,-3662 }, { 38,-3710 }, - - { 39, 428 }, { 40, 428 }, { 41,-3710 }, { 42,-3710 }, { 43,-3710 }, - { 44,-3710 }, { 45,-3710 }, { 46,-3614 }, { 0, 11 }, { 0,1259 }, - { 0, 0 }, { 2,-2542 }, { 3,-2542 }, { 4,-2542 }, { 5,-1504 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 16,-3614 }, { 0, 0 }, { 0, 0 }, { 19, 428 }, { 20, 428 }, - { 21, 428 }, { 22, 428 }, { 23, 428 }, { 24, 428 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 428 }, - { 31, 428 }, { 32, 428 }, { 33,-3614 }, { 34,-3614 }, { 35,-3614 }, - { 36,-3614 }, { 37,-3566 }, { 0, 0 }, { 39, 428 }, { 40, 428 }, - - { 41,-3614 }, { 42,-3614 }, { 43,-3614 }, { 0, 0 }, { 0, 0 }, - { 46,-3614 }, { 0, 18 }, { 0,1211 }, { 1,-3566 }, { 2,-1459 }, - { 3,-2497 }, { 4,-2497 }, { 5,-1411 }, { 6,-3566 }, { 7,-3566 }, - { 8,-3566 }, { 9,-3566 }, { 10,-3566 }, { 11,-3928 }, { 12,-3566 }, - { 13,-3566 }, { 14,-3566 }, { 15,-3566 }, { 16,-3566 }, { 17,-3566 }, - { 18,-3566 }, { 19, 428 }, { 20, 428 }, { 21, 428 }, { 22, 428 }, - { 23, 428 }, { 24, 428 }, { 25,-3566 }, { 26,-3566 }, { 27,-3566 }, - { 28,-3566 }, { 29,-3566 }, { 30, 428 }, { 31, 428 }, { 32, 428 }, - { 33,-3566 }, { 34,-3566 }, { 35,-3566 }, { 36,-3566 }, { 37,-3518 }, - { 38,-3566 }, { 39, 428 }, { 40, 428 }, { 41,-3566 }, { 42,-3566 }, - - { 43,-3566 }, { 44,-3566 }, { 45,-3566 }, { 46,-3470 }, { 0, 20 }, - { 0,1163 }, { 0, 0 }, { 2,-1315 }, { 3,-1315 }, { 4,-1315 }, - { 5,-537 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-2305 }, { 0, 0 }, { 0, 0 }, { 19, 428 }, - { 20, 428 }, { 21, 428 }, { 22, 428 }, { 23, 428 }, { 24, 428 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, 428 }, { 31, 428 }, { 32, 428 }, { 33,-2305 }, { 34,-2305 }, - { 35,-2305 }, { 36,-2305 }, { 37,-2257 }, { 0, 0 }, { 39, 428 }, - { 40, 428 }, { 41,-2305 }, { 42,-2305 }, { 43,-2305 }, { 0, 20 }, - - { 0,1118 }, { 46,-2305 }, { 2,-2254 }, { 3,-2254 }, { 4,-2254 }, - { 5,-1270 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-2350 }, { 0, 0 }, { 0, 0 }, { 19, 428 }, - { 20, 428 }, { 21, 428 }, { 22, 428 }, { 23, 428 }, { 24, 428 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, 428 }, { 31, 428 }, { 32, 428 }, { 33,-2350 }, { 34,-2350 }, - { 35,-2350 }, { 36,-2350 }, { 37,-2302 }, { 0, 0 }, { 39, 428 }, - { 40, 428 }, { 41,-2350 }, { 42,-2350 }, { 43,-2350 }, { 0, 0 }, - { 0,1073 }, { 46,-2350 }, { 2,-991 }, { 3,-991 }, { 4,-991 }, - - { 5,-946 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 17 }, { 0,1062 }, { 12,-2097 }, { 2,-1196 }, { 3,-1196 }, - { 4,-1196 }, { 5,-473 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 16,-2214 }, { 0, 0 }, { 0, 0 }, - { 19, 417 }, { 20, 417 }, { 21, 417 }, { 22, 417 }, { 23, 417 }, - { 24, 417 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 30, 417 }, { 31, 417 }, { 32, 417 }, { 33,-2214 }, - { 34,-2214 }, { 35,-2214 }, { 36,-2214 }, { 37,-2166 }, { 0, 0 }, - { 39, 417 }, { 40, 417 }, { 41,-2214 }, { 42,-2214 }, { 43,-2214 }, - - { 0, 17 }, { 0,1017 }, { 46,-2214 }, { 2,-2163 }, { 3,-2163 }, - { 4,-2163 }, { 5,-1151 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 16,-2259 }, { 0, 0 }, { 0, 0 }, - { 19, 417 }, { 20, 417 }, { 21, 417 }, { 22, 417 }, { 23, 417 }, - { 24, 417 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 30, 417 }, { 31, 417 }, { 32, 417 }, { 33,-2259 }, - { 34,-2259 }, { 35,-2259 }, { 36,-2259 }, { 37,-2211 }, { 0, 0 }, - { 39, 417 }, { 40, 417 }, { 41,-2259 }, { 42,-2259 }, { 43,-2259 }, - { 0, 7 }, { 0, 972 }, { 46,-2259 }, { 2,-2118 }, { 3,-2118 }, - - { 4,-2118 }, { 5,-1106 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 12,-3311 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 16,-3162 }, { 0, 0 }, { 0, 0 }, - { 19, 417 }, { 20, 417 }, { 21, 417 }, { 22, 417 }, { 23, 417 }, - { 24, 417 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 30, 417 }, { 31, 417 }, { 32, 417 }, { 33,-3162 }, - { 34,-3162 }, { 35,-3162 }, { 36,-3162 }, { 37,-3114 }, { 0, 0 }, - { 39, 417 }, { 40, 417 }, { 41,-3162 }, { 42,-3162 }, { 43,-3162 }, - { 0, 7 }, { 0, 927 }, { 46,-3162 }, { 2,-3111 }, { 3,-3111 }, - { 4,-3111 }, { 5,-2073 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 12,-3356 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 16,-3207 }, { 0, 0 }, { 0, 0 }, - { 19, 417 }, { 20, 417 }, { 21, 417 }, { 22, 417 }, { 23, 417 }, - { 24, 417 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 30, 417 }, { 31, 417 }, { 32, 417 }, { 33,-3207 }, - { 34,-3207 }, { 35,-3207 }, { 36,-3207 }, { 37,-3159 }, { 0, 0 }, - { 39, 417 }, { 40, 417 }, { 41,-3207 }, { 42,-3207 }, { 43,-3207 }, - { 0, 0 }, { 0, 0 }, { 46,-3207 }, { 0, 18 }, { 0, 879 }, - { 1,-4138 }, { 2,-2028 }, { 3,-3066 }, { 4,-3066 }, { 5,-1980 }, - { 6,-4138 }, { 7,-4260 }, { 8,-4138 }, { 9,-4138 }, { 10,-4138 }, - - { 11,-4138 }, { 12,-4138 }, { 13,-4138 }, { 14,-4138 }, { 15,-4138 }, - { 16,-4138 }, { 17,-4138 }, { 18,-4138 }, { 19, 417 }, { 20, 417 }, - { 21, 417 }, { 22, 417 }, { 23, 417 }, { 24, 417 }, { 25,-4138 }, - { 26,-4138 }, { 27,-4138 }, { 28,-4138 }, { 29,-4138 }, { 30, 417 }, - { 31, 417 }, { 32, 417 }, { 33,-4138 }, { 34,-4138 }, { 35,-4138 }, - { 36,-4138 }, { 37,-4090 }, { 38,-4138 }, { 39, 417 }, { 40, 417 }, - { 41,-4138 }, { 42,-4138 }, { 43,-4138 }, { 44,-4138 }, { 45,-4138 }, - { 46,-4042 }, { 0, 11 }, { 0, 831 }, { 0, 0 }, { 2,-2970 }, - { 3,-2970 }, { 4,-2970 }, { 5,-1932 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-4042 }, { 0, 0 }, - { 0, 0 }, { 19, 417 }, { 20, 417 }, { 21, 417 }, { 22, 417 }, - { 23, 417 }, { 24, 417 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 30, 417 }, { 31, 417 }, { 32, 417 }, - { 33,-4042 }, { 34,-4042 }, { 35,-4042 }, { 36,-4042 }, { 37,-3994 }, - { 0, 0 }, { 39, 417 }, { 40, 417 }, { 41,-4042 }, { 42,-4042 }, - { 43,-4042 }, { 0, 0 }, { 0, 0 }, { 46,-4042 }, { 0, 18 }, - { 0, 783 }, { 1,-3994 }, { 2,-1887 }, { 3,-2925 }, { 4,-2925 }, - { 5,-1839 }, { 6,-3994 }, { 7,-3994 }, { 8,-3994 }, { 9,-3994 }, - { 10,-3994 }, { 11,-4356 }, { 12,-3994 }, { 13,-3994 }, { 14,-3994 }, - - { 15,-3994 }, { 16,-3994 }, { 17,-3994 }, { 18,-3994 }, { 19, 417 }, - { 20, 417 }, { 21, 417 }, { 22, 417 }, { 23, 417 }, { 24, 417 }, - { 25,-3994 }, { 26,-3994 }, { 27,-3994 }, { 28,-3994 }, { 29,-3994 }, - { 30, 417 }, { 31, 417 }, { 32, 417 }, { 33,-3994 }, { 34,-3994 }, - { 35,-3994 }, { 36,-3994 }, { 37,-3946 }, { 38,-3994 }, { 39, 417 }, - { 40, 417 }, { 41,-3994 }, { 42,-3994 }, { 43,-3994 }, { 44,-3994 }, - { 45,-3994 }, { 46,-3898 }, { 0, 20 }, { 0, 735 }, { 0, 0 }, - { 2,-1743 }, { 3,-1743 }, { 4,-1743 }, { 5,-965 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-2733 }, - - { 0, 0 }, { 0, 0 }, { 19, 417 }, { 20, 417 }, { 21, 417 }, - { 22, 417 }, { 23, 417 }, { 24, 417 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 417 }, { 31, 417 }, - { 32, 417 }, { 33,-2733 }, { 34,-2733 }, { 35,-2733 }, { 36,-2733 }, - { 37,-2685 }, { 0, 0 }, { 39, 417 }, { 40, 417 }, { 41,-2733 }, - { 42,-2733 }, { 43,-2733 }, { 0, 20 }, { 0, 690 }, { 46,-2733 }, - { 2,-2682 }, { 3,-2682 }, { 4,-2682 }, { 5,-1698 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-2778 }, - { 0, 0 }, { 0, 0 }, { 19, 417 }, { 20, 417 }, { 21, 417 }, - - { 22, 417 }, { 23, 417 }, { 24, 417 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 417 }, { 31, 417 }, - { 32, 417 }, { 33,-2778 }, { 34,-2778 }, { 35,-2778 }, { 36,-2778 }, - { 37,-2730 }, { 0, 0 }, { 39, 417 }, { 40, 417 }, { 41,-2778 }, - { 42,-2778 }, { 43,-2778 }, { 0, 17 }, { 0, 645 }, { 46,-2778 }, - { 2,-1613 }, { 3,-1613 }, { 4,-1613 }, { 5,-890 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-2631 }, - { 0, 0 }, { 0, 0 }, { 19, 417 }, { 20, 417 }, { 21, 417 }, - { 22, 417 }, { 23, 417 }, { 24, 417 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 417 }, { 31, 417 }, - { 32, 417 }, { 33,-2631 }, { 34,-2631 }, { 35,-2631 }, { 36,-2631 }, - { 37,-2583 }, { 0, 0 }, { 39, 417 }, { 40, 417 }, { 41,-2631 }, - { 42,-2631 }, { 43,-2631 }, { 0, 17 }, { 0, 600 }, { 46,-2631 }, - { 2,-2580 }, { 3,-2580 }, { 4,-2580 }, { 5,-1568 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-2676 }, - { 0, 0 }, { 0, 0 }, { 19, 417 }, { 20, 417 }, { 21, 417 }, - { 22, 417 }, { 23, 417 }, { 24, 417 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 417 }, { 31, 417 }, - - { 32, 417 }, { 33,-2676 }, { 34,-2676 }, { 35,-2676 }, { 36,-2676 }, - { 37,-2628 }, { 0, 0 }, { 39, 417 }, { 40, 417 }, { 41,-2676 }, - { 42,-2676 }, { 43,-2676 }, { 0, 7 }, { 0, 555 }, { 46,-2676 }, - { 2,-2535 }, { 3,-2535 }, { 4,-2535 }, { 5,-1523 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 12,-3728 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-3579 }, - { 0, 0 }, { 0, 0 }, { 19, 417 }, { 20, 417 }, { 21, 417 }, - { 22, 417 }, { 23, 417 }, { 24, 417 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 417 }, { 31, 417 }, - { 32, 417 }, { 33,-3579 }, { 34,-3579 }, { 35,-3579 }, { 36,-3579 }, - - { 37,-3531 }, { 0, 0 }, { 39, 417 }, { 40, 417 }, { 41,-3579 }, - { 42,-3579 }, { 43,-3579 }, { 0, 7 }, { 0, 510 }, { 46,-3579 }, - { 2,-3528 }, { 3,-3528 }, { 4,-3528 }, { 5,-2490 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 12,-3773 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16,-3624 }, - { 0, 0 }, { 0, 0 }, { 19,-3624 }, { 20,-3624 }, { 21,-3624 }, - { 22,-3624 }, { 23,-3624 }, { 24,-3624 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30,-3624 }, { 31,-3624 }, - { 32,-3624 }, { 33,-3624 }, { 34,-3624 }, { 35,-3624 }, { 36,-3624 }, - { 37,-3576 }, { 0, 0 }, { 39,-3624 }, { 40,-3624 }, { 41,-3624 }, - - { 42,-3624 }, { 43,-3624 }, { 0, 0 }, { 0, 0 }, { 46,-3624 }, - { 0, 18 }, { 0, 462 }, { 1,-4555 }, { 2,-2445 }, { 3,-3483 }, - { 4,-3483 }, { 5,-2397 }, { 6,-4555 }, { 7,-4677 }, { 8,-4555 }, - { 9,-4555 }, { 10,-4555 }, { 11,-4555 }, { 12,-4555 }, { 13,-4555 }, - { 14,-4555 }, { 15,-4555 }, { 16,-4555 }, { 17,-4555 }, { 18,-4555 }, - { 19,-4555 }, { 20,-4555 }, { 21,-4555 }, { 22,-4555 }, { 23,-4555 }, - { 24,-4555 }, { 25,-4555 }, { 26,-4555 }, { 27,-4555 }, { 28,-4555 }, - { 29,-4555 }, { 30,-4555 }, { 31,-4555 }, { 32,-4555 }, { 33,-4555 }, - { 34,-4555 }, { 35,-4555 }, { 36,-4555 }, { 37,-4507 }, { 38,-4555 }, - { 39,-4555 }, { 40,-4555 }, { 41,-4555 }, { 42,-4555 }, { 43,-4555 }, - - { 44,-4555 }, { 45,-4555 }, { 46,-4459 }, { 0, 11 }, { 0, 414 }, - { 0, 0 }, { 2,-3387 }, { 3,-3387 }, { 4,-3387 }, { 5,-2349 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 16,-4459 }, { 0, 0 }, { 0, 0 }, { 19,-4459 }, { 20,-4459 }, - { 21,-4459 }, { 22,-4459 }, { 23,-4459 }, { 24,-4459 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30,-4459 }, - { 31,-4459 }, { 32,-4459 }, { 33,-4459 }, { 34,-4459 }, { 35,-4459 }, - { 36,-4459 }, { 37,-4411 }, { 0, 0 }, { 39,-4459 }, { 40,-4459 }, - { 41,-4459 }, { 42,-4459 }, { 43,-4459 }, { 0, 0 }, { 0, 0 }, - - { 46,-4459 }, { 0, 18 }, { 0, 366 }, { 1,-4411 }, { 2,-2304 }, - { 3,-3342 }, { 4,-3342 }, { 5,-2256 }, { 6,-4411 }, { 7,-4411 }, - { 8,-4411 }, { 9,-4411 }, { 10,-4411 }, { 11,-4773 }, { 12,-4411 }, - { 13,-4411 }, { 14,-4411 }, { 15,-4411 }, { 16,-4411 }, { 17,-4411 }, - { 18,-4411 }, { 19,-4411 }, { 20,-4411 }, { 21,-4411 }, { 22,-4411 }, - { 23,-4411 }, { 24,-4411 }, { 25,-4411 }, { 26,-4411 }, { 27,-4411 }, - { 28,-4411 }, { 29,-4411 }, { 30,-4411 }, { 31,-4411 }, { 32,-4411 }, - { 33,-4411 }, { 34,-4411 }, { 35,-4411 }, { 36,-4411 }, { 37,-4363 }, - { 38,-4411 }, { 39,-4411 }, { 40,-4411 }, { 41,-4411 }, { 42,-4411 }, - { 43,-4411 }, { 44,-4411 }, { 45,-4411 }, { 46,-4315 }, { 0, 20 }, - - { 0, 318 }, { 0, 0 }, { 2,-2160 }, { 3,-2160 }, { 4,-2160 }, - { 5,-1382 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-3150 }, { 0, 0 }, { 0, 0 }, { 19, 225 }, - { 20, 225 }, { 21, 225 }, { 22, 225 }, { 23, 225 }, { 24, 225 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, 225 }, { 31, 225 }, { 32, 225 }, { 33,-3150 }, { 34,-3150 }, - { 35,-3150 }, { 36,-3150 }, { 37,-3102 }, { 0, 0 }, { 39, 225 }, - { 40, 225 }, { 41,-3150 }, { 42,-3150 }, { 43,-3150 }, { 0, 20 }, - { 0, 273 }, { 46,-3150 }, { 2,-3099 }, { 3,-3099 }, { 4,-3099 }, - - { 5,-2115 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-3195 }, { 0, 0 }, { 0, 0 }, { 19,-3195 }, - { 20,-3195 }, { 21,-3195 }, { 22,-3195 }, { 23,-3195 }, { 24,-3195 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30,-3195 }, { 31,-3195 }, { 32,-3195 }, { 33,-3195 }, { 34,-3195 }, - { 35,-3195 }, { 36,-3195 }, { 37,-3147 }, { 0, 0 }, { 39,-3195 }, - { 40,-3195 }, { 41,-3195 }, { 42,-3195 }, { 43,-3195 }, { 0, 17 }, - { 0, 228 }, { 46,-3195 }, { 2,-2030 }, { 3,-2030 }, { 4,-2030 }, - { 5,-1307 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-3048 }, { 0, 0 }, { 0, 0 }, { 19, 180 }, - { 20, 180 }, { 21, 180 }, { 22, 180 }, { 23, 180 }, { 24, 180 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30, 180 }, { 31, 180 }, { 32, 180 }, { 33,-3048 }, { 34,-3048 }, - { 35,-3048 }, { 36,-3048 }, { 37,-3000 }, { 0, 0 }, { 39, 180 }, - { 40, 180 }, { 41,-3048 }, { 42,-3048 }, { 43,-3048 }, { 0, 17 }, - { 0, 183 }, { 46,-3048 }, { 2,-2997 }, { 3,-2997 }, { 4,-2997 }, - { 5,-1985 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 0, 0 }, { 16,-3093 }, { 0, 0 }, { 0, 0 }, { 19,-3093 }, - { 20,-3093 }, { 21,-3093 }, { 22,-3093 }, { 23,-3093 }, { 24,-3093 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30,-3093 }, { 31,-3093 }, { 32,-3093 }, { 33,-3093 }, { 34,-3093 }, - { 35,-3093 }, { 36,-3093 }, { 37,-3045 }, { 0, 0 }, { 39,-3093 }, - { 40,-3093 }, { 41,-3093 }, { 42,-3093 }, { 43,-3093 }, { 0, 7 }, - { 0, 138 }, { 46,-3093 }, { 2,-2952 }, { 3,-2952 }, { 4,-2952 }, - { 5,-1940 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 12,-4145 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-3996 }, { 0, 0 }, { 0, 0 }, { 19,-3996 }, - - { 20,-3996 }, { 21,-3996 }, { 22,-3996 }, { 23,-3996 }, { 24,-3996 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30,-3996 }, { 31,-3996 }, { 32,-3996 }, { 33,-3996 }, { 34,-3996 }, - { 35,-3996 }, { 36,-3996 }, { 37,-3948 }, { 0, 0 }, { 39,-3996 }, - { 40,-3996 }, { 41,-3996 }, { 42,-3996 }, { 43,-3996 }, { 0, 20 }, - { 0, 93 }, { 46,-3996 }, { 2,-2385 }, { 3,-2385 }, { 4,-2385 }, - { 5,-1607 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-3375 }, { 0, 0 }, { 0, 0 }, { 19,-3375 }, - { 20,-3375 }, { 21,-3375 }, { 22,-3375 }, { 23,-3375 }, { 24,-3375 }, - - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 30,-3375 }, { 31,-3375 }, { 32,-3375 }, { 33,-3375 }, { 34,-3375 }, - { 35,-3375 }, { 36,-3375 }, { 37,-3327 }, { 0, 0 }, { 39,-3375 }, - { 40,-3375 }, { 41,-3375 }, { 42,-3375 }, { 43,-3375 }, { 0, 17 }, - { 0, 48 }, { 46,-3375 }, { 2,-2210 }, { 3,-2210 }, { 4,-2210 }, - { 5,-1487 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 16,-3228 }, { 0, 0 }, { 0, 0 }, { 19,-3228 }, - { 20,-3228 }, { 21,-3228 }, { 22,-3228 }, { 23,-3228 }, { 24,-3228 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - { 30,-3228 }, { 31,-3228 }, { 32,-3228 }, { 33,-3228 }, { 34,-3228 }, - { 35,-3228 }, { 36,-3228 }, { 37,-3180 }, { 0, 0 }, { 39,-3228 }, - { 40,-3228 }, { 41,-3228 }, { 42,-3228 }, { 43,-3228 }, { 0, 0 }, - { 0, 0 }, { 46,-3228 }, { 47, 26 }, { 1, 0 }, }; - -static yyconst struct yy_trans_info *yy_start_state_list[3] = -{ - &yy_transition[1], - &yy_transition[3], - &yy_transition[51], - -} ; - -static yyconst flex_int32_t yy_ec[256] = -{ 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 4, 5, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 6, 7, 8, 9, 10, 1, 11, 12, - 1, 13, 14, 15, 16, 17, 18, 19, 20, 20, - 20, 21, 22, 23, 24, 20, 20, 25, 1, 26, - 27, 28, 1, 29, 30, 30, 30, 30, 31, 32, - 33, 33, 33, 33, 33, 33, 33, 34, 35, 33, - 33, 33, 33, 36, 33, 33, 33, 33, 33, 33, - 1, 37, 1, 38, 33, 1, 30, 30, 30, 30, - - 39, 40, 33, 33, 33, 33, 33, 33, 33, 41, - 42, 33, 33, 33, 33, 43, 33, 33, 33, 33, - 33, 33, 1, 44, 1, 45, 1, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46 -} ; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -#define YY_NO_INPUT 1 -enum css_token { - SPACE = 1, - INCLUDES, - DASHMATCH, - PREFIXMATCH, - SUFFIXMATCH, - SUBSTRINGMATCH, - IDENT, - STRING, - FUNCTION, - NUMBER, - HASH, - PLUS, - GREATER, - COMMA, - TILDE, - NOT, - ATKEYWORD, - INVALID, - PERCENTAGE, - DIMENSION, - CDO, - CDC -}; - -#define INITIAL 0 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -/* Holds the entire state of the reentrant scanner. */ -struct yyguts_t -{ - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - yy_size_t yy_n_chars; - yy_size_t yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - -}; /* end struct yyguts_t */ - -static int yy_init_globals (yyscan_t yyscanner ); - -int csslex_init (yyscan_t* scanner); - -int csslex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int csslex_destroy (yyscan_t yyscanner ); - -int cssget_debug (yyscan_t yyscanner ); - -void cssset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE cssget_extra (yyscan_t yyscanner ); - -void cssset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *cssget_in (yyscan_t yyscanner ); - -void cssset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *cssget_out (yyscan_t yyscanner ); - -void cssset_out (FILE * out_str ,yyscan_t yyscanner ); - -yy_size_t cssget_leng (yyscan_t yyscanner ); - -char *cssget_text (yyscan_t yyscanner ); - -int cssget_lineno (yyscan_t yyscanner ); - -void cssset_lineno (int line_number ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int csswrap (yyscan_t yyscanner ); -#else -extern int csswrap (yyscan_t yyscanner ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); -#else -static int input (yyscan_t yyscanner ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ -errno=0; \ -while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \ -{ \ -if( errno != EINTR) \ -{ \ -YY_FATAL_ERROR( "input in flex scanner failed" ); \ -break; \ -} \ -errno=0; \ -clearerr(yyin); \ -}\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int csslex (yyscan_t yyscanner); - -#define YY_DECL int csslex (yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ -YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - cssensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - css_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - css_load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yyg->yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yyg->yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yy_start_state_list[yyg->yy_start]; - yy_match: - { - register yyconst struct yy_trans_info *yy_trans_info; - - register YY_CHAR yy_c; - - for ( yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; - (yy_trans_info = &yy_current_state[(unsigned int) yy_c])-> - yy_verify == yy_c; - yy_c = yy_ec[YY_SC_TO_UI(*++yy_cp)] ) - { - yy_current_state += yy_trans_info->yy_nxt; - - if ( yy_current_state[-1].yy_nxt ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - } - } - - yy_find_action: - yy_act = yy_current_state[-1].yy_nxt; - - YY_DO_BEFORE_ACTION; - - do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yyg->yy_hold_char; - yy_cp = yyg->yy_last_accepting_cpos + 1; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - - case 1: - /* rule 1 can match eol */ - YY_RULE_SETUP - return SPACE; - YY_BREAK - case 2: - YY_RULE_SETUP - return INCLUDES; - YY_BREAK - case 3: - YY_RULE_SETUP - return DASHMATCH; - YY_BREAK - case 4: - YY_RULE_SETUP - return PREFIXMATCH; - YY_BREAK - case 5: - YY_RULE_SETUP - return SUFFIXMATCH; - YY_BREAK - case 6: - YY_RULE_SETUP - return SUBSTRINGMATCH; - YY_BREAK - case 7: - /* rule 7 can match eol */ - YY_RULE_SETUP - return IDENT; - YY_BREAK - case 8: - /* rule 8 can match eol */ - YY_RULE_SETUP - return STRING; - YY_BREAK - case 9: - /* rule 9 can match eol */ - YY_RULE_SETUP - return FUNCTION; - YY_BREAK - case 10: - YY_RULE_SETUP - return NUMBER; - YY_BREAK - case 11: - /* rule 11 can match eol */ - YY_RULE_SETUP - return HASH; - YY_BREAK - case 12: - /* rule 12 can match eol */ - YY_RULE_SETUP - return PLUS; - YY_BREAK - case 13: - /* rule 13 can match eol */ - YY_RULE_SETUP - return GREATER; - YY_BREAK - case 14: - /* rule 14 can match eol */ - YY_RULE_SETUP - return COMMA; - YY_BREAK - case 15: - /* rule 15 can match eol */ - YY_RULE_SETUP - return TILDE; - YY_BREAK - case 16: - /* rule 16 can match eol */ - YY_RULE_SETUP - return NOT; - YY_BREAK - case 17: - /* rule 17 can match eol */ - YY_RULE_SETUP - return ATKEYWORD; - YY_BREAK - case 18: - /* rule 18 can match eol */ - YY_RULE_SETUP - return INVALID; - YY_BREAK - case 19: - YY_RULE_SETUP - return PERCENTAGE; - YY_BREAK - case 20: - /* rule 20 can match eol */ - YY_RULE_SETUP - return DIMENSION; - YY_BREAK - case 21: - YY_RULE_SETUP - return CDO; - YY_BREAK - case 22: - YY_RULE_SETUP - return CDC; - YY_BREAK - case 23: - /* rule 23 can match eol */ - YY_RULE_SETUP - /* ignore comments */ - YY_BREAK - case 24: - YY_RULE_SETUP - return *yytext; - YY_BREAK - case 25: - YY_RULE_SETUP - YY_FATAL_ERROR( "flex scanner jammed" ); - YY_BREAK - case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * csslex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); - - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yyg->yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yyg->yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_END_OF_FILE: - { - yyg->yy_did_buffer_switch_on_eof = 0; - - if ( csswrap(yyscanner ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yyg->yy_c_buf_p = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of csslex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; - - else - { - yy_size_t num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) (yyg->yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - yy_size_t new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - cssrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - if ( yyg->yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - cssrestart(yyin ,yyscanner); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cssrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - yyg->yy_n_chars += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_current_state = yy_start_state_list[yyg->yy_start]; - - for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) - { - yy_current_state += yy_current_state[(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)].yy_nxt; - if ( yy_current_state[-1].yy_nxt ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ -static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) -{ - register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; - - register int yy_c = 1; - register yyconst struct yy_trans_info *yy_trans_info; - - yy_trans_info = &yy_current_state[(unsigned int) yy_c]; - yy_current_state += yy_trans_info->yy_nxt; - yy_is_jam = (yy_trans_info->yy_verify != yy_c); - - if ( ! yy_is_jam ) - { - if ( yy_current_state[-1].yy_nxt ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - } - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner) -#else -static int input (yyscan_t yyscanner) -#endif - -{ - int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - *yyg->yy_c_buf_p = yyg->yy_hold_char; - - if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - /* This was really a NUL. */ - *yyg->yy_c_buf_p = '\0'; - - else - { /* need more input */ - yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; - ++yyg->yy_c_buf_p; - - switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - cssrestart(yyin ,yyscanner); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( csswrap(yyscanner ) ) - return 0; - - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(yyscanner); -#else - return input(yyscanner); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ - *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ - yyg->yy_hold_char = *++yyg->yy_c_buf_p; - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ -void cssrestart (FILE * input_file , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! YY_CURRENT_BUFFER ){ - cssensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - css_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - css_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - css_load_buffer_state(yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ -void css_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* TODO. We should be able to replace this entire function body - * with - * csspop_buffer_state(); - * csspush_buffer_state(new_buffer); - */ - cssensure_buffer_stack (yyscanner); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - css_load_buffer_state(yyscanner ); - - /* We don't actually know whether we did this switch during - * EOF (csswrap()) processing, but the only time this flag - * is looked at is after csswrap() is called, so it's safe - * to go ahead and always set it. - */ - yyg->yy_did_buffer_switch_on_eof = 1; -} - -static void css_load_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - yyg->yy_hold_char = *yyg->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ -YY_BUFFER_STATE css_create_buffer (FILE * file, int size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) cssalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in css_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) cssalloc(b->yy_buf_size + 2 ,yyscanner ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in css_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - css_init_buffer(b,file ,yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with css_create_buffer() - * @param yyscanner The scanner object. - */ -void css_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - cssfree((void *) b->yy_ch_buf ,yyscanner ); - - cssfree((void *) b ,yyscanner ); -} - -#ifndef __cplusplus -extern int isatty (int ); -#endif /* __cplusplus */ - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a cssrestart() or at EOF. - */ -static void css_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) - -{ - int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - css_flush_buffer(b ,yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then css_init_buffer was _probably_ - * called from cssrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * @param yyscanner The scanner object. - */ -void css_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - css_load_buffer_state(yyscanner ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void csspush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (new_buffer == NULL) - return; - - cssensure_buffer_stack(yyscanner); - - /* This block is copied from css_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - yyg->yy_buffer_stack_top++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from css_switch_to_buffer. */ - css_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void csspop_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (!YY_CURRENT_BUFFER) - return; - - css_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); - YY_CURRENT_BUFFER_LVALUE = NULL; - if (yyg->yy_buffer_stack_top > 0) - --yyg->yy_buffer_stack_top; - - if (YY_CURRENT_BUFFER) { - css_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void cssensure_buffer_stack (yyscan_t yyscanner) -{ - yy_size_t num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (!yyg->yy_buffer_stack) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)cssalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in cssensure_buffer_stack()" ); - - memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyg->yy_buffer_stack_max = num_to_alloc; - yyg->yy_buffer_stack_top = 0; - return; - } - - if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)cssrealloc - (yyg->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in cssensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyg->yy_buffer_stack_max = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE css_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) cssalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in css_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - css_switch_to_buffer(b ,yyscanner ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to csslex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * css_scan_bytes() instead. - */ -YY_BUFFER_STATE css_scan_string (yyconst char * yystr , yyscan_t yyscanner) -{ - - return css_scan_bytes(yystr,strlen(yystr) ,yyscanner); -} - -/** Setup the input buffer state to scan the given bytes. The next call to csslex() will - * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE css_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n, i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) cssalloc(n ,yyscanner ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in css_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = css_scan_buffer(buf,n ,yyscanner); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in css_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ -do \ -{ \ -/* Undo effects of setting up yytext. */ \ -int yyless_macro_arg = (n); \ -YY_LESS_LINENO(yyless_macro_arg);\ -yytext[yyleng] = yyg->yy_hold_char; \ -yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ -yyg->yy_hold_char = *yyg->yy_c_buf_p; \ -*yyg->yy_c_buf_p = '\0'; \ -yyleng = yyless_macro_arg; \ -} \ -while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -YY_EXTRA_TYPE cssget_extra (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; -} - -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int cssget_lineno (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; -} - -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int cssget_column (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; -} - -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *cssget_in (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; -} - -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *cssget_out (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; -} - -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -yy_size_t cssget_leng (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; -} - -/** Get the current token. - * @param yyscanner The scanner object. - */ - -char *cssget_text (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; -} - -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void cssset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; -} - -/** Set the current line number. - * @param line_number - * @param yyscanner The scanner object. - */ -void cssset_lineno (int line_number , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "cssset_lineno called with no buffer" , yyscanner); - - yylineno = line_number; -} - -/** Set the current column. - * @param line_number - * @param yyscanner The scanner object. - */ -void cssset_column (int column_no , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "cssset_column called with no buffer" , yyscanner); - - yycolumn = column_no; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * @param yyscanner The scanner object. - * @see css_switch_to_buffer - */ -void cssset_in (FILE * in_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; -} - -void cssset_out (FILE * out_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; -} - -int cssget_debug (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; -} - -void cssset_debug (int bdebug , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; -} - -/* Accessor methods for yylval and yylloc */ - -/* User-visible API */ - -/* csslex_init is special because it creates the scanner itself, so it is - * the ONLY reentrant function that doesn't take the scanner as the last argument. - * That's why we explicitly handle the declaration, instead of using our macros. - */ - -int csslex_init(yyscan_t* ptr_yy_globals) - -{ - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) cssalloc ( sizeof( struct yyguts_t ), NULL ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - return yy_init_globals ( *ptr_yy_globals ); -} - -/* csslex_init_extra has the same functionality as csslex_init, but follows the - * convention of taking the scanner as the last argument. Note however, that - * this is a *pointer* to a scanner, as it will be allocated by this call (and - * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to cssalloc in - * the yyextra field. - */ - -int csslex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) - -{ - struct yyguts_t dummy_yyguts; - - cssset_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) cssalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - cssset_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); -} - -static int yy_init_globals (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from csslex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - - /* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * csslex_init() - */ - return 0; -} - -/* csslex_destroy is for both reentrant and non-reentrant scanners. */ -int csslex_destroy (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - css_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); - YY_CURRENT_BUFFER_LVALUE = NULL; - csspop_buffer_state(yyscanner); - } - - /* Destroy the stack itself. */ - cssfree(yyg->yy_buffer_stack ,yyscanner); - yyg->yy_buffer_stack = NULL; - - /* Destroy the start condition stack. */ - cssfree(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * csslex() is called, initialization will occur. */ - yy_init_globals( yyscanner); - - /* Destroy the main struct (reentrant only). */ - cssfree ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *cssalloc (yy_size_t size , yyscan_t yyscanner) -{ - return (void *) malloc( size ); -} - -void *cssrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void cssfree (void * ptr , yyscan_t yyscanner) -{ - free( (char *) ptr ); /* see cssrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" diff --git a/HTMLKit/CSSLexer.h b/HTMLKit/CSSLexer.h deleted file mode 100644 index 7e85d1d..0000000 --- a/HTMLKit/CSSLexer.h +++ /dev/null @@ -1,329 +0,0 @@ -#ifndef cssHEADER_H -#define cssHEADER_H 1 -#define cssIN_HEADER 1 - -#line 6 "CSSLexer.h" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -typedef uint64_t flex_uint64_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state -{ - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - yy_size_t yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -}; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -void cssrestart (FILE *input_file ,yyscan_t yyscanner ); -void css_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE css_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void css_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void css_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void csspush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void csspop_buffer_state (yyscan_t yyscanner ); - -YY_BUFFER_STATE css_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE css_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE css_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); - -void *cssalloc (yy_size_t ,yyscan_t yyscanner ); -void *cssrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void cssfree (void * ,yyscan_t yyscanner ); - -#define csswrap(n) 1 -#define YY_SKIP_YYWRAP - -#define yytext_ptr yytext_r - -#ifdef YY_HEADER_EXPORT_START_CONDITIONS -#define INITIAL 0 - -#endif - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -int csslex_init (yyscan_t* scanner); - -int csslex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int csslex_destroy (yyscan_t yyscanner ); - -int cssget_debug (yyscan_t yyscanner ); - -void cssset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE cssget_extra (yyscan_t yyscanner ); - -void cssset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *cssget_in (yyscan_t yyscanner ); - -void cssset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *cssget_out (yyscan_t yyscanner ); - -void cssset_out (FILE * out_str ,yyscan_t yyscanner ); - -yy_size_t cssget_leng (yyscan_t yyscanner ); - -char *cssget_text (yyscan_t yyscanner ); - -int cssget_lineno (yyscan_t yyscanner ); - -void cssset_lineno (int line_number ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int csswrap (yyscan_t yyscanner ); -#else -extern int csswrap (yyscan_t yyscanner ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int csslex (yyscan_t yyscanner); - -#define YY_DECL int csslex (yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -#undef YY_NEW_FILE -#undef YY_FLUSH_BUFFER -#undef yy_set_bol -#undef yy_new_buffer -#undef yy_set_interactive -#undef YY_DO_BEFORE_ACTION - -#ifdef YY_DECL_IS_OURS -#undef YY_DECL_IS_OURS -#undef YY_DECL -#endif - -#line 328 "CSSLexer.h" -#undef cssIN_HEADER -#endif /* cssHEADER_H */ From 23d0d622958de7445f71c98f1917ffef48e03374 Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 22 Jun 2015 23:48:31 +0200 Subject: [PATCH 029/103] Reorganize CSS related classes --- HTMLKit.xcodeproj/project.pbxproj | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 9c55ebf..738d61f 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -72,14 +72,6 @@ 624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */; }; 624493AD19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; }; 624493AE19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; }; - 624AB3171B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; - 624AB3181B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; - 624AB31A1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; - 624AB31B1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; - 624AB31E1B05373600F3830D /* CSSSimpleSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AB31C1B05373600F3830D /* CSSSimpleSequence.h */; }; - 624AB31F1B05373600F3830D /* CSSSimpleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */; }; - 624AB3201B05373600F3830D /* CSSSimpleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */; }; - 624AB3221B053A5800F3830D /* CSSSimpleSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */; }; 624717181B22333200C11912 /* HTMLNodeTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = 624717161B22333200C11912 /* HTMLNodeTraversal.h */; }; 624717191B22333200C11912 /* HTMLNodeTraversal.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717171B22333200C11912 /* HTMLNodeTraversal.m */; }; 6247171A1B22333200C11912 /* HTMLNodeTraversal.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717171B22333200C11912 /* HTMLNodeTraversal.m */; }; @@ -94,6 +86,14 @@ 6247A9441B152F4F00CCF25C /* HTMLNodeIterator.m in Sources */ = {isa = PBXBuildFile; fileRef = 6247A9421B152F4F00CCF25C /* HTMLNodeIterator.m */; }; 6247A9451B152F4F00CCF25C /* HTMLNodeIterator.m in Sources */ = {isa = PBXBuildFile; fileRef = 6247A9421B152F4F00CCF25C /* HTMLNodeIterator.m */; }; 6247A9471B152F8C00CCF25C /* HTMLNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6247A9461B152F8C00CCF25C /* HTMLNodeFilter.h */; }; + 624AB3171B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; + 624AB3181B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; + 624AB31A1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; + 624AB31B1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; + 624AB31E1B05373600F3830D /* CSSSimpleSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AB31C1B05373600F3830D /* CSSSimpleSequence.h */; }; + 624AB31F1B05373600F3830D /* CSSSimpleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */; }; + 624AB3201B05373600F3830D /* CSSSimpleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */; }; + 624AB3221B053A5800F3830D /* CSSSimpleSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */; }; 624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */; }; 624AC90119FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; 624AC90219FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; @@ -255,12 +255,6 @@ 624493A919CCE84A00BCDDF4 /* HTMLTokenizerStates.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokenizerStates.h; sourceTree = ""; }; 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLToken.h; sourceTree = ""; }; 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLToken.m; sourceTree = ""; }; - 624AB3151B04EA4200F3830D /* CSSSelectors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSSelectors.h; sourceTree = ""; }; - 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTypeSelectorTests.m; sourceTree = ""; }; - 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSAttributeSelectorTests.m; sourceTree = ""; }; - 624AB31C1B05373600F3830D /* CSSSimpleSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSimpleSequence.h; sourceTree = ""; }; - 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSimpleSequence.m; sourceTree = ""; }; - 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSimpleSelector.h; sourceTree = ""; }; 624717161B22333200C11912 /* HTMLNodeTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNodeTraversal.h; sourceTree = ""; }; 624717171B22333200C11912 /* HTMLNodeTraversal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLNodeTraversal.m; sourceTree = ""; }; 6247171B1B2240B800C11912 /* HTMLTreeWalkerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTreeWalkerTests.m; sourceTree = ""; }; @@ -270,6 +264,12 @@ 6247A9411B152F4F00CCF25C /* HTMLNodeIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNodeIterator.h; sourceTree = ""; }; 6247A9421B152F4F00CCF25C /* HTMLNodeIterator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLNodeIterator.m; sourceTree = ""; }; 6247A9461B152F8C00CCF25C /* HTMLNodeFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNodeFilter.h; sourceTree = ""; }; + 624AB3151B04EA4200F3830D /* CSSSelectors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSSelectors.h; sourceTree = ""; }; + 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTypeSelectorTests.m; sourceTree = ""; }; + 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSAttributeSelectorTests.m; sourceTree = ""; }; + 624AB31C1B05373600F3830D /* CSSSimpleSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSimpleSequence.h; sourceTree = ""; }; + 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSimpleSequence.m; sourceTree = ""; }; + 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSimpleSelector.h; sourceTree = ""; }; 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokens.h; sourceTree = ""; }; 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitTokenizerTests.m; sourceTree = ""; }; 624AC90419FBFE8A00BD3C4A /* html5lib-tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "html5lib-tests"; sourceTree = ""; }; From af4444e9a8d29004220113f7df4f8a4bfa189efa Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 23 Jun 2015 00:07:47 +0200 Subject: [PATCH 030/103] Add log message on CSS Tokenizer error Proper handling will be implemented later --- HTMLKit/CSSTokenizer.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/HTMLKit/CSSTokenizer.m b/HTMLKit/CSSTokenizer.m index 1cb1275..c56f3dd 100644 --- a/HTMLKit/CSSTokenizer.m +++ b/HTMLKit/CSSTokenizer.m @@ -59,7 +59,8 @@ - (void)parseError { - + NSString *errorMessage = [NSString stringWithFormat:@"Parse error at %lu", (unsigned long)_inputStream.location]; + NSLog(@"%@", errorMessage); } - (CSSToken *)consumeToken @@ -319,7 +320,7 @@ - (CSSToken *)consumeStringTokenWithEndingCodePoint:(UTF32Char)endingCodePoint { CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); - CSSToken *token = [CSSToken tokenWithType:CSSTokenTypeWhitespace]; + CSSToken *token = [CSSToken tokenWithType:CSSTokenTypeString]; while (YES) { UTF32Char codePoint = [_inputStream consumeNextCodePoint]; From 3c7e6e1913f9dc5644b498467c10da160b9b2e47 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 2 Oct 2015 19:28:32 +0200 Subject: [PATCH 031/103] Change returned code points to UniChar instead of UTF32Chars in CSS input stream --- HTMLKit/CSSInputStream.h | 8 ++++---- HTMLKit/CSSInputStream.m | 14 +++++++------- HTMLKit/CSSTokenizer.h | 2 ++ HTMLKit/CSSTokenizer.m | 39 +++++++++++++++++++++------------------ 4 files changed, 34 insertions(+), 29 deletions(-) diff --git a/HTMLKit/CSSInputStream.h b/HTMLKit/CSSInputStream.h index 3a6699f..32c08ee 100644 --- a/HTMLKit/CSSInputStream.h +++ b/HTMLKit/CSSInputStream.h @@ -14,10 +14,10 @@ - (instancetype)initWithString:(NSString *)string; -- (UTF32Char)currentCodePoint; -- (UTF32Char)nextCodePoint; -- (UTF32Char)nextCodePointAtOffset:(NSUInteger)offset; -- (UTF32Char)consumeNextCodePoint; +- (UniChar)currentCodePoint; +- (UniChar)nextCodePoint; +- (UniChar)nextCodePointAtOffset:(NSUInteger)offset; +- (UniChar)consumeNextCodePoint; - (void)reconsumeCurrentCodePoint; @end diff --git a/HTMLKit/CSSInputStream.m b/HTMLKit/CSSInputStream.m index a3a3053..3dc56cb 100644 --- a/HTMLKit/CSSInputStream.m +++ b/HTMLKit/CSSInputStream.m @@ -12,7 +12,7 @@ { CFStringInlineBuffer _buffer; NSUInteger _location; - UTF32Char _currentCodePoint; + UniChar _currentCodePoint; } @end @@ -30,25 +30,25 @@ return self; } -- (UTF32Char)currentCodePoint +- (UniChar)currentCodePoint { return _currentCodePoint; } -- (UTF32Char)nextCodePointAtOffset:(NSUInteger)offset; +- (UniChar)nextCodePointAtOffset:(NSUInteger)offset; { - UTF32Char codePoint = CFStringGetCharacterFromInlineBuffer(&_buffer, _location + offset); + UniChar codePoint = CFStringGetCharacterFromInlineBuffer(&_buffer, _location + offset); return codePoint; } -- (UTF32Char)nextCodePoint +- (UniChar)nextCodePoint { return [self nextCodePointAtOffset:0]; } -- (UTF32Char)consumeNextCodePoint +- (UniChar)consumeNextCodePoint { - UTF32Char codePoint = [self nextCodePoint]; + UniChar codePoint = [self nextCodePoint]; _currentCodePoint = codePoint; if (codePoint != 0) { _location++; diff --git a/HTMLKit/CSSTokenizer.h b/HTMLKit/CSSTokenizer.h index 31397fd..262468d 100644 --- a/HTMLKit/CSSTokenizer.h +++ b/HTMLKit/CSSTokenizer.h @@ -11,6 +11,8 @@ @interface CSSTokenizer : NSEnumerator +@property (nonatomic, readonly, strong) NSString *string; + - (instancetype)initWithString:(NSString *)string; @end diff --git a/HTMLKit/CSSTokenizer.m b/HTMLKit/CSSTokenizer.m index c56f3dd..b22c808 100644 --- a/HTMLKit/CSSTokenizer.m +++ b/HTMLKit/CSSTokenizer.m @@ -19,6 +19,7 @@ @end @implementation CSSTokenizer +@synthesize string = _string; #pragma mark - Lifecycle @@ -68,7 +69,7 @@ [self consumeComments]; NSUInteger start = _inputStream.location; - UTF32Char codePoint = [_inputStream consumeNextCodePoint]; + UniChar codePoint = [_inputStream consumeNextCodePoint]; CSSToken *token = nil; if (isWhitespace(codePoint)) { @@ -246,7 +247,7 @@ [_inputStream consumeNextCodePoint]; [_inputStream consumeNextCodePoint]; while (YES) { - UTF32Char codePoint = [_inputStream consumeNextCodePoint]; + UniChar codePoint = [_inputStream consumeNextCodePoint]; if (codePoint == EOF_CHARACTER) { return; } @@ -317,13 +318,13 @@ } } -- (CSSToken *)consumeStringTokenWithEndingCodePoint:(UTF32Char)endingCodePoint +- (CSSToken *)consumeStringTokenWithEndingCodePoint:(UniChar)endingCodePoint { CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); CSSToken *token = [CSSToken tokenWithType:CSSTokenTypeString]; while (YES) { - UTF32Char codePoint = [_inputStream consumeNextCodePoint]; + UniChar codePoint = [_inputStream consumeNextCodePoint]; if (codePoint == endingCodePoint || codePoint == EOF_CHARACTER) { break; @@ -342,7 +343,7 @@ AppendCodePoint(value, escapedCodePoint); } } else { - AppendCodePoint(value, codePoint); + CFStringAppendCharacters(value, &codePoint, 1); } } @@ -367,7 +368,7 @@ return token; } - UTF32Char codePoint = [_inputStream consumeNextCodePoint]; + UniChar codePoint = [_inputStream consumeNextCodePoint]; if (codePoint == QUOTATION_MARK || codePoint == APOSTROPHE) { CSSToken *stringToken = [self consumeStringTokenWithEndingCodePoint:codePoint]; if (stringToken.type == CSSTokenTypeBadString) { @@ -390,7 +391,7 @@ CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); while (YES) { - UTF32Char codePoint = [_inputStream consumeNextCodePoint]; + UniChar codePoint = [_inputStream consumeNextCodePoint]; if (codePoint == RIGHT_PARENTHESIS || codePoint == EOF_CHARACTER) { return token; @@ -419,7 +420,8 @@ if (codePoint == REVERSE_SOLIDUS) { if (isValidEscape([_inputStream currentCodePoint], [_inputStream nextCodePoint])) { - AppendCodePoint(value, [self consumeEscapedCodePoint]); + UTF32Char escapedCodePoint = [self consumeEscapedCodePoint]; + AppendCodePoint(value, escapedCodePoint); } else { [self parseError]; [self consumeRemnantsOfBadURL]; @@ -427,7 +429,7 @@ } } - AppendCodePoint(value, codePoint); + CFStringAppendCharacters(value, &codePoint, 1); } return token; @@ -493,11 +495,11 @@ - (UTF32Char)consumeEscapedCodePoint { - UTF32Char codePoint = [_inputStream consumeNextCodePoint]; + UniChar codePoint = [_inputStream consumeNextCodePoint]; if (isHexDigit(codePoint)) { CFMutableStringRef hexString = CFStringCreateMutable(kCFAllocatorDefault, 6); - AppendCodePoint(hexString, codePoint); + CFStringAppendCharacters(hexString, &codePoint, 1); while (isHexDigit([_inputStream nextCodePoint]) && CFStringGetLength(hexString) <= 6) { UniChar codePoint = [_inputStream consumeNextCodePoint]; @@ -524,11 +526,12 @@ { CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); while (YES) { - UTF32Char codePoint = [_inputStream consumeNextCodePoint]; + UniChar codePoint = [_inputStream consumeNextCodePoint]; if (isName(codePoint)) { - AppendCodePoint(value, codePoint); + CFStringAppendCharacters(value, &codePoint, 1); } else if (isValidEscape([_inputStream nextCodePoint], [_inputStream nextCodePointAtOffset:1])) { - AppendCodePoint(value, [self consumeEscapedCodePoint]); + UTF32Char escapedCodePoint = [self consumeEscapedCodePoint]; + AppendCodePoint(value, escapedCodePoint); } else { break; } @@ -567,9 +570,9 @@ consumeDigits(); } - UTF32Char first = [_inputStream nextCodePoint]; - UTF32Char second = [_inputStream nextCodePointAtOffset:1]; - UTF32Char third = [_inputStream nextCodePointAtOffset:2]; + 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)) { @@ -646,7 +649,7 @@ - (void)consumeRemnantsOfBadURL { while (YES) { - UTF32Char codePoint = [_inputStream consumeNextCodePoint]; + UniChar codePoint = [_inputStream consumeNextCodePoint]; if (codePoint == RIGHT_PARENTHESIS || codePoint == EOF_CHARACTER) { return; } From 43705dac69cfc6cd00503ab30889f74db23e1ff4 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 2 Oct 2015 19:29:10 +0200 Subject: [PATCH 032/103] Update gitignore file --- .gitignore | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index bd9f093..b0f2379 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,12 @@ -# OS X -.DS_Store - # Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated build/ +DerivedData + +## Various settings *.pbxuser !default.pbxuser *.mode1v3 @@ -12,13 +16,28 @@ build/ *.perspectivev3 !default.perspectivev3 xcuserdata + +## Other *.xccheckout -profile *.moved-aside -DerivedData +*.xcuserstate +*.xcscmblueprint + +## Obj-C/Swift specific *.hmap *.ipa # CocoaPods -Pods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +Pods/ +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +Carthage/Checkouts + +Carthage/Build \ No newline at end of file From bf751d94b1498aaef91b985d6b7d419a9c0537ed Mon Sep 17 00:00:00 2001 From: iska Date: Sun, 4 Oct 2015 23:50:39 +0200 Subject: [PATCH 033/103] Add category method for the hex number character set and use a dispatch once to initialize the set only once --- HTMLKit/HTMLInputStreamReader.m | 3 ++- HTMLKit/NSCharacterSet+HTMLKit.h | 1 + HTMLKit/NSCharacterSet+HTMLKit.m | 17 ++++++++++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/HTMLKit/HTMLInputStreamReader.m b/HTMLKit/HTMLInputStreamReader.m index b2fcb88..2e5b393 100644 --- a/HTMLKit/HTMLInputStreamReader.m +++ b/HTMLKit/HTMLInputStreamReader.m @@ -8,6 +8,7 @@ #import "HTMLInputStreamReader.h" #import "HTMLTokenizerCharacters.h" +#import "NSCharacterSet+HTMLKit.h" #pragma mark - HTMLInputStreamReader @@ -145,7 +146,7 @@ - (BOOL)consumeHexNumber:(unsigned long long *)result { - NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEFabcdef"]; + NSCharacterSet *set = [NSCharacterSet HTMLHexNumberCharacterSet]; NSString *string = nil; BOOL success = [_scanner scanCharactersFromSet:set intoString:&string]; diff --git a/HTMLKit/NSCharacterSet+HTMLKit.h b/HTMLKit/NSCharacterSet+HTMLKit.h index d987429..513da2d 100644 --- a/HTMLKit/NSCharacterSet+HTMLKit.h +++ b/HTMLKit/NSCharacterSet+HTMLKit.h @@ -11,5 +11,6 @@ @interface NSCharacterSet (HTMLKit) + (instancetype)HTMLWhitespaceCharacterSet; ++ (instancetype)HTMLHexNumberCharacterSet; @end diff --git a/HTMLKit/NSCharacterSet+HTMLKit.m b/HTMLKit/NSCharacterSet+HTMLKit.m index 78d4fb7..d33e2af 100644 --- a/HTMLKit/NSCharacterSet+HTMLKit.m +++ b/HTMLKit/NSCharacterSet+HTMLKit.m @@ -12,7 +12,22 @@ + (instancetype)HTMLWhitespaceCharacterSet { - return [NSCharacterSet characterSetWithCharactersInString:@" \t\n\r\f"]; + static NSCharacterSet *set = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + set = [NSCharacterSet characterSetWithCharactersInString:@" \t\n\r\f"]; + }); + return set; +} + ++ (instancetype)HTMLHexNumberCharacterSet +{ + static NSCharacterSet *set = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + set = [NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEFabcdef"]; + }); + return set; } @end From 1a05c41f86cba26d6239f0f491f69cd2cae147d8 Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 6 Oct 2015 23:01:31 +0200 Subject: [PATCH 034/103] Refactor CSS input stream to subclass the HTML input stream class to prevent duplication --- HTMLKit/CSSInputStream.h | 15 +++---- HTMLKit/CSSInputStream.m | 78 ++++++++++++++++++--------------- HTMLKit/HTMLInputStreamReader.h | 1 + HTMLKit/HTMLInputStreamReader.m | 5 +++ 4 files changed, 53 insertions(+), 46 deletions(-) diff --git a/HTMLKit/CSSInputStream.h b/HTMLKit/CSSInputStream.h index 32c08ee..a1e9512 100644 --- a/HTMLKit/CSSInputStream.h +++ b/HTMLKit/CSSInputStream.h @@ -7,17 +7,12 @@ // #import +#import "HTMLInputStreamReader.h" -@interface CSSInputStream : NSObject +@interface CSSInputStream : HTMLInputStreamReader -@property (nonatomic, readonly) NSUInteger location; - -- (instancetype)initWithString:(NSString *)string; - -- (UniChar)currentCodePoint; -- (UniChar)nextCodePoint; -- (UniChar)nextCodePointAtOffset:(NSUInteger)offset; -- (UniChar)consumeNextCodePoint; -- (void)reconsumeCurrentCodePoint; +- (void)consumeWhitespace; +- (NSString *)consumeIdentifier; +- (UTF32Char)consumeEscapedCodePoint; @end diff --git a/HTMLKit/CSSInputStream.m b/HTMLKit/CSSInputStream.m index 3dc56cb..cb54a2d 100644 --- a/HTMLKit/CSSInputStream.m +++ b/HTMLKit/CSSInputStream.m @@ -7,59 +7,65 @@ // #import "CSSInputStream.h" - -@interface CSSInputStream () -{ - CFStringInlineBuffer _buffer; - NSUInteger _location; - UniChar _currentCodePoint; -} -@end +#import "CSSTokenizerCodePoints.h" @implementation CSSInputStream -@synthesize location = _location; -- (instancetype)initWithString:(NSString *)string +- (void)consumeWhitespace { - self = [super init]; - if (self) { - CFStringInitInlineBuffer((CFStringRef)string, &_buffer, CFRangeMake(0, string.length)); - _location = 0; - _currentCodePoint = 0; + while (isWhitespace(self.nextInputCharacter)) { + [self consumeNextInputCharacter]; } - return self; } -- (UniChar)currentCodePoint +- (NSString *)consumeIdentifier { - return _currentCodePoint; + CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); + + while (YES) { + UniChar codePoint = [self consumeNextInputCharacter]; + if (isName(codePoint)) { + CFStringAppendCharacters(value, &codePoint, 1); + } else if (isValidEscape(self.nextInputCharacter, [self inputCharacterPointAtOffset:1])) { + UTF32Char escapedCodePoint = [self consumeNextInputCharacter]; + AppendCodePoint(value, escapedCodePoint); + } else { + [self reconsumeCurrentInputCharacter]; + break; + } + } + + return (__bridge NSString *)(CFStringGetLength(value) > 0 ? value : nil); } -- (UniChar)nextCodePointAtOffset:(NSUInteger)offset; +- (UTF32Char)consumeEscapedCodePoint { - UniChar codePoint = CFStringGetCharacterFromInlineBuffer(&_buffer, _location + offset); - return codePoint; -} + UniChar codePoint = [self consumeNextInputCharacter]; -- (UniChar)nextCodePoint -{ - return [self nextCodePointAtOffset:0]; -} + if (isHexDigit(codePoint)) { + CFMutableStringRef hexString = CFStringCreateMutable(kCFAllocatorDefault, 6); + CFStringAppendCharacters(hexString, &codePoint, 1); -- (UniChar)consumeNextCodePoint -{ - UniChar codePoint = [self nextCodePoint]; - _currentCodePoint = codePoint; - if (codePoint != 0) { - _location++; + while (isHexDigit(self.nextInputCharacter) && CFStringGetLength(hexString) <= 6) { + UniChar codePoint = [self consumeNextInputCharacter]; + CFStringAppendCharacters(hexString, &codePoint, 1); + } + + if (isWhitespace(self.nextInputCharacter)) { + [self consumeNextInputCharacter]; + } + + 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; } -- (void)reconsumeCurrentCodePoint -{ - _location = _location - 1; -} @end diff --git a/HTMLKit/HTMLInputStreamReader.h b/HTMLKit/HTMLInputStreamReader.h index 1ffdce8..0d7a0b8 100644 --- a/HTMLKit/HTMLInputStreamReader.h +++ b/HTMLKit/HTMLInputStreamReader.h @@ -24,6 +24,7 @@ typedef void (^ HTMLStreamReaderErrorCallback)(NSString *reason); - (UTF32Char)currentInputCharacter; - (UTF32Char)nextInputCharacter; +- (UTF32Char)inputCharacterPointAtOffset:(NSUInteger)offset; - (UTF32Char)consumeNextInputCharacter; - (void)reconsumeCurrentInputCharacter; diff --git a/HTMLKit/HTMLInputStreamReader.m b/HTMLKit/HTMLInputStreamReader.m index 2e5b393..21229c2 100644 --- a/HTMLKit/HTMLInputStreamReader.m +++ b/HTMLKit/HTMLInputStreamReader.m @@ -107,6 +107,11 @@ return nextInputCharacter; } +- (UTF32Char)inputCharacterPointAtOffset:(NSUInteger)offset +{ + return CFStringGetCharacterFromInlineBuffer(&_buffer, _location + offset); +} + - (UTF32Char)consumeNextInputCharacter { if (_reconsume) { From 79fda9fdbeb932ee23871fbcf8edd484eada4556 Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 6 Oct 2015 23:05:25 +0200 Subject: [PATCH 035/103] Remove extra initializer methods from type and attribute selectors keep it simple --- HTMLKit/CSSSimpleSequence.h | 3 --- HTMLKit/CSSSimpleSequence.m | 10 ---------- HTMLKit/CSSTypeSelector.h | 1 - HTMLKit/CSSTypeSelector.m | 5 ----- 4 files changed, 19 deletions(-) diff --git a/HTMLKit/CSSSimpleSequence.h b/HTMLKit/CSSSimpleSequence.h index 667856d..99948bc 100644 --- a/HTMLKit/CSSSimpleSequence.h +++ b/HTMLKit/CSSSimpleSequence.h @@ -14,9 +14,6 @@ @interface CSSSimpleSequence : CSSSelector -+ (instancetype)sequenceForType:(CSSTypeSelector *)typeSelector; -+ (instancetype)sequenceWithSelectors:(NSArray *)selectors; - - (instancetype)initWithType:(CSSTypeSelector *)selector; - (instancetype)initWithSelectors:(NSArray *)selectors; diff --git a/HTMLKit/CSSSimpleSequence.m b/HTMLKit/CSSSimpleSequence.m index e651bb6..7f9b627 100644 --- a/HTMLKit/CSSSimpleSequence.m +++ b/HTMLKit/CSSSimpleSequence.m @@ -16,16 +16,6 @@ @implementation CSSSimpleSequence -+ (instancetype)sequenceForType:(CSSTypeSelector *)typeSelector -{ - return [[self alloc] initWithType:typeSelector]; -} - -+ (instancetype)sequenceWithSelectors:(NSArray *)selectors -{ - return [[self alloc] initWithSelectors:selectors]; -} - - (instancetype)init { return [self initWithSelectors:nil]; diff --git a/HTMLKit/CSSTypeSelector.h b/HTMLKit/CSSTypeSelector.h index 1d5c82e..9446996 100644 --- a/HTMLKit/CSSTypeSelector.h +++ b/HTMLKit/CSSTypeSelector.h @@ -15,7 +15,6 @@ @property (nonatomic, copy) NSString *type; + (instancetype)universalSelector; -+ (instancetype)selectorForType:(NSString *)type; - (instancetype)initWithType:(NSString *)type; diff --git a/HTMLKit/CSSTypeSelector.m b/HTMLKit/CSSTypeSelector.m index d1e9321..97d09f7 100644 --- a/HTMLKit/CSSTypeSelector.m +++ b/HTMLKit/CSSTypeSelector.m @@ -23,11 +23,6 @@ return [[self alloc] initWithType:@"*"]; } -+ (instancetype)selectorForType:(NSString *)type -{ - return [[self alloc] initWithType:type]; -} - - (instancetype)initWithType:(NSString *)type { self = [super init]; From a2096b0e54493cfea8b0acc583108c1ffb5f51d5 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 10 Oct 2015 00:06:09 +0200 Subject: [PATCH 036/103] Add debug descriptions for the attribute, type & sequence selectors --- HTMLKit/CSSAttributeSelector.m | 9 +++++++-- HTMLKit/CSSSimpleSequence.m | 11 +++++++++++ HTMLKit/CSSTypeSelector.m | 7 ++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index 6be673d..c42309f 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -93,7 +93,7 @@ } } -- (NSString *)description +- (NSString *)debugDescription { if (self.type == CSSAttributeSelectorExists) { return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.name]; @@ -106,7 +106,12 @@ @(CSSAttributeSelectorContains): @"*=", @(CSSAttributeSelectorHyphen): @"|="}[@(self.type)]; - return [NSString stringWithFormat:@"<%@: %p '%@' %@ '%@'>", self.class, self, self.name, matcher, self.value]; + return [NSString stringWithFormat:@"[%@%@'%@']", self.name, matcher, self.value]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.debugDescription]; } @end diff --git a/HTMLKit/CSSSimpleSequence.m b/HTMLKit/CSSSimpleSequence.m index 7f9b627..b35a2f0 100644 --- a/HTMLKit/CSSSimpleSequence.m +++ b/HTMLKit/CSSSimpleSequence.m @@ -50,4 +50,15 @@ return HTMLNodeFilterAccept; } +- (NSString *)debugDescription +{ + NSArray *descriptions = [_selectors valueForKey:@"debugDescription"]; + return [descriptions componentsJoinedByString:@""]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.debugDescription]; +} + @end diff --git a/HTMLKit/CSSTypeSelector.m b/HTMLKit/CSSTypeSelector.m index 97d09f7..eb20bb7 100644 --- a/HTMLKit/CSSTypeSelector.m +++ b/HTMLKit/CSSTypeSelector.m @@ -45,9 +45,14 @@ return HTMLNodeFilterSkip; } +- (NSString *)debugDescription +{ + return self.type; +} + - (NSString *)description { - return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.type]; + return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.debugDescription]; } @end From 6cfe3b6f834865d68d0bd06d14ae4eed9a936975 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 10 Oct 2015 21:34:50 +0200 Subject: [PATCH 037/103] Add implementation for CSS nth-expressions https://drafts.csswg.org/css-syntax/#anb-microsyntax --- HTMLKit.xcodeproj/project.pbxproj | 16 ++ HTMLKit/CSSNthExpressionParser.h | 32 ++++ HTMLKit/CSSNthExpressionParser.m | 50 +++++++ HTMLKit/NSCharacterSet+HTMLKit.h | 1 + HTMLKit/NSCharacterSet+HTMLKit.m | 10 ++ HTMLKitTests/CSSNthExpressionsParserTests.m | 158 ++++++++++++++++++++ 6 files changed, 267 insertions(+) create mode 100644 HTMLKit/CSSNthExpressionParser.h create mode 100644 HTMLKit/CSSNthExpressionParser.m create mode 100644 HTMLKitTests/CSSNthExpressionsParserTests.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 738d61f..0ed1358 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -142,6 +142,8 @@ 6279F87419E1808D00F12EE5 /* HTMLElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 6279F87219E1808D00F12EE5 /* HTMLElement.h */; }; 6279F87519E1808D00F12EE5 /* HTMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6279F87319E1808D00F12EE5 /* HTMLElement.m */; }; 6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6279F87319E1808D00F12EE5 /* HTMLElement.m */; }; + 628AF62F1BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */; settings = {ASSET_TAGS = (); }; }; + 628AF6301BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */; settings = {ASSET_TAGS = (); }; }; 62AE593519F97D880043F069 /* HTMLParseErrorToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593319F97D880043F069 /* HTMLParseErrorToken.h */; }; 62AE593619F97D880043F069 /* HTMLParseErrorToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593419F97D880043F069 /* HTMLParseErrorToken.m */; }; 62AE593719F97D880043F069 /* HTMLParseErrorToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593419F97D880043F069 /* HTMLParseErrorToken.m */; }; @@ -172,6 +174,9 @@ 62F31FDD19E9DCCF007F0657 /* HTMLTokenizerEntities.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F31FDB19E9DCCF007F0657 /* HTMLTokenizerEntities.h */; }; 62F31FDE19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */; }; 62F31FDF19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */; }; + 62F501651BC9576B0069F47B /* CSSNthExpressionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */; settings = {ASSET_TAGS = (); }; }; + 62F501661BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */; settings = {ASSET_TAGS = (); }; }; + 62F501671BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */; settings = {ASSET_TAGS = (); }; }; 62F873EB19E088C90062683C /* HTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F873E919E088C90062683C /* HTMLParser.h */; }; 62F873EC19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; }; 62F873ED19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; }; @@ -311,6 +316,7 @@ 6279F87119E17DC700F12EE5 /* HTMLParserInsertionModes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLParserInsertionModes.h; sourceTree = ""; }; 6279F87219E1808D00F12EE5 /* HTMLElement.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = HTMLElement.h; sourceTree = ""; }; 6279F87319E1808D00F12EE5 /* HTMLElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLElement.m; sourceTree = ""; }; + 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionsParserTests.m; sourceTree = ""; }; 628B7CE61A080E1000602C87 /* HTMLNamespaces.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLNamespaces.h; sourceTree = ""; }; 62AE593319F97D880043F069 /* HTMLParseErrorToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLParseErrorToken.h; sourceTree = ""; }; 62AE593419F97D880043F069 /* HTMLParseErrorToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLParseErrorToken.m; sourceTree = ""; }; @@ -328,6 +334,8 @@ 62EC7AE51AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitMutationAlgorithmsTests.m; sourceTree = ""; }; 62F31FDB19E9DCCF007F0657 /* HTMLTokenizerEntities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLTokenizerEntities.h; sourceTree = ""; }; 62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTokenizerEntities.m; sourceTree = ""; }; + 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSNthExpressionParser.h; sourceTree = ""; }; + 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionParser.m; sourceTree = ""; }; 62F873E919E088C90062683C /* HTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLParser.h; sourceTree = ""; }; 62F873EA19E088C90062683C /* HTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLParser.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -378,6 +386,8 @@ 624AB3151B04EA4200F3830D /* CSSSelectors.h */, 624B371C1B24E9BA0010BDDF /* CSSInputStream.h */, 624B371D1B24E9BA0010BDDF /* CSSInputStream.m */, + 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */, + 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */, 623F13A81AFC11D900C90BF4 /* CSSTokenizer.h */, 623F13A91AFC11D900C90BF4 /* CSSTokenizer.m */, 624B7DDA1B2E3AAB00A4BD61 /* CSSToken.h */, @@ -561,6 +571,7 @@ 625A14CB19C7829400AD0C32 /* Supporting Files */, 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */, 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */, + 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */, ); name = Tests; path = HTMLKitTests; @@ -701,6 +712,7 @@ 624717BC1B22009200B38302 /* HTMLTreeWalker.h in Headers */, 62362A3C1A9FA70400301989 /* HTMLText.h in Headers */, 6234584E1A9D2FA4009BD491 /* HTMLNode.h in Headers */, + 62F501651BC9576B0069F47B /* CSSNthExpressionParser.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -850,6 +862,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 62F501671BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */, 62362A3E1A9FA70400301989 /* HTMLText.m in Sources */, 6235CE9D1AA509430026937B /* NSString+HTMLKit.m in Sources */, 6247A9451B152F4F00CCF25C /* HTMLNodeIterator.m in Sources */, @@ -909,6 +922,7 @@ 62D8345A19FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */, 6239755F1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m in Sources */, 624FC37B1AE591D80015DDF9 /* HTMLKitNodesTests.m in Sources */, + 628AF6301BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -926,6 +940,7 @@ 623424891AB467B200726190 /* HTMLOrderedDictionary.m in Sources */, 624717BD1B22009200B38302 /* HTMLTreeWalker.m in Sources */, 62AE594019F9907C0043F069 /* HTMLTagToken.m in Sources */, + 62F501661BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */, 624B371F1B24E9BA0010BDDF /* CSSInputStream.m in Sources */, 62AE594519F992F30043F069 /* HTMLCommentToken.m in Sources */, 62363C3E1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m in Sources */, @@ -975,6 +990,7 @@ 62D8345919FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */, 6239755E1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m in Sources */, 624FC37A1AE591D80015DDF9 /* HTMLKitNodesTests.m in Sources */, + 628AF62F1BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/HTMLKit/CSSNthExpressionParser.h b/HTMLKit/CSSNthExpressionParser.h new file mode 100644 index 0000000..e00f8dc --- /dev/null +++ b/HTMLKit/CSSNthExpressionParser.h @@ -0,0 +1,32 @@ +// +// CSSNthExpression.h +// HTMLKit +// +// Created by Iska on 10/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import + +typedef struct CSSNthExpression +{ + NSInteger an; + NSInteger b; +} CSSNthExpression; + +NS_INLINE CSSNthExpression CSSNthExpressionMake(NSInteger an, NSInteger b) { + return (CSSNthExpression){ .an = an, .b = b }; +} + +const CSSNthExpression CSSNthExpressionOdd = (CSSNthExpression){ + .an = 2, .b = 1 +}; +const CSSNthExpression CSSNthExpressionEven = (CSSNthExpression){ + .an = 2, .b = 0 +}; + +@interface CSSNthExpressionParser : NSObject + ++ (CSSNthExpression)parseExpression:(NSString *)string; + +@end diff --git a/HTMLKit/CSSNthExpressionParser.m b/HTMLKit/CSSNthExpressionParser.m new file mode 100644 index 0000000..43a176c --- /dev/null +++ b/HTMLKit/CSSNthExpressionParser.m @@ -0,0 +1,50 @@ +// +// CSSNthExpression.m +// HTMLKit +// +// Created by Iska on 10/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSNthExpressionParser.h" +#import "CSSTokenizerCodePoints.h" +#import "NSString+HTMLKit.h" +#import "NSCharacterSet+HTMLKit.h" + +@implementation CSSNthExpressionParser + ++ (CSSNthExpression)parseExpression:(NSString *)string +{ + NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet]; + + string = [string stringByTrimmingCharactersInSet:whitespace]; + string = string.lowercaseString; + + if ([string isEqualToStringIgnoringCase:@"odd"]) { + return CSSNthExpressionOdd; + } else if ([string isEqualToStringIgnoringCase:@"even"]) { + return CSSNthExpressionEven; + } + + NSCharacterSet *set = [[NSCharacterSet CSSNthExpressionCharacterSet] invertedSet]; + if ([string rangeOfCharacterFromSet:set].location != NSNotFound) { + return CSSNthExpressionMake(0, 0); + } + NSArray *parts = [string componentsSeparatedByString:@"n"]; + + if (parts.count == 1) { + NSInteger b = [parts[0] integerValue]; + return CSSNthExpressionMake(0, b); + } else if (parts.count == 2) { + NSInteger a = [parts[0] integerValue]; + if (a == 0) { + a = [parts[0] isEqualToString:@"-"] ? -1 : 1; + } + NSInteger b = [parts[1] integerValue]; + return CSSNthExpressionMake(a, b); + } else { + return CSSNthExpressionMake(0, 0); + } +} + +@end diff --git a/HTMLKit/NSCharacterSet+HTMLKit.h b/HTMLKit/NSCharacterSet+HTMLKit.h index 513da2d..59dd2c7 100644 --- a/HTMLKit/NSCharacterSet+HTMLKit.h +++ b/HTMLKit/NSCharacterSet+HTMLKit.h @@ -12,5 +12,6 @@ + (instancetype)HTMLWhitespaceCharacterSet; + (instancetype)HTMLHexNumberCharacterSet; ++ (instancetype)CSSNthExpressionCharacterSet; @end diff --git a/HTMLKit/NSCharacterSet+HTMLKit.m b/HTMLKit/NSCharacterSet+HTMLKit.m index d33e2af..8ad588c 100644 --- a/HTMLKit/NSCharacterSet+HTMLKit.m +++ b/HTMLKit/NSCharacterSet+HTMLKit.m @@ -30,4 +30,14 @@ return set; } ++ (instancetype)CSSNthExpressionCharacterSet +{ + static NSCharacterSet *set = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + set = [NSCharacterSet characterSetWithCharactersInString:@" 0123456789nN-+"]; + }); + return set; +} + @end diff --git a/HTMLKitTests/CSSNthExpressionsParserTests.m b/HTMLKitTests/CSSNthExpressionsParserTests.m new file mode 100644 index 0000000..6a811e0 --- /dev/null +++ b/HTMLKitTests/CSSNthExpressionsParserTests.m @@ -0,0 +1,158 @@ +// +// CSSNthExpressionsParserTests.m +// HTMLKit +// +// Created by Iska on 10/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import +#import "CSSNthExpressionParser.h" + +@interface CSSNthExpressionsParserTests : XCTestCase + +@end + +@implementation CSSNthExpressionsParserTests + +- (void)testOddEvenExpression +{ + CSSNthExpression odd = [CSSNthExpressionParser parseExpression:@"odd"]; + XCTAssertEqual(odd.an, 2); + XCTAssertEqual(odd.b, 1); + + odd = [CSSNthExpressionParser parseExpression:@" odd"]; + XCTAssertEqual(odd.an, 2); + XCTAssertEqual(odd.b, 1); + + odd = [CSSNthExpressionParser parseExpression:@"odd "]; + XCTAssertEqual(odd.an, 2); + XCTAssertEqual(odd.b, 1); + + odd = [CSSNthExpressionParser parseExpression:@" odd "]; + XCTAssertEqual(odd.an, 2); + XCTAssertEqual(odd.b, 1); + + CSSNthExpression even = [CSSNthExpressionParser parseExpression:@"even"]; + XCTAssertEqual(even.an, 2); + XCTAssertEqual(even.b, 0); + + even = [CSSNthExpressionParser parseExpression:@" even"]; + XCTAssertEqual(even.an, 2); + XCTAssertEqual(even.b, 0); + + even = [CSSNthExpressionParser parseExpression:@"even "]; + XCTAssertEqual(even.an, 2); + XCTAssertEqual(even.b, 0); + + even = [CSSNthExpressionParser parseExpression:@" even "]; + XCTAssertEqual(even.an, 2); + XCTAssertEqual(even.b, 0); +} + +- (void)test_B_Expression +{ + CSSNthExpression expression = [CSSNthExpressionParser parseExpression:@"1"]; + XCTAssertEqual(expression.an, 0); + XCTAssertEqual(expression.b, 1); + + expression = [CSSNthExpressionParser parseExpression:@"+1"]; + XCTAssertEqual(expression.an, 0); + XCTAssertEqual(expression.b, 1); + + expression = [CSSNthExpressionParser parseExpression:@"-1"]; + XCTAssertEqual(expression.an, 0); + XCTAssertEqual(expression.b, -1); + + expression = [CSSNthExpressionParser parseExpression:@" -1"]; + XCTAssertEqual(expression.an, 0); + XCTAssertEqual(expression.b, -1); + + expression = [CSSNthExpressionParser parseExpression:@"+1 "]; + XCTAssertEqual(expression.an, 0); + XCTAssertEqual(expression.b, 1); + + expression = [CSSNthExpressionParser parseExpression:@" +1 "]; + XCTAssertEqual(expression.an, 0); + XCTAssertEqual(expression.b, 1); +} + +- (void)test_AN_Expression +{ + CSSNthExpression expression = [CSSNthExpressionParser parseExpression:@"n"]; + XCTAssertEqual(expression.an, 1); + XCTAssertEqual(expression.b, 0); + + expression = [CSSNthExpressionParser parseExpression:@"+n"]; + XCTAssertEqual(expression.an, 1); + XCTAssertEqual(expression.b, 0); + + expression = [CSSNthExpressionParser parseExpression:@"2n"]; + XCTAssertEqual(expression.an, 2); + XCTAssertEqual(expression.b, 0); + + expression = [CSSNthExpressionParser parseExpression:@"+2n"]; + XCTAssertEqual(expression.an, 2); + XCTAssertEqual(expression.b, 0); + + expression = [CSSNthExpressionParser parseExpression:@"-n"]; + XCTAssertEqual(expression.an, -1); + XCTAssertEqual(expression.b, 0); + + expression = [CSSNthExpressionParser parseExpression:@"-2n"]; + XCTAssertEqual(expression.an, -2); + XCTAssertEqual(expression.b, 0); +} + +- (void)test_AN_B_Expression +{ + CSSNthExpression expression = [CSSNthExpressionParser parseExpression:@"2n+1"]; + XCTAssertEqual(expression.an, 2); + XCTAssertEqual(expression.b, 1); + + expression = [CSSNthExpressionParser parseExpression:@"+2n+1"]; + XCTAssertEqual(expression.an, 2); + XCTAssertEqual(expression.b, 1); + + expression = [CSSNthExpressionParser parseExpression:@"-2n+1"]; + XCTAssertEqual(expression.an, -2); + XCTAssertEqual(expression.b, 1); + + expression = [CSSNthExpressionParser parseExpression:@"2n-1"]; + XCTAssertEqual(expression.an, 2); + XCTAssertEqual(expression.b, -1); + + expression = [CSSNthExpressionParser parseExpression:@"-2n-1"]; + XCTAssertEqual(expression.an, -2); + XCTAssertEqual(expression.b, -1); + + expression = [CSSNthExpressionParser parseExpression:@"n-1"]; + XCTAssertEqual(expression.an, 1); + XCTAssertEqual(expression.b, -1); + + expression = [CSSNthExpressionParser parseExpression:@"-n-1"]; + XCTAssertEqual(expression.an, -1); + XCTAssertEqual(expression.b, -1); + + expression = [CSSNthExpressionParser parseExpression:@"+n-1"]; + XCTAssertEqual(expression.an, 1); + XCTAssertEqual(expression.b, -1); + + expression = [CSSNthExpressionParser parseExpression:@"+2n + 1"]; + XCTAssertEqual(expression.an, 2); + XCTAssertEqual(expression.b, 1); + + expression = [CSSNthExpressionParser parseExpression:@"-2n + 1"]; + XCTAssertEqual(expression.an, -2); + XCTAssertEqual(expression.b, 1); + + expression = [CSSNthExpressionParser parseExpression:@" 2n - 1"]; + XCTAssertEqual(expression.an, 2); + XCTAssertEqual(expression.b, -1); + + expression = [CSSNthExpressionParser parseExpression:@" -2n -1 "]; + XCTAssertEqual(expression.an, -2); + XCTAssertEqual(expression.b, -1); +} + +@end From ad902e3138ff67a76e7c3d8d6bf7d7d4f76fc479 Mon Sep 17 00:00:00 2001 From: iska Date: Sun, 11 Oct 2015 23:40:03 +0200 Subject: [PATCH 038/103] Add nullability specifiers to attribute selector --- HTMLKit/CSSAttributeSelector.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/HTMLKit/CSSAttributeSelector.h b/HTMLKit/CSSAttributeSelector.h index b7e6a99..f78d389 100644 --- a/HTMLKit/CSSAttributeSelector.h +++ b/HTMLKit/CSSAttributeSelector.h @@ -18,20 +18,21 @@ typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType) CSSAttributeSelectorBegins, CSSAttributeSelectorEnds, CSSAttributeSelectorContains, - CSSAttributeSelectorHyphen + CSSAttributeSelectorHyphen, + CSSAttributeSelectorNot }; @interface CSSAttributeSelector : CSSSelector @property (nonatomic, assign) CSSAttributeSelectorType type; -@property (nonatomic, copy) NSString *name; -@property (nonatomic, copy) NSString *value; +@property (nonatomic, copy) NSString * _Nonnull name; +@property (nonatomic, copy) NSString * _Nonnull value; -+ (instancetype)selectorForClass:(NSString *)className; -+ (instancetype)selectorForId:(NSString *)elementId; ++ (nullable instancetype)selectorForClass:(nonnull NSString *)className; ++ (nullable instancetype)selectorForId:(nonnull NSString *)elementId; -- (instancetype)initWithType:(CSSAttributeSelectorType)type - attributeName:(NSString *)name - attrbiuteValue:(NSString *)value; +- (nullable instancetype)initWithType:(CSSAttributeSelectorType)type + attributeName:(nonnull NSString *)name + attrbiuteValue:(nullable NSString *)value; @end From 7cd47486ac530cc991248d59d04260c0d297b05d Mon Sep 17 00:00:00 2001 From: iska Date: Sun, 11 Oct 2015 23:40:15 +0200 Subject: [PATCH 039/103] Add nullability specifiers to type selector --- HTMLKit/CSSTypeSelector.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HTMLKit/CSSTypeSelector.h b/HTMLKit/CSSTypeSelector.h index 9446996..ccbe9fc 100644 --- a/HTMLKit/CSSTypeSelector.h +++ b/HTMLKit/CSSTypeSelector.h @@ -12,10 +12,10 @@ @interface CSSTypeSelector : CSSSelector -@property (nonatomic, copy) NSString *type; +@property (nonatomic, copy) NSString * _Nonnull type; -+ (instancetype)universalSelector; ++ (nullable instancetype)universalSelector; -- (instancetype)initWithType:(NSString *)type; +- (nullable instancetype)initWithType:(nonnull NSString *)type; @end From a74be4dfa9526fdfd37bd297d5efd3a7070053f1 Mon Sep 17 00:00:00 2001 From: iska Date: Sun, 11 Oct 2015 23:40:44 +0200 Subject: [PATCH 040/103] Add nullability specifiers to the simple sequence of selectors --- HTMLKit/CSSSimpleSequence.h | 6 +++--- HTMLKit/CSSSimpleSequence.m | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/HTMLKit/CSSSimpleSequence.h b/HTMLKit/CSSSimpleSequence.h index 99948bc..f5adfec 100644 --- a/HTMLKit/CSSSimpleSequence.h +++ b/HTMLKit/CSSSimpleSequence.h @@ -14,9 +14,9 @@ @interface CSSSimpleSequence : CSSSelector -- (instancetype)initWithType:(CSSTypeSelector *)selector; -- (instancetype)initWithSelectors:(NSArray *)selectors; +- (nullable instancetype)initWithType:(nonnull CSSTypeSelector *)selector; +- (nullable instancetype)initWithSelectors:(nonnull NSArray> *)selectors; -- (void)addSelector:(id)selector; +- (void)addSelector:(nonnull id)selector; @end diff --git a/HTMLKit/CSSSimpleSequence.m b/HTMLKit/CSSSimpleSequence.m index b35a2f0..832c2c3 100644 --- a/HTMLKit/CSSSimpleSequence.m +++ b/HTMLKit/CSSSimpleSequence.m @@ -18,7 +18,7 @@ - (instancetype)init { - return [self initWithSelectors:nil]; + return [self initWithSelectors:@[]]; } - (instancetype)initWithType:(CSSTypeSelector *)selector From dc93bb07f64351daac82511d818b3e62be4b88e5 Mon Sep 17 00:00:00 2001 From: iska Date: Sun, 11 Oct 2015 23:41:15 +0200 Subject: [PATCH 041/103] Remove unneeded methods from the base selector class --- HTMLKit/CSSSelector.h | 2 -- HTMLKit/CSSSelector.m | 11 ----------- 2 files changed, 13 deletions(-) diff --git a/HTMLKit/CSSSelector.h b/HTMLKit/CSSSelector.h index b1e5c43..c77c060 100644 --- a/HTMLKit/CSSSelector.h +++ b/HTMLKit/CSSSelector.h @@ -13,6 +13,4 @@ @interface CSSSelector : NSObject -+ (instancetype)selectorWithSting:(NSString *)string; - @end diff --git a/HTMLKit/CSSSelector.m b/HTMLKit/CSSSelector.m index 7f624ec..c5400f9 100644 --- a/HTMLKit/CSSSelector.m +++ b/HTMLKit/CSSSelector.m @@ -10,19 +10,8 @@ #import "HTMLNode.h" #import "HTMLElement.h" -@interface CSSSelector () -{ - NSString *_string; -} -@end - @implementation CSSSelector -+ (instancetype)selectorWithSting:(NSString *)string -{ - return nil; -} - - (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node { [self doesNotRecognizeSelector:_cmd]; From 1917fb1f1c648046ec3ac7a1fd89b3a4a33a2361 Mon Sep 17 00:00:00 2001 From: iska Date: Sun, 11 Oct 2015 23:43:29 +0200 Subject: [PATCH 042/103] Add base class for pseudo class selectors http://www.w3.org/TR/css3-selectors/#pseudo-classes --- HTMLKit.xcodeproj/project.pbxproj | 10 ++++++ HTMLKit/CSSPseudoClassSelector.h | 19 +++++++++++ HTMLKit/CSSPseudoClassSelector.m | 54 +++++++++++++++++++++++++++++++ HTMLKit/CSSSelectors.h | 1 + 4 files changed, 84 insertions(+) create mode 100644 HTMLKit/CSSPseudoClassSelector.h create mode 100644 HTMLKit/CSSPseudoClassSelector.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 0ed1358..73d31eb 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -11,6 +11,9 @@ 62079BEA1AF56F1E00D3B402 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62079BE81AF56F1E00D3B402 /* CSSSelector.m */; }; 62079BEB1AF56F1E00D3B402 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62079BE81AF56F1E00D3B402 /* CSSSelector.m */; }; 620802021AFD939200F2962F /* CSSTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 623F13A81AFC11D900C90BF4 /* CSSTokenizer.h */; }; + 620EE9491BC46F2A0028ED34 /* CSSPseudoClassSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */; settings = {ASSET_TAGS = (); }; }; + 620EE94A1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; settings = {ASSET_TAGS = (); }; }; + 620EE94B1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; settings = {ASSET_TAGS = (); }; }; 623406E11ADB04F9004677A3 /* HTMLTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 623406DF1ADB04F9004677A3 /* HTMLTemplate.h */; }; 623406E21ADB04F9004677A3 /* HTMLTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E01ADB04F9004677A3 /* HTMLTemplate.m */; }; 623406E31ADB04F9004677A3 /* HTMLTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E01ADB04F9004677A3 /* HTMLTemplate.m */; }; @@ -215,6 +218,8 @@ /* Begin PBXFileReference section */ 62079BE71AF56F1E00D3B402 /* CSSSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelector.h; sourceTree = ""; }; 62079BE81AF56F1E00D3B402 /* CSSSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelector.m; sourceTree = ""; }; + 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPseudoClassSelector.h; sourceTree = ""; }; + 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSPseudoClassSelector.m; sourceTree = ""; }; 6223211D1A969B9300BACED5 /* HTMLElementTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLElementTypes.h; sourceTree = ""; }; 623406DF1ADB04F9004677A3 /* HTMLTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLTemplate.h; sourceTree = ""; }; 623406E01ADB04F9004677A3 /* HTMLTemplate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTemplate.m; sourceTree = ""; }; @@ -402,6 +407,8 @@ 624B28B71B03DA820048D328 /* CSSTypeSelector.m */, 624B28BD1B0413200048D328 /* CSSAttributeSelector.h */, 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */, + 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */, + 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */, ); name = Selectors; sourceTree = ""; @@ -697,6 +704,7 @@ 624B28C41B04190D0048D328 /* NSCharacterSet+HTMLKit.h in Headers */, 624493A619CCC54100BCDDF4 /* HTMLTokenizer.h in Headers */, 62AE593A19F97E1C0043F069 /* HTMLDOCTYPEToken.h in Headers */, + 620EE9491BC46F2A0028ED34 /* CSSPseudoClassSelector.h in Headers */, 6247A9471B152F8C00CCF25C /* HTMLNodeFilter.h in Headers */, 623424881AB467B200726190 /* HTMLOrderedDictionary.h in Headers */, 6247A9431B152F4F00CCF25C /* HTMLNodeIterator.h in Headers */, @@ -889,6 +897,7 @@ 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 */, 624AB3201B05373600F3830D /* CSSSimpleSequence.m in Sources */, 623F13AC1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, @@ -957,6 +966,7 @@ 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 */, 624AB31F1B05373600F3830D /* CSSSimpleSequence.m in Sources */, 623F13AB1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, diff --git a/HTMLKit/CSSPseudoClassSelector.h b/HTMLKit/CSSPseudoClassSelector.h new file mode 100644 index 0000000..bcd35bc --- /dev/null +++ b/HTMLKit/CSSPseudoClassSelector.h @@ -0,0 +1,19 @@ +// +// CSSPseudoClassSelector.h +// HTMLKit +// +// Created by Iska on 06/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelector.h" +#import "CSSSimpleSelector.h" + +@interface CSSPseudoClassSelector : CSSSelector + +@property (nonatomic, strong, readonly) NSString * _Nonnull className; + +- (nullable instancetype)initWithClassName:(nonnull NSString *)className + andBlock:(nonnull CSSSelectorAcceptNodeBlock)block; + +@end diff --git a/HTMLKit/CSSPseudoClassSelector.m b/HTMLKit/CSSPseudoClassSelector.m new file mode 100644 index 0000000..06278ed --- /dev/null +++ b/HTMLKit/CSSPseudoClassSelector.m @@ -0,0 +1,54 @@ +// +// CSSPseudoClassSelector.m +// HTMLKit +// +// Created by Iska on 06/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSPseudoClassSelector.h" +#import "HTMLElement.h" +#import "NSString+HTMLKit.h" + +@interface CSSPseudoClassSelector () +{ + CSSSelectorAcceptNodeBlock _block; +} +@end + +@interface CSSPseudoClassSelector () +{ + NSString *_className; +} +@end + +@implementation CSSPseudoClassSelector + +- (instancetype)initWithClassName:(NSString *)className andBlock:(CSSSelectorAcceptNodeBlock)block +{ + self = [super init]; + if (self) { + _block = block; + } + return self; +} + +- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node +{ + if (node.nodeType != HTMLNodeElement) { + return HTMLNodeFilterSkip; + } + return _block(node); +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@":%@", self.className]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.debugDescription]; +} + +@end diff --git a/HTMLKit/CSSSelectors.h b/HTMLKit/CSSSelectors.h index 1698518..50f30b5 100644 --- a/HTMLKit/CSSSelectors.h +++ b/HTMLKit/CSSSelectors.h @@ -11,3 +11,4 @@ #import "CSSSimpleSequence.h" #import "CSSTypeSelector.h" #import "CSSAttributeSelector.h" +#import "CSSPseudoClassSelector.h" From 8f38aed6c68ab62b4a60346407201603d88ba200 Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 12 Oct 2015 20:00:08 +0200 Subject: [PATCH 043/103] Add "not" attribute selector to match attribute not-having given value --- HTMLKit/CSSAttributeSelector.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index c42309f..40b55b1 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -88,6 +88,10 @@ { return [element[_name] isEqualToString:_value] || [element[_name] hasPrefix:[_value stringByAppendingString:@"-"]]; } + case CSSAttributeSelectorNot: + { + return ![element[_name] isEqualTo:_value]; + } default: return NO; } @@ -104,7 +108,8 @@ @(CSSAttributeSelectorBegins): @"^=", @(CSSAttributeSelectorEnds): @"$=", @(CSSAttributeSelectorContains): @"*=", - @(CSSAttributeSelectorHyphen): @"|="}[@(self.type)]; + @(CSSAttributeSelectorHyphen): @"|=", + @(CSSAttributeSelectorNot): @"!="}[@(self.type)]; return [NSString stringWithFormat:@"[%@%@'%@']", self.name, matcher, self.value]; } From c868bd1a56093abe0310461b7922fff03a87c361 Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 12 Oct 2015 20:00:44 +0200 Subject: [PATCH 044/103] Add HTML stream method to consume characters in given string --- HTMLKit/HTMLInputStreamReader.h | 1 + HTMLKit/HTMLInputStreamReader.m | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/HTMLKit/HTMLInputStreamReader.h b/HTMLKit/HTMLInputStreamReader.h index 0d7a0b8..dea5e29 100644 --- a/HTMLKit/HTMLInputStreamReader.h +++ b/HTMLKit/HTMLInputStreamReader.h @@ -36,6 +36,7 @@ typedef void (^ HTMLStreamReaderErrorCallback)(NSString *reason); - (BOOL)consumeString:(NSString *)string caseSensitive:(BOOL)caseSensitive; - (NSString *)consumeCharactersUpToCharactersInString:(NSString *)characters; - (NSString *)consumeCharactersUpToString:(NSString *)string; +- (NSString *)consumeCharactersInString:(NSString *)characters; - (NSString *)consumeAlphanumericCharacters; - (void)markCurrentLocation; diff --git a/HTMLKit/HTMLInputStreamReader.m b/HTMLKit/HTMLInputStreamReader.m index 21229c2..667ce8f 100644 --- a/HTMLKit/HTMLInputStreamReader.m +++ b/HTMLKit/HTMLInputStreamReader.m @@ -64,7 +64,6 @@ - (UTF32Char)nextInputCharacter { if (_reconsume) { - _reconsume = NO; return _currentInputCharacter; } @@ -199,6 +198,23 @@ return consumed; } +- (NSString *)consumeCharactersInString:(NSString *)characters +{ + NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:characters]; + + if (_reconsume) { + _reconsume = NO; + _scanner.scanLocation--; + } + + NSString *string = nil; + BOOL success = [_scanner scanCharactersFromSet:set intoString:&string]; + if (success == NO) return nil; + + _location = _scanner.scanLocation; + return string; +} + - (NSString *)consumeAlphanumericCharacters { NSCharacterSet *set = [NSCharacterSet alphanumericCharacterSet]; From 9905f45e279c1f3048fcab4ba3ba589d38056c91 Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 12 Oct 2015 20:12:50 +0200 Subject: [PATCH 045/103] Change the CSS selector base class to a protocol unrelated to the HTML Node Filter --- HTMLKit.xcodeproj/project.pbxproj | 6 ------ HTMLKit/CSSAttributeSelector.h | 3 +-- HTMLKit/CSSAttributeSelector.m | 13 ------------- HTMLKit/CSSPseudoClassSelector.h | 4 ++-- HTMLKit/CSSPseudoClassSelector.m | 11 ++++------- HTMLKit/CSSSelector.h | 6 ++++-- HTMLKit/CSSSelector.m | 21 --------------------- HTMLKit/CSSSimpleSelector.h | 3 ++- HTMLKit/CSSSimpleSequence.h | 2 +- HTMLKit/CSSSimpleSequence.m | 10 +++++----- HTMLKit/CSSTypeSelector.h | 2 +- HTMLKit/CSSTypeSelector.m | 12 ++++-------- 12 files changed, 24 insertions(+), 69 deletions(-) delete mode 100644 HTMLKit/CSSSelector.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 73d31eb..8ccebac 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -8,8 +8,6 @@ /* Begin PBXBuildFile section */ 62079BE91AF56F1E00D3B402 /* CSSSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62079BE71AF56F1E00D3B402 /* CSSSelector.h */; }; - 62079BEA1AF56F1E00D3B402 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62079BE81AF56F1E00D3B402 /* CSSSelector.m */; }; - 62079BEB1AF56F1E00D3B402 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62079BE81AF56F1E00D3B402 /* CSSSelector.m */; }; 620802021AFD939200F2962F /* CSSTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 623F13A81AFC11D900C90BF4 /* CSSTokenizer.h */; }; 620EE9491BC46F2A0028ED34 /* CSSPseudoClassSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */; settings = {ASSET_TAGS = (); }; }; 620EE94A1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; settings = {ASSET_TAGS = (); }; }; @@ -217,7 +215,6 @@ /* Begin PBXFileReference section */ 62079BE71AF56F1E00D3B402 /* CSSSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelector.h; sourceTree = ""; }; - 62079BE81AF56F1E00D3B402 /* CSSSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelector.m; sourceTree = ""; }; 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPseudoClassSelector.h; sourceTree = ""; }; 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSPseudoClassSelector.m; sourceTree = ""; }; 6223211D1A969B9300BACED5 /* HTMLElementTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLElementTypes.h; sourceTree = ""; }; @@ -399,7 +396,6 @@ 624B7DDB1B2E3AAB00A4BD61 /* CSSToken.m */, 624B37211B250BB50010BDDF /* CSSTokenizerCodePoints.h */, 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, - 62079BE81AF56F1E00D3B402 /* CSSSelector.m */, 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */, 624AB31C1B05373600F3830D /* CSSSimpleSequence.h */, 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */, @@ -904,7 +900,6 @@ 624B28BA1B03DA820048D328 /* CSSTypeSelector.m in Sources */, 625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */, 623857981A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, - 62079BEB1AF56F1E00D3B402 /* CSSSelector.m in Sources */, 62AE594B19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, 623458501A9D2FA4009BD491 /* HTMLNode.m in Sources */, 624B28C11B0413200048D328 /* CSSAttributeSelector.m in Sources */, @@ -973,7 +968,6 @@ 624B28B91B03DA820048D328 /* CSSTypeSelector.m in Sources */, 625A150219C783DE00AD0C32 /* HTMLKit.m in Sources */, 623857971A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, - 62079BEA1AF56F1E00D3B402 /* CSSSelector.m in Sources */, 62AE594A19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, 6234584F1A9D2FA4009BD491 /* HTMLNode.m in Sources */, 624B28C01B0413200048D328 /* CSSAttributeSelector.m in Sources */, diff --git a/HTMLKit/CSSAttributeSelector.h b/HTMLKit/CSSAttributeSelector.h index f78d389..a7d9a09 100644 --- a/HTMLKit/CSSAttributeSelector.h +++ b/HTMLKit/CSSAttributeSelector.h @@ -7,7 +7,6 @@ // #import -#import "CSSSelector.h" #import "CSSSimpleSelector.h" typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType) @@ -22,7 +21,7 @@ typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType) CSSAttributeSelectorNot }; -@interface CSSAttributeSelector : CSSSelector +@interface CSSAttributeSelector : NSObject @property (nonatomic, assign) CSSAttributeSelectorType type; @property (nonatomic, copy) NSString * _Nonnull name; diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index 40b55b1..f73c147 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -43,19 +43,6 @@ return self; } -- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node -{ - if (node.nodeType != HTMLNodeElement) { - return HTMLNodeFilterSkip; - } - - if ([self acceptElement:node.asElement]) { - return HTMLNodeFilterAccept; - } - - return HTMLNodeFilterSkip; -} - - (BOOL)acceptElement:(HTMLElement *)element { switch (_type) { diff --git a/HTMLKit/CSSPseudoClassSelector.h b/HTMLKit/CSSPseudoClassSelector.h index bcd35bc..8d977e7 100644 --- a/HTMLKit/CSSPseudoClassSelector.h +++ b/HTMLKit/CSSPseudoClassSelector.h @@ -9,11 +9,11 @@ #import "CSSSelector.h" #import "CSSSimpleSelector.h" -@interface CSSPseudoClassSelector : CSSSelector +@interface CSSPseudoClassSelector : NSObject @property (nonatomic, strong, readonly) NSString * _Nonnull className; - (nullable instancetype)initWithClassName:(nonnull NSString *)className - andBlock:(nonnull CSSSelectorAcceptNodeBlock)block; + andBlock:(nonnull CSSSelectorAcceptElementBlock)block; @end diff --git a/HTMLKit/CSSPseudoClassSelector.m b/HTMLKit/CSSPseudoClassSelector.m index 06278ed..8be8258 100644 --- a/HTMLKit/CSSPseudoClassSelector.m +++ b/HTMLKit/CSSPseudoClassSelector.m @@ -12,7 +12,7 @@ @interface CSSPseudoClassSelector () { - CSSSelectorAcceptNodeBlock _block; + CSSSelectorAcceptElementBlock _block; } @end @@ -24,7 +24,7 @@ @implementation CSSPseudoClassSelector -- (instancetype)initWithClassName:(NSString *)className andBlock:(CSSSelectorAcceptNodeBlock)block +- (instancetype)initWithClassName:(NSString *)className andBlock:(CSSSelectorAcceptElementBlock)block { self = [super init]; if (self) { @@ -33,12 +33,9 @@ return self; } -- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node +-(BOOL)acceptElement:(HTMLElement *)element { - if (node.nodeType != HTMLNodeElement) { - return HTMLNodeFilterSkip; - } - return _block(node); + return _block ? _block(element) : NO; } - (NSString *)debugDescription diff --git a/HTMLKit/CSSSelector.h b/HTMLKit/CSSSelector.h index c77c060..9d6e210 100644 --- a/HTMLKit/CSSSelector.h +++ b/HTMLKit/CSSSelector.h @@ -7,10 +7,12 @@ // #import -#import "HTMLNodeFilter.h" @class HTMLElement; -@interface CSSSelector : NSObject +typedef BOOL (^ CSSSelectorAcceptElementBlock)(HTMLElement * _Nonnull node); +@protocol CSSSelector +@required +- (BOOL)acceptElement:(nonnull HTMLElement *)element; @end diff --git a/HTMLKit/CSSSelector.m b/HTMLKit/CSSSelector.m deleted file mode 100644 index c5400f9..0000000 --- a/HTMLKit/CSSSelector.m +++ /dev/null @@ -1,21 +0,0 @@ -// -// HTMLSelector.m -// HTMLKit -// -// Created by Iska on 02/05/15. -// Copyright (c) 2015 BrainCookie. All rights reserved. -// - -#import "CSSSelector.h" -#import "HTMLNode.h" -#import "HTMLElement.h" - -@implementation CSSSelector - -- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node -{ - [self doesNotRecognizeSelector:_cmd]; - return HTMLNodeFilterSkip; -} - -@end diff --git a/HTMLKit/CSSSimpleSelector.h b/HTMLKit/CSSSimpleSelector.h index 0f9cd28..bbaa10a 100644 --- a/HTMLKit/CSSSimpleSelector.h +++ b/HTMLKit/CSSSimpleSelector.h @@ -7,7 +7,8 @@ // #import +#import "CSSSelector.h" -@protocol CSSSimpleSelector +@protocol CSSSimpleSelector @end diff --git a/HTMLKit/CSSSimpleSequence.h b/HTMLKit/CSSSimpleSequence.h index f5adfec..7bf48be 100644 --- a/HTMLKit/CSSSimpleSequence.h +++ b/HTMLKit/CSSSimpleSequence.h @@ -12,7 +12,7 @@ @class CSSTypeSelector; -@interface CSSSimpleSequence : CSSSelector +@interface CSSSimpleSequence : NSObject - (nullable instancetype)initWithType:(nonnull CSSTypeSelector *)selector; - (nullable instancetype)initWithSelectors:(nonnull NSArray> *)selectors; diff --git a/HTMLKit/CSSSimpleSequence.m b/HTMLKit/CSSSimpleSequence.m index 832c2c3..e0b8b7e 100644 --- a/HTMLKit/CSSSimpleSequence.m +++ b/HTMLKit/CSSSimpleSequence.m @@ -40,14 +40,14 @@ [_selectors addObject:selector]; } -- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node +- (BOOL)acceptElement:(HTMLElement *)element { - for (CSSSelector *selector in _selectors) { - if (![selector acceptNode:node]) { - return HTMLNodeFilterSkip; + for (id selector in _selectors) { + if (![selector acceptElement:element]) { + return NO; } } - return HTMLNodeFilterAccept; + return YES; } - (NSString *)debugDescription diff --git a/HTMLKit/CSSTypeSelector.h b/HTMLKit/CSSTypeSelector.h index ccbe9fc..0f7ad30 100644 --- a/HTMLKit/CSSTypeSelector.h +++ b/HTMLKit/CSSTypeSelector.h @@ -10,7 +10,7 @@ #import "CSSSelector.h" #import "CSSSimpleSelector.h" -@interface CSSTypeSelector : CSSSelector +@interface CSSTypeSelector : NSObject @property (nonatomic, copy) NSString * _Nonnull type; diff --git a/HTMLKit/CSSTypeSelector.m b/HTMLKit/CSSTypeSelector.m index eb20bb7..23f26bc 100644 --- a/HTMLKit/CSSTypeSelector.m +++ b/HTMLKit/CSSTypeSelector.m @@ -32,17 +32,13 @@ return self; } -- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node +- (BOOL)acceptElement:(HTMLElement *)element { - if (node.nodeType != HTMLNodeElement) { - return HTMLNodeFilterSkip; + if ([_type isEqualToString:@"*"] || [_type isEqualToStringIgnoringCase:element.tagName]) { + return YES; } - if ([_type isEqualToString:@"*"] || [_type isEqualToStringIgnoringCase:[node.asElement tagName]]) { - return HTMLNodeFilterAccept; - } - - return HTMLNodeFilterSkip; + return NO; } - (NSString *)debugDescription From c44c77d63d014c2dfb80174dbbb348644c2e81b6 Mon Sep 17 00:00:00 2001 From: iska Date: Sun, 18 Oct 2015 22:34:49 +0200 Subject: [PATCH 046/103] Refactor selectors code - Remove simple sequence - Remove simple selector protocol - Let selectors subclass CSSSelector directly --- HTMLKit.xcodeproj/project.pbxproj | 20 +++------- HTMLKit/CSSAttributeSelector.h | 15 ++++---- HTMLKit/CSSAttributeSelector.m | 20 +++++----- HTMLKit/CSSSelector.h | 5 +-- HTMLKit/CSSSelector.m | 33 ++++++++++++++++ HTMLKit/CSSSelectors.h | 2 - HTMLKit/CSSSimpleSelector.h | 14 ------- HTMLKit/CSSSimpleSequence.h | 22 ----------- HTMLKit/CSSSimpleSequence.m | 64 ------------------------------- HTMLKit/CSSTypeSelector.h | 5 +-- HTMLKit/CSSTypeSelector.m | 10 ++--- 11 files changed, 65 insertions(+), 145 deletions(-) create mode 100644 HTMLKit/CSSSelector.m delete mode 100644 HTMLKit/CSSSimpleSelector.h delete mode 100644 HTMLKit/CSSSimpleSequence.h delete mode 100644 HTMLKit/CSSSimpleSequence.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 8ccebac..aba4d35 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -91,10 +91,6 @@ 624AB3181B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; 624AB31A1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; 624AB31B1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; - 624AB31E1B05373600F3830D /* CSSSimpleSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AB31C1B05373600F3830D /* CSSSimpleSequence.h */; }; - 624AB31F1B05373600F3830D /* CSSSimpleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */; }; - 624AB3201B05373600F3830D /* CSSSimpleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */; }; - 624AB3221B053A5800F3830D /* CSSSimpleSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */; }; 624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */; }; 624AC90119FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; 624AC90219FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; @@ -181,6 +177,8 @@ 62F873EB19E088C90062683C /* HTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F873E919E088C90062683C /* HTMLParser.h */; }; 62F873EC19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; }; 62F873ED19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; }; + 62FC60461BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; settings = {ASSET_TAGS = (); }; }; + 62FC60471BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; settings = {ASSET_TAGS = (); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -274,9 +272,6 @@ 624AB3151B04EA4200F3830D /* CSSSelectors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSSelectors.h; sourceTree = ""; }; 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTypeSelectorTests.m; sourceTree = ""; }; 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSAttributeSelectorTests.m; sourceTree = ""; }; - 624AB31C1B05373600F3830D /* CSSSimpleSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSimpleSequence.h; sourceTree = ""; }; - 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSimpleSequence.m; sourceTree = ""; }; - 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSimpleSelector.h; sourceTree = ""; }; 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokens.h; sourceTree = ""; }; 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitTokenizerTests.m; sourceTree = ""; }; 624AC90419FBFE8A00BD3C4A /* html5lib-tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "html5lib-tests"; sourceTree = ""; }; @@ -340,6 +335,7 @@ 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionParser.m; sourceTree = ""; }; 62F873E919E088C90062683C /* HTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLParser.h; sourceTree = ""; }; 62F873EA19E088C90062683C /* HTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLParser.m; sourceTree = ""; }; + 62FC60451BD0519B0042BBE7 /* CSSSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelector.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -396,9 +392,7 @@ 624B7DDB1B2E3AAB00A4BD61 /* CSSToken.m */, 624B37211B250BB50010BDDF /* CSSTokenizerCodePoints.h */, 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, - 624AB3211B053A5800F3830D /* CSSSimpleSelector.h */, - 624AB31C1B05373600F3830D /* CSSSimpleSequence.h */, - 624AB31D1B05373600F3830D /* CSSSimpleSequence.m */, + 62FC60451BD0519B0042BBE7 /* CSSSelector.m */, 624B28B61B03DA820048D328 /* CSSTypeSelector.h */, 624B28B71B03DA820048D328 /* CSSTypeSelector.m */, 624B28BD1B0413200048D328 /* CSSAttributeSelector.h */, @@ -686,12 +680,10 @@ 624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */, 624B371E1B24E9BA0010BDDF /* CSSInputStream.h in Headers */, 6235CEA01AA5170A0026937B /* HTMLMarker.h in Headers */, - 624AB31E1B05373600F3830D /* CSSSimpleSequence.h in Headers */, 62F31FDD19E9DCCF007F0657 /* HTMLTokenizerEntities.h in Headers */, 623406E11ADB04F9004677A3 /* HTMLTemplate.h in Headers */, 624B28B81B03DA820048D328 /* CSSTypeSelector.h in Headers */, 6234BEEE1AABBF1400DEB15F /* HTMLStackOfOpenElements.h in Headers */, - 624AB3221B053A5800F3830D /* CSSSimpleSelector.h in Headers */, 6238C9851AB8D6330006512E /* HTMLKitDOMExceptions.h in Headers */, 6238039F1AB63A8C008A53D0 /* HTMLEOFToken.h in Headers */, 6279F87419E1808D00F12EE5 /* HTMLElement.h in Headers */, @@ -895,10 +887,10 @@ 624717B91B21FE5400B38302 /* HTMLNodeFilter.m in Sources */, 620EE94B1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */, 624493A819CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, - 624AB3201B05373600F3830D /* CSSSimpleSequence.m in Sources */, 623F13AC1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, 624B28BA1B03DA820048D328 /* CSSTypeSelector.m in Sources */, 625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */, + 62FC60471BD0519B0042BBE7 /* CSSSelector.m in Sources */, 623857981A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, 62AE594B19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, 623458501A9D2FA4009BD491 /* HTMLNode.m in Sources */, @@ -963,11 +955,11 @@ 624717B81B21FE5400B38302 /* HTMLNodeFilter.m in Sources */, 620EE94A1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */, 624493A719CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, - 624AB31F1B05373600F3830D /* CSSSimpleSequence.m in Sources */, 623F13AB1AFC11D900C90BF4 /* CSSTokenizer.m in Sources */, 624B28B91B03DA820048D328 /* CSSTypeSelector.m in Sources */, 625A150219C783DE00AD0C32 /* HTMLKit.m in Sources */, 623857971A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, + 62FC60461BD0519B0042BBE7 /* CSSSelector.m in Sources */, 62AE594A19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, 6234584F1A9D2FA4009BD491 /* HTMLNode.m in Sources */, 624B28C01B0413200048D328 /* CSSAttributeSelector.m in Sources */, diff --git a/HTMLKit/CSSAttributeSelector.h b/HTMLKit/CSSAttributeSelector.h index a7d9a09..ca343a6 100644 --- a/HTMLKit/CSSAttributeSelector.h +++ b/HTMLKit/CSSAttributeSelector.h @@ -7,7 +7,7 @@ // #import -#import "CSSSimpleSelector.h" +#import "CSSSelector.h" typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType) { @@ -21,17 +21,18 @@ typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType) CSSAttributeSelectorNot }; -@interface CSSAttributeSelector : NSObject +@interface CSSAttributeSelector : CSSSelector @property (nonatomic, assign) CSSAttributeSelectorType type; -@property (nonatomic, copy) NSString * _Nonnull name; -@property (nonatomic, copy) NSString * _Nonnull value; +@property (nonatomic, strong, readonly) NSString * _Nonnull name; +@property (nonatomic, strong, readonly) NSString * _Nonnull value; -+ (nullable instancetype)selectorForClass:(nonnull NSString *)className; -+ (nullable instancetype)selectorForId:(nonnull NSString *)elementId; ++ (nullable instancetype)classSelector:(nonnull NSString *)className; ++ (nullable instancetype)idSelector:(nonnull NSString *)elementId; ++ (nullable instancetype)attributeSelector:(nonnull NSString *)attributeName; - (nullable instancetype)initWithType:(CSSAttributeSelectorType)type attributeName:(nonnull NSString *)name - attrbiuteValue:(nullable NSString *)value; + attrbiuteValue:(nonnull NSString *)value; @end diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index f73c147..433be22 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -20,16 +20,21 @@ @implementation CSSAttributeSelector -+ (instancetype)selectorForClass:(NSString *)className ++ (instancetype)classSelector:(NSString *)className { return [[self alloc] initWithType:CSSAttributeSelectorIncludes attributeName:@"class" attrbiuteValue:className]; } -+ (instancetype)selectorForId:(NSString *)elementId ++ (instancetype)idSelector:(NSString *)elementId { return [[self alloc] initWithType:CSSAttributeSelectorExactMatch attributeName:@"id" attrbiuteValue:elementId]; } ++ (nullable instancetype)attributeSelector:(nonnull NSString *)attributeName +{ + return [[self alloc] initWithType:CSSAttributeSelectorExists attributeName:attributeName attrbiuteValue:@""]; +} + - (instancetype)initWithType:(CSSAttributeSelectorType)type attributeName:(NSString *)name attrbiuteValue:(NSString *)value @@ -37,8 +42,8 @@ self = [super init]; if (self) { self.type = type; - self.name = [name copy]; - self.value = [value copy]; + _name = [name copy]; + _value = [value copy]; } return self; } @@ -84,6 +89,8 @@ } } +#pragma mark - Description + - (NSString *)debugDescription { if (self.type == CSSAttributeSelectorExists) { @@ -101,9 +108,4 @@ return [NSString stringWithFormat:@"[%@%@'%@']", self.name, matcher, self.value]; } -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.debugDescription]; -} - @end diff --git a/HTMLKit/CSSSelector.h b/HTMLKit/CSSSelector.h index 9d6e210..b16f2a9 100644 --- a/HTMLKit/CSSSelector.h +++ b/HTMLKit/CSSSelector.h @@ -10,9 +10,8 @@ @class HTMLElement; -typedef BOOL (^ CSSSelectorAcceptElementBlock)(HTMLElement * _Nonnull node); +@interface CSSSelector : NSObject -@protocol CSSSelector -@required - (BOOL)acceptElement:(nonnull HTMLElement *)element; + @end diff --git a/HTMLKit/CSSSelector.m b/HTMLKit/CSSSelector.m new file mode 100644 index 0000000..f3a8e52 --- /dev/null +++ b/HTMLKit/CSSSelector.m @@ -0,0 +1,33 @@ +// +// CSSSelector.m +// HTMLKit +// +// Created by Iska on 15/10/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import +#import "CSSSelector.h" + +@implementation CSSSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + [self doesNotRecognizeSelector:_cmd]; + return NO; +} + +#pragma mark - Description + +- (NSString *)debugDescription +{ + [self doesNotRecognizeSelector:_cmd]; + return @""; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.debugDescription]; +} + +@end diff --git a/HTMLKit/CSSSelectors.h b/HTMLKit/CSSSelectors.h index 50f30b5..c9f9932 100644 --- a/HTMLKit/CSSSelectors.h +++ b/HTMLKit/CSSSelectors.h @@ -7,8 +7,6 @@ // #import "CSSSelector.h" -#import "CSSSimpleSelector.h" -#import "CSSSimpleSequence.h" #import "CSSTypeSelector.h" #import "CSSAttributeSelector.h" #import "CSSPseudoClassSelector.h" diff --git a/HTMLKit/CSSSimpleSelector.h b/HTMLKit/CSSSimpleSelector.h deleted file mode 100644 index bbaa10a..0000000 --- a/HTMLKit/CSSSimpleSelector.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// CSSSimpleSelector.h -// HTMLKit -// -// Created by Iska on 14/05/15. -// Copyright (c) 2015 BrainCookie. All rights reserved. -// - -#import -#import "CSSSelector.h" - -@protocol CSSSimpleSelector - -@end diff --git a/HTMLKit/CSSSimpleSequence.h b/HTMLKit/CSSSimpleSequence.h deleted file mode 100644 index 7bf48be..0000000 --- a/HTMLKit/CSSSimpleSequence.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// CSSSimpleSequence.h -// HTMLKit -// -// Created by Iska on 14/05/15. -// Copyright (c) 2015 BrainCookie. All rights reserved. -// - -#import -#import "CSSSelector.h" -#import "CSSSimpleSelector.h" - -@class CSSTypeSelector; - -@interface CSSSimpleSequence : NSObject - -- (nullable instancetype)initWithType:(nonnull CSSTypeSelector *)selector; -- (nullable instancetype)initWithSelectors:(nonnull NSArray> *)selectors; - -- (void)addSelector:(nonnull id)selector; - -@end diff --git a/HTMLKit/CSSSimpleSequence.m b/HTMLKit/CSSSimpleSequence.m deleted file mode 100644 index e0b8b7e..0000000 --- a/HTMLKit/CSSSimpleSequence.m +++ /dev/null @@ -1,64 +0,0 @@ -// -// CSSSimpleSequence.m -// HTMLKit -// -// Created by Iska on 14/05/15. -// Copyright (c) 2015 BrainCookie. All rights reserved. -// - -#import "CSSSimpleSequence.h" - -@interface CSSSimpleSequence () -{ - NSMutableArray *_selectors; -} -@end - -@implementation CSSSimpleSequence - -- (instancetype)init -{ - return [self initWithSelectors:@[]]; -} - -- (instancetype)initWithType:(CSSTypeSelector *)selector -{ - return [self initWithSelectors:@[selector]]; -} - -- (instancetype)initWithSelectors:(NSArray *)selectors -{ - self = [super init]; - if (self) { - _selectors = [[NSMutableArray alloc] initWithArray:selectors]; - } - return self; -} - -- (void)addSelector:(id)selector -{ - [_selectors addObject:selector]; -} - -- (BOOL)acceptElement:(HTMLElement *)element -{ - for (id selector in _selectors) { - if (![selector acceptElement:element]) { - return NO; - } - } - return YES; -} - -- (NSString *)debugDescription -{ - NSArray *descriptions = [_selectors valueForKey:@"debugDescription"]; - return [descriptions componentsJoinedByString:@""]; -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.debugDescription]; -} - -@end diff --git a/HTMLKit/CSSTypeSelector.h b/HTMLKit/CSSTypeSelector.h index 0f7ad30..c36ebff 100644 --- a/HTMLKit/CSSTypeSelector.h +++ b/HTMLKit/CSSTypeSelector.h @@ -8,11 +8,10 @@ #import #import "CSSSelector.h" -#import "CSSSimpleSelector.h" -@interface CSSTypeSelector : NSObject +@interface CSSTypeSelector : CSSSelector -@property (nonatomic, copy) NSString * _Nonnull type; +@property (nonatomic, strong, readonly) NSString * _Nonnull type; + (nullable instancetype)universalSelector; diff --git a/HTMLKit/CSSTypeSelector.m b/HTMLKit/CSSTypeSelector.m index 23f26bc..053ec74 100644 --- a/HTMLKit/CSSTypeSelector.m +++ b/HTMLKit/CSSTypeSelector.m @@ -27,7 +27,7 @@ { self = [super init]; if (self) { - self.type = [type copy]; + _type = [type copy]; } return self; } @@ -37,18 +37,14 @@ if ([_type isEqualToString:@"*"] || [_type isEqualToStringIgnoringCase:element.tagName]) { return YES; } - return NO; } +#pragma mark - Description + - (NSString *)debugDescription { return self.type; } -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.debugDescription]; -} - @end From 6020b2bdd9d2682db075fbfdab0a17f5dee1d581 Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 19 Oct 2015 21:40:04 +0200 Subject: [PATCH 047/103] Add implementation for the negation and "has" selectors The negation selector is specified here: http://www.w3.org/TR/css3-selectors/#negation The "has" selector is an extra convenience selector --- HTMLKit.xcodeproj/project.pbxproj | 8 +++ HTMLKit/CSSPseudoFunctionSelector.h | 16 ++++++ HTMLKit/CSSPseudoFunctionSelector.m | 89 +++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 HTMLKit/CSSPseudoFunctionSelector.h create mode 100644 HTMLKit/CSSPseudoFunctionSelector.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index aba4d35..d79d0fc 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* 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 */; }; + 620C877E1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */; settings = {ASSET_TAGS = (); }; }; + 620C877F1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */; settings = {ASSET_TAGS = (); }; }; 620EE9491BC46F2A0028ED34 /* CSSPseudoClassSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */; settings = {ASSET_TAGS = (); }; }; 620EE94A1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; settings = {ASSET_TAGS = (); }; }; 620EE94B1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; settings = {ASSET_TAGS = (); }; }; @@ -315,6 +317,8 @@ 6279F87319E1808D00F12EE5 /* HTMLElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLElement.m; sourceTree = ""; }; 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionsParserTests.m; sourceTree = ""; }; 628B7CE61A080E1000602C87 /* HTMLNamespaces.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLNamespaces.h; sourceTree = ""; }; + 62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPseudoFunctionSelector.h; sourceTree = ""; }; + 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSPseudoFunctionSelector.m; sourceTree = ""; }; 62AE593319F97D880043F069 /* HTMLParseErrorToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLParseErrorToken.h; sourceTree = ""; }; 62AE593419F97D880043F069 /* HTMLParseErrorToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLParseErrorToken.m; sourceTree = ""; }; 62AE593819F97E1C0043F069 /* HTMLDOCTYPEToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLDOCTYPEToken.h; sourceTree = ""; }; @@ -399,6 +403,8 @@ 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */, 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */, 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */, + 62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */, + 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */, ); name = Selectors; sourceTree = ""; @@ -892,6 +898,7 @@ 625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */, 62FC60471BD0519B0042BBE7 /* CSSSelector.m in Sources */, 623857981A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, + 620C877F1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */, 62AE594B19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, 623458501A9D2FA4009BD491 /* HTMLNode.m in Sources */, 624B28C11B0413200048D328 /* CSSAttributeSelector.m in Sources */, @@ -961,6 +968,7 @@ 623857971A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, 62FC60461BD0519B0042BBE7 /* CSSSelector.m in Sources */, 62AE594A19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, + 620C877E1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */, 6234584F1A9D2FA4009BD491 /* HTMLNode.m in Sources */, 624B28C01B0413200048D328 /* CSSAttributeSelector.m in Sources */, 62F31FDE19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */, diff --git a/HTMLKit/CSSPseudoFunctionSelector.h b/HTMLKit/CSSPseudoFunctionSelector.h new file mode 100644 index 0000000..5580201 --- /dev/null +++ b/HTMLKit/CSSPseudoFunctionSelector.h @@ -0,0 +1,16 @@ +// +// CSSPseudoFunctionSelector.h +// HTMLKit +// +// Created by Iska on 07/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelector.h" + +@interface CSSPseudoFunctionSelector : CSSSelector + ++ (nullable instancetype)notSelector:(nonnull CSSSelector *)selector; ++ (nullable instancetype)hasSelector:(nonnull CSSSelector *)selector; + +@end diff --git a/HTMLKit/CSSPseudoFunctionSelector.m b/HTMLKit/CSSPseudoFunctionSelector.m new file mode 100644 index 0000000..e16f71b --- /dev/null +++ b/HTMLKit/CSSPseudoFunctionSelector.m @@ -0,0 +1,89 @@ +// +// CSSPseudoFunctionSelector.m +// HTMLKit +// +// Created by Iska on 07/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSPseudoFunctionSelector.h" +#import "HTMLElement.h" + +#pragma mark - Declarations + +@interface CSSNotSelector : CSSPseudoFunctionSelector +@end + +@interface CSSHasSelector : CSSPseudoFunctionSelector +@end + +#pragma mark - Base Function Selector + +@interface CSSPseudoFunctionSelector () +{ + CSSSelector *_selector; +} +@property (nonatomic, strong, readonly) CSSSelector *selector; +@end + +@implementation CSSPseudoFunctionSelector +@synthesize selector = _selector; + ++ (nullable instancetype)notSelector:(nonnull CSSSelector *)selector +{ + return [[CSSNotSelector alloc] initWithSelector:selector]; +} + ++ (nullable instancetype)hasSelector:(nonnull CSSSelector *)selector +{ + return [[CSSHasSelector alloc] initWithSelector:selector]; +} + +- (instancetype)initWithSelector:(CSSSelector *)selector +{ + self = [super init]; + if (self) { + _selector = selector; + } + return self; +} + +@end + +#pragma mark - Not Selector + +@implementation CSSNotSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + return ![self.selector acceptElement:element]; +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@":not(%@)", self.selector.debugDescription]; +} + +@end + +#pragma mark - Has Selector + +@implementation CSSHasSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + for (HTMLNode *child in element.childNodes) { + if (child.nodeType == HTMLNodeElement && [self.selector acceptElement:child.asElement]) { + return YES; + } + } + + return NO; +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@":has(%@)", self.selector.debugDescription]; +} + +@end From 33df9e7fb2517fc4b0bed1c9b8365e1e995844de Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 19 Oct 2015 21:49:51 +0200 Subject: [PATCH 048/103] Add implementation for combining multiple selectors with "All" and "Exists" quantifiers --- HTMLKit.xcodeproj/project.pbxproj | 10 ++++ HTMLKit/CSSCompoundSelector.h | 16 ++++++ HTMLKit/CSSCompoundSelector.m | 88 +++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 HTMLKit/CSSCompoundSelector.h create mode 100644 HTMLKit/CSSCompoundSelector.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index d79d0fc..b10774c 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -9,6 +9,9 @@ /* 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 = (); }; }; 620C877E1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */; settings = {ASSET_TAGS = (); }; }; 620C877F1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */; settings = {ASSET_TAGS = (); }; }; 620EE9491BC46F2A0028ED34 /* CSSPseudoClassSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */; settings = {ASSET_TAGS = (); }; }; @@ -215,6 +218,8 @@ /* Begin PBXFileReference section */ 62079BE71AF56F1E00D3B402 /* CSSSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelector.h; sourceTree = ""; }; + 620C87791BD44CBE00FB3EEE /* CSSCompoundSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSCompoundSelector.h; sourceTree = ""; }; + 620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSCompoundSelector.m; sourceTree = ""; }; 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPseudoClassSelector.h; sourceTree = ""; }; 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSPseudoClassSelector.m; sourceTree = ""; }; 6223211D1A969B9300BACED5 /* HTMLElementTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLElementTypes.h; sourceTree = ""; }; @@ -405,6 +410,8 @@ 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */, 62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */, 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */, + 620C87791BD44CBE00FB3EEE /* CSSCompoundSelector.h */, + 620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */, ); name = Selectors; sourceTree = ""; @@ -690,6 +697,7 @@ 623406E11ADB04F9004677A3 /* HTMLTemplate.h in Headers */, 624B28B81B03DA820048D328 /* CSSTypeSelector.h in Headers */, 6234BEEE1AABBF1400DEB15F /* HTMLStackOfOpenElements.h in Headers */, + 620C877B1BD44CBE00FB3EEE /* CSSCompoundSelector.h in Headers */, 6238C9851AB8D6330006512E /* HTMLKitDOMExceptions.h in Headers */, 6238039F1AB63A8C008A53D0 /* HTMLEOFToken.h in Headers */, 6279F87419E1808D00F12EE5 /* HTMLElement.h in Headers */, @@ -886,6 +894,7 @@ 623803A11AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */, 624B28C61B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */, 6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */, + 620C877D1BD44CBE00FB3EEE /* CSSCompoundSelector.m in Sources */, 625A150A19C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */, 623857931A9E772B003A45D9 /* HTMLDocument.m in Sources */, 624B7DDE1B2E3AAB00A4BD61 /* CSSToken.m in Sources */, @@ -955,6 +964,7 @@ 623803A01AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */, 624B28C51B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */, 6279F87519E1808D00F12EE5 /* HTMLElement.m in Sources */, + 620C877C1BD44CBE00FB3EEE /* CSSCompoundSelector.m in Sources */, 625A150919C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */, 623857921A9E772B003A45D9 /* HTMLDocument.m in Sources */, 624B7DDD1B2E3AAB00A4BD61 /* CSSToken.m in Sources */, diff --git a/HTMLKit/CSSCompoundSelector.h b/HTMLKit/CSSCompoundSelector.h new file mode 100644 index 0000000..5e76ff8 --- /dev/null +++ b/HTMLKit/CSSCompoundSelector.h @@ -0,0 +1,16 @@ +// +// CSSCompoundSelector.h +// HTMLKit +// +// Created by Iska on 18/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelector.h" + +@interface CSSCompoundSelector : CSSSelector + ++ (nullable instancetype)andSelector:(nonnull NSArray *)selectors; ++ (nullable instancetype)orSelector:(nonnull NSArray *)selectors; + +@end diff --git a/HTMLKit/CSSCompoundSelector.m b/HTMLKit/CSSCompoundSelector.m new file mode 100644 index 0000000..c414f1d --- /dev/null +++ b/HTMLKit/CSSCompoundSelector.m @@ -0,0 +1,88 @@ +// +// CSSCompoundSelector.m +// HTMLKit +// +// Created by Iska on 18/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSCompoundSelector.h" + +#pragma mark - Declarations + +@interface CSSAndCompoundSelector : CSSCompoundSelector +@end + +@interface CSSOrCompoundSelector : CSSCompoundSelector +@end + +#pragma mark - Base Combinator + +@interface CSSCompoundSelector () +{ + NSArray *_selectors; +} +@property (nonatomic, strong, readonly) NSArray *selectors; +@end + +@implementation CSSCompoundSelector +@synthesize selectors = _selectors; + ++ (instancetype)andSelector:(NSArray *)selectors +{ + return [[CSSAndCompoundSelector alloc] initWithSelectors:selectors]; +} + ++ (instancetype)orSelector:(NSArray *)selectors +{ + return [[CSSOrCompoundSelector alloc] initWithSelectors:selectors]; +} + +- (instancetype)initWithSelectors:(NSArray *)selectors +{ + self = [super init]; + if (self) { + _selectors = [[NSArray alloc] initWithArray:selectors]; + } + return self; +} + +- (NSString *)debugDescription +{ + NSArray *descriptions = [_selectors valueForKey:@"debugDescription"]; + return [descriptions componentsJoinedByString:@""]; +} + +@end + +#pragma mark - And Compound Selector + +@implementation CSSAndCompoundSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + for (CSSSelector *selector in self.selectors) { + if (![selector acceptElement:element]) { + return NO; + } + } + return YES; +} + +@end + +#pragma mark - Or Compound Selector + +@implementation CSSOrCompoundSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + for (CSSSelector *selector in self.selectors) { + if ([selector acceptElement:element]) { + return YES; + } + } + return NO; +} + +@end From 02393ddedd5e969a38dd8c396de8b887ce478a8f Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 19 Oct 2015 21:51:46 +0200 Subject: [PATCH 049/103] Add implementation for the CSS Combinators http://www.w3.org/TR/css3-selectors/#combinators --- HTMLKit.xcodeproj/project.pbxproj | 8 ++ HTMLKit/CSSCombinatorSelector.h | 18 ++++ HTMLKit/CSSCombinatorSelector.m | 154 ++++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 HTMLKit/CSSCombinatorSelector.h create mode 100644 HTMLKit/CSSCombinatorSelector.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index b10774c..dc1a9bb 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -182,6 +182,9 @@ 62F873EB19E088C90062683C /* HTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F873E919E088C90062683C /* HTMLParser.h */; }; 62F873EC19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; }; 62F873ED19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; }; + 62FA04E31BCC360D009ABF98 /* CSSCombinatorSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62FA04E11BCC360D009ABF98 /* CSSCombinatorSelector.h */; settings = {ASSET_TAGS = (); }; }; + 62FA04E41BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */; settings = {ASSET_TAGS = (); }; }; + 62FA04E51BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */; settings = {ASSET_TAGS = (); }; }; 62FC60461BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; settings = {ASSET_TAGS = (); }; }; 62FC60471BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; settings = {ASSET_TAGS = (); }; }; /* End PBXBuildFile section */ @@ -410,6 +413,8 @@ 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */, 62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */, 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */, + 62FA04E11BCC360D009ABF98 /* CSSCombinatorSelector.h */, + 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */, 620C87791BD44CBE00FB3EEE /* CSSCompoundSelector.h */, 620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */, ); @@ -712,6 +717,7 @@ 6247A9431B152F4F00CCF25C /* HTMLNodeIterator.h in Headers */, 625A150419C783EB00AD0C32 /* HTMLKit.h in Headers */, 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 */, @@ -888,6 +894,7 @@ 62363C3F1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m in Sources */, 62AE593C19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */, 623406E31ADB04F9004677A3 /* HTMLTemplate.m in Sources */, + 62FA04E51BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */, 6238C9871AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */, 6247171A1B22333200C11912 /* HTMLNodeTraversal.m in Sources */, 62F873ED19E088C90062683C /* HTMLParser.m in Sources */, @@ -958,6 +965,7 @@ 62363C3E1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m in Sources */, 62AE593B19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */, 623406E21ADB04F9004677A3 /* HTMLTemplate.m in Sources */, + 62FA04E41BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */, 6238C9861AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */, 624717191B22333200C11912 /* HTMLNodeTraversal.m in Sources */, 62F873EC19E088C90062683C /* HTMLParser.m in Sources */, diff --git a/HTMLKit/CSSCombinatorSelector.h b/HTMLKit/CSSCombinatorSelector.h new file mode 100644 index 0000000..91a0419 --- /dev/null +++ b/HTMLKit/CSSCombinatorSelector.h @@ -0,0 +1,18 @@ +// +// CSSCombinatorSelector.h +// HTMLKit +// +// Created by Iska on 12/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelector.h" + +@interface CSSCombinatorSelector : CSSSelector + ++ (nullable instancetype)childOfElementCombinator:(nonnull CSSSelector *)selector; ++ (nullable instancetype)descendantOfElementCombinator:(nonnull CSSSelector *)selector; ++ (nullable instancetype)adjacentSiblingCombinator:(nonnull CSSSelector *)selector; ++ (nullable instancetype)generalSiblingCombinator:(nonnull CSSSelector *)selector; + +@end diff --git a/HTMLKit/CSSCombinatorSelector.m b/HTMLKit/CSSCombinatorSelector.m new file mode 100644 index 0000000..fb3aa21 --- /dev/null +++ b/HTMLKit/CSSCombinatorSelector.m @@ -0,0 +1,154 @@ +// +// CSSCombinatorSelector.m +// HTMLKit +// +// Created by Iska on 12/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSCombinatorSelector.h" +#import "HTMLElement.h" + +#pragma mark - Declarations + +@interface CSSChildOfElementCombinatorSelector : CSSCombinatorSelector +@end + +@interface CSSDecendantOfElementCombinatorSelector : CSSCombinatorSelector +@end + +@interface CSSAdjacentSiblingCombinatorSelector : CSSCombinatorSelector +@end + +@interface CSSGeneralSiblingCombinatorSelector : CSSCombinatorSelector +@end + +#pragma mark - Base Combinator + +@interface CSSCombinatorSelector () +{ + CSSSelector *_selector; +} +@property (nonatomic, strong, readonly) CSSSelector *selector; +@end + +@implementation CSSCombinatorSelector +@synthesize selector = _selector; + ++ (nullable instancetype)childOfElementCombinator:(nonnull CSSSelector *)selector +{ + return [[CSSChildOfElementCombinatorSelector alloc] initWithSelector:selector]; +} + ++ (nullable instancetype)descendantOfElementCombinator:(nonnull CSSSelector *)selector +{ + return [[CSSDecendantOfElementCombinatorSelector alloc] initWithSelector:selector]; +} + ++ (nullable instancetype)adjacentSiblingCombinator:(nonnull CSSSelector *)selector +{ + return [[CSSAdjacentSiblingCombinatorSelector alloc] initWithSelector:selector]; +} + ++ (nullable instancetype)generalSiblingCombinator:(nonnull CSSSelector *)selector +{ + return [[CSSGeneralSiblingCombinatorSelector alloc] initWithSelector:selector]; +} + +- (instancetype)initWithSelector:(CSSSelector *)selector +{ + self = [super init]; + if (self) { + _selector = selector; + } + return self; +} + +@end + +#pragma mark - Child OfElement Combinator + +@implementation CSSChildOfElementCombinatorSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + HTMLElement *parent = element.parentElement; + return parent != nil && [self.selector acceptElement:element]; +} + +- (NSString *)debugDescription +{ + return @" > "; +} + +@end + +#pragma mark - Decendant Of Element Combinator + +@implementation CSSDecendantOfElementCombinatorSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + HTMLElement *parent = element.parentElement; + + while (parent != nil) { + if ([self.selector acceptElement:parent]) { + return YES; + } + parent = parent.parentElement; + } + + return NO; +} + +- (NSString *)debugDescription +{ + return @" "; +} + +@end + +#pragma mark - Adjacent Sibling Combinator + +@implementation CSSAdjacentSiblingCombinatorSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + HTMLNode *previous = element.previousSibling; + if (previous == nil || previous.nodeType != HTMLNodeElement) { + return NO; + } + return [self.selector acceptElement:previous.asElement]; +} + +- (NSString *)debugDescription +{ + return @" + "; +} + +@end + +#pragma mark - General Sibling Combinator + +@implementation CSSGeneralSiblingCombinatorSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + HTMLNode *previous = element.previousSibling; + + while (previous != nil && previous.nodeType == HTMLNodeElement) { + if ([self.selector acceptElement:previous.asElement]) { + return YES; + } + previous = previous.previousSibling; + } + + return NO; +} + +- (NSString *)debugDescription +{ + return @" ~ "; +} + +@end From 5ca3bf11927463bfeba1db3d5d904ec6fd2f9360 Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 20 Oct 2015 21:15:30 +0200 Subject: [PATCH 050/103] Replace nullability specifiers from methods and properties with nullability-regions --- HTMLKit/CSSAttributeSelector.h | 30 +++++++++++------------------ HTMLKit/CSSAttributeSelector.m | 2 +- HTMLKit/CSSCombinatorSelector.h | 12 ++++++++---- HTMLKit/CSSCombinatorSelector.m | 14 +++++++------- HTMLKit/CSSCompoundSelector.h | 8 ++++++-- HTMLKit/CSSPseudoClassSelector.h | 12 +++++++----- HTMLKit/CSSPseudoClassSelector.m | 17 ++++++---------- HTMLKit/CSSPseudoFunctionSelector.h | 8 ++++++-- HTMLKit/CSSPseudoFunctionSelector.m | 4 ++-- HTMLKit/CSSTypeSelector.h | 10 +++++++--- 10 files changed, 61 insertions(+), 56 deletions(-) diff --git a/HTMLKit/CSSAttributeSelector.h b/HTMLKit/CSSAttributeSelector.h index ca343a6..d1ba040 100644 --- a/HTMLKit/CSSAttributeSelector.h +++ b/HTMLKit/CSSAttributeSelector.h @@ -9,30 +9,22 @@ #import #import "CSSSelector.h" -typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType) -{ - CSSAttributeSelectorExists, - CSSAttributeSelectorExactMatch, - CSSAttributeSelectorIncludes, - CSSAttributeSelectorBegins, - CSSAttributeSelectorEnds, - CSSAttributeSelectorContains, - CSSAttributeSelectorHyphen, - CSSAttributeSelectorNot -}; +NS_ASSUME_NONNULL_BEGIN @interface CSSAttributeSelector : CSSSelector @property (nonatomic, assign) CSSAttributeSelectorType type; -@property (nonatomic, strong, readonly) NSString * _Nonnull name; -@property (nonatomic, strong, readonly) NSString * _Nonnull value; +@property (nonatomic, strong, readonly) NSString *name; +@property (nonatomic, strong, readonly) NSString *value; -+ (nullable instancetype)classSelector:(nonnull NSString *)className; -+ (nullable instancetype)idSelector:(nonnull NSString *)elementId; -+ (nullable instancetype)attributeSelector:(nonnull NSString *)attributeName; ++ (instancetype)classSelector:(NSString *)className; ++ (instancetype)idSelector:(NSString *)elementId; ++ (instancetype)hasAttributeSelector:(NSString *)attributeName; -- (nullable instancetype)initWithType:(CSSAttributeSelectorType)type - attributeName:(nonnull NSString *)name - attrbiuteValue:(nonnull NSString *)value; +- (instancetype)initWithType:(CSSAttributeSelectorType)type + attributeName:(NSString *)name + attrbiuteValue:(NSString *)value; @end + +NS_ASSUME_NONNULL_END diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index 433be22..79b5055 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -30,7 +30,7 @@ return [[self alloc] initWithType:CSSAttributeSelectorExactMatch attributeName:@"id" attrbiuteValue:elementId]; } -+ (nullable instancetype)attributeSelector:(nonnull NSString *)attributeName ++ (instancetype)hasAttributeSelector:(NSString *)attributeName { return [[self alloc] initWithType:CSSAttributeSelectorExists attributeName:attributeName attrbiuteValue:@""]; } diff --git a/HTMLKit/CSSCombinatorSelector.h b/HTMLKit/CSSCombinatorSelector.h index 91a0419..b227736 100644 --- a/HTMLKit/CSSCombinatorSelector.h +++ b/HTMLKit/CSSCombinatorSelector.h @@ -8,11 +8,15 @@ #import "CSSSelector.h" +NS_ASSUME_NONNULL_BEGIN + @interface CSSCombinatorSelector : CSSSelector -+ (nullable instancetype)childOfElementCombinator:(nonnull CSSSelector *)selector; -+ (nullable instancetype)descendantOfElementCombinator:(nonnull CSSSelector *)selector; -+ (nullable instancetype)adjacentSiblingCombinator:(nonnull CSSSelector *)selector; -+ (nullable instancetype)generalSiblingCombinator:(nonnull CSSSelector *)selector; ++ (instancetype)childOfElementCombinator:(CSSSelector *)selector; ++ (instancetype)descendantOfElementCombinator:(CSSSelector *)selector; ++ (instancetype)adjacentSiblingCombinator:(CSSSelector *)selector; ++ (instancetype)generalSiblingCombinator:(CSSSelector *)selector; @end + +NS_ASSUME_NONNULL_END diff --git a/HTMLKit/CSSCombinatorSelector.m b/HTMLKit/CSSCombinatorSelector.m index fb3aa21..d5263cc 100644 --- a/HTMLKit/CSSCombinatorSelector.m +++ b/HTMLKit/CSSCombinatorSelector.m @@ -35,22 +35,22 @@ @implementation CSSCombinatorSelector @synthesize selector = _selector; -+ (nullable instancetype)childOfElementCombinator:(nonnull CSSSelector *)selector ++ (instancetype)childOfElementCombinator:(CSSSelector *)selector { return [[CSSChildOfElementCombinatorSelector alloc] initWithSelector:selector]; } -+ (nullable instancetype)descendantOfElementCombinator:(nonnull CSSSelector *)selector ++ (instancetype)descendantOfElementCombinator:(CSSSelector *)selector { return [[CSSDecendantOfElementCombinatorSelector alloc] initWithSelector:selector]; } -+ (nullable instancetype)adjacentSiblingCombinator:(nonnull CSSSelector *)selector ++ (instancetype)adjacentSiblingCombinator:(CSSSelector *)selector { return [[CSSAdjacentSiblingCombinatorSelector alloc] initWithSelector:selector]; } -+ (nullable instancetype)generalSiblingCombinator:(nonnull CSSSelector *)selector ++ (instancetype)generalSiblingCombinator:(CSSSelector *)selector { return [[CSSGeneralSiblingCombinatorSelector alloc] initWithSelector:selector]; } @@ -78,7 +78,7 @@ - (NSString *)debugDescription { - return @" > "; + return @">"; } @end @@ -123,7 +123,7 @@ - (NSString *)debugDescription { - return @" + "; + return @"+"; } @end @@ -148,7 +148,7 @@ - (NSString *)debugDescription { - return @" ~ "; + return @"~"; } @end diff --git a/HTMLKit/CSSCompoundSelector.h b/HTMLKit/CSSCompoundSelector.h index 5e76ff8..b6eab0e 100644 --- a/HTMLKit/CSSCompoundSelector.h +++ b/HTMLKit/CSSCompoundSelector.h @@ -8,9 +8,13 @@ #import "CSSSelector.h" +NS_ASSUME_NONNULL_BEGIN + @interface CSSCompoundSelector : CSSSelector -+ (nullable instancetype)andSelector:(nonnull NSArray *)selectors; -+ (nullable instancetype)orSelector:(nonnull NSArray *)selectors; ++ (instancetype)andSelector:(NSArray *)selectors; ++ (instancetype)orSelector:(NSArray *)selectors; @end + +NS_ASSUME_NONNULL_END diff --git a/HTMLKit/CSSPseudoClassSelector.h b/HTMLKit/CSSPseudoClassSelector.h index 8d977e7..7f15cd9 100644 --- a/HTMLKit/CSSPseudoClassSelector.h +++ b/HTMLKit/CSSPseudoClassSelector.h @@ -7,13 +7,15 @@ // #import "CSSSelector.h" -#import "CSSSimpleSelector.h" -@interface CSSPseudoClassSelector : NSObject +NS_ASSUME_NONNULL_BEGIN -@property (nonatomic, strong, readonly) NSString * _Nonnull className; +@interface CSSPseudoClassSelector : CSSSelector -- (nullable instancetype)initWithClassName:(nonnull NSString *)className - andBlock:(nonnull CSSSelectorAcceptElementBlock)block; +@property (nonatomic, strong, readonly) NSString *className; + +- (instancetype)initWithClassName:(NSString *)className selector:(CSSSelector *)selector; @end + +NS_ASSUME_NONNULL_END diff --git a/HTMLKit/CSSPseudoClassSelector.m b/HTMLKit/CSSPseudoClassSelector.m index 8be8258..3471670 100644 --- a/HTMLKit/CSSPseudoClassSelector.m +++ b/HTMLKit/CSSPseudoClassSelector.m @@ -7,35 +7,30 @@ // #import "CSSPseudoClassSelector.h" -#import "HTMLElement.h" -#import "NSString+HTMLKit.h" - -@interface CSSPseudoClassSelector () -{ - CSSSelectorAcceptElementBlock _block; -} -@end @interface CSSPseudoClassSelector () { NSString *_className; + CSSSelector *_selector; } @end @implementation CSSPseudoClassSelector +@synthesize className = _className; -- (instancetype)initWithClassName:(NSString *)className andBlock:(CSSSelectorAcceptElementBlock)block +- (instancetype)initWithClassName:(NSString *)className selector:(CSSSelector *)selector { self = [super init]; if (self) { - _block = block; + _className = [className copy]; + _selector = selector; } return self; } -(BOOL)acceptElement:(HTMLElement *)element { - return _block ? _block(element) : NO; + return [_selector acceptElement:element]; } - (NSString *)debugDescription diff --git a/HTMLKit/CSSPseudoFunctionSelector.h b/HTMLKit/CSSPseudoFunctionSelector.h index 5580201..d5d69f3 100644 --- a/HTMLKit/CSSPseudoFunctionSelector.h +++ b/HTMLKit/CSSPseudoFunctionSelector.h @@ -8,9 +8,13 @@ #import "CSSSelector.h" +NS_ASSUME_NONNULL_BEGIN + @interface CSSPseudoFunctionSelector : CSSSelector -+ (nullable instancetype)notSelector:(nonnull CSSSelector *)selector; -+ (nullable instancetype)hasSelector:(nonnull CSSSelector *)selector; ++ (instancetype)notSelector:(CSSSelector *)selector; ++ (instancetype)hasSelector:(CSSSelector *)selector; @end + +NS_ASSUME_NONNULL_END diff --git a/HTMLKit/CSSPseudoFunctionSelector.m b/HTMLKit/CSSPseudoFunctionSelector.m index e16f71b..9c22407 100644 --- a/HTMLKit/CSSPseudoFunctionSelector.m +++ b/HTMLKit/CSSPseudoFunctionSelector.m @@ -29,12 +29,12 @@ @implementation CSSPseudoFunctionSelector @synthesize selector = _selector; -+ (nullable instancetype)notSelector:(nonnull CSSSelector *)selector ++ (instancetype)notSelector:(CSSSelector *)selector { return [[CSSNotSelector alloc] initWithSelector:selector]; } -+ (nullable instancetype)hasSelector:(nonnull CSSSelector *)selector ++ (instancetype)hasSelector:(CSSSelector *)selector { return [[CSSHasSelector alloc] initWithSelector:selector]; } diff --git a/HTMLKit/CSSTypeSelector.h b/HTMLKit/CSSTypeSelector.h index c36ebff..6bd1f93 100644 --- a/HTMLKit/CSSTypeSelector.h +++ b/HTMLKit/CSSTypeSelector.h @@ -9,12 +9,16 @@ #import #import "CSSSelector.h" +NS_ASSUME_NONNULL_BEGIN + @interface CSSTypeSelector : CSSSelector -@property (nonatomic, strong, readonly) NSString * _Nonnull type; +@property (nonatomic, strong, readonly) NSString *type; -+ (nullable instancetype)universalSelector; ++ (instancetype)universalSelector; -- (nullable instancetype)initWithType:(nonnull NSString *)type; +- (instancetype)initWithType:(NSString *)type; @end + +NS_ASSUME_NONNULL_END From d107c05a4426514778b0f1d29986c7838e07c425 Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 20 Oct 2015 21:17:42 +0200 Subject: [PATCH 051/103] Add stubs for the Nth-Expression Selectors http://www.w3.org/TR/css3-selectors/#structural-pseudos --- HTMLKit.xcodeproj/project.pbxproj | 10 ++++ HTMLKit/CSSNthExpressionSelector.h | 24 +++++++++ HTMLKit/CSSNthExpressionSelector.m | 81 ++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 HTMLKit/CSSNthExpressionSelector.h create mode 100644 HTMLKit/CSSNthExpressionSelector.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index dc1a9bb..4ccd890 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -146,6 +146,9 @@ 6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6279F87319E1808D00F12EE5 /* HTMLElement.m */; }; 628AF62F1BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */; settings = {ASSET_TAGS = (); }; }; 628AF6301BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */; settings = {ASSET_TAGS = (); }; }; + 628AF6331BC9A63D00496128 /* CSSNthExpressionSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 628AF6311BC9A63D00496128 /* CSSNthExpressionSelector.h */; settings = {ASSET_TAGS = (); }; }; + 628AF6341BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */; settings = {ASSET_TAGS = (); }; }; + 628AF6351BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */; settings = {ASSET_TAGS = (); }; }; 62AE593519F97D880043F069 /* HTMLParseErrorToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593319F97D880043F069 /* HTMLParseErrorToken.h */; }; 62AE593619F97D880043F069 /* HTMLParseErrorToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593419F97D880043F069 /* HTMLParseErrorToken.m */; }; 62AE593719F97D880043F069 /* HTMLParseErrorToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593419F97D880043F069 /* HTMLParseErrorToken.m */; }; @@ -324,6 +327,8 @@ 6279F87219E1808D00F12EE5 /* HTMLElement.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = HTMLElement.h; sourceTree = ""; }; 6279F87319E1808D00F12EE5 /* HTMLElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLElement.m; sourceTree = ""; }; 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionsParserTests.m; sourceTree = ""; }; + 628AF6311BC9A63D00496128 /* CSSNthExpressionSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSNthExpressionSelector.h; sourceTree = ""; }; + 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionSelector.m; sourceTree = ""; }; 628B7CE61A080E1000602C87 /* HTMLNamespaces.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLNamespaces.h; sourceTree = ""; }; 62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPseudoFunctionSelector.h; sourceTree = ""; }; 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSPseudoFunctionSelector.m; sourceTree = ""; }; @@ -411,6 +416,8 @@ 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */, 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */, 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */, + 628AF6311BC9A63D00496128 /* CSSNthExpressionSelector.h */, + 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */, 62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */, 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */, 62FA04E11BCC360D009ABF98 /* CSSCombinatorSelector.h */, @@ -688,6 +695,7 @@ 624B7DDC1B2E3AAB00A4BD61 /* CSSToken.h in Headers */, 624B28BF1B0413200048D328 /* CSSAttributeSelector.h in Headers */, 62D89DB41AE7081600B6243D /* HTMLElementTypes.h in Headers */, + 628AF6331BC9A63D00496128 /* CSSNthExpressionSelector.h in Headers */, 62D89DB51AE7081600B6243D /* HTMLElementAdjustment.h in Headers */, 62D89DB61AE7081600B6243D /* HTMLParserInsertionModes.h in Headers */, 62D89DB71AE7081600B6243D /* HTMLQuirksMode.h in Headers */, @@ -903,6 +911,7 @@ 6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */, 620C877D1BD44CBE00FB3EEE /* CSSCompoundSelector.m in Sources */, 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 */, @@ -989,6 +998,7 @@ 620C877E1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */, 6234584F1A9D2FA4009BD491 /* HTMLNode.m in Sources */, 624B28C01B0413200048D328 /* CSSAttributeSelector.m in Sources */, + 628AF6341BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */, 62F31FDE19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */, 62AE593619F97D880043F069 /* HTMLParseErrorToken.m in Sources */, ); diff --git a/HTMLKit/CSSNthExpressionSelector.h b/HTMLKit/CSSNthExpressionSelector.h new file mode 100644 index 0000000..77c3949 --- /dev/null +++ b/HTMLKit/CSSNthExpressionSelector.h @@ -0,0 +1,24 @@ +// +// CSSNthExpressionSelector.h +// HTMLKit +// +// Created by Iska on 10/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelector.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface CSSNthExpressionSelector : CSSSelector + +@property (nonatomic, assign, readonly) CSSNthExpression expression; + ++ (instancetype)nthChildSelector:(CSSNthExpression)expression; ++ (instancetype)nthLastChildSelector:(CSSNthExpression)expression; ++ (instancetype)nthOfTypeSelector:(CSSNthExpression)expression; ++ (instancetype)nthLastOfTypeSelector:(CSSNthExpression)expression; + +@end + +NS_ASSUME_NONNULL_END diff --git a/HTMLKit/CSSNthExpressionSelector.m b/HTMLKit/CSSNthExpressionSelector.m new file mode 100644 index 0000000..8519ae9 --- /dev/null +++ b/HTMLKit/CSSNthExpressionSelector.m @@ -0,0 +1,81 @@ +// +// CSSNthExpressionSelector.m +// HTMLKit +// +// Created by Iska on 10/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSNthExpressionSelector.h" +#import "HTMLElement.h" + +#pragma mark - Nth-Expression + +const CSSNthExpression CSSNthExpressionOdd = (CSSNthExpression) { + .an = 2, .b = 1 +}; + +const CSSNthExpression CSSNthExpressionEven = (CSSNthExpression) { + .an = 2, .b = 0 +}; + +NSString * _Nonnull NSStringFromNthExpression(CSSNthExpression expression) +{ + if (expression.an == 0 && expression.b == 0) { + return @"invalid"; + } + + if (expression.an == 0) { + return [NSString stringWithFormat:@"%ld", expression.b]; + } + if (expression.b == 0) { + return [NSString stringWithFormat:@"%ldn", expression.an]; + } + + return [NSString stringWithFormat:@"%ldn%+ld", expression.an, expression.b]; +} + +#pragma mark - Implementation + +@interface CSSNthExpressionSelector () +{ + CSSNthExpression _expression; +} +@end + +@implementation CSSNthExpressionSelector +@synthesize expression = _expression; + ++ (instancetype)nthChildSelector:(CSSNthExpression)expression +{ + return nil; +} + ++ (instancetype)nthLastChildSelector:(CSSNthExpression)expression +{ + return nil; +} + ++ (instancetype)nthOfTypeSelector:(CSSNthExpression)expression +{ + return nil; +} + ++ (instancetype)nthLastOfTypeSelector:(CSSNthExpression)expression +{ + return nil; +} + +#pragma mark - + +- (BOOL)acceptElement:(HTMLElement *)element +{ + return NO; +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@":%@(%@)", self.className, NSStringFromNthExpression(self.expression)]; +} + +@end From 0366f39d1a24adda28e831cc7b3624433ca906ee Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 20 Oct 2015 21:30:39 +0200 Subject: [PATCH 052/103] Add public header for all available selectors and hide the actual implementations --- HTMLKit.xcodeproj/project.pbxproj | 5 + HTMLKit/CSSSelectors.h | 60 ++++++++++- HTMLKit/CSSSelectors.m | 169 ++++++++++++++++++++++++++++++ 3 files changed, 231 insertions(+), 3 deletions(-) create mode 100644 HTMLKit/CSSSelectors.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 4ccd890..a7e55f8 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -188,6 +188,8 @@ 62FA04E31BCC360D009ABF98 /* CSSCombinatorSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62FA04E11BCC360D009ABF98 /* CSSCombinatorSelector.h */; settings = {ASSET_TAGS = (); }; }; 62FA04E41BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */; settings = {ASSET_TAGS = (); }; }; 62FA04E51BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */; settings = {ASSET_TAGS = (); }; }; + 62FA98041BD57B6200A2AF86 /* CSSSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */; settings = {ASSET_TAGS = (); }; }; + 62FA98051BD57B6200A2AF86 /* CSSSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */; settings = {ASSET_TAGS = (); }; }; 62FC60461BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; settings = {ASSET_TAGS = (); }; }; 62FC60471BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; settings = {ASSET_TAGS = (); }; }; /* End PBXBuildFile section */ @@ -352,6 +354,7 @@ 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionParser.m; sourceTree = ""; }; 62F873E919E088C90062683C /* HTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLParser.h; sourceTree = ""; }; 62F873EA19E088C90062683C /* HTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLParser.m; sourceTree = ""; }; + 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectors.m; sourceTree = ""; }; 62FC60451BD0519B0042BBE7 /* CSSSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelector.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -399,6 +402,7 @@ isa = PBXGroup; children = ( 624AB3151B04EA4200F3830D /* CSSSelectors.h */, + 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */, 624B371C1B24E9BA0010BDDF /* CSSInputStream.h */, 624B371D1B24E9BA0010BDDF /* CSSInputStream.m */, 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */, @@ -966,6 +970,7 @@ 624493AD19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */, 6235CEA11AA5170A0026937B /* HTMLMarker.m in Sources */, 623424891AB467B200726190 /* HTMLOrderedDictionary.m in Sources */, + 62FA98041BD57B6200A2AF86 /* CSSSelectors.m in Sources */, 624717BD1B22009200B38302 /* HTMLTreeWalker.m in Sources */, 62AE594019F9907C0043F069 /* HTMLTagToken.m in Sources */, 62F501661BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */, diff --git a/HTMLKit/CSSSelectors.h b/HTMLKit/CSSSelectors.h index c9f9932..fa416cd 100644 --- a/HTMLKit/CSSSelectors.h +++ b/HTMLKit/CSSSelectors.h @@ -7,6 +7,60 @@ // #import "CSSSelector.h" -#import "CSSTypeSelector.h" -#import "CSSAttributeSelector.h" -#import "CSSPseudoClassSelector.h" + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Type Selectors + +extern CSSSelector * universalSelector(); +extern CSSSelector * typeSelector(NSString *type); + +#pragma mark - Atribute Selectors + +extern CSSSelector * idSelector(NSString *elementId); +extern CSSSelector * classSelector(NSString *className); +extern CSSSelector * hasAttributeSelector(NSString *attribute); +extern CSSSelector * attributeSelector(CSSAttributeSelectorType type, + NSString *attribute, + NSString *value); + +#pragma mark - Nth-Expression Selectors + +extern CSSSelector * nthChildSelector(CSSNthExpression expression); +extern CSSSelector * nthLastChildSelector(CSSNthExpression expression); +extern CSSSelector * nthOfTypeSelector(CSSNthExpression expression); +extern CSSSelector * nthLastOfTypeSelector(CSSNthExpression expression); + +extern CSSSelector * oddSelector(); +extern CSSSelector * evenSlector(); + +extern CSSSelector * firstChildSelector(); +extern CSSSelector * lastChildSelector(); +extern CSSSelector * firstOfTypeSelector(); +extern CSSSelector * lastOfTypeSelector(); + +extern CSSSelector * onlyChildSelector(); +extern CSSSelector * onlyOfTypeSelector(); + +#pragma mark - Combinators + +extern CSSSelector * childOfElementSelector(CSSSelector *selector); +extern CSSSelector * descendantOfElementSelector(CSSSelector *selector); +extern CSSSelector * adjacentSiblingSelector(CSSSelector *selector); +extern CSSSelector * generalSiblingSelector(CSSSelector *selector); + +#pragma mark - Pseudo Functions + +extern CSSSelector * nay(CSSSelector *selector); +extern CSSSelector * has(CSSSelector *selector); + +#pragma mark - Compound Selectors + +extern CSSSelector * allOf(NSArray *selectors); +extern CSSSelector * anyOf(NSArray *selectors); + +#pragma mark - Block + +extern CSSSelector * selectorWithBlock(BOOL (^ acceptBlock)(HTMLElement *)); + +NS_ASSUME_NONNULL_END diff --git a/HTMLKit/CSSSelectors.m b/HTMLKit/CSSSelectors.m new file mode 100644 index 0000000..d88f0e7 --- /dev/null +++ b/HTMLKit/CSSSelectors.m @@ -0,0 +1,169 @@ +// +// CSSSelectors.m +// HTMLKit +// +// Created by Iska on 19/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelectors.h" +#import "CSSTypeSelector.h" +#import "CSSAttributeSelector.h" +#import "CSSPseudoClassSelector.h" +#import "CSSPseudoFunctionSelector.h" +#import "CSSNthExpressionSelector.h" +#import "CSSStructuralPseudoSelector.h" +#import "CSSCombinatorSelector.h" +#import "CSSCompoundSelector.h" +#import "CSSSelectorBlock.h" + +#pragma mark - Type Selectors + +CSSSelector *universalSelector() +{ + return [CSSTypeSelector universalSelector]; +} + +CSSSelector *typeSelector(NSString *type) +{ + return [[CSSTypeSelector alloc] initWithType:type]; +} + +#pragma mark - Atribute Selectors + +CSSSelector *idSelector(NSString *elementId) +{ + return [CSSAttributeSelector idSelector:elementId]; +} + +CSSSelector *classSelector(NSString *className) +{ + return [CSSAttributeSelector classSelector:className]; +} + +CSSSelector *hasAttributeSelector(NSString *attribute) +{ + return [CSSAttributeSelector hasAttributeSelector:attribute]; +} + +CSSSelector *attributeSelector(CSSAttributeSelectorType type, + NSString *attribute, + NSString *value) +{ + return [[CSSAttributeSelector alloc] initWithType:type attributeName:attribute attrbiuteValue:value]; +} + +#pragma mark - Nth-Expression Selectors + +CSSSelector *nthChildSelector(CSSNthExpression expression) +{ + return [CSSNthExpressionSelector nthChildSelector:expression]; +} + +CSSSelector *nthLastChildSelector(CSSNthExpression expression) +{ + return [CSSNthExpressionSelector nthLastChildSelector:expression]; +} + +CSSSelector *nthOfTypeSelector(CSSNthExpression expression) +{ + return [CSSNthExpressionSelector nthOfTypeSelector:expression]; +} + +CSSSelector *nthLastOfTypeSelector(CSSNthExpression expression) +{ + return [CSSNthExpressionSelector nthLastOfTypeSelector:expression]; +} + +CSSSelector * oddSelector() +{ + return [CSSNthExpressionSelector nthChildSelector:CSSNthExpressionOdd]; +} + +CSSSelector * evenSlector() +{ + return [CSSNthExpressionSelector nthChildSelector:CSSNthExpressionEven]; +} + +CSSSelector *firstChildSelector() +{ + return [CSSNthExpressionSelector nthChildSelector:CSSNthExpressionMake(0, 1)]; +} + +CSSSelector *lastChildSelector() +{ + return [CSSNthExpressionSelector nthLastChildSelector:CSSNthExpressionMake(0, 1)]; +} + +CSSSelector *firstOfTypeSelector() +{ + return [CSSNthExpressionSelector nthOfTypeSelector:CSSNthExpressionMake(0, 1)]; +} + +CSSSelector *lastOfTypeSelector() +{ + return [CSSNthExpressionSelector nthLastOfTypeSelector:CSSNthExpressionMake(0, 1)]; +} + +CSSSelector *onlyChildSelector() +{ + return allOf(@[firstChildSelector(), lastChildSelector()]); +} + +CSSSelector *onlyOfTypeSelector() +{ + return allOf(@[firstOfTypeSelector(), lastOfTypeSelector()]); +} + +#pragma mark - Combinators + +CSSSelector *childOfElementSelector(CSSSelector *selector) +{ + return [CSSCombinatorSelector childOfElementCombinator:selector]; +} + +CSSSelector *descendantOfElementSelector(CSSSelector *selector) +{ + return [CSSCombinatorSelector descendantOfElementCombinator:selector]; +} + +CSSSelector *adjacentSiblingSelector(CSSSelector *selector) +{ + return [CSSCombinatorSelector adjacentSiblingCombinator:selector]; +} + +CSSSelector *generalSiblingSelector(CSSSelector *selector) +{ + return [CSSCombinatorSelector generalSiblingCombinator:selector]; +} + +#pragma mark - Pseudo Functions + +CSSSelector *nay(CSSSelector *selector) +{ + return [CSSPseudoFunctionSelector notSelector:selector]; +} + +CSSSelector *has(CSSSelector *selector) +{ + return [CSSPseudoFunctionSelector hasSelector:selector]; +} + +#pragma mark - Compound Selectors + +CSSSelector *allOf( NSArray * selectors) +{ + return [CSSCompoundSelector andSelector:selectors]; +} + +CSSSelector *anyOf( NSArray * selectors) +{ + return [CSSCompoundSelector andSelector:selectors]; +} + +#pragma mark - Block + +CSSSelector * selectorWithBlock(BOOL (^ acceptBlock)(HTMLElement *)) +{ + return nil; +} From 118ea137f407480ffa3c55d891dec15c29a1ce0c Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 20 Oct 2015 21:31:08 +0200 Subject: [PATCH 053/103] Update existing type and attribute tests for new structure --- HTMLKitTests/CSSAttributeSelectorTests.m | 206 +++++++++-------------- HTMLKitTests/CSSTypeSelectorTests.m | 51 +++--- 2 files changed, 97 insertions(+), 160 deletions(-) diff --git a/HTMLKitTests/CSSAttributeSelectorTests.m b/HTMLKitTests/CSSAttributeSelectorTests.m index 8bb9b8c..32d7fdd 100644 --- a/HTMLKitTests/CSSAttributeSelectorTests.m +++ b/HTMLKitTests/CSSAttributeSelectorTests.m @@ -26,251 +26,199 @@ - (void)testAttributeExists { - CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorExists - attributeName:@"attr" - attrbiuteValue:@""]; + CSSSelector *selector = hasAttributeSelector(@"attr"); - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"class"] = @"class"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); _element[@"attr"] = @"value 2"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); _element[@"attr"] = @"value 3"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); } - (void)testAttributeExactMatch { - CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorExactMatch - attributeName:@"attr" - attrbiuteValue:@"value"]; + CSSSelector *selector = attributeSelector(CSSAttributeSelectorExactMatch, @"attr", @"value"); - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"class"] = @"class"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"value 1"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"value 2"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"value 3"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); } - (void)testAttributeIncludes { - CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorIncludes - attributeName:@"attr" - attrbiuteValue:@"value"]; + CSSSelector *selector = attributeSelector(CSSAttributeSelectorIncludes, @"attr", @"value"); - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"class"] = @"class"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); _element[@"attr"] = @"a b value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); _element[@"attr"] = @"a value b"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); } - (void)testAttributeBegins { - CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorBegins - attributeName:@"attr" - attrbiuteValue:@"value"]; + CSSSelector *selector = attributeSelector(CSSAttributeSelectorBegins, @"attr", @"value"); - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"class"] = @"class"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"val"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"a value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); _element[@"attr"] = @"values"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); } - (void)testAttributeEnds { - CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorEnds - attributeName:@"attr" - attrbiuteValue:@"value"]; + CSSSelector *selector = attributeSelector(CSSAttributeSelectorEnds, @"attr", @"value"); - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"class"] = @"class"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"val"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); _element[@"attr"] = @"a value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); _element[@"attr"] = @"some-value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); } - (void)testAttributeContains { - CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorContains - attributeName:@"attr" - attrbiuteValue:@"value"]; + CSSSelector *selector = attributeSelector(CSSAttributeSelectorContains, @"attr", @"value"); - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"class"] = @"class"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"val"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); _element[@"attr"] = @"a value b"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); _element[@"attr"] = @"some-values"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); } - (void)testAttributeHyphen { - CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorHyphen - attributeName:@"attr" - attrbiuteValue:@"top"]; + CSSSelector *selector = attributeSelector(CSSAttributeSelectorHyphen, @"attr", @"value"); - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"class"] = @"class"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"top_text"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"toptext"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); _element[@"attr"] = @"top"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); _element[@"attr"] = @"top-text"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], YES); [_element.attributes removeObjectForKey:@"attr"]; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:_element], NO); } -- (void)testChangeAttributeName +- (void)testAttributeNot { - CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorExists - attributeName:@"attr" - attrbiuteValue:@""]; + CSSSelector *selector = attributeSelector(CSSAttributeSelectorNot, @"attr", @"value"); + + XCTAssertEqual([selector acceptElement:_element], YES); + + _element[@"class"] = @"class"; + XCTAssertEqual([selector acceptElement:_element], YES); + + _element[@"attr"] = @"top_text"; + XCTAssertEqual([selector acceptElement:_element], YES); + + _element[@"attr"] = @"toptext"; + XCTAssertEqual([selector acceptElement:_element], YES); + + _element[@"attr"] = @"top"; + XCTAssertEqual([selector acceptElement:_element], YES); + + _element[@"attr"] = @"top-text"; + XCTAssertEqual([selector acceptElement:_element], YES); + + [_element.attributes removeObjectForKey:@"attr"]; + XCTAssertEqual([selector acceptElement:_element], YES); _element[@"attr"] = @"value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); - - selector.name = @"new-attr"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); - - _element[@"new-attr"] = @"value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); -} - -- (void)testChangeAttributeValue -{ - CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorExactMatch - attributeName:@"attr" - attrbiuteValue:@"value"]; - - _element[@"attr"] = @"value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); - - selector.value = @"new-value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterSkip); - - _element[@"attr"] = @"new-value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); -} - -- (void)testChangeAttributeType -{ - CSSAttributeSelector *selector = [[CSSAttributeSelector alloc] initWithType:CSSAttributeSelectorExists - attributeName:@"attr" - attrbiuteValue:@"value"]; - - _element[@"attr"] = @""; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); - - selector.type = CSSAttributeSelectorExactMatch; - _element[@"attr"] = @"value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); - - selector.type = CSSAttributeSelectorIncludes; - _element[@"attr"] = @"first-value value another-value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); - - selector.type = CSSAttributeSelectorBegins; - _element[@"attr"] = @"values"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); - - selector.type = CSSAttributeSelectorEnds; - _element[@"attr"] = @"some-value"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); - - selector.type = CSSAttributeSelectorContains; - _element[@"attr"] = @"here-is-a-value-"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); - - selector.type = CSSAttributeSelectorHyphen; - _element[@"attr"] = @"value-"; - XCTAssertEqual([selector acceptNode:_element], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:_element], NO); } @end diff --git a/HTMLKitTests/CSSTypeSelectorTests.m b/HTMLKitTests/CSSTypeSelectorTests.m index 490619e..5d0d8c0 100644 --- a/HTMLKitTests/CSSTypeSelectorTests.m +++ b/HTMLKitTests/CSSTypeSelectorTests.m @@ -9,6 +9,7 @@ #import #import "CSSSelectors.h" #import "HTMLDOM.h" +#import "CSSSelectorParser.h" @interface CSSTypeSelectorTests : XCTestCase @@ -16,46 +17,34 @@ @implementation CSSTypeSelectorTests +- (void)testX +{ + CSSSelectorParser *parser = [[CSSSelectorParser alloc] initWithString:@"div:root"]; + CSSSimpleSequence *sequence = [parser parse]; + NSLog(@"%@", sequence); +} + - (void)testUniversalSelector { - CSSTypeSelector *selector = [CSSTypeSelector universalSelector]; + CSSSelector *selector = universalSelector(); - XCTAssertEqual([selector acceptNode:[HTMLDocumentType new]], HTMLNodeFilterSkip); - XCTAssertEqual([selector acceptNode:[HTMLDocumentFragment new]], HTMLNodeFilterSkip); - XCTAssertEqual([selector acceptNode:[[HTMLText alloc] initWithData:@"Text"]], HTMLNodeFilterSkip); - XCTAssertEqual([selector acceptNode:[[HTMLComment alloc] initWithData:@"Comment"]], HTMLNodeFilterSkip); - - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:nil]], HTMLNodeFilterAccept); - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@""]], HTMLNodeFilterAccept); - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]], HTMLNodeFilterAccept); - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"p"]], HTMLNodeFilterAccept); - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"any other name"]], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:nil]], YES); + XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@""]], YES); + XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@"div"]], YES); + XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@"p"]], YES); + XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@"any other name"]], YES); } - (void)testTypeSelector { - CSSTypeSelector *selector = [[CSSTypeSelector alloc] initWithType:@"div"]; + CSSSelector *selector = typeSelector(@"div"); - XCTAssertEqual([selector acceptNode:[HTMLDocumentType new]], HTMLNodeFilterSkip); - XCTAssertEqual([selector acceptNode:[HTMLDocumentFragment new]], HTMLNodeFilterSkip); - XCTAssertEqual([selector acceptNode:[[HTMLText alloc] initWithData:@"Text"]], HTMLNodeFilterSkip); - XCTAssertEqual([selector acceptNode:[[HTMLComment alloc] initWithData:@"Comment"]], HTMLNodeFilterSkip); - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:nil]], HTMLNodeFilterSkip); - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@""]], HTMLNodeFilterSkip); - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"p"]], HTMLNodeFilterSkip); - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"any other name"]], HTMLNodeFilterSkip); + XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:nil]], NO); + XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@""]], NO); + XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@"p"]], NO); + XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@"any other name"]], NO); - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]], HTMLNodeFilterAccept); -} - -- (void)testChangeSelectorType -{ - CSSTypeSelector *selector = [[CSSTypeSelector alloc] initWithType:@"div"]; - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]], HTMLNodeFilterAccept); - - selector.type = @"p"; - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"div"]], HTMLNodeFilterSkip); - XCTAssertEqual([selector acceptNode:[[HTMLElement alloc] initWithTagName:@"p"]], HTMLNodeFilterAccept); + XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@"div"]], YES); } @end From f248b39d26fc4ffde8da073ef03f39026aa6f56c Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 21 Oct 2015 00:35:07 +0200 Subject: [PATCH 054/103] Move Nth-Expression typedef to the public header --- HTMLKit/CSSNthExpressionParser.h | 19 +------------------ HTMLKit/CSSNthExpressionParser.m | 4 +++- HTMLKit/CSSSelector.h | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/HTMLKit/CSSNthExpressionParser.h b/HTMLKit/CSSNthExpressionParser.h index e00f8dc..2fd75af 100644 --- a/HTMLKit/CSSNthExpressionParser.h +++ b/HTMLKit/CSSNthExpressionParser.h @@ -8,25 +8,8 @@ #import -typedef struct CSSNthExpression -{ - NSInteger an; - NSInteger b; -} CSSNthExpression; - -NS_INLINE CSSNthExpression CSSNthExpressionMake(NSInteger an, NSInteger b) { - return (CSSNthExpression){ .an = an, .b = b }; -} - -const CSSNthExpression CSSNthExpressionOdd = (CSSNthExpression){ - .an = 2, .b = 1 -}; -const CSSNthExpression CSSNthExpressionEven = (CSSNthExpression){ - .an = 2, .b = 0 -}; - @interface CSSNthExpressionParser : NSObject -+ (CSSNthExpression)parseExpression:(NSString *)string; ++ (CSSNthExpression)parseExpression:(NSString *)expression; @end diff --git a/HTMLKit/CSSNthExpressionParser.m b/HTMLKit/CSSNthExpressionParser.m index 43a176c..a36915d 100644 --- a/HTMLKit/CSSNthExpressionParser.m +++ b/HTMLKit/CSSNthExpressionParser.m @@ -13,10 +13,12 @@ @implementation CSSNthExpressionParser -+ (CSSNthExpression)parseExpression:(NSString *)string ++ (CSSNthExpression)parseExpression:(NSString *)expression { NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet]; + NSString *string = [expression copy]; + string = [string stringByTrimmingCharactersInSet:whitespace]; string = string.lowercaseString; diff --git a/HTMLKit/CSSSelector.h b/HTMLKit/CSSSelector.h index b16f2a9..d13fb58 100644 --- a/HTMLKit/CSSSelector.h +++ b/HTMLKit/CSSSelector.h @@ -8,6 +8,38 @@ #import +#pragma mark - Attribute Selector Type + +typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType) +{ + CSSAttributeSelectorExists, + CSSAttributeSelectorExactMatch, + CSSAttributeSelectorIncludes, + CSSAttributeSelectorBegins, + CSSAttributeSelectorEnds, + CSSAttributeSelectorContains, + CSSAttributeSelectorHyphen, + CSSAttributeSelectorNot +}; + +#pragma mark - CSS Nth-Expression + +typedef struct CSSNthExpression +{ + NSInteger an; + NSInteger b; +} CSSNthExpression; + +NS_INLINE CSSNthExpression CSSNthExpressionMake(NSInteger an, NSInteger b) { + return (CSSNthExpression){ .an = an, .b = b }; +} + +extern const CSSNthExpression CSSNthExpressionOdd; +extern const CSSNthExpression CSSNthExpressionEven; +extern NSString * _Nonnull NSStringFromNthExpression(CSSNthExpression expression); + +#pragma mark - Base Selector Class + @class HTMLElement; @interface CSSSelector : NSObject From bd84884bf7c3b36755c1746f4a9f22d249a67b20 Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 21 Oct 2015 22:13:03 +0200 Subject: [PATCH 055/103] Add a block-based selector class for inline selector implementations --- HTMLKit.xcodeproj/project.pbxproj | 10 ++++++++ HTMLKit/CSSSelectorBlock.h | 21 ++++++++++++++++ HTMLKit/CSSSelectorBlock.m | 40 +++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 HTMLKit/CSSSelectorBlock.h create mode 100644 HTMLKit/CSSSelectorBlock.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index a7e55f8..472307f 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -190,6 +190,9 @@ 62FA04E51BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */; settings = {ASSET_TAGS = (); }; }; 62FA98041BD57B6200A2AF86 /* CSSSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */; settings = {ASSET_TAGS = (); }; }; 62FA98051BD57B6200A2AF86 /* CSSSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */; settings = {ASSET_TAGS = (); }; }; + 62FA98081BD5A7E200A2AF86 /* CSSSelectorBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 62FA98061BD5A7E200A2AF86 /* CSSSelectorBlock.h */; settings = {ASSET_TAGS = (); }; }; + 62FA98091BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */; settings = {ASSET_TAGS = (); }; }; + 62FA980A1BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */; settings = {ASSET_TAGS = (); }; }; 62FC60461BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; settings = {ASSET_TAGS = (); }; }; 62FC60471BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; settings = {ASSET_TAGS = (); }; }; /* End PBXBuildFile section */ @@ -355,6 +358,8 @@ 62F873E919E088C90062683C /* HTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLParser.h; sourceTree = ""; }; 62F873EA19E088C90062683C /* HTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLParser.m; sourceTree = ""; }; 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectors.m; sourceTree = ""; }; + 62FA98061BD5A7E200A2AF86 /* CSSSelectorBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelectorBlock.h; sourceTree = ""; }; + 62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectorBlock.m; sourceTree = ""; }; 62FC60451BD0519B0042BBE7 /* CSSSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelector.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -414,6 +419,8 @@ 624B37211B250BB50010BDDF /* CSSTokenizerCodePoints.h */, 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, 62FC60451BD0519B0042BBE7 /* CSSSelector.m */, + 62FA98061BD5A7E200A2AF86 /* CSSSelectorBlock.h */, + 62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */, 624B28B61B03DA820048D328 /* CSSTypeSelector.h */, 624B28B71B03DA820048D328 /* CSSTypeSelector.m */, 624B28BD1B0413200048D328 /* CSSAttributeSelector.h */, @@ -693,6 +700,7 @@ 6235CE9B1AA509430026937B /* NSString+HTMLKit.h in Headers */, 62D89DB11AE7081600B6243D /* HTMLTokenizerStates.h in Headers */, 62079BE91AF56F1E00D3B402 /* CSSSelector.h in Headers */, + 62FA98081BD5A7E200A2AF86 /* CSSSelectorBlock.h in Headers */, 62D89DB21AE7081600B6243D /* HTMLTokenizerCharacters.h in Headers */, 62D89DB31AE7081600B6243D /* HTMLNamespaces.h in Headers */, 624B28BC1B03DAB70048D328 /* HTMLNodeFilter.h in Headers */, @@ -908,6 +916,7 @@ 623406E31ADB04F9004677A3 /* HTMLTemplate.m in Sources */, 62FA04E51BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */, 6238C9871AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */, + 62FA980A1BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */, 6247171A1B22333200C11912 /* HTMLNodeTraversal.m in Sources */, 62F873ED19E088C90062683C /* HTMLParser.m in Sources */, 623803A11AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */, @@ -980,6 +989,7 @@ 62AE593B19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */, 623406E21ADB04F9004677A3 /* HTMLTemplate.m in Sources */, 62FA04E41BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */, + 62FA98091BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */, 6238C9861AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */, 624717191B22333200C11912 /* HTMLNodeTraversal.m in Sources */, 62F873EC19E088C90062683C /* HTMLParser.m in Sources */, diff --git a/HTMLKit/CSSSelectorBlock.h b/HTMLKit/CSSSelectorBlock.h new file mode 100644 index 0000000..f1030e7 --- /dev/null +++ b/HTMLKit/CSSSelectorBlock.h @@ -0,0 +1,21 @@ +// +// CSSSelectorBlock.h +// HTMLKit +// +// Created by Iska on 20/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelector.h" + +NS_ASSUME_NONNULL_BEGIN + +@class HTMLElement; + +@interface CSSSelectorBlock : CSSSelector + +- (instancetype)initWithName:(NSString *)name block:(BOOL (^)(HTMLElement *))block; + +@end + +NS_ASSUME_NONNULL_END diff --git a/HTMLKit/CSSSelectorBlock.m b/HTMLKit/CSSSelectorBlock.m new file mode 100644 index 0000000..c8d44d6 --- /dev/null +++ b/HTMLKit/CSSSelectorBlock.m @@ -0,0 +1,40 @@ +// +// CSSSelectorBlock.m +// HTMLKit +// +// Created by Iska on 20/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelectorBlock.h" + +@interface CSSSelectorBlock () +{ + NSString *_name; + BOOL (^ _acceptBlock)(HTMLElement *); +} +@end + +@implementation CSSSelectorBlock + +- (instancetype)initWithName:(NSString *)name block:(BOOL (^)(HTMLElement *))block +{ + self = [super init]; + if (self) { + _name = [name copy]; + _acceptBlock = [block copy]; + } + return self; +} + +- (BOOL)acceptElement:(HTMLElement *)element +{ + return _acceptBlock ? _acceptBlock(element) : NO; +} + +- (NSString *)debugDescription +{ + return _name; +} + +@end From 61d7c683fbc7502813200358e8d33e1095e808fd Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 21 Oct 2015 22:15:36 +0200 Subject: [PATCH 056/103] Add implementations for structural pseudo class selectors https://html.spec.whatwg.org/multipage/scripting.html#selectors http://api.jquery.com/category/selectors/jquery-selector-extensions/ http://sizzlejs.com --- HTMLKit.xcodeproj/project.pbxproj | 10 + HTMLKit/CSSStructuralPseudoSelectors.h | 38 ++++ HTMLKit/CSSStructuralPseudoSelectors.m | 271 +++++++++++++++++++++++++ 3 files changed, 319 insertions(+) create mode 100644 HTMLKit/CSSStructuralPseudoSelectors.h create mode 100644 HTMLKit/CSSStructuralPseudoSelectors.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 472307f..1646a5e 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -149,6 +149,9 @@ 628AF6331BC9A63D00496128 /* CSSNthExpressionSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 628AF6311BC9A63D00496128 /* CSSNthExpressionSelector.h */; settings = {ASSET_TAGS = (); }; }; 628AF6341BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */; settings = {ASSET_TAGS = (); }; }; 628AF6351BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */; settings = {ASSET_TAGS = (); }; }; + 628AF63E1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h in Headers */ = {isa = PBXBuildFile; fileRef = 628AF63C1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h */; settings = {ASSET_TAGS = (); }; }; + 628AF63F1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF63D1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m */; settings = {ASSET_TAGS = (); }; }; + 628AF6401BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF63D1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m */; settings = {ASSET_TAGS = (); }; }; 62AE593519F97D880043F069 /* HTMLParseErrorToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593319F97D880043F069 /* HTMLParseErrorToken.h */; }; 62AE593619F97D880043F069 /* HTMLParseErrorToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593419F97D880043F069 /* HTMLParseErrorToken.m */; }; 62AE593719F97D880043F069 /* HTMLParseErrorToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593419F97D880043F069 /* HTMLParseErrorToken.m */; }; @@ -334,6 +337,8 @@ 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionsParserTests.m; sourceTree = ""; }; 628AF6311BC9A63D00496128 /* CSSNthExpressionSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSNthExpressionSelector.h; sourceTree = ""; }; 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionSelector.m; sourceTree = ""; }; + 628AF63C1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSStructuralPseudoSelectors.h; sourceTree = ""; }; + 628AF63D1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSStructuralPseudoSelectors.m; sourceTree = ""; }; 628B7CE61A080E1000602C87 /* HTMLNamespaces.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLNamespaces.h; sourceTree = ""; }; 62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPseudoFunctionSelector.h; sourceTree = ""; }; 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSPseudoFunctionSelector.m; sourceTree = ""; }; @@ -427,6 +432,8 @@ 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */, 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */, 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */, + 628AF63C1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h */, + 628AF63D1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m */, 628AF6311BC9A63D00496128 /* CSSNthExpressionSelector.h */, 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */, 62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */, @@ -713,6 +720,7 @@ 62D89DB71AE7081600B6243D /* HTMLQuirksMode.h in Headers */, 62D89DB01AE7080300B6243D /* HTMLDOM.h in Headers */, 62F873EB19E088C90062683C /* HTMLParser.h in Headers */, + 628AF63E1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h in Headers */, 624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */, 62AE594419F992F30043F069 /* HTMLCommentToken.h in Headers */, 624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */, @@ -917,6 +925,7 @@ 62FA04E51BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */, 6238C9871AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */, 62FA980A1BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */, + 628AF6401BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m in Sources */, 6247171A1B22333200C11912 /* HTMLNodeTraversal.m in Sources */, 62F873ED19E088C90062683C /* HTMLParser.m in Sources */, 623803A11AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */, @@ -989,6 +998,7 @@ 62AE593B19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */, 623406E21ADB04F9004677A3 /* HTMLTemplate.m in Sources */, 62FA04E41BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */, + 628AF63F1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m in Sources */, 62FA98091BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */, 6238C9861AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */, 624717191B22333200C11912 /* HTMLNodeTraversal.m in Sources */, diff --git a/HTMLKit/CSSStructuralPseudoSelectors.h b/HTMLKit/CSSStructuralPseudoSelectors.h new file mode 100644 index 0000000..013bd9a --- /dev/null +++ b/HTMLKit/CSSStructuralPseudoSelectors.h @@ -0,0 +1,38 @@ +// +// CSSStructuralPseudoSelector.h +// HTMLKit +// +// Created by Iska on 11/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +@class CSSSelector; + +NS_ASSUME_NONNULL_BEGIN + +extern CSSSelector * rootSelector(); +extern CSSSelector * emptySelector(); +extern CSSSelector * parentSelector(); + +extern CSSSelector * buttonSelector(); +extern CSSSelector * checkboxSelector(); +extern CSSSelector * fileSelector(); +extern CSSSelector * headerSelector(); +extern CSSSelector * imageSelector(); +extern CSSSelector * inputSelector(); +extern CSSSelector * linkSelector(); +extern CSSSelector * passwordSelector(); +extern CSSSelector * radioSelector(); +extern CSSSelector * resetSelector(); +extern CSSSelector * submitSelector(); +extern CSSSelector * textSelector(); + +extern CSSSelector * enabledSelector(); +extern CSSSelector * disabledSelector(); +extern CSSSelector * checkedSelector(); + +extern CSSSelector * ltSelector(); +extern CSSSelector * gtSelector(); +extern CSSSelector * eqSelector(); + +NS_ASSUME_NONNULL_END diff --git a/HTMLKit/CSSStructuralPseudoSelectors.m b/HTMLKit/CSSStructuralPseudoSelectors.m new file mode 100644 index 0000000..7d5b411 --- /dev/null +++ b/HTMLKit/CSSStructuralPseudoSelectors.m @@ -0,0 +1,271 @@ +// +// CSSStructuralPseudoSelector.m +// HTMLKit +// +// Created by Iska on 11/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSStructuralPseudoSelectors.h" +#import "CSSSelectors.h" +#import "HTMLElement.h" +#import "NSString+HTMLKit.h" + +#pragma mark - Elements + +CSSSelector * rootSelector() +{ + return namedBlockSelector(@"root", ^BOOL(HTMLElement * element) { + return !!element.parentElement; + }); +} + +CSSSelector * emptySelector() +{ + return namedBlockSelector(@"empty", ^BOOL(HTMLElement * element) { + for (HTMLNode *child in element.childNodes) { + if (child.nodeType == HTMLNodeElement) { + return NO; + } else if (child.nodeType == HTMLNodeText && child.textContent.length > 0) { + return NO; + } + } + return YES; + }); +} + +CSSSelector * parentSelector() +{ + return namedBlockSelector(@"parent", ^BOOL(HTMLElement * element) { + return element.childNodesCount > 0; + }); +} + +CSSSelector * buttonSelector() +{ + return namedBlockSelector(@"button", ^BOOL(HTMLElement * _Nonnull element) { + if ([element.tagName isEqualToString:@"button"]) { + return YES; + } + if ([element.tagName isEqualToString:@"input"] && [element[@"type"] isEqualToString:@"button"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * checkboxSelector() +{ + return namedBlockSelector(@"checkbox", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"checkbox"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * fileSelector() +{ + return namedBlockSelector(@"file", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"file"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * headerSelector() +{ + return namedBlockSelector(@"header", ^BOOL(HTMLElement * _Nonnull element) { + if ([element.tagName isEqualToAny:@"h1", @"h2", @"h3", @"h4", @"h5", @"h6", nil]) { + return YES; + } + return NO; + }); +} + +CSSSelector * imageSelector() +{ + return namedBlockSelector(@"image", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"image"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * inputSelector() +{ + return namedBlockSelector(@"input", ^BOOL(HTMLElement * _Nonnull element) { + if ([element.tagName isEqualToAny:@"button", @"input", @"select", @"textarea", nil]) { + return YES; + } + return NO; + }); +} + +CSSSelector * linkSelector() +{ + // https://html.spec.whatwg.org/multipage/scripting.html#selector-link + return namedBlockSelector(@"root", ^BOOL(HTMLElement * element) { + if ([element hasAttribute:@"href"]) { + return [element.tagName isEqualToAny:@"a", @"area", @"link", nil]; + } + return NO; + }); +} + +CSSSelector * passwordSelector() +{ + return namedBlockSelector(@"password", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"password"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * radioSelector() +{ + return namedBlockSelector(@"radio", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"radio"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * resetSelector() +{ + return namedBlockSelector(@"reset", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"reset"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * submitSelector() +{ + return namedBlockSelector(@"submit", ^BOOL(HTMLElement * _Nonnull element) { + if ([element.tagName isEqualToString:@"input"] && [element[@"type"] isEqualToString:@"submit"]) { + return YES; + } + if ([element.tagName isEqualToString:@"button"] && [element[@"type"] isEqualToString:@"submit"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * textSelector() +{ + return namedBlockSelector(@"text", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"text"]) { + return YES; + } + return NO; + }); +} + +#pragma mark - State + +CSSSelector * enabledSelector() +{ + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + CSSSelector *candiate = anyOf(@[ + typeSelector(@"button"), + typeSelector(@"input"), + typeSelector(@"select"), + typeSelector(@"textarea"), + typeSelector(@"optgroup"), + typeSelector(@"option"), + typeSelector(@"menuitem"), + typeSelector(@"fieldset"), + ]); + return namedPseudoSelector(@"enabled", allOf(@[candiate, nay(disabledSelector())])); +} + +CSSSelector * disabledSelector() +{ + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + CSSSelector *disabledAttribute = hasAttributeSelector(@"disabled"); + + // https://html.spec.whatwg.org/multipage/forms.html#concept-fieldset-disabled + CSSSelector *disabledFieldset = allOf(@[typeSelector(@"fieldset"), disabledAttribute]); + CSSSelector *firstLegend = allOf(@[typeSelector(@"legend"), firstOfTypeSelector()]); + CSSSelector *firstLegendDecendantDisabledFieldSet = allOf(@[firstLegend, descendantOfElementSelector(disabledFieldset)]); + + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + CSSSelector *disabledForm = anyOf(@[ + allOf(@[ + allOf(@[typeSelector(@"button"), disabledAttribute]), + allOf(@[typeSelector(@"input"), disabledAttribute]), + allOf(@[typeSelector(@"select"), disabledAttribute]), + allOf(@[typeSelector(@"textarea"), disabledAttribute]) + ]), + allOf(@[ + descendantOfElementSelector(disabledFieldset), + nay(firstLegendDecendantDisabledFieldSet) + ]) + ]); + + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + CSSSelector *disabledMenuItem = allOf(@[typeSelector(@"menuitem"), disabledAttribute]); + CSSSelector *disabledOptgroup = allOf(@[typeSelector(@"optgroup"), disabledAttribute]); + + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + CSSSelector *disabledOption = allOf(@[ + typeSelector(@"option"), + anyOf(@[ + disabledAttribute, + descendantOfElementSelector(disabledOptgroup)]) + ]); + return namedPseudoSelector(@"disabled", + anyOf(@[disabledOption, disabledOptgroup, disabledMenuItem, disabledForm, disabledFieldset])); +} + +CSSSelector * checkedElementSelector() +{ + // https://html.spec.whatwg.org/multipage/scripting.html#selector-checked + CSSSelector *candidate = anyOf(@[ + typeSelector(@"input"), + typeSelector(@"option"), + typeSelector(@"menutitem") + ]); + CSSSelector *hasAttribute = anyOf(@[ + hasAttributeSelector(@"checked"), + hasAttributeSelector(@"selected") + ]); + + return namedPseudoSelector(@"checked", allOf(@[candidate, hasAttribute])); +} + +#pragma mark - Positional + +CSSSelector * ltSelector(NSUInteger index) +{ + return namedBlockSelector(@"lt", ^BOOL(HTMLElement * _Nonnull element) { + return [element.parentElement indexOfChildNode:element] < index; + }); +} + +CSSSelector * gtSelector(NSUInteger index) +{ + return namedBlockSelector(@"gt", ^BOOL(HTMLElement * _Nonnull element) { + return [element.parentElement indexOfChildNode:element] > index; + }); +} + +CSSSelector * eqSelector(NSInteger index) +{ + return namedBlockSelector(@"eq", ^BOOL(HTMLElement * _Nonnull element) { + NSUInteger elementIndex = [element.parentElement indexOfChildNode:element]; + + if (index > 0) { + return elementIndex == index; + } else { + return elementIndex == element.parentElement.childNodesCount - index - 1; + } + }); +} From ee82cacc4859e8e5539da4b22dad9078e9c556dd Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 21 Oct 2015 22:16:18 +0200 Subject: [PATCH 057/103] Add CSS input stream method to consume characters till given codepoint is met --- HTMLKit/CSSInputStream.h | 1 + HTMLKit/CSSInputStream.m | 56 +++++++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/HTMLKit/CSSInputStream.h b/HTMLKit/CSSInputStream.h index a1e9512..b7afc7b 100644 --- a/HTMLKit/CSSInputStream.h +++ b/HTMLKit/CSSInputStream.h @@ -13,6 +13,7 @@ - (void)consumeWhitespace; - (NSString *)consumeIdentifier; +- (NSString *)consumeStringWithEndingCodePoint:(UTF32Char)endingCodePoint; - (UTF32Char)consumeEscapedCodePoint; @end diff --git a/HTMLKit/CSSInputStream.m b/HTMLKit/CSSInputStream.m index cb54a2d..78dc724 100644 --- a/HTMLKit/CSSInputStream.m +++ b/HTMLKit/CSSInputStream.m @@ -9,6 +9,10 @@ #import "CSSInputStream.h" #import "CSSTokenizerCodePoints.h" +@interface HTMLInputStreamReader () +- (void)emitParseError:(NSString *)reason; +@end + @implementation CSSInputStream - (void)consumeWhitespace @@ -23,9 +27,11 @@ CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); while (YES) { - UniChar codePoint = [self consumeNextInputCharacter]; - if (isName(codePoint)) { - CFStringAppendCharacters(value, &codePoint, 1); + UTF32Char codePoint = [self consumeNextInputCharacter]; + if (codePoint == EOF) { + break; + } else if (isName(codePoint)) { + AppendCodePoint(value, codePoint); } else if (isValidEscape(self.nextInputCharacter, [self inputCharacterPointAtOffset:1])) { UTF32Char escapedCodePoint = [self consumeNextInputCharacter]; AppendCodePoint(value, escapedCodePoint); @@ -38,13 +44,51 @@ return (__bridge NSString *)(CFStringGetLength(value) > 0 ? value : nil); } +- (NSString *)consumeStringWithEndingCodePoint:(UTF32Char)endingCodePoint +{ + CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); + + while (YES) { + UTF32Char codePoint = [self consumeNextInputCharacter]; + if (codePoint == endingCodePoint) { + break; + } + + switch (codePoint) { + case EOF: + break; + case LINE_FEED: + [self emitParseError:@"New-line character (0x000A) in CSS attribute value"]; + [self reconsumeCurrentInputCharacter]; + break; + case REVERSE_SOLIDUS: + { + UTF32Char next = self.nextInputCharacter; + if (next == EOF) { + continue; + } else if (next == LINE_FEED) { + [self consumeNextInputCharacter]; + } else { + UTF32Char escapedCodePoint = [self consumeNextInputCharacter]; + AppendCodePoint(value, escapedCodePoint); + } + } + default: + AppendCodePoint(value, codePoint); + break; + } + } + + return (__bridge NSString *)(CFStringGetLength(value) > 0 ? value : nil); +} + - (UTF32Char)consumeEscapedCodePoint { - UniChar codePoint = [self consumeNextInputCharacter]; + UTF32Char codePoint = [self consumeNextInputCharacter]; if (isHexDigit(codePoint)) { CFMutableStringRef hexString = CFStringCreateMutable(kCFAllocatorDefault, 6); - CFStringAppendCharacters(hexString, &codePoint, 1); + AppendCodePoint(hexString, codePoint); while (isHexDigit(self.nextInputCharacter) && CFStringGetLength(hexString) <= 6) { UniChar codePoint = [self consumeNextInputCharacter]; @@ -60,7 +104,7 @@ [scanner scanHexInt:&number]; return isValidEscapedCodePoint(number) ? number : REPLACEMENT_CHARACTER; - } else if (codePoint == EOF_CHARACTER) { + } else if (codePoint == EOF) { return REPLACEMENT_CHARACTER; } From 15e768267afb0dd4b8fff8c698578fa7a3807aaf Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 21 Oct 2015 22:21:14 +0200 Subject: [PATCH 058/103] Rename CSS tokenizer code points header file --- HTMLKit.xcodeproj/project.pbxproj | 4 +- ...STokenizerCodePoints.h => CSSCodePoints.h} | 77 ++++--------------- HTMLKit/CSSInputStream.m | 2 +- HTMLKit/CSSNthExpressionParser.h | 1 + HTMLKit/CSSNthExpressionParser.m | 2 +- 5 files changed, 20 insertions(+), 66 deletions(-) rename HTMLKit/{CSSTokenizerCodePoints.h => CSSCodePoints.h} (62%) diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 1646a5e..a4c407d 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -306,7 +306,7 @@ 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSCharacterSet+HTMLKit.m"; sourceTree = ""; }; 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 /* CSSTokenizerCodePoints.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSTokenizerCodePoints.h; 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 = ""; }; @@ -413,6 +413,7 @@ children = ( 624AB3151B04EA4200F3830D /* CSSSelectors.h */, 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */, + 624B37211B250BB50010BDDF /* CSSCodePoints.h */, 624B371C1B24E9BA0010BDDF /* CSSInputStream.h */, 624B371D1B24E9BA0010BDDF /* CSSInputStream.m */, 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */, @@ -421,7 +422,6 @@ 623F13A91AFC11D900C90BF4 /* CSSTokenizer.m */, 624B7DDA1B2E3AAB00A4BD61 /* CSSToken.h */, 624B7DDB1B2E3AAB00A4BD61 /* CSSToken.m */, - 624B37211B250BB50010BDDF /* CSSTokenizerCodePoints.h */, 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, 62FC60451BD0519B0042BBE7 /* CSSSelector.m */, 62FA98061BD5A7E200A2AF86 /* CSSSelectorBlock.h */, diff --git a/HTMLKit/CSSTokenizerCodePoints.h b/HTMLKit/CSSCodePoints.h similarity index 62% rename from HTMLKit/CSSTokenizerCodePoints.h rename to HTMLKit/CSSCodePoints.h index 1ff909a..93ae3ef 100644 --- a/HTMLKit/CSSTokenizerCodePoints.h +++ b/HTMLKit/CSSCodePoints.h @@ -7,20 +7,13 @@ // #define CODEPOINTS \ - CODEPOINT( EOF_CHARACTER, 0x0000 ) \ - CODEPOINT( BACK_SPACE, 0x0008 ) \ + CODEPOINT( CONTROL, 0x0080 ) \ CODEPOINT( CHARACTER_TABULATION, 0x0009 ) \ CODEPOINT( LINE_FEED, 0x000A ) \ - CODEPOINT( LINE_TABULATION, 0x000B ) \ - CODEPOINT( SHIFT_OUT, 0x000E ) \ - CODEPOINT( INFORMATION_SEPARATOR_ONE, 0x001F ) \ - CODEPOINT( DELETE, 0x007F ) \ CODEPOINT( SPACE, 0x0020 ) \ - CODEPOINT( EXCLAMATION_MARK, 0x0021 ) \ CODEPOINT( QUOTATION_MARK, 0x0022 ) \ CODEPOINT( NUMBER_SIGN, 0x0023 ) \ CODEPOINT( DOLLAR_SIGN, 0x0024 ) \ - CODEPOINT( PERCENTAGE_SIGN, 0x0025 ) \ CODEPOINT( APOSTROPHE, 0x0027 ) \ CODEPOINT( LEFT_PARENTHESIS, 0x0028 ) \ CODEPOINT( RIGHT_PARENTHESIS, 0x0029 ) \ @@ -29,19 +22,13 @@ CODEPOINT( COMMA, 0x002C ) \ CODEPOINT( HYPHEN_MINUS, 0x002D ) \ CODEPOINT( FULL_STOP, 0x002E ) \ - CODEPOINT( SOLIDUS, 0x002F ) \ CODEPOINT( DIGIT_ZERO, 0x0030 ) \ CODEPOINT( DIGIT_NINE, 0x0039 ) \ CODEPOINT( COLON, 0x003A ) \ - CODEPOINT( SEMICOLON, 0x003B ) \ - CODEPOINT( LESS_THAN_SIGN, 0x003C ) \ CODEPOINT( EQUALS_SIGN, 0x003D ) \ - CODEPOINT( QUESTION_MARK, 0x003F ) \ - CODEPOINT( COMMERCIAL_AT, 0x0040) \ + CODEPOINT( GREATER_THAN_SIGN, 0x003E ) \ CODEPOINT( LATIN_CAPITAL_LETTER_A, 0x0041 ) \ - CODEPOINT( LATIN_CAPITAL_LETTER_E, 0x0045 ) \ CODEPOINT( LATIN_CAPITAL_LETTER_F, 0x0046 ) \ - CODEPOINT( LATIN_CAPITAL_LETTER_U, 0x0055 ) \ CODEPOINT( LATIN_CAPITAL_LETTER_Z, 0x005A ) \ CODEPOINT( LEFT_SQUARE_BRACKET, 0x005B ) \ CODEPOINT( REVERSE_SOLIDUS, 0x005C ) \ @@ -49,15 +36,10 @@ CODEPOINT( CIRCUMFLEX_ACCENT, 0x005E ) \ CODEPOINT( LOW_LINE, 0x005F ) \ CODEPOINT( LATIN_SMALL_LETTER_A, 0x0061 ) \ - CODEPOINT( LATIN_SMALL_LETTER_E, 0x0065 ) \ CODEPOINT( LATIN_SMALL_LETTER_F, 0x0066 ) \ - CODEPOINT( LATIN_SMALL_LETTER_U, 0x0075 ) \ CODEPOINT( LATIN_SMALL_LETTER_Z, 0x007A ) \ - CODEPOINT( LEFT_CURLY_BRACKET, 0x007B ) \ - CODEPOINT( RIGHT_CURLY_BRACKET, 0x007D ) \ - CODEPOINT( VERTICAL_LINE, 0x007A ) \ + CODEPOINT( VERTICAL_LINE, 0x007C ) \ CODEPOINT( TILDE, 0x007E ) \ - CODEPOINT( CONTROL, 0x0080 ) \ CODEPOINT( REPLACEMENT_CHARACTER, 0xFFFD ) #define CODEPOINT( name, value ) static UniChar const name = value; @@ -66,7 +48,18 @@ CODEPOINTS NS_INLINE BOOL isWhitespace(UTF32Char codePoint) { - return codePoint == CHARACTER_TABULATION || codePoint == LINE_FEED || codePoint == SPACE; + return (codePoint == CHARACTER_TABULATION || + codePoint == LINE_FEED || + codePoint == SPACE); +} + +NS_INLINE BOOL isCombinator(UTF32Char codePoint) +{ + return (codePoint == SPACE || + codePoint == PLUS_SIGN || + codePoint == COMMA || + codePoint == GREATER_THAN_SIGN || + codePoint == TILDE); } NS_INLINE BOOL isDigit(UTF32Char codePoint) @@ -120,46 +113,6 @@ NS_INLINE BOOL isValidEscapedCodePoint(UTF32Char codePoint) codePoint <= 0x10FFFF); } -NS_INLINE BOOL isNumberStart(UTF32Char first, UTF32Char second, UTF32Char third) -{ - if (first == PLUS_SIGN || first == HYPHEN_MINUS) { - if (isDigit(second)) { - return YES; - } else if (second == FULL_STOP || isDigit(third)) { - return YES; - } else { - return NO; - } - } else if (first == FULL_STOP) { - return isDigit(second); - } else if (isDigit(first)) { - return YES; - } - - return NO; -} - -NS_INLINE BOOL isIdentifierStart(UTF32Char first, UTF32Char second, UTF32Char third) -{ - if (first == HYPHEN_MINUS) { - return isNameStart(second) || isValidEscape(second, third); - } else if (isNameStart(first)) { - return YES; - } else if (first == REVERSE_SOLIDUS) { - return isValidEscape(second, third); - } - - return NO; -} - -NS_INLINE BOOL isNonPrintable(UTF32Char codePoint) -{ - return ((codePoint >= EOF_CHARACTER && codePoint <= BACK_SPACE) || - codePoint == LINE_TABULATION || - (codePoint >= SHIFT_OUT && codePoint <= INFORMATION_SEPARATOR_ONE) || - codePoint == DELETE); -} - NS_INLINE void AppendCodePoint(CFMutableStringRef string, UTF32Char codePoint) { UniChar pair[2]; diff --git a/HTMLKit/CSSInputStream.m b/HTMLKit/CSSInputStream.m index 78dc724..e9825a7 100644 --- a/HTMLKit/CSSInputStream.m +++ b/HTMLKit/CSSInputStream.m @@ -7,7 +7,7 @@ // #import "CSSInputStream.h" -#import "CSSTokenizerCodePoints.h" +#import "CSSCodePoints.h" @interface HTMLInputStreamReader () - (void)emitParseError:(NSString *)reason; diff --git a/HTMLKit/CSSNthExpressionParser.h b/HTMLKit/CSSNthExpressionParser.h index 2fd75af..e484bab 100644 --- a/HTMLKit/CSSNthExpressionParser.h +++ b/HTMLKit/CSSNthExpressionParser.h @@ -7,6 +7,7 @@ // #import +#import "CSSSelectors.h" @interface CSSNthExpressionParser : NSObject diff --git a/HTMLKit/CSSNthExpressionParser.m b/HTMLKit/CSSNthExpressionParser.m index a36915d..aee5e3f 100644 --- a/HTMLKit/CSSNthExpressionParser.m +++ b/HTMLKit/CSSNthExpressionParser.m @@ -7,7 +7,7 @@ // #import "CSSNthExpressionParser.h" -#import "CSSTokenizerCodePoints.h" +#import "CSSCodePoints.h" #import "NSString+HTMLKit.h" #import "NSCharacterSet+HTMLKit.h" From ab7de014cf5c50d316469516e65ce2897386bfa4 Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 21 Oct 2015 22:30:22 +0200 Subject: [PATCH 059/103] Add implementation for "required" and "optional" selectors https://html.spec.whatwg.org/multipage/scripting.html#selector-reqiored https://html.spec.whatwg.org/multipage/scripting.html#selector-optional --- HTMLKit/CSSStructuralPseudoSelectors.h | 2 ++ HTMLKit/CSSStructuralPseudoSelectors.m | 27 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/HTMLKit/CSSStructuralPseudoSelectors.h b/HTMLKit/CSSStructuralPseudoSelectors.h index 013bd9a..d004235 100644 --- a/HTMLKit/CSSStructuralPseudoSelectors.h +++ b/HTMLKit/CSSStructuralPseudoSelectors.h @@ -30,6 +30,8 @@ extern CSSSelector * textSelector(); extern CSSSelector * enabledSelector(); extern CSSSelector * disabledSelector(); extern CSSSelector * checkedSelector(); +extern CSSSelector * optionalSelector(); +extern CSSSelector * requiredSelector(); extern CSSSelector * ltSelector(); extern CSSSelector * gtSelector(); diff --git a/HTMLKit/CSSStructuralPseudoSelectors.m b/HTMLKit/CSSStructuralPseudoSelectors.m index 7d5b411..9e66f7d 100644 --- a/HTMLKit/CSSStructuralPseudoSelectors.m +++ b/HTMLKit/CSSStructuralPseudoSelectors.m @@ -241,6 +241,33 @@ CSSSelector * checkedElementSelector() return namedPseudoSelector(@"checked", allOf(@[candidate, hasAttribute])); } +CSSSelector * optionalSelector() +{ + // https://html.spec.whatwg.org/multipage/scripting.html#selector-optional + CSSSelector *candidate = anyOf(@[ + typeSelector(@"input"), + typeSelector(@"select"), + typeSelector(@"textarea") + ]); + CSSSelector *noAttribute = nay(hasAttributeSelector(@"required")); + + return namedPseudoSelector(@"optional", allOf(@[candidate, noAttribute])); +} + +CSSSelector * requiredSelector() +{ + // https://html.spec.whatwg.org/multipage/scripting.html#selector-required + // https://html.spec.whatwg.org/multipage/forms.html#concept-input-required + CSSSelector *candidate = anyOf(@[ + typeSelector(@"input"), + typeSelector(@"select"), + typeSelector(@"textarea") + ]); + CSSSelector *hasAttribute = hasAttributeSelector(@"required"); + + return namedPseudoSelector(@"required", allOf(@[candidate, hasAttribute])); +} + #pragma mark - Positional CSSSelector * ltSelector(NSUInteger index) From 2574736359432f5d97040e33b1050ca7e655e368 Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 21 Oct 2015 22:30:58 +0200 Subject: [PATCH 060/103] Use pseudo class and block selectors for parameterless pseudo class selectors --- HTMLKit/CSSSelectors.h | 7 +++- HTMLKit/CSSSelectors.m | 78 +++++++++++++++++++++++------------------- 2 files changed, 49 insertions(+), 36 deletions(-) diff --git a/HTMLKit/CSSSelectors.h b/HTMLKit/CSSSelectors.h index fa416cd..bf9c1af 100644 --- a/HTMLKit/CSSSelectors.h +++ b/HTMLKit/CSSSelectors.h @@ -7,6 +7,7 @@ // #import "CSSSelector.h" +#import "CSSStructuralPseudoSelectors.h" NS_ASSUME_NONNULL_BEGIN @@ -59,8 +60,12 @@ extern CSSSelector * has(CSSSelector *selector); extern CSSSelector * allOf(NSArray *selectors); extern CSSSelector * anyOf(NSArray *selectors); +#pragma mark - Pseudo + +extern CSSSelector * namedPseudoSelector(NSString *name, CSSSelector *selector); + #pragma mark - Block -extern CSSSelector * selectorWithBlock(BOOL (^ acceptBlock)(HTMLElement *)); +extern CSSSelector * namedBlockSelector(NSString *name, BOOL (^ acceptBlock)(HTMLElement *element)); NS_ASSUME_NONNULL_END diff --git a/HTMLKit/CSSSelectors.m b/HTMLKit/CSSSelectors.m index d88f0e7..6f0498c 100644 --- a/HTMLKit/CSSSelectors.m +++ b/HTMLKit/CSSSelectors.m @@ -12,41 +12,40 @@ #import "CSSPseudoClassSelector.h" #import "CSSPseudoFunctionSelector.h" #import "CSSNthExpressionSelector.h" -#import "CSSStructuralPseudoSelector.h" #import "CSSCombinatorSelector.h" #import "CSSCompoundSelector.h" #import "CSSSelectorBlock.h" #pragma mark - Type Selectors -CSSSelector *universalSelector() +CSSSelector * universalSelector() { return [CSSTypeSelector universalSelector]; } -CSSSelector *typeSelector(NSString *type) +CSSSelector * typeSelector(NSString *type) { return [[CSSTypeSelector alloc] initWithType:type]; } #pragma mark - Atribute Selectors -CSSSelector *idSelector(NSString *elementId) +CSSSelector * idSelector(NSString *elementId) { return [CSSAttributeSelector idSelector:elementId]; } -CSSSelector *classSelector(NSString *className) +CSSSelector * classSelector(NSString *className) { return [CSSAttributeSelector classSelector:className]; } -CSSSelector *hasAttributeSelector(NSString *attribute) +CSSSelector * hasAttributeSelector(NSString *attribute) { return [CSSAttributeSelector hasAttributeSelector:attribute]; } -CSSSelector *attributeSelector(CSSAttributeSelectorType type, +CSSSelector * attributeSelector(CSSAttributeSelectorType type, NSString *attribute, NSString *value) { @@ -55,115 +54,124 @@ CSSSelector *attributeSelector(CSSAttributeSelectorType type, #pragma mark - Nth-Expression Selectors -CSSSelector *nthChildSelector(CSSNthExpression expression) +CSSSelector * nthChildSelector(CSSNthExpression expression) { return [CSSNthExpressionSelector nthChildSelector:expression]; } -CSSSelector *nthLastChildSelector(CSSNthExpression expression) +CSSSelector * nthLastChildSelector(CSSNthExpression expression) { return [CSSNthExpressionSelector nthLastChildSelector:expression]; } -CSSSelector *nthOfTypeSelector(CSSNthExpression expression) +CSSSelector * nthOfTypeSelector(CSSNthExpression expression) { return [CSSNthExpressionSelector nthOfTypeSelector:expression]; } -CSSSelector *nthLastOfTypeSelector(CSSNthExpression expression) +CSSSelector * nthLastOfTypeSelector(CSSNthExpression expression) { return [CSSNthExpressionSelector nthLastOfTypeSelector:expression]; } +#pragma mark - Nth-Expression Shorthand + CSSSelector * oddSelector() { - return [CSSNthExpressionSelector nthChildSelector:CSSNthExpressionOdd]; + return namedPseudoSelector(@"odd", nthChildSelector(CSSNthExpressionOdd)); } CSSSelector * evenSlector() { - return [CSSNthExpressionSelector nthChildSelector:CSSNthExpressionEven]; + return namedPseudoSelector(@"even", nthChildSelector(CSSNthExpressionEven)); } -CSSSelector *firstChildSelector() +CSSSelector * firstChildSelector() { - return [CSSNthExpressionSelector nthChildSelector:CSSNthExpressionMake(0, 1)]; + return namedPseudoSelector(@"first-child", nthChildSelector(CSSNthExpressionMake(0, 1))); } -CSSSelector *lastChildSelector() +CSSSelector * lastChildSelector() { - return [CSSNthExpressionSelector nthLastChildSelector:CSSNthExpressionMake(0, 1)]; + return namedPseudoSelector(@"last-child", nthChildSelector(CSSNthExpressionMake(0, 1))); } -CSSSelector *firstOfTypeSelector() +CSSSelector * firstOfTypeSelector() { - return [CSSNthExpressionSelector nthOfTypeSelector:CSSNthExpressionMake(0, 1)]; + return namedPseudoSelector(@"first-of-type", nthChildSelector(CSSNthExpressionMake(0, 1))); } -CSSSelector *lastOfTypeSelector() +CSSSelector * lastOfTypeSelector() { - return [CSSNthExpressionSelector nthLastOfTypeSelector:CSSNthExpressionMake(0, 1)]; + return namedPseudoSelector(@"last-of-type", nthChildSelector(CSSNthExpressionMake(0, 1))); } -CSSSelector *onlyChildSelector() +CSSSelector * onlyChildSelector() { - return allOf(@[firstChildSelector(), lastChildSelector()]); + return namedPseudoSelector(@"only-child", allOf(@[firstChildSelector(), lastChildSelector()])); } -CSSSelector *onlyOfTypeSelector() +CSSSelector * onlyOfTypeSelector() { - return allOf(@[firstOfTypeSelector(), lastOfTypeSelector()]); + return namedPseudoSelector(@"only-of-type", allOf(@[firstOfTypeSelector(), lastOfTypeSelector()])); } #pragma mark - Combinators -CSSSelector *childOfElementSelector(CSSSelector *selector) +CSSSelector * childOfElementSelector(CSSSelector *selector) { return [CSSCombinatorSelector childOfElementCombinator:selector]; } -CSSSelector *descendantOfElementSelector(CSSSelector *selector) +CSSSelector * descendantOfElementSelector(CSSSelector *selector) { return [CSSCombinatorSelector descendantOfElementCombinator:selector]; } -CSSSelector *adjacentSiblingSelector(CSSSelector *selector) +CSSSelector * adjacentSiblingSelector(CSSSelector *selector) { return [CSSCombinatorSelector adjacentSiblingCombinator:selector]; } -CSSSelector *generalSiblingSelector(CSSSelector *selector) +CSSSelector * generalSiblingSelector(CSSSelector *selector) { return [CSSCombinatorSelector generalSiblingCombinator:selector]; } #pragma mark - Pseudo Functions -CSSSelector *nay(CSSSelector *selector) +CSSSelector * nay(CSSSelector *selector) { return [CSSPseudoFunctionSelector notSelector:selector]; } -CSSSelector *has(CSSSelector *selector) +CSSSelector * has(CSSSelector *selector) { return [CSSPseudoFunctionSelector hasSelector:selector]; } #pragma mark - Compound Selectors -CSSSelector *allOf( NSArray * selectors) +CSSSelector * allOf( NSArray * selectors) { return [CSSCompoundSelector andSelector:selectors]; } -CSSSelector *anyOf( NSArray * selectors) +CSSSelector * anyOf( NSArray * selectors) { return [CSSCompoundSelector andSelector:selectors]; } +#pragma mark - Pseudo + +CSSSelector * namedPseudoSelector(NSString *name, CSSSelector *selector) +{ + return [[CSSPseudoClassSelector alloc] initWithClassName:name selector:selector]; +} + #pragma mark - Block -CSSSelector * selectorWithBlock(BOOL (^ acceptBlock)(HTMLElement *)) +CSSSelector * namedBlockSelector(NSString *name, BOOL (^ acceptBlock)(HTMLElement *element)) { - return nil; + return [[CSSSelectorBlock alloc] initWithName:name block:acceptBlock]; } From bed2edf22a2e39321bcb7b5ec2c3073cc793d28c Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 21 Oct 2015 22:32:09 +0200 Subject: [PATCH 061/103] 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 From f05adfb56bf8c2681a8d96088960920d89614aad Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 21 Oct 2015 23:34:24 +0200 Subject: [PATCH 062/103] Add implementation for the Nth-Expressions selector http://www.w3.org/TR/css3-selectors/#structural-pseudos --- HTMLKit/CSSNthExpressionSelector.h | 1 + HTMLKit/CSSNthExpressionSelector.m | 61 +++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/HTMLKit/CSSNthExpressionSelector.h b/HTMLKit/CSSNthExpressionSelector.h index 77c3949..f8ddccf 100644 --- a/HTMLKit/CSSNthExpressionSelector.h +++ b/HTMLKit/CSSNthExpressionSelector.h @@ -12,6 +12,7 @@ NS_ASSUME_NONNULL_BEGIN @interface CSSNthExpressionSelector : CSSSelector +@property (nonatomic, strong, readonly) NSString *className; @property (nonatomic, assign, readonly) CSSNthExpression expression; + (instancetype)nthChildSelector:(CSSNthExpression)expression; diff --git a/HTMLKit/CSSNthExpressionSelector.m b/HTMLKit/CSSNthExpressionSelector.m index 8519ae9..e6a29c8 100644 --- a/HTMLKit/CSSNthExpressionSelector.m +++ b/HTMLKit/CSSNthExpressionSelector.m @@ -37,40 +37,89 @@ NSString * _Nonnull NSStringFromNthExpression(CSSNthExpression expression) #pragma mark - Implementation +NSInteger computeIndex(NSEnumerator *enumerator, HTMLElement *element) +{ + NSInteger index = 0; + for (HTMLNode *node in enumerator) { + if (node.nodeType != HTMLNodeElement) { + continue; + } + + if ([node.asElement.tagName isEqualToString:element.tagName]) { + index++; + } + + if (node == element) { + break; + } + } + + return index; +} + @interface CSSNthExpressionSelector () { + NSString *_className; CSSNthExpression _expression; + NSInteger (^ _computeIndex)(HTMLElement *); } @end @implementation CSSNthExpressionSelector @synthesize expression = _expression; +@synthesize className = _className; + (instancetype)nthChildSelector:(CSSNthExpression)expression { - return nil; + return [[self alloc] initWithClassName:@"nth-child" expression:expression block:^NSInteger(HTMLElement *element) { + return [element.parentElement indexOfChildNode:element] + 1; + }]; } + (instancetype)nthLastChildSelector:(CSSNthExpression)expression { - return nil; + return [[self alloc] initWithClassName:@"nth-last-child" expression:expression block:^NSInteger(HTMLElement *element) { + return element.parentElement.childNodesCount - [element.parentElement indexOfChildNode:element]; + }]; } + (instancetype)nthOfTypeSelector:(CSSNthExpression)expression { - return nil; + return [[self alloc] initWithClassName:@"nth-of-type" expression:expression block:^NSInteger(HTMLElement *element) { + return computeIndex(element.parentElement.childNodes.array.objectEnumerator, element); + }]; } + (instancetype)nthLastOfTypeSelector:(CSSNthExpression)expression { - return nil; + return [[self alloc] initWithClassName:@"nth-last-of-type" expression:expression block:^NSInteger(HTMLElement *element) { + return computeIndex(element.parentElement.childNodes.array.reverseObjectEnumerator, element); + }]; } -#pragma mark - +- (instancetype)initWithClassName:(NSString *)className + expression:(CSSNthExpression)expression + block:(NSInteger (^)(HTMLElement *element))block +{ + self = [super init]; + if (self) { + _className = [className copy]; + _expression = expression; + _computeIndex = [block copy]; + } + return self; +} - (BOOL)acceptElement:(HTMLElement *)element { - return NO; + NSInteger index = _computeIndex(element); + + if (_expression.an == 0) { + return index == _expression.b; + } else { + NSInteger diff = (index - _expression.b); + return (diff * _expression.an >= 0) && (diff % _expression.an == 0); + } } - (NSString *)debugDescription From 667693939f0331f32134c3bcc8e1cd102823c8ae Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 22 Oct 2015 19:12:42 +0200 Subject: [PATCH 063/103] Update project settings for Xcode7 --- HTMLKit.xcodeproj/project.pbxproj | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index bf20a73..3f93ffb 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -824,7 +824,7 @@ 625A14A319C7829400AD0C32 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0610; + LastUpgradeCheck = 0700; ORGANIZATIONNAME = BrainCookie; TargetAttributes = { 625A14C219C7829400AD0C32 = { @@ -1083,6 +1083,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; @@ -1146,6 +1147,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch"; INFOPLIST_FILE = "HTMLKit/HTMLKit-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = HTMLKit; WRAPPER_EXTENSION = framework; }; @@ -1161,6 +1163,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch"; INFOPLIST_FILE = "HTMLKit/HTMLKit-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = HTMLKit; WRAPPER_EXTENSION = framework; }; @@ -1182,6 +1185,7 @@ "$(inherited)", ); INFOPLIST_FILE = "HTMLKitTests/HTMLKitTests-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUNDLE_LOADER)"; WRAPPER_EXTENSION = xctest; @@ -1200,6 +1204,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch"; INFOPLIST_FILE = "HTMLKitTests/HTMLKitTests-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUNDLE_LOADER)"; WRAPPER_EXTENSION = xctest; @@ -1255,6 +1260,7 @@ ); INFOPLIST_FILE = "HTMLKitTests/HTMLKitTests-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 7.1; + PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; TEST_HOST = "$(BUNDLE_LOADER)"; @@ -1274,6 +1280,7 @@ GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch"; INFOPLIST_FILE = "HTMLKitTests/HTMLKitTests-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 7.1; + PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; TEST_HOST = "$(BUNDLE_LOADER)"; From 6af01a1214777f4a49b89f899141dd3e905e7b9d Mon Sep 17 00:00:00 2001 From: iska Date: Thu, 22 Oct 2015 19:20:22 +0200 Subject: [PATCH 064/103] Add -ObjC to iOS testing target to load category methods --- HTMLKit.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 3f93ffb..331e6d4 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -1260,6 +1260,7 @@ ); INFOPLIST_FILE = "HTMLKitTests/HTMLKitTests-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 7.1; + OTHER_LDFLAGS = " -ObjC"; PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1280,6 +1281,7 @@ GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch"; INFOPLIST_FILE = "HTMLKitTests/HTMLKitTests-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 7.1; + OTHER_LDFLAGS = " -ObjC"; PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; From 95ffccf67b29881bc860c82c367338cc2f3ab3cd Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 23 Oct 2015 22:49:25 +0200 Subject: [PATCH 065/103] Add HTML Node methods for selecting elements with given CSS Selectors --- HTMLKit/HTMLNode.h | 4 ++++ HTMLKit/HTMLNode.m | 31 +++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/HTMLKit/HTMLNode.h b/HTMLKit/HTMLNode.h index eb07dbc..9d753a5 100644 --- a/HTMLKit/HTMLNode.h +++ b/HTMLKit/HTMLNode.h @@ -38,6 +38,7 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition) @class HTMLDocument; @class HTMLElement; +@class CSSSelector; @interface HTMLNode : NSObject @@ -121,6 +122,9 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition) - (HTMLNodeIterator *)nodeIteratorWithShowOptions:(HTMLNodeFilterShowOptions)showOptions filterBlock:(HTMLNodeFilterValue (^)(HTMLNode *node))filter; +- (HTMLElement *)firstElementMatchingSelector:(CSSSelector *)selector; +- (NSArray *)elementsMatchingSelector:(CSSSelector *)selector; + - (NSString *)treeDescription; @end diff --git a/HTMLKit/HTMLNode.m b/HTMLKit/HTMLNode.m index fdff072..bcfcfaa 100644 --- a/HTMLKit/HTMLNode.m +++ b/HTMLKit/HTMLNode.m @@ -13,6 +13,7 @@ #import "HTMLText.h" #import "HTMLComment.h" #import "HTMLKitDOMExceptions.h" +#import "CSSSelector.h" @interface HTMLDocument (Private) - (void)runRemovingStepsForNode:(HTMLNode *)oldNode @@ -386,6 +387,29 @@ return [HTMLNodeIterator iteratorWithNode:self showOptions:showOptions filter:filter]; } +#pragma mark - Selectors + +- (HTMLElement *)firstElementMatchingSelector:(CSSSelector *)selector +{ + for (HTMLElement *element in [self nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:nil]) { + if ([selector acceptElement:element]) { + return element; + } + } + return nil; +} + +- (NSArray *)elementsMatchingSelector:(CSSSelector *)selector +{ + NSMutableArray *result = [NSMutableArray array]; + for (HTMLElement *element in [self nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:nil]) { + if ([selector acceptElement:element]) { + [result addObject:element]; + } + } + return result; +} + #ifndef HTMLKIT_NO_DOM_CHECKS #pragma mark - Validity Checks @@ -610,12 +634,7 @@ NS_INLINE void CheckInvalidCombination(HTMLNode *parent, HTMLNode *node, NSStrin - (NSString *)description { - return [NSString stringWithFormat:@"<%@: %p %@>", self.class, self, self.name]; -} - -- (NSString *)debugDescription -{ - return self.treeDescription; + return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.name]; } - (id)debugQuickLookObject From b5bb0a48b698cdc9967d80d5566f33732c6fc9d4 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 23 Oct 2015 22:50:20 +0200 Subject: [PATCH 066/103] Add tests for the Nth-Expression selectors --- HTMLKit.xcodeproj/project.pbxproj | 6 + HTMLKitTests/CSSNThExpressionSelectorTests.m | 352 +++++++++++++++++++ 2 files changed, 358 insertions(+) create mode 100644 HTMLKitTests/CSSNThExpressionSelectorTests.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 331e6d4..0770a06 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -179,6 +179,8 @@ 62F501651BC9576B0069F47B /* CSSNthExpressionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */; settings = {ASSET_TAGS = (); }; }; 62F501661BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */; settings = {ASSET_TAGS = (); }; }; 62F501671BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */; settings = {ASSET_TAGS = (); }; }; + 62F658701BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */; settings = {ASSET_TAGS = (); }; }; + 62F658711BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */; settings = {ASSET_TAGS = (); }; }; 62F873EB19E088C90062683C /* HTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F873E919E088C90062683C /* HTMLParser.h */; }; 62F873EC19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; }; 62F873ED19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; }; @@ -350,6 +352,7 @@ 62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTokenizerEntities.m; sourceTree = ""; }; 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSNthExpressionParser.h; sourceTree = ""; }; 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionParser.m; sourceTree = ""; }; + 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNThExpressionSelectorTests.m; sourceTree = ""; }; 62F873E919E088C90062683C /* HTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLParser.h; sourceTree = ""; }; 62F873EA19E088C90062683C /* HTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLParser.m; sourceTree = ""; }; 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectors.m; sourceTree = ""; }; @@ -598,6 +601,7 @@ 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */, 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */, 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */, + 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */, ); name = Tests; path = HTMLKitTests; @@ -941,6 +945,7 @@ buildActionMask = 2147483647; files = ( 6239755B1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */, + 62F658711BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */, 623CAF9E1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */, 6247171D1B2240B800C11912 /* HTMLTreeWalkerTests.m in Sources */, 62EC7AE71AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */, @@ -1014,6 +1019,7 @@ buildActionMask = 2147483647; files = ( 6239755A1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */, + 62F658701BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */, 623CAF9D1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */, 6247171C1B2240B800C11912 /* HTMLTreeWalkerTests.m in Sources */, 62EC7AE61AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */, diff --git a/HTMLKitTests/CSSNThExpressionSelectorTests.m b/HTMLKitTests/CSSNThExpressionSelectorTests.m new file mode 100644 index 0000000..b107eeb --- /dev/null +++ b/HTMLKitTests/CSSNThExpressionSelectorTests.m @@ -0,0 +1,352 @@ +// +// CSSNThExpressionSelectorTests.m +// HTMLKit +// +// Created by Iska on 21/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import +#import "CSSSelectors.h" +#import "HTMLParser.h" +#import "HTMLDOM.h" + +@interface CSSNThExpressionSelectorTests : XCTestCase +{ + HTMLDocument *_childTree; + HTMLDocument *_typeTree; +} +@end + +@implementation CSSNThExpressionSelectorTests + +- (void)setUp +{ + [super setUp]; + + /* + |
+ | + | + | + | + | + |
11
12
13
14
+ |
+ |
+ | + | + |
21
+ |
+ |
+ | + | + | + | + | + | + | + |
31
32
33
34
35
36
+ |
+ */ + _childTree = [[[HTMLParser alloc] initWithString:@"
" + "" + "" + "" + "" + "
11
12
13
14
" + "
" + "" + "
21
" + "
" + "" + "" + "" + "" + "" + "" + "
31
32
33
34
35
36
"] document]; + + /* + |
+ | s11 + | s12 + | s13 + | b1 + |
+ |
+ | b2 + | s21 + | s22 + | s23 + |
+ |
+ | s31 + | b3 + | s32 + | b4 + | s33 + | b5 + | s34 + |
+ */ + _typeTree = [[[HTMLParser alloc] initWithString:@"
" + "s11" + "s12" + "s13" + "b1" + "
" + "
" + "b2" + "s21" + "s22" + "s23" + "
" + "
" + "s31" + "b3" + "s32" + "b4" + "s33" + "b5" + "s34" + "
"] document]; +} + +- (void)testOddSelector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), oddSelector()])]; + NSArray *expected = @[@"11", @"13", @"21", @"31", @"33", @"35"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testEvenSelector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), evenSlector()])]; + NSArray *expected = @[@"12", @"14", @"32", @"34", @"36"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testFirstChildSelector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), firstChildSelector()])]; + NSArray *expected = @[@"11", @"21", @"31"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testLastChildSelector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), lastChildSelector()])]; + NSArray *expected = @[@"14", @"21", @"36"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testFirstOfTypeSelector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), firstOfTypeSelector()])]; + NSArray *expected = @[@"s11", @"s21", @"s31"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testLastOfTypeSelector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), lastOfTypeSelector()])]; + NSArray *expected = @[@"s13", @"s23", @"s34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testOnlyChildSelector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), onlyChildSelector()])]; + NSArray *expected = @[@"21"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testOnlyOfTypeSelector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), onlyOfTypeSelector()])]; + NSArray *expected = @[]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), onlyOfTypeSelector()])]; + expected = @[]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"b"), onlyOfTypeSelector()])]; + expected = @[@"b1", @"b2"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +#pragma mark - Nth-Child Selector + +- (void)test_NthChild_B_Selector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(0, 1))])]; + NSArray *expected = @[@"11", @"21", @"31"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(0, 2))])]; + expected = @[@"12", @"32"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(0, 3))])]; + expected = @[@"13", @"33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthChild_An_Selector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(2, 0))])]; + NSArray *expected = @[@"12", @"14", @"32", @"34", @"36"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(3, 0))])]; + expected = @[@"13", @"33", @"36"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(4, 0))])]; + expected = @[@"14", @"34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthChild_An_B_Selector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(3, 1))])]; + NSArray *expected = @[@"11", @"14", @"21", @"31", @"34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(3, 2))])]; + expected = @[@"12", @"32", @"35"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +#pragma mark - Nth-Last-Child Selector + +- (void)test_NthLastChild_B_Selector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(0, 1))])]; + NSArray *expected = @[@"14", @"21", @"36"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(0, 2))])]; + expected = @[@"13", @"35"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(0, 3))])]; + expected = @[@"12", @"34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthLastChild_An_Selector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(2, 0))])]; + NSArray *expected = @[@"11", @"13", @"31", @"33", @"35"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(3, 0))])]; + expected = @[@"12", @"31", @"34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(4, 0))])]; + expected = @[@"11", @"33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthLastChild_An_B_Selector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(3, 1))])]; + NSArray *expected = @[@"11", @"14", @"21", @"33", @"36"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(3, 2))])]; + expected = @[@"13", @"32", @"35"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +#pragma mark - Nth-Of-Type Selector + +- (void)test_NthOfType_B_Selector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(0, 1))])]; + NSArray *expected = @[@"s11", @"s21", @"s31"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(0, 2))])]; + expected = @[@"s12", @"s22", @"s32"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(0, 3))])]; + expected = @[@"s13", @"s23", @"s33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthOfType_An_Selector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(2, 0))])]; + NSArray *expected = @[@"s12", @"s22", @"s32", @"s34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(3, 0))])]; + expected = @[@"s13", @"s23", @"s33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(4, 0))])]; + expected = @[@"s34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthOfType_An_B_Selector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(2, 1))])]; + NSArray *expected = @[@"s11", @"s13", @"s21", @"s23", @"s31", @"s33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(2, 2))])]; + expected = @[@"s12", @"s22", @"s32", @"s34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +#pragma mark - Nth-Last-Of-Type Selector + +- (void)test_NthLastOfType_B_Selector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(0, 1))])]; + NSArray *expected = @[@"s13", @"s23", @"s34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(0, 2))])]; + expected = @[@"s12", @"s22", @"s33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(0, 3))])]; + expected = @[@"s11", @"s21", @"s32"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthLastOfType_An_Selector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(2, 0))])]; + NSArray *expected = @[@"s12", @"s22", @"s31", @"s33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(3, 0))])]; + expected = @[@"s11", @"s21", @"s32"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(4, 0))])]; + expected = @[@"s31"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthLastOfType_An_B_Selector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(2, 1))])]; + NSArray *expected = @[@"s11", @"s13", @"s21", @"s23", @"s32", @"s34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(2, 2))])]; + expected = @[@"s12", @"s22", @"s31", @"s33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +@end From 0635744a2d3e1258ad738f9c3c3e43bb5d814322 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 23 Oct 2015 22:50:51 +0200 Subject: [PATCH 067/103] Add a CSS selector-base Node Filter implementation --- HTMLKit/HTMLNodeFilter.h | 15 ++++++++++++++ HTMLKit/HTMLNodeFilter.m | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/HTMLKit/HTMLNodeFilter.h b/HTMLKit/HTMLNodeFilter.h index a32a2ea..3046762 100644 --- a/HTMLKit/HTMLNodeFilter.h +++ b/HTMLKit/HTMLNodeFilter.h @@ -26,6 +26,9 @@ typedef NS_OPTIONS(unsigned long, HTMLNodeFilterShowOptions) HTMLNodeFilterShowDocumentFragment = 0x400 }; + +#pragma mark - Node Filter + @class HTMLNode; @protocol HTMLNodeFilter @@ -34,8 +37,20 @@ typedef NS_OPTIONS(unsigned long, HTMLNodeFilterShowOptions) @end +#pragma mark - Block Filter + @interface HTMLNodeFilterBlock : NSObject + (instancetype)filterWithBlock:(HTMLNodeFilterValue (^)(HTMLNode *node))block; @end + +#pragma mark - CSS Selector Filter + +@class CSSSelector; + +@interface HTMLSelectorNodeFilter : NSObject + ++ (instancetype)filterWithSelector:(CSSSelector *)selector; + +@end diff --git a/HTMLKit/HTMLNodeFilter.m b/HTMLKit/HTMLNodeFilter.m index 96e4843..a1e0d2b 100644 --- a/HTMLKit/HTMLNodeFilter.m +++ b/HTMLKit/HTMLNodeFilter.m @@ -7,6 +7,10 @@ // #import "HTMLNodeFilter.h" +#import "HTMLNode.h" +#import "CSSSelector.h" + +#pragma mark - Block Filter @interface HTMLNodeFilterBlock () { @@ -40,3 +44,42 @@ } @end + +#pragma mark - CSS Selector Filter + +@interface HTMLSelectorNodeFilter () +{ + CSSSelector *_selector; +} +@end + +@implementation HTMLSelectorNodeFilter + ++ (instancetype)filterWithSelector:(CSSSelector *)selector +{ + return [[self alloc] initWithSelector:selector]; +} + +- (instancetype)initWithSelector:(CSSSelector *)selector +{ + self = [super init]; + if (self) { + _selector = selector; + } + return self; +} + +- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node +{ + if (node.nodeType != HTMLNodeElement) { + return HTMLNodeFilterSkip; + } + + if ([_selector acceptElement:node.asElement]) { + return HTMLNodeFilterAccept; + } + + return HTMLNodeFilterSkip; +} + +@end From cc101b9f4e7087a6d53f24334107ea644d2f8a4a Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 23 Oct 2015 22:52:14 +0200 Subject: [PATCH 068/103] Fix type selectors in the main header's implementation --- HTMLKit/CSSSelectors.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HTMLKit/CSSSelectors.m b/HTMLKit/CSSSelectors.m index 6f0498c..6d3f8ee 100644 --- a/HTMLKit/CSSSelectors.m +++ b/HTMLKit/CSSSelectors.m @@ -93,17 +93,17 @@ CSSSelector * firstChildSelector() CSSSelector * lastChildSelector() { - return namedPseudoSelector(@"last-child", nthChildSelector(CSSNthExpressionMake(0, 1))); + return namedPseudoSelector(@"last-child", nthLastChildSelector(CSSNthExpressionMake(0, 1))); } CSSSelector * firstOfTypeSelector() { - return namedPseudoSelector(@"first-of-type", nthChildSelector(CSSNthExpressionMake(0, 1))); + return namedPseudoSelector(@"first-of-type", nthOfTypeSelector(CSSNthExpressionMake(0, 1))); } CSSSelector * lastOfTypeSelector() { - return namedPseudoSelector(@"last-of-type", nthChildSelector(CSSNthExpressionMake(0, 1))); + return namedPseudoSelector(@"last-of-type", nthLastOfTypeSelector(CSSNthExpressionMake(0, 1))); } CSSSelector * onlyChildSelector() From 2e441727bcd63b093495693a07896af7e99d89c5 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 23 Oct 2015 22:52:40 +0200 Subject: [PATCH 069/103] Fix equals method in the attribute selector for iOS target --- HTMLKit/CSSAttributeSelector.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index 79b5055..c959635 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -82,7 +82,7 @@ } case CSSAttributeSelectorNot: { - return ![element[_name] isEqualTo:_value]; + return ![element[_name] isEqualToString:_value]; } default: return NO; From 46beae1b2d8970f4480b4f1f98a047673db505d7 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 23 Oct 2015 22:53:06 +0200 Subject: [PATCH 070/103] Change attribute selector's debug description string --- HTMLKit/CSSAttributeSelector.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index c959635..ccd9c55 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -94,7 +94,7 @@ - (NSString *)debugDescription { if (self.type == CSSAttributeSelectorExists) { - return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.name]; + return [NSString stringWithFormat:@"[%@]", self.name]; } NSString *matcher = @{@(CSSAttributeSelectorExactMatch): @"=", From 4f47a750e0171be08fc24840aef6c2dae108f19a Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 23 Oct 2015 22:54:06 +0200 Subject: [PATCH 071/103] Use lowercase string in the Nth-Expression selector parser --- HTMLKit/CSSNthExpressionParser.m | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/HTMLKit/CSSNthExpressionParser.m b/HTMLKit/CSSNthExpressionParser.m index aee5e3f..392acb4 100644 --- a/HTMLKit/CSSNthExpressionParser.m +++ b/HTMLKit/CSSNthExpressionParser.m @@ -17,10 +17,8 @@ { NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet]; - NSString *string = [expression copy]; - - string = [string stringByTrimmingCharactersInSet:whitespace]; - string = string.lowercaseString; + NSString *string = [expression.lowercaseString copy]; + string = [[string stringByTrimmingCharactersInSet:whitespace] copy]; if ([string isEqualToStringIgnoringCase:@"odd"]) { return CSSNthExpressionOdd; From 2e10c23f5241065cd328ca899505b2a7c36a1f7b Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 23 Oct 2015 22:54:34 +0200 Subject: [PATCH 072/103] Add debug description method to HTML Element --- HTMLKit/HTMLElement.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/HTMLKit/HTMLElement.m b/HTMLKit/HTMLElement.m index 6083537..9ebc3ad 100644 --- a/HTMLKit/HTMLElement.m +++ b/HTMLKit/HTMLElement.m @@ -180,4 +180,9 @@ return description; } +- (NSString *)debugDescription +{ + return self.description; +} + @end From 55bb8effb28ee666dac9fb2a69f611c62fcad564 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 23 Oct 2015 23:48:29 +0200 Subject: [PATCH 073/103] Add tests for the CSS Combinator selectors --- HTMLKit.xcodeproj/project.pbxproj | 6 ++ HTMLKit/CSSCombinatorSelector.m | 2 +- HTMLKitTests/CSSCombinatorSelectorTests.m | 116 ++++++++++++++++++++++ 3 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 HTMLKitTests/CSSCombinatorSelectorTests.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 0770a06..7bd8161 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -16,6 +16,8 @@ 620EE9491BC46F2A0028ED34 /* CSSPseudoClassSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */; settings = {ASSET_TAGS = (); }; }; 620EE94A1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; settings = {ASSET_TAGS = (); }; }; 620EE94B1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; settings = {ASSET_TAGS = (); }; }; + 621FBE5D1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */; settings = {ASSET_TAGS = (); }; }; + 621FBE5E1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */; settings = {ASSET_TAGS = (); }; }; 623406E11ADB04F9004677A3 /* HTMLTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 623406DF1ADB04F9004677A3 /* HTMLTemplate.h */; }; 623406E21ADB04F9004677A3 /* HTMLTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E01ADB04F9004677A3 /* HTMLTemplate.m */; }; 623406E31ADB04F9004677A3 /* HTMLTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E01ADB04F9004677A3 /* HTMLTemplate.m */; }; @@ -232,6 +234,7 @@ 620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSCompoundSelector.m; sourceTree = ""; }; 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPseudoClassSelector.h; sourceTree = ""; }; 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSPseudoClassSelector.m; sourceTree = ""; }; + 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSCombinatorSelectorTests.m; sourceTree = ""; }; 6223211D1A969B9300BACED5 /* HTMLElementTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLElementTypes.h; sourceTree = ""; }; 623406DF1ADB04F9004677A3 /* HTMLTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLTemplate.h; sourceTree = ""; }; 623406E01ADB04F9004677A3 /* HTMLTemplate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTemplate.m; sourceTree = ""; }; @@ -602,6 +605,7 @@ 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */, 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */, 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */, + 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */, ); name = Tests; path = HTMLKitTests; @@ -959,6 +963,7 @@ 62D8345A19FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */, 6239755F1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m in Sources */, 624FC37B1AE591D80015DDF9 /* HTMLKitNodesTests.m in Sources */, + 621FBE5E1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */, 628AF6301BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1033,6 +1038,7 @@ 62D8345919FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */, 6239755E1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m in Sources */, 624FC37A1AE591D80015DDF9 /* HTMLKitNodesTests.m in Sources */, + 621FBE5D1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */, 628AF62F1BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/HTMLKit/CSSCombinatorSelector.m b/HTMLKit/CSSCombinatorSelector.m index d5263cc..c75e608 100644 --- a/HTMLKit/CSSCombinatorSelector.m +++ b/HTMLKit/CSSCombinatorSelector.m @@ -73,7 +73,7 @@ - (BOOL)acceptElement:(HTMLElement *)element { HTMLElement *parent = element.parentElement; - return parent != nil && [self.selector acceptElement:element]; + return parent != nil && [self.selector acceptElement:parent]; } - (NSString *)debugDescription diff --git a/HTMLKitTests/CSSCombinatorSelectorTests.m b/HTMLKitTests/CSSCombinatorSelectorTests.m new file mode 100644 index 0000000..4296068 --- /dev/null +++ b/HTMLKitTests/CSSCombinatorSelectorTests.m @@ -0,0 +1,116 @@ +// +// CSSCombinatorSelectorTests.m +// HTMLKit +// +// Created by Iska on 23/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import +#import "CSSSelectors.h" +#import "HTMLParser.h" +#import "HTMLDOM.h" + +@interface CSSCombinatorSelectorTests : XCTestCase +{ + HTMLDocument *_document; +} +@end + +@implementation CSSCombinatorSelectorTests + +- (void)setUp +{ + [super setUp]; + + /* + | + |

+ | A paragraphA span + | + | + | + | + | + | + | + | + |
+ | Span in table + |
+ |

+ |
+ |

+ |
+ |
+ |

+ |
+ | + */ + _document = [[[HTMLParser alloc] initWithString:@"" + "

" + "A paragraphA span" + "" + "" + "" + "" + "" + "" + "
" + "Span in table" + "
" + "

" + "
" + "

" + "
" + "
" + "

" + "
" + ""] document]; +} + +-(void)testChildOfElementCombinator +{ + NSArray *elements = [_document elementsMatchingSelector:childOfElementSelector(typeSelector(@"body"))]; + NSArray *expected = @[@"p1", @"inner-div1", @"inner-div2"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_document elementsMatchingSelector:childOfElementSelector(typeSelector(@"p"))]; + expected = @[@"span1", @"table"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +-(void)testDescendantOfElementCombinator +{ + NSArray *elements = [_document elementsMatchingSelector:descendantOfElementSelector(typeSelector(@"p"))]; + NSArray *expected = @[@"span1", @"table", @"tbody", @"tr1", @"td", @"span2", @"tr2", @"tr3"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_document elementsMatchingSelector:descendantOfElementSelector(typeSelector(@"table"))]; + expected = @[@"tbody", @"tr1", @"td", @"span2", @"tr2", @"tr3"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +-(void)testAdjacentSiblingCombinator +{ + NSArray *elements = [_document elementsMatchingSelector:adjacentSiblingSelector(typeSelector(@"tr"))]; + NSArray *expected = @[@"tr2", @"tr3"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_document elementsMatchingSelector:adjacentSiblingSelector(typeSelector(@"p"))]; + expected = @[@"inner-div1"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +-(void)testGeneralSiblingCombinator +{ + NSArray *elements = [_document elementsMatchingSelector:generalSiblingSelector(typeSelector(@"tr"))]; + NSArray *expected = @[@"tr2", @"tr3"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_document elementsMatchingSelector:generalSiblingSelector(typeSelector(@"p"))]; + expected = @[@"inner-div1", @"inner-div2"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +@end From 7896f1687e3d0afe4078492786d5e838342a0ebe Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 23 Oct 2015 23:51:30 +0200 Subject: [PATCH 074/103] Remove temp test case from type selector tests class --- HTMLKitTests/CSSTypeSelectorTests.m | 7 ------- 1 file changed, 7 deletions(-) diff --git a/HTMLKitTests/CSSTypeSelectorTests.m b/HTMLKitTests/CSSTypeSelectorTests.m index 5d0d8c0..58b26a8 100644 --- a/HTMLKitTests/CSSTypeSelectorTests.m +++ b/HTMLKitTests/CSSTypeSelectorTests.m @@ -17,13 +17,6 @@ @implementation CSSTypeSelectorTests -- (void)testX -{ - CSSSelectorParser *parser = [[CSSSelectorParser alloc] initWithString:@"div:root"]; - CSSSimpleSequence *sequence = [parser parse]; - NSLog(@"%@", sequence); -} - - (void)testUniversalSelector { CSSSelector *selector = universalSelector(); From 4ceb913b9f1fc1db5381044fca1645d210011e33 Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 26 Oct 2015 22:25:40 +0100 Subject: [PATCH 075/103] Add HTMLKit workspace and setup project headers --- HTMLKit.xcodeproj/project.pbxproj | 294 ++++++++++--------- HTMLKit.xcworkspace/contents.xcworkspacedata | 7 + HTMLKit/HTMLKit.h | 8 +- HTMLKit/HTMLKit.m | 13 - 4 files changed, 166 insertions(+), 156 deletions(-) create mode 100644 HTMLKit.xcworkspace/contents.xcworkspacedata delete mode 100644 HTMLKit/HTMLKit.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 7bd8161..c404383 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -7,60 +7,47 @@ objects = { /* Begin PBXBuildFile section */ - 62079BE91AF56F1E00D3B402 /* CSSSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62079BE71AF56F1E00D3B402 /* CSSSelector.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 = (); }; }; - 620C877E1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */; settings = {ASSET_TAGS = (); }; }; - 620C877F1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */; settings = {ASSET_TAGS = (); }; }; - 620EE9491BC46F2A0028ED34 /* CSSPseudoClassSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */; settings = {ASSET_TAGS = (); }; }; - 620EE94A1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; settings = {ASSET_TAGS = (); }; }; - 620EE94B1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; settings = {ASSET_TAGS = (); }; }; - 621FBE5D1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */; settings = {ASSET_TAGS = (); }; }; - 621FBE5E1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */; settings = {ASSET_TAGS = (); }; }; - 623406E11ADB04F9004677A3 /* HTMLTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 623406DF1ADB04F9004677A3 /* HTMLTemplate.h */; }; + 620C877C1BD44CBE00FB3EEE /* CSSCompoundSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */; }; + 620C877D1BD44CBE00FB3EEE /* CSSCompoundSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */; }; + 620C877E1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */; }; + 620C877F1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */; }; + 620EE94A1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; }; + 620EE94B1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; }; + 621FBE5A1BDAD68700BC9555 /* CSSSelectorParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE591BDAD68700BC9555 /* CSSSelectorParserTests.m */; }; + 621FBE5B1BDAD68700BC9555 /* CSSSelectorParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE591BDAD68700BC9555 /* CSSSelectorParserTests.m */; }; + 621FBE5D1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */; }; + 621FBE5E1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */; }; + 622BF5821BBF2FD700363583 /* CSSSelectorParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 622BF5801BBF2FD700363583 /* CSSSelectorParser.m */; }; + 622BF5831BBF2FD700363583 /* CSSSelectorParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 622BF5801BBF2FD700363583 /* CSSSelectorParser.m */; }; 623406E21ADB04F9004677A3 /* HTMLTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E01ADB04F9004677A3 /* HTMLTemplate.m */; }; 623406E31ADB04F9004677A3 /* HTMLTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E01ADB04F9004677A3 /* HTMLTemplate.m */; }; - 623406E61ADB05AD004677A3 /* HTMLDocumentFragment.h in Headers */ = {isa = PBXBuildFile; fileRef = 623406E41ADB05AD004677A3 /* HTMLDocumentFragment.h */; }; 623406E71ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E51ADB05AD004677A3 /* HTMLDocumentFragment.m */; }; 623406E81ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E51ADB05AD004677A3 /* HTMLDocumentFragment.m */; }; - 623424881AB467B200726190 /* HTMLOrderedDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 623424861AB467B200726190 /* HTMLOrderedDictionary.h */; }; 623424891AB467B200726190 /* HTMLOrderedDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 623424871AB467B200726190 /* HTMLOrderedDictionary.m */; }; 6234248A1AB467B200726190 /* HTMLOrderedDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 623424871AB467B200726190 /* HTMLOrderedDictionary.m */; }; - 6234584E1A9D2FA4009BD491 /* HTMLNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234584C1A9D2FA4009BD491 /* HTMLNode.h */; }; 6234584F1A9D2FA4009BD491 /* HTMLNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 6234584D1A9D2FA4009BD491 /* HTMLNode.m */; }; 623458501A9D2FA4009BD491 /* HTMLNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 6234584D1A9D2FA4009BD491 /* HTMLNode.m */; }; - 6234BEEE1AABBF1400DEB15F /* HTMLStackOfOpenElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234BEEC1AABBF1400DEB15F /* HTMLStackOfOpenElements.h */; }; 6234BEEF1AABBF1400DEB15F /* HTMLStackOfOpenElements.m in Sources */ = {isa = PBXBuildFile; fileRef = 6234BEED1AABBF1400DEB15F /* HTMLStackOfOpenElements.m */; }; 6234BEF01AABBF1400DEB15F /* HTMLStackOfOpenElements.m in Sources */ = {isa = PBXBuildFile; fileRef = 6234BEED1AABBF1400DEB15F /* HTMLStackOfOpenElements.m */; }; 6234CF571ABF892400B6077D /* libHTMLKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14DE19C7834000AD0C32 /* libHTMLKit.a */; }; - 6235CE9B1AA509430026937B /* NSString+HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6235CE991AA509430026937B /* NSString+HTMLKit.h */; }; 6235CE9C1AA509430026937B /* NSString+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 6235CE9A1AA509430026937B /* NSString+HTMLKit.m */; }; 6235CE9D1AA509430026937B /* NSString+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 6235CE9A1AA509430026937B /* NSString+HTMLKit.m */; }; - 6235CEA01AA5170A0026937B /* HTMLMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 6235CE9E1AA5170A0026937B /* HTMLMarker.h */; }; 6235CEA11AA5170A0026937B /* HTMLMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6235CE9F1AA5170A0026937B /* HTMLMarker.m */; }; 6235CEA21AA5170A0026937B /* HTMLMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6235CE9F1AA5170A0026937B /* HTMLMarker.m */; }; - 62362A3C1A9FA70400301989 /* HTMLText.h in Headers */ = {isa = PBXBuildFile; fileRef = 62362A3A1A9FA70400301989 /* HTMLText.h */; }; 62362A3D1A9FA70400301989 /* HTMLText.m in Sources */ = {isa = PBXBuildFile; fileRef = 62362A3B1A9FA70400301989 /* HTMLText.m */; }; 62362A3E1A9FA70400301989 /* HTMLText.m in Sources */ = {isa = PBXBuildFile; fileRef = 62362A3B1A9FA70400301989 /* HTMLText.m */; }; - 62363C3D1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 62363C3B1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.h */; }; 62363C3E1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m in Sources */ = {isa = PBXBuildFile; fileRef = 62363C3C1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m */; }; 62363C3F1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m in Sources */ = {isa = PBXBuildFile; fileRef = 62363C3C1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m */; }; 6236738E1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m in Sources */ = {isa = PBXBuildFile; fileRef = 6236738D1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m */; }; 6236738F1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m in Sources */ = {isa = PBXBuildFile; fileRef = 6236738D1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m */; }; - 6238039F1AB63A8C008A53D0 /* HTMLEOFToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 6238039D1AB63A8C008A53D0 /* HTMLEOFToken.h */; }; 623803A01AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 6238039E1AB63A8C008A53D0 /* HTMLEOFToken.m */; }; 623803A11AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 6238039E1AB63A8C008A53D0 /* HTMLEOFToken.m */; }; - 623857911A9E772B003A45D9 /* HTMLDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 6238578F1A9E772B003A45D9 /* HTMLDocument.h */; }; 623857921A9E772B003A45D9 /* HTMLDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 623857901A9E772B003A45D9 /* HTMLDocument.m */; }; 623857931A9E772B003A45D9 /* HTMLDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 623857901A9E772B003A45D9 /* HTMLDocument.m */; }; - 623857961A9E8606003A45D9 /* HTMLDocumentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 623857941A9E8606003A45D9 /* HTMLDocumentType.h */; }; 623857971A9E8606003A45D9 /* HTMLDocumentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 623857951A9E8606003A45D9 /* HTMLDocumentType.m */; }; 623857981A9E8606003A45D9 /* HTMLDocumentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 623857951A9E8606003A45D9 /* HTMLDocumentType.m */; }; - 6238579B1A9E8934003A45D9 /* HTMLComment.h in Headers */ = {isa = PBXBuildFile; fileRef = 623857991A9E8934003A45D9 /* HTMLComment.h */; }; 6238579C1A9E8934003A45D9 /* HTMLComment.m in Sources */ = {isa = PBXBuildFile; fileRef = 6238579A1A9E8934003A45D9 /* HTMLComment.m */; }; 6238579D1A9E8934003A45D9 /* HTMLComment.m in Sources */ = {isa = PBXBuildFile; fileRef = 6238579A1A9E8934003A45D9 /* HTMLComment.m */; }; - 6238C9851AB8D6330006512E /* HTMLKitDOMExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 6238C9831AB8D6330006512E /* HTMLKitDOMExceptions.h */; }; 6238C9861AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 6238C9841AB8D6330006512E /* HTMLKitDOMExceptions.m */; }; 6238C9871AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 6238C9841AB8D6330006512E /* HTMLKitDOMExceptions.m */; }; 623916C71AC7209E0066B4FE /* HTMLKitNodeIteratorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 623916C61AC7209E0066B4FE /* HTMLKitNodeIteratorTests.m */; }; @@ -71,48 +58,36 @@ 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 */; }; - 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 */; }; - 624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */; }; 624493AD19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; }; 624493AE19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; }; - 624717181B22333200C11912 /* HTMLNodeTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = 624717161B22333200C11912 /* HTMLNodeTraversal.h */; }; 624717191B22333200C11912 /* HTMLNodeTraversal.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717171B22333200C11912 /* HTMLNodeTraversal.m */; }; 6247171A1B22333200C11912 /* HTMLNodeTraversal.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717171B22333200C11912 /* HTMLNodeTraversal.m */; }; 6247171C1B2240B800C11912 /* HTMLTreeWalkerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6247171B1B2240B800C11912 /* HTMLTreeWalkerTests.m */; }; 6247171D1B2240B800C11912 /* HTMLTreeWalkerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6247171B1B2240B800C11912 /* HTMLTreeWalkerTests.m */; }; 624717B81B21FE5400B38302 /* HTMLNodeFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717B71B21FE5400B38302 /* HTMLNodeFilter.m */; }; 624717B91B21FE5400B38302 /* HTMLNodeFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717B71B21FE5400B38302 /* HTMLNodeFilter.m */; }; - 624717BC1B22009200B38302 /* HTMLTreeWalker.h in Headers */ = {isa = PBXBuildFile; fileRef = 624717BA1B22009200B38302 /* HTMLTreeWalker.h */; }; 624717BD1B22009200B38302 /* HTMLTreeWalker.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717BB1B22009200B38302 /* HTMLTreeWalker.m */; }; 624717BE1B22009200B38302 /* HTMLTreeWalker.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717BB1B22009200B38302 /* HTMLTreeWalker.m */; }; - 6247A9431B152F4F00CCF25C /* HTMLNodeIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 6247A9411B152F4F00CCF25C /* HTMLNodeIterator.h */; }; 6247A9441B152F4F00CCF25C /* HTMLNodeIterator.m in Sources */ = {isa = PBXBuildFile; fileRef = 6247A9421B152F4F00CCF25C /* HTMLNodeIterator.m */; }; 6247A9451B152F4F00CCF25C /* HTMLNodeIterator.m in Sources */ = {isa = PBXBuildFile; fileRef = 6247A9421B152F4F00CCF25C /* HTMLNodeIterator.m */; }; - 6247A9471B152F8C00CCF25C /* HTMLNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6247A9461B152F8C00CCF25C /* HTMLNodeFilter.h */; }; 624AB3171B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; 624AB3181B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; }; 624AB31A1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; 624AB31B1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; }; - 624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */; }; 624AC90119FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; 624AC90219FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; }; 624AC90519FBFE9A00BD3C4A /* html5lib-tests in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90419FBFE8A00BD3C4A /* html5lib-tests */; }; 624AC90619FBFEA000BD3C4A /* html5lib-tests in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90419FBFE8A00BD3C4A /* html5lib-tests */; }; 624AC90E19FC702E00BD3C4A /* HTML Standard.html in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90D19FC702E00BD3C4A /* HTML Standard.html */; }; 624AC90F19FC702E00BD3C4A /* HTML Standard.html in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90D19FC702E00BD3C4A /* HTML Standard.html */; }; - 624B28B81B03DA820048D328 /* CSSTypeSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28B61B03DA820048D328 /* CSSTypeSelector.h */; }; 624B28B91B03DA820048D328 /* CSSTypeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28B71B03DA820048D328 /* CSSTypeSelector.m */; }; 624B28BA1B03DA820048D328 /* CSSTypeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28B71B03DA820048D328 /* CSSTypeSelector.m */; }; - 624B28BC1B03DAB70048D328 /* HTMLNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28BB1B03DAB70048D328 /* HTMLNodeFilter.h */; }; - 624B28BF1B0413200048D328 /* CSSAttributeSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28BD1B0413200048D328 /* CSSAttributeSelector.h */; }; 624B28C01B0413200048D328 /* CSSAttributeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */; }; 624B28C11B0413200048D328 /* CSSAttributeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */; }; - 624B28C41B04190D0048D328 /* NSCharacterSet+HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */; }; 624B28C51B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */; }; 624B28C61B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */; }; - 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 */; }; 624B9FB21AE0313300646C4C /* HTMLKitStringCategoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B9FB11AE0313300646C4C /* HTMLKitStringCategoryTests.m */; }; @@ -123,7 +98,6 @@ 624FC37B1AE591D80015DDF9 /* HTMLKitNodesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624FC3791AE591D80015DDF9 /* HTMLKitNodesTests.m */; }; 625A14B019C7829400AD0C32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14AF19C7829400AD0C32 /* Cocoa.framework */; }; 625A14BA19C7829400AD0C32 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 625A14B819C7829400AD0C32 /* InfoPlist.strings */; }; - 625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A14BD19C7829400AD0C32 /* HTMLKit.m */; }; 625A14C519C7829400AD0C32 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14C419C7829400AD0C32 /* XCTest.framework */; }; 625A14C619C7829400AD0C32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14AF19C7829400AD0C32 /* Cocoa.framework */; }; 625A14C919C7829400AD0C32 /* HTMLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14AC19C7829400AD0C32 /* HTMLKit.framework */; }; @@ -131,71 +105,101 @@ 625A14E019C7834100AD0C32 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14DF19C7834100AD0C32 /* Foundation.framework */; }; 625A14ED19C7834100AD0C32 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14C419C7829400AD0C32 /* XCTest.framework */; }; 625A14EE19C7834100AD0C32 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14DF19C7834100AD0C32 /* Foundation.framework */; }; - 625A150219C783DE00AD0C32 /* HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A14BD19C7829400AD0C32 /* HTMLKit.m */; }; 625A150319C783E200AD0C32 /* HTMLKit.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 625A14BC19C7829400AD0C32 /* HTMLKit.h */; }; - 625A150419C783EB00AD0C32 /* HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 625A14BC19C7829400AD0C32 /* HTMLKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 625A150819C78ABA00AD0C32 /* HTMLInputStreamReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 625A150619C78ABA00AD0C32 /* HTMLInputStreamReader.h */; }; 625A150919C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */; }; 625A150A19C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */; }; - 6279F87419E1808D00F12EE5 /* HTMLElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 6279F87219E1808D00F12EE5 /* HTMLElement.h */; }; 6279F87519E1808D00F12EE5 /* HTMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6279F87319E1808D00F12EE5 /* HTMLElement.m */; }; 6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6279F87319E1808D00F12EE5 /* HTMLElement.m */; }; - 628AF62F1BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */; settings = {ASSET_TAGS = (); }; }; - 628AF6301BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */; settings = {ASSET_TAGS = (); }; }; - 628AF6331BC9A63D00496128 /* CSSNthExpressionSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 628AF6311BC9A63D00496128 /* CSSNthExpressionSelector.h */; settings = {ASSET_TAGS = (); }; }; - 628AF6341BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */; settings = {ASSET_TAGS = (); }; }; - 628AF6351BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */; settings = {ASSET_TAGS = (); }; }; - 628AF63E1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h in Headers */ = {isa = PBXBuildFile; fileRef = 628AF63C1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h */; settings = {ASSET_TAGS = (); }; }; - 628AF63F1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF63D1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m */; settings = {ASSET_TAGS = (); }; }; - 628AF6401BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF63D1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m */; settings = {ASSET_TAGS = (); }; }; - 62AE593519F97D880043F069 /* HTMLParseErrorToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593319F97D880043F069 /* HTMLParseErrorToken.h */; }; + 628AF62F1BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */; }; + 628AF6301BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */; }; + 628AF6341BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */; }; + 628AF6351BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */; }; + 628AF63F1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF63D1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m */; }; + 628AF6401BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF63D1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m */; }; + 629AA0EA1BDD9C2900D5CC98 /* HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 625A14BC19C7829400AD0C32 /* HTMLKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0EB1BDD9C2900D5CC98 /* HTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F873E919E088C90062683C /* HTMLParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0EC1BDD9C2900D5CC98 /* HTMLDOM.h in Headers */ = {isa = PBXBuildFile; fileRef = 62362A3F1A9FDE8A00301989 /* HTMLDOM.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0ED1BDD9C2900D5CC98 /* HTMLNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234584C1A9D2FA4009BD491 /* HTMLNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0EE1BDD9C2900D5CC98 /* HTMLDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 6238578F1A9E772B003A45D9 /* HTMLDocument.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0EF1BDD9C2900D5CC98 /* HTMLDocumentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 623857941A9E8606003A45D9 /* HTMLDocumentType.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0F01BDD9C2900D5CC98 /* HTMLDocumentFragment.h in Headers */ = {isa = PBXBuildFile; fileRef = 623406E41ADB05AD004677A3 /* HTMLDocumentFragment.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0F11BDD9C2900D5CC98 /* HTMLElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 6279F87219E1808D00F12EE5 /* HTMLElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0F21BDD9C2900D5CC98 /* HTMLComment.h in Headers */ = {isa = PBXBuildFile; fileRef = 623857991A9E8934003A45D9 /* HTMLComment.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0F31BDD9C2900D5CC98 /* HTMLText.h in Headers */ = {isa = PBXBuildFile; fileRef = 62362A3A1A9FA70400301989 /* HTMLText.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0F41BDD9C2A00D5CC98 /* HTMLTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 623406DF1ADB04F9004677A3 /* HTMLTemplate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0F51BDD9C2A00D5CC98 /* HTMLNodeIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 6247A9411B152F4F00CCF25C /* HTMLNodeIterator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0F61BDD9C2A00D5CC98 /* HTMLTreeWalker.h in Headers */ = {isa = PBXBuildFile; fileRef = 624717BA1B22009200B38302 /* HTMLTreeWalker.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0F71BDD9C2A00D5CC98 /* HTMLNodeTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = 624717161B22333200C11912 /* HTMLNodeTraversal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0F81BDD9C2A00D5CC98 /* HTMLNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6247A9461B152F8C00CCF25C /* HTMLNodeFilter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0F91BDD9C2A00D5CC98 /* HTMLKitDOMExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 6238C9831AB8D6330006512E /* HTMLKitDOMExceptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0FA1BDD9C2A00D5CC98 /* HTMLNamespaces.h in Headers */ = {isa = PBXBuildFile; fileRef = 628B7CE61A080E1000602C87 /* HTMLNamespaces.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0FB1BDD9C2A00D5CC98 /* HTMLQuirksMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 623719431AA12EE8002E03C8 /* HTMLQuirksMode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0FC1BDD9C2A00D5CC98 /* NSString+HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6235CE991AA509430026937B /* NSString+HTMLKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0FD1BDD9C2A00D5CC98 /* NSCharacterSet+HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0FE1BDD9C2A00D5CC98 /* HTMLOrderedDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 623424861AB467B200726190 /* HTMLOrderedDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA0FF1BDD9C2A00D5CC98 /* CSSSelectors.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AB3151B04EA4200F3830D /* CSSSelectors.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA1001BDD9C2A00D5CC98 /* CSSSelectorParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 622BF57F1BBF2FD700363583 /* CSSSelectorParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA1011BDD9C2A00D5CC98 /* CSSSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62079BE71AF56F1E00D3B402 /* CSSSelector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA1021BDD9C2B00D5CC98 /* CSSSelectorBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 62FA98061BD5A7E200A2AF86 /* CSSSelectorBlock.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA1031BDD9C2B00D5CC98 /* CSSTypeSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28B61B03DA820048D328 /* CSSTypeSelector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA1041BDD9C2B00D5CC98 /* CSSAttributeSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28BD1B0413200048D328 /* CSSAttributeSelector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA1051BDD9C2B00D5CC98 /* CSSPseudoClassSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA1061BDD9C2B00D5CC98 /* CSSStructuralPseudoSelectors.h in Headers */ = {isa = PBXBuildFile; fileRef = 628AF63C1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA1071BDD9C2B00D5CC98 /* CSSNthExpressionSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 628AF6311BC9A63D00496128 /* CSSNthExpressionSelector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA1081BDD9C2B00D5CC98 /* CSSPseudoFunctionSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA1091BDD9C2B00D5CC98 /* CSSCombinatorSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62FA04E11BCC360D009ABF98 /* CSSCombinatorSelector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA10A1BDD9C2B00D5CC98 /* CSSCompoundSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 620C87791BD44CBE00FB3EEE /* CSSCompoundSelector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629AA10B1BDD9C5200D5CC98 /* HTMLTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493A419CCC54100BCDDF4 /* HTMLTokenizer.h */; }; + 629AA10C1BDD9C5200D5CC98 /* HTMLTokenizerStates.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493A919CCE84A00BCDDF4 /* HTMLTokenizerStates.h */; }; + 629AA10D1BDD9C5300D5CC98 /* HTMLTokenizerCharacters.h in Headers */ = {isa = PBXBuildFile; fileRef = 62E7CAAE19CDFFB500465A83 /* HTMLTokenizerCharacters.h */; }; + 629AA10E1BDD9C5300D5CC98 /* HTMLTokenizerEntities.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F31FDB19E9DCCF007F0657 /* HTMLTokenizerEntities.h */; }; + 629AA10F1BDD9C5300D5CC98 /* HTMLTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */; }; + 629AA1101BDD9C5300D5CC98 /* HTMLToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */; }; + 629AA1111BDD9C5300D5CC98 /* HTMLCharacterToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE594719F9948A0043F069 /* HTMLCharacterToken.h */; }; + 629AA1121BDD9C5300D5CC98 /* HTMLCommentToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE594219F992F30043F069 /* HTMLCommentToken.h */; }; + 629AA1131BDD9C5300D5CC98 /* HTMLDOCTYPEToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593819F97E1C0043F069 /* HTMLDOCTYPEToken.h */; }; + 629AA1141BDD9C5400D5CC98 /* HTMLParseErrorToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593319F97D880043F069 /* HTMLParseErrorToken.h */; }; + 629AA1151BDD9C5400D5CC98 /* HTMLTagToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593D19F9907C0043F069 /* HTMLTagToken.h */; }; + 629AA1161BDD9C5400D5CC98 /* HTMLEOFToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 6238039D1AB63A8C008A53D0 /* HTMLEOFToken.h */; }; + 629AA1171BDD9C5400D5CC98 /* HTMLStackOfOpenElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234BEEC1AABBF1400DEB15F /* HTMLStackOfOpenElements.h */; }; + 629AA1181BDD9C5400D5CC98 /* HTMLListOfActiveFormattingElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 62363C3B1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.h */; }; + 629AA1191BDD9C5400D5CC98 /* HTMLElementTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6223211D1A969B9300BACED5 /* HTMLElementTypes.h */; }; + 629AA11A1BDD9C5400D5CC98 /* HTMLElementAdjustment.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234C3361AB3BF710046F527 /* HTMLElementAdjustment.h */; }; + 629AA11B1BDD9C5500D5CC98 /* HTMLParserInsertionModes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6279F87119E17DC700F12EE5 /* HTMLParserInsertionModes.h */; }; + 629AA11C1BDD9C5500D5CC98 /* HTMLMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 6235CE9E1AA5170A0026937B /* HTMLMarker.h */; }; + 629AA11D1BDD9C5500D5CC98 /* CSSCodePoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B37211B250BB50010BDDF /* CSSCodePoints.h */; }; + 629AA11E1BDD9C5500D5CC98 /* CSSInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B371C1B24E9BA0010BDDF /* CSSInputStream.h */; }; + 629AA11F1BDD9C5E00D5CC98 /* CSSNthExpressionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; 62AE593619F97D880043F069 /* HTMLParseErrorToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593419F97D880043F069 /* HTMLParseErrorToken.m */; }; 62AE593719F97D880043F069 /* HTMLParseErrorToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593419F97D880043F069 /* HTMLParseErrorToken.m */; }; - 62AE593A19F97E1C0043F069 /* HTMLDOCTYPEToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593819F97E1C0043F069 /* HTMLDOCTYPEToken.h */; }; 62AE593B19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593919F97E1C0043F069 /* HTMLDOCTYPEToken.m */; }; 62AE593C19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593919F97E1C0043F069 /* HTMLDOCTYPEToken.m */; }; - 62AE593F19F9907C0043F069 /* HTMLTagToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593D19F9907C0043F069 /* HTMLTagToken.h */; }; 62AE594019F9907C0043F069 /* HTMLTagToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593E19F9907C0043F069 /* HTMLTagToken.m */; }; 62AE594119F9907C0043F069 /* HTMLTagToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593E19F9907C0043F069 /* HTMLTagToken.m */; }; - 62AE594419F992F30043F069 /* HTMLCommentToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE594219F992F30043F069 /* HTMLCommentToken.h */; }; 62AE594519F992F30043F069 /* HTMLCommentToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE594319F992F30043F069 /* HTMLCommentToken.m */; }; 62AE594619F992F30043F069 /* HTMLCommentToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE594319F992F30043F069 /* HTMLCommentToken.m */; }; - 62AE594919F9948A0043F069 /* HTMLCharacterToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE594719F9948A0043F069 /* HTMLCharacterToken.h */; }; 62AE594A19F9948A0043F069 /* HTMLCharacterToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE594819F9948A0043F069 /* HTMLCharacterToken.m */; }; 62AE594B19F9948A0043F069 /* HTMLCharacterToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE594819F9948A0043F069 /* HTMLCharacterToken.m */; }; 62D8345919FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62D8345819FB1AC4009205A9 /* HTML5LibTokenizerTest.m */; }; 62D8345A19FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62D8345819FB1AC4009205A9 /* HTML5LibTokenizerTest.m */; }; - 62D89DB01AE7080300B6243D /* HTMLDOM.h in Headers */ = {isa = PBXBuildFile; fileRef = 62362A3F1A9FDE8A00301989 /* HTMLDOM.h */; }; - 62D89DB11AE7081600B6243D /* HTMLTokenizerStates.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493A919CCE84A00BCDDF4 /* HTMLTokenizerStates.h */; }; - 62D89DB21AE7081600B6243D /* HTMLTokenizerCharacters.h in Headers */ = {isa = PBXBuildFile; fileRef = 62E7CAAE19CDFFB500465A83 /* HTMLTokenizerCharacters.h */; }; - 62D89DB31AE7081600B6243D /* HTMLNamespaces.h in Headers */ = {isa = PBXBuildFile; fileRef = 628B7CE61A080E1000602C87 /* HTMLNamespaces.h */; }; - 62D89DB41AE7081600B6243D /* HTMLElementTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6223211D1A969B9300BACED5 /* HTMLElementTypes.h */; }; - 62D89DB51AE7081600B6243D /* HTMLElementAdjustment.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234C3361AB3BF710046F527 /* HTMLElementAdjustment.h */; }; - 62D89DB61AE7081600B6243D /* HTMLParserInsertionModes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6279F87119E17DC700F12EE5 /* HTMLParserInsertionModes.h */; }; - 62D89DB71AE7081600B6243D /* HTMLQuirksMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 623719431AA12EE8002E03C8 /* HTMLQuirksMode.h */; }; 62EC7AE61AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62EC7AE51AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m */; }; 62EC7AE71AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62EC7AE51AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m */; }; - 62F31FDD19E9DCCF007F0657 /* HTMLTokenizerEntities.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F31FDB19E9DCCF007F0657 /* HTMLTokenizerEntities.h */; }; 62F31FDE19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */; }; 62F31FDF19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */; }; - 62F501651BC9576B0069F47B /* CSSNthExpressionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */; settings = {ASSET_TAGS = (); }; }; - 62F501661BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */; settings = {ASSET_TAGS = (); }; }; - 62F501671BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */; settings = {ASSET_TAGS = (); }; }; - 62F658701BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */; settings = {ASSET_TAGS = (); }; }; - 62F658711BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */; settings = {ASSET_TAGS = (); }; }; - 62F873EB19E088C90062683C /* HTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F873E919E088C90062683C /* HTMLParser.h */; }; + 62F501661BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */; }; + 62F501671BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */; }; + 62F658701BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */; }; + 62F658711BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */; }; 62F873EC19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; }; 62F873ED19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; }; - 62FA04E31BCC360D009ABF98 /* CSSCombinatorSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62FA04E11BCC360D009ABF98 /* CSSCombinatorSelector.h */; settings = {ASSET_TAGS = (); }; }; - 62FA04E41BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */; settings = {ASSET_TAGS = (); }; }; - 62FA04E51BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */; settings = {ASSET_TAGS = (); }; }; - 62FA98041BD57B6200A2AF86 /* CSSSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */; settings = {ASSET_TAGS = (); }; }; - 62FA98051BD57B6200A2AF86 /* CSSSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */; settings = {ASSET_TAGS = (); }; }; - 62FA98081BD5A7E200A2AF86 /* CSSSelectorBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 62FA98061BD5A7E200A2AF86 /* CSSSelectorBlock.h */; settings = {ASSET_TAGS = (); }; }; - 62FA98091BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */; settings = {ASSET_TAGS = (); }; }; - 62FA980A1BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */; settings = {ASSET_TAGS = (); }; }; - 62FC60461BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; settings = {ASSET_TAGS = (); }; }; - 62FC60471BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; settings = {ASSET_TAGS = (); }; }; + 62FA04E41BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */; }; + 62FA04E51BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */; }; + 62FA98041BD57B6200A2AF86 /* CSSSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */; }; + 62FA98051BD57B6200A2AF86 /* CSSSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */; }; + 62FA98091BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */; }; + 62FA980A1BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */; }; + 62FC60461BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; }; + 62FC60471BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -234,8 +238,11 @@ 620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSCompoundSelector.m; sourceTree = ""; }; 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPseudoClassSelector.h; sourceTree = ""; }; 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSPseudoClassSelector.m; sourceTree = ""; }; + 621FBE591BDAD68700BC9555 /* CSSSelectorParserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectorParserTests.m; sourceTree = ""; }; 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSCombinatorSelectorTests.m; sourceTree = ""; }; 6223211D1A969B9300BACED5 /* HTMLElementTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLElementTypes.h; sourceTree = ""; }; + 622BF57F1BBF2FD700363583 /* CSSSelectorParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelectorParser.h; sourceTree = ""; }; + 622BF5801BBF2FD700363583 /* CSSSelectorParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectorParser.m; sourceTree = ""; }; 623406DF1ADB04F9004677A3 /* HTMLTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLTemplate.h; sourceTree = ""; }; 623406E01ADB04F9004677A3 /* HTMLTemplate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTemplate.m; sourceTree = ""; }; 623406E41ADB05AD004677A3 /* HTMLDocumentFragment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLDocumentFragment.h; sourceTree = ""; }; @@ -296,7 +303,6 @@ 624AC90D19FC702E00BD3C4A /* HTML Standard.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "HTML Standard.html"; sourceTree = ""; }; 624B28B61B03DA820048D328 /* CSSTypeSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSTypeSelector.h; sourceTree = ""; }; 624B28B71B03DA820048D328 /* CSSTypeSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTypeSelector.m; sourceTree = ""; }; - 624B28BB1B03DAB70048D328 /* HTMLNodeFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNodeFilter.h; sourceTree = ""; }; 624B28BD1B0413200048D328 /* CSSAttributeSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSAttributeSelector.h; sourceTree = ""; }; 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSAttributeSelector.m; sourceTree = ""; }; 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSCharacterSet+HTMLKit.h"; sourceTree = ""; }; @@ -316,7 +322,6 @@ 625A14B919C7829400AD0C32 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 625A14BB19C7829400AD0C32 /* HTMLKit-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "HTMLKit-Prefix.pch"; sourceTree = ""; }; 625A14BC19C7829400AD0C32 /* HTMLKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLKit.h; sourceTree = ""; }; - 625A14BD19C7829400AD0C32 /* HTMLKit.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HTMLKit.m; sourceTree = ""; }; 625A14C319C7829400AD0C32 /* HTMLKitFrameworkTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HTMLKitFrameworkTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 625A14C419C7829400AD0C32 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 625A14CC19C7829400AD0C32 /* HTMLKitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "HTMLKitTests-Info.plist"; sourceTree = ""; }; @@ -358,6 +363,8 @@ 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNThExpressionSelectorTests.m; sourceTree = ""; }; 62F873E919E088C90062683C /* HTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLParser.h; sourceTree = ""; }; 62F873EA19E088C90062683C /* HTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLParser.m; sourceTree = ""; }; + 62FA04E11BCC360D009ABF98 /* CSSCombinatorSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSCombinatorSelector.h; sourceTree = ""; }; + 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSCombinatorSelector.m; sourceTree = ""; }; 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectors.m; sourceTree = ""; }; 62FA98061BD5A7E200A2AF86 /* CSSSelectorBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelectorBlock.h; sourceTree = ""; }; 62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectorBlock.m; sourceTree = ""; }; @@ -412,6 +419,8 @@ 624B37211B250BB50010BDDF /* CSSCodePoints.h */, 624B371C1B24E9BA0010BDDF /* CSSInputStream.h */, 624B371D1B24E9BA0010BDDF /* CSSInputStream.m */, + 622BF57F1BBF2FD700363583 /* CSSSelectorParser.h */, + 622BF5801BBF2FD700363583 /* CSSSelectorParser.m */, 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */, 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */, 62079BE71AF56F1E00D3B402 /* CSSSelector.h */, @@ -569,7 +578,6 @@ isa = PBXGroup; children = ( 625A14BC19C7829400AD0C32 /* HTMLKit.h */, - 625A14BD19C7829400AD0C32 /* HTMLKit.m */, 62AE593219F97CCA0043F069 /* Tokenizing */, 628E16EC1ADAE71700B15A06 /* Parsing */, 623719441AA1472B002E03C8 /* DOM */, @@ -601,9 +609,10 @@ 624B9FB81AE072D500646C4C /* Categories */, 624E1A2D1B1D1C8A00E66AAC /* Structures */, 625A14CB19C7829400AD0C32 /* Supporting Files */, + 621FBE591BDAD68700BC9555 /* CSSSelectorParserTests.m */, + 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */, 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */, 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */, - 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */, 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */, 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */, ); @@ -697,58 +706,60 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 624717181B22333200C11912 /* HTMLNodeTraversal.h in Headers */, - 6235CE9B1AA509430026937B /* NSString+HTMLKit.h in Headers */, - 62D89DB11AE7081600B6243D /* HTMLTokenizerStates.h in Headers */, - 62079BE91AF56F1E00D3B402 /* CSSSelector.h in Headers */, - 62FA98081BD5A7E200A2AF86 /* CSSSelectorBlock.h in Headers */, - 62D89DB21AE7081600B6243D /* HTMLTokenizerCharacters.h in Headers */, - 62D89DB31AE7081600B6243D /* HTMLNamespaces.h in Headers */, - 624B28BC1B03DAB70048D328 /* HTMLNodeFilter.h in Headers */, - 624B28BF1B0413200048D328 /* CSSAttributeSelector.h in Headers */, - 62D89DB41AE7081600B6243D /* HTMLElementTypes.h in Headers */, - 628AF6331BC9A63D00496128 /* CSSNthExpressionSelector.h in Headers */, - 62D89DB51AE7081600B6243D /* HTMLElementAdjustment.h in Headers */, - 62D89DB61AE7081600B6243D /* HTMLParserInsertionModes.h in Headers */, - 62D89DB71AE7081600B6243D /* HTMLQuirksMode.h in Headers */, - 62D89DB01AE7080300B6243D /* HTMLDOM.h in Headers */, - 62F873EB19E088C90062683C /* HTMLParser.h in Headers */, - 628AF63E1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h in Headers */, - 624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */, - 62AE594419F992F30043F069 /* HTMLCommentToken.h in Headers */, - 624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */, - 624B371E1B24E9BA0010BDDF /* CSSInputStream.h in Headers */, - 6235CEA01AA5170A0026937B /* HTMLMarker.h in Headers */, - 62F31FDD19E9DCCF007F0657 /* HTMLTokenizerEntities.h in Headers */, - 623406E11ADB04F9004677A3 /* HTMLTemplate.h in Headers */, - 624B28B81B03DA820048D328 /* CSSTypeSelector.h in Headers */, - 6234BEEE1AABBF1400DEB15F /* HTMLStackOfOpenElements.h in Headers */, - 620C877B1BD44CBE00FB3EEE /* CSSCompoundSelector.h in Headers */, - 6238C9851AB8D6330006512E /* HTMLKitDOMExceptions.h in Headers */, - 6238039F1AB63A8C008A53D0 /* HTMLEOFToken.h in Headers */, - 6279F87419E1808D00F12EE5 /* HTMLElement.h in Headers */, - 62AE593F19F9907C0043F069 /* HTMLTagToken.h in Headers */, - 623857911A9E772B003A45D9 /* HTMLDocument.h in Headers */, - 624B28C41B04190D0048D328 /* NSCharacterSet+HTMLKit.h in Headers */, - 624493A619CCC54100BCDDF4 /* HTMLTokenizer.h in Headers */, - 62AE593A19F97E1C0043F069 /* HTMLDOCTYPEToken.h in Headers */, - 620EE9491BC46F2A0028ED34 /* CSSPseudoClassSelector.h in Headers */, - 6247A9471B152F8C00CCF25C /* HTMLNodeFilter.h in Headers */, - 623424881AB467B200726190 /* HTMLOrderedDictionary.h in Headers */, - 6247A9431B152F4F00CCF25C /* HTMLNodeIterator.h in Headers */, - 625A150419C783EB00AD0C32 /* HTMLKit.h in Headers */, - 625A150819C78ABA00AD0C32 /* HTMLInputStreamReader.h in Headers */, - 62FA04E31BCC360D009ABF98 /* CSSCombinatorSelector.h in Headers */, - 6238579B1A9E8934003A45D9 /* HTMLComment.h in Headers */, - 62AE593519F97D880043F069 /* HTMLParseErrorToken.h in Headers */, - 62AE594919F9948A0043F069 /* HTMLCharacterToken.h in Headers */, - 623857961A9E8606003A45D9 /* HTMLDocumentType.h in Headers */, - 623406E61ADB05AD004677A3 /* HTMLDocumentFragment.h in Headers */, - 62363C3D1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.h in Headers */, - 624717BC1B22009200B38302 /* HTMLTreeWalker.h in Headers */, - 62362A3C1A9FA70400301989 /* HTMLText.h in Headers */, - 6234584E1A9D2FA4009BD491 /* HTMLNode.h in Headers */, - 62F501651BC9576B0069F47B /* CSSNthExpressionParser.h in Headers */, + 629AA0EA1BDD9C2900D5CC98 /* HTMLKit.h in Headers */, + 629AA0EB1BDD9C2900D5CC98 /* HTMLParser.h in Headers */, + 629AA0EC1BDD9C2900D5CC98 /* HTMLDOM.h in Headers */, + 629AA0ED1BDD9C2900D5CC98 /* HTMLNode.h in Headers */, + 629AA0EE1BDD9C2900D5CC98 /* HTMLDocument.h in Headers */, + 629AA0EF1BDD9C2900D5CC98 /* HTMLDocumentType.h in Headers */, + 629AA0F01BDD9C2900D5CC98 /* HTMLDocumentFragment.h in Headers */, + 629AA0F11BDD9C2900D5CC98 /* HTMLElement.h in Headers */, + 629AA0F21BDD9C2900D5CC98 /* HTMLComment.h in Headers */, + 629AA0F31BDD9C2900D5CC98 /* HTMLText.h in Headers */, + 629AA0F41BDD9C2A00D5CC98 /* HTMLTemplate.h in Headers */, + 629AA0F51BDD9C2A00D5CC98 /* HTMLNodeIterator.h in Headers */, + 629AA0F61BDD9C2A00D5CC98 /* HTMLTreeWalker.h in Headers */, + 629AA0F71BDD9C2A00D5CC98 /* HTMLNodeTraversal.h in Headers */, + 629AA0F81BDD9C2A00D5CC98 /* HTMLNodeFilter.h in Headers */, + 629AA0F91BDD9C2A00D5CC98 /* HTMLKitDOMExceptions.h in Headers */, + 629AA0FA1BDD9C2A00D5CC98 /* HTMLNamespaces.h in Headers */, + 629AA0FB1BDD9C2A00D5CC98 /* HTMLQuirksMode.h in Headers */, + 629AA0FC1BDD9C2A00D5CC98 /* NSString+HTMLKit.h in Headers */, + 629AA0FD1BDD9C2A00D5CC98 /* NSCharacterSet+HTMLKit.h in Headers */, + 629AA0FE1BDD9C2A00D5CC98 /* HTMLOrderedDictionary.h in Headers */, + 629AA0FF1BDD9C2A00D5CC98 /* CSSSelectors.h in Headers */, + 629AA1001BDD9C2A00D5CC98 /* CSSSelectorParser.h in Headers */, + 629AA11F1BDD9C5E00D5CC98 /* CSSNthExpressionParser.h in Headers */, + 629AA1011BDD9C2A00D5CC98 /* CSSSelector.h in Headers */, + 629AA1021BDD9C2B00D5CC98 /* CSSSelectorBlock.h in Headers */, + 629AA1031BDD9C2B00D5CC98 /* CSSTypeSelector.h in Headers */, + 629AA1041BDD9C2B00D5CC98 /* CSSAttributeSelector.h in Headers */, + 629AA1051BDD9C2B00D5CC98 /* CSSPseudoClassSelector.h in Headers */, + 629AA1061BDD9C2B00D5CC98 /* CSSStructuralPseudoSelectors.h in Headers */, + 629AA1071BDD9C2B00D5CC98 /* CSSNthExpressionSelector.h in Headers */, + 629AA1081BDD9C2B00D5CC98 /* CSSPseudoFunctionSelector.h in Headers */, + 629AA1091BDD9C2B00D5CC98 /* CSSCombinatorSelector.h in Headers */, + 629AA10A1BDD9C2B00D5CC98 /* CSSCompoundSelector.h in Headers */, + 629AA10B1BDD9C5200D5CC98 /* HTMLTokenizer.h in Headers */, + 629AA10C1BDD9C5200D5CC98 /* HTMLTokenizerStates.h in Headers */, + 629AA10D1BDD9C5300D5CC98 /* HTMLTokenizerCharacters.h in Headers */, + 629AA10E1BDD9C5300D5CC98 /* HTMLTokenizerEntities.h in Headers */, + 629AA10F1BDD9C5300D5CC98 /* HTMLTokens.h in Headers */, + 629AA1101BDD9C5300D5CC98 /* HTMLToken.h in Headers */, + 629AA1111BDD9C5300D5CC98 /* HTMLCharacterToken.h in Headers */, + 629AA1121BDD9C5300D5CC98 /* HTMLCommentToken.h in Headers */, + 629AA1131BDD9C5300D5CC98 /* HTMLDOCTYPEToken.h in Headers */, + 629AA1141BDD9C5400D5CC98 /* HTMLParseErrorToken.h in Headers */, + 629AA1151BDD9C5400D5CC98 /* HTMLTagToken.h in Headers */, + 629AA1161BDD9C5400D5CC98 /* HTMLEOFToken.h in Headers */, + 629AA1171BDD9C5400D5CC98 /* HTMLStackOfOpenElements.h in Headers */, + 629AA1181BDD9C5400D5CC98 /* HTMLListOfActiveFormattingElements.h in Headers */, + 629AA1191BDD9C5400D5CC98 /* HTMLElementTypes.h in Headers */, + 629AA11A1BDD9C5400D5CC98 /* HTMLElementAdjustment.h in Headers */, + 629AA11B1BDD9C5500D5CC98 /* HTMLParserInsertionModes.h in Headers */, + 629AA11C1BDD9C5500D5CC98 /* HTMLMarker.h in Headers */, + 629AA11D1BDD9C5500D5CC98 /* CSSCodePoints.h in Headers */, + 629AA11E1BDD9C5500D5CC98 /* CSSInputStream.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -900,12 +911,14 @@ files = ( 62F501671BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */, 62362A3E1A9FA70400301989 /* HTMLText.m in Sources */, + 622BF5831BBF2FD700363583 /* CSSSelectorParser.m in Sources */, 6235CE9D1AA509430026937B /* NSString+HTMLKit.m in Sources */, 6247A9451B152F4F00CCF25C /* HTMLNodeIterator.m in Sources */, 6238579D1A9E8934003A45D9 /* HTMLComment.m in Sources */, 6234BEF01AABBF1400DEB15F /* HTMLStackOfOpenElements.m in Sources */, 624493AE19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */, 6235CEA21AA5170A0026937B /* HTMLMarker.m in Sources */, + 62FA98051BD57B6200A2AF86 /* CSSSelectors.m in Sources */, 6234248A1AB467B200726190 /* HTMLOrderedDictionary.m in Sources */, 624717BE1B22009200B38302 /* HTMLTreeWalker.m in Sources */, 62AE594119F9907C0043F069 /* HTMLTagToken.m in Sources */, @@ -932,7 +945,6 @@ 620EE94B1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */, 624493A819CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, 624B28BA1B03DA820048D328 /* CSSTypeSelector.m in Sources */, - 625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */, 62FC60471BD0519B0042BBE7 /* CSSSelector.m in Sources */, 623857981A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, 620C877F1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */, @@ -963,6 +975,7 @@ 62D8345A19FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */, 6239755F1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m in Sources */, 624FC37B1AE591D80015DDF9 /* HTMLKitNodesTests.m in Sources */, + 621FBE5B1BDAD68700BC9555 /* CSSSelectorParserTests.m in Sources */, 621FBE5E1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */, 628AF6301BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */, ); @@ -973,6 +986,7 @@ buildActionMask = 2147483647; files = ( 62362A3D1A9FA70400301989 /* HTMLText.m in Sources */, + 622BF5821BBF2FD700363583 /* CSSSelectorParser.m in Sources */, 6235CE9C1AA509430026937B /* NSString+HTMLKit.m in Sources */, 6247A9441B152F4F00CCF25C /* HTMLNodeIterator.m in Sources */, 6238579C1A9E8934003A45D9 /* HTMLComment.m in Sources */, @@ -1006,7 +1020,6 @@ 620EE94A1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */, 624493A719CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, 624B28B91B03DA820048D328 /* CSSTypeSelector.m in Sources */, - 625A150219C783DE00AD0C32 /* HTMLKit.m in Sources */, 623857971A9E8606003A45D9 /* HTMLDocumentType.m in Sources */, 62FC60461BD0519B0042BBE7 /* CSSSelector.m in Sources */, 62AE594A19F9948A0043F069 /* HTMLCharacterToken.m in Sources */, @@ -1038,6 +1051,7 @@ 62D8345919FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */, 6239755E1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m in Sources */, 624FC37A1AE591D80015DDF9 /* HTMLKitNodesTests.m in Sources */, + 621FBE5A1BDAD68700BC9555 /* CSSSelectorParserTests.m in Sources */, 621FBE5D1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */, 628AF62F1BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */, ); @@ -1153,6 +1167,7 @@ isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; @@ -1169,6 +1184,7 @@ isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; @@ -1226,6 +1242,7 @@ 625A14FD19C7834100AD0C32 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + DEFINES_MODULE = YES; DSTROOT = /tmp/HTMLKit.dst; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch"; @@ -1244,6 +1261,7 @@ 625A14FE19C7834100AD0C32 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + DEFINES_MODULE = YES; DSTROOT = /tmp/HTMLKit.dst; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch"; diff --git a/HTMLKit.xcworkspace/contents.xcworkspacedata b/HTMLKit.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..da024c6 --- /dev/null +++ b/HTMLKit.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/HTMLKit/HTMLKit.h b/HTMLKit/HTMLKit.h index 3b5c810..debd2df 100644 --- a/HTMLKit/HTMLKit.h +++ b/HTMLKit/HTMLKit.h @@ -6,8 +6,6 @@ // Copyright (c) 2014 BrainCookie. All rights reserved. // -#import - -@interface HTMLKit : NSObject - -@end +#import "HTMLParser.h" +#import "HTMLDOM.h" +#import "CSSSelectors.h" diff --git a/HTMLKit/HTMLKit.m b/HTMLKit/HTMLKit.m deleted file mode 100644 index da149aa..0000000 --- a/HTMLKit/HTMLKit.m +++ /dev/null @@ -1,13 +0,0 @@ -// -// HTMLKit.m -// HTMLKit -// -// Created by Iska on 15/09/14. -// Copyright (c) 2014 BrainCookie. All rights reserved. -// - -#import "HTMLKit.h" - -@implementation HTMLKit - -@end From 203d15348727c7287fdbf352497618456f533f21 Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 26 Oct 2015 22:26:19 +0100 Subject: [PATCH 076/103] Fix hyphen-attribute test --- HTMLKitTests/CSSAttributeSelectorTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTMLKitTests/CSSAttributeSelectorTests.m b/HTMLKitTests/CSSAttributeSelectorTests.m index 32d7fdd..b92db7c 100644 --- a/HTMLKitTests/CSSAttributeSelectorTests.m +++ b/HTMLKitTests/CSSAttributeSelectorTests.m @@ -170,7 +170,7 @@ - (void)testAttributeHyphen { - CSSSelector *selector = attributeSelector(CSSAttributeSelectorHyphen, @"attr", @"value"); + CSSSelector *selector = attributeSelector(CSSAttributeSelectorHyphen, @"attr", @"top"); XCTAssertEqual([selector acceptElement:_element], NO); From a4131565144e213b6e18f0b0c5fad9a97020d01b Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 26 Oct 2015 22:26:43 +0100 Subject: [PATCH 077/103] Fix method name for checked element selector --- HTMLKit/CSSStructuralPseudoSelectors.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTMLKit/CSSStructuralPseudoSelectors.m b/HTMLKit/CSSStructuralPseudoSelectors.m index 9e66f7d..e217a7a 100644 --- a/HTMLKit/CSSStructuralPseudoSelectors.m +++ b/HTMLKit/CSSStructuralPseudoSelectors.m @@ -225,7 +225,7 @@ CSSSelector * disabledSelector() anyOf(@[disabledOption, disabledOptgroup, disabledMenuItem, disabledForm, disabledFieldset])); } -CSSSelector * checkedElementSelector() +CSSSelector * checkedSelector() { // https://html.spec.whatwg.org/multipage/scripting.html#selector-checked CSSSelector *candidate = anyOf(@[ From c57d3453fcaa730dc33d1309faf3b481e614993c Mon Sep 17 00:00:00 2001 From: iska Date: Mon, 26 Oct 2015 22:27:00 +0100 Subject: [PATCH 078/103] Add id & class selector tests --- HTMLKitTests/CSSAttributeSelectorTests.m | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/HTMLKitTests/CSSAttributeSelectorTests.m b/HTMLKitTests/CSSAttributeSelectorTests.m index b92db7c..8811dff 100644 --- a/HTMLKitTests/CSSAttributeSelectorTests.m +++ b/HTMLKitTests/CSSAttributeSelectorTests.m @@ -221,4 +221,18 @@ XCTAssertEqual([selector acceptElement:_element], NO); } +- (void)testIdSelector +{ + _element[@"id"] = @"id"; + XCTAssertEqual([idSelector(@"id") acceptElement:_element], YES); + XCTAssertEqual([idSelector(@"other id") acceptElement:_element], NO); +} + +- (void)testClassSelector +{ + _element[@"class"] = @"class"; + XCTAssertEqual([classSelector(@"class") acceptElement:_element], YES); + XCTAssertEqual([classSelector(@"other class") acceptElement:_element], NO); +} + @end From c8dd1d77918ca62bbdaa8439a17cc74a047cb0e4 Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 24 Nov 2015 23:01:11 +0100 Subject: [PATCH 079/103] Fix consume CSS identifier input stream method http://www.w3.org/TR/CSS21/syndata.html#characters https://drafts.csswg.org/css-syntax/#consume-name --- HTMLKit/CSSCodePoints.h | 19 +++++++++++++++++++ HTMLKit/CSSInputStream.m | 6 ++++++ 2 files changed, 25 insertions(+) diff --git a/HTMLKit/CSSCodePoints.h b/HTMLKit/CSSCodePoints.h index 93ae3ef..0d1a0fc 100644 --- a/HTMLKit/CSSCodePoints.h +++ b/HTMLKit/CSSCodePoints.h @@ -113,6 +113,25 @@ NS_INLINE BOOL isValidEscapedCodePoint(UTF32Char codePoint) codePoint <= 0x10FFFF); } +NS_INLINE BOOL isValidIdentifierStart(UTF32Char first, UTF32Char second, UTF32Char third) +{ + if (first == HYPHEN_MINUS) { + if (isNameStart(second) || + second == HYPHEN_MINUS || + isValidEscape(second, third)) { + return YES; + } else { + return NO; + } + } else if (isNameStart(first)) { + return YES; + } else if (first == REVERSE_SOLIDUS) { + return isValidEscape(first, second); + } else { + return NO; + } +} + NS_INLINE void AppendCodePoint(CFMutableStringRef string, UTF32Char codePoint) { UniChar pair[2]; diff --git a/HTMLKit/CSSInputStream.m b/HTMLKit/CSSInputStream.m index e9825a7..5a024bd 100644 --- a/HTMLKit/CSSInputStream.m +++ b/HTMLKit/CSSInputStream.m @@ -26,6 +26,12 @@ { CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); + if (!isValidIdentifierStart([self inputCharacterPointAtOffset:0], + [self inputCharacterPointAtOffset:1], + [self inputCharacterPointAtOffset:2])) { + return nil; + } + while (YES) { UTF32Char codePoint = [self consumeNextInputCharacter]; if (codePoint == EOF) { From 56f99f916899a38c5f22485b30c5450fa32fa66d Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 24 Nov 2015 23:01:27 +0100 Subject: [PATCH 080/103] Add input stream method to consume a CSS combinator --- HTMLKit/CSSInputStream.h | 1 + HTMLKit/CSSInputStream.m | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/HTMLKit/CSSInputStream.h b/HTMLKit/CSSInputStream.h index b7afc7b..3bf9c1e 100644 --- a/HTMLKit/CSSInputStream.h +++ b/HTMLKit/CSSInputStream.h @@ -15,5 +15,6 @@ - (NSString *)consumeIdentifier; - (NSString *)consumeStringWithEndingCodePoint:(UTF32Char)endingCodePoint; - (UTF32Char)consumeEscapedCodePoint; +- (NSString *)consumeCombinator; @end diff --git a/HTMLKit/CSSInputStream.m b/HTMLKit/CSSInputStream.m index 5a024bd..661ab6f 100644 --- a/HTMLKit/CSSInputStream.m +++ b/HTMLKit/CSSInputStream.m @@ -117,5 +117,12 @@ return codePoint; } +- (NSString *)consumeCombinator +{ + NSString *combinator = [self consumeCharactersInString:@" >+~"]; + combinator = [combinator stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + + return combinator; +} @end From f4d42e0753ce9e45e44c17451e23180fc991eb3b Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 24 Nov 2015 23:01:49 +0100 Subject: [PATCH 081/103] Fix description methods for combinator selectors --- HTMLKit/CSSCombinatorSelector.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/HTMLKit/CSSCombinatorSelector.m b/HTMLKit/CSSCombinatorSelector.m index c75e608..d26e340 100644 --- a/HTMLKit/CSSCombinatorSelector.m +++ b/HTMLKit/CSSCombinatorSelector.m @@ -78,7 +78,7 @@ - (NSString *)debugDescription { - return @">"; + return [NSString stringWithFormat:@"%@ > ", self.selector]; } @end @@ -103,7 +103,7 @@ - (NSString *)debugDescription { - return @" "; + return [NSString stringWithFormat:@"%@ ", self.selector]; } @end @@ -123,7 +123,7 @@ - (NSString *)debugDescription { - return @"+"; + return [NSString stringWithFormat:@"%@ + ", self.selector]; } @end @@ -148,7 +148,7 @@ - (NSString *)debugDescription { - return @"~"; + return [NSString stringWithFormat:@"%@ ~ ", self.selector]; } @end From 7923efb02bdd50f719f33a6600c91b7f14117158 Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 24 Nov 2015 23:02:14 +0100 Subject: [PATCH 082/103] Add compound selector method to append further selectors --- HTMLKit/CSSCompoundSelector.h | 2 ++ HTMLKit/CSSCompoundSelector.m | 9 ++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/HTMLKit/CSSCompoundSelector.h b/HTMLKit/CSSCompoundSelector.h index b6eab0e..00873d3 100644 --- a/HTMLKit/CSSCompoundSelector.h +++ b/HTMLKit/CSSCompoundSelector.h @@ -15,6 +15,8 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)andSelector:(NSArray *)selectors; + (instancetype)orSelector:(NSArray *)selectors; +- (void)addSelector:(CSSSelector *)selector; + @end NS_ASSUME_NONNULL_END diff --git a/HTMLKit/CSSCompoundSelector.m b/HTMLKit/CSSCompoundSelector.m index c414f1d..552c514 100644 --- a/HTMLKit/CSSCompoundSelector.m +++ b/HTMLKit/CSSCompoundSelector.m @@ -20,7 +20,7 @@ @interface CSSCompoundSelector () { - NSArray *_selectors; + NSMutableArray *_selectors; } @property (nonatomic, strong, readonly) NSArray *selectors; @end @@ -42,15 +42,14 @@ { self = [super init]; if (self) { - _selectors = [[NSArray alloc] initWithArray:selectors]; + _selectors = [[NSMutableArray alloc] initWithArray:selectors]; } return self; } -- (NSString *)debugDescription +- (void)addSelector:(CSSSelector *)selector { - NSArray *descriptions = [_selectors valueForKey:@"debugDescription"]; - return [descriptions componentsJoinedByString:@""]; + [_selectors addObject:selector]; } @end From 578806ec2fe94027c42563a4ac49ac3ab830a48a Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 24 Nov 2015 23:02:32 +0100 Subject: [PATCH 083/103] Add description methods for compound selectors --- HTMLKit/CSSCompoundSelector.m | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/HTMLKit/CSSCompoundSelector.m b/HTMLKit/CSSCompoundSelector.m index 552c514..712d55f 100644 --- a/HTMLKit/CSSCompoundSelector.m +++ b/HTMLKit/CSSCompoundSelector.m @@ -68,6 +68,12 @@ return YES; } +- (NSString *)debugDescription +{ + NSArray *descriptions = [self.selectors valueForKey:@"debugDescription"]; + return [descriptions componentsJoinedByString:@""]; +} + @end #pragma mark - Or Compound Selector @@ -84,4 +90,10 @@ return NO; } +- (NSString *)debugDescription +{ + NSArray *descriptions = [self.selectors valueForKey:@"debugDescription"]; + return [descriptions componentsJoinedByString:@","]; +} + @end From 85abf350998b9088cd776e44deb5bfb38b35ab2d Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 24 Nov 2015 23:03:13 +0100 Subject: [PATCH 084/103] Fix implementation of the shorthand "anyOf" selector --- HTMLKit/CSSSelectors.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTMLKit/CSSSelectors.m b/HTMLKit/CSSSelectors.m index 6d3f8ee..d4e864f 100644 --- a/HTMLKit/CSSSelectors.m +++ b/HTMLKit/CSSSelectors.m @@ -159,7 +159,7 @@ CSSSelector * allOf( NSArray * selectors) CSSSelector * anyOf( NSArray * selectors) { - return [CSSCompoundSelector andSelector:selectors]; + return [CSSCompoundSelector orSelector:selectors]; } #pragma mark - Pseudo From 4c80c520d4aab84b2a2c8416c4b6e73a4937466e Mon Sep 17 00:00:00 2001 From: iska Date: Tue, 24 Nov 2015 23:04:21 +0100 Subject: [PATCH 085/103] Fix reconsume checks in input stream reader for CSS logic --- HTMLKit/HTMLInputStreamReader.m | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/HTMLKit/HTMLInputStreamReader.m b/HTMLKit/HTMLInputStreamReader.m index 667ce8f..2493b44 100644 --- a/HTMLKit/HTMLInputStreamReader.m +++ b/HTMLKit/HTMLInputStreamReader.m @@ -40,6 +40,7 @@ if (self) { _string = [string copy]; _scanner = [[NSScanner alloc] initWithString:string]; + _scanner.charactersToBeSkipped = nil; CFStringInitInlineBuffer((CFStringRef)_string, &_buffer, CFRangeMake(0, _string.length)); } return self; @@ -132,6 +133,7 @@ _location += _consume; _scanner.scanLocation = _location; _currentInputCharacter = nextInputCharacter; + _reconsume = NO; return YES; } return NO; @@ -203,14 +205,17 @@ NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:characters]; if (_reconsume) { - _reconsume = NO; _scanner.scanLocation--; } NSString *string = nil; BOOL success = [_scanner scanCharactersFromSet:set intoString:&string]; - if (success == NO) return nil; + if (success == NO) { + _scanner.scanLocation++; + return nil; + } + _reconsume = NO; _location = _scanner.scanLocation; return string; } From 002564f9aef38a85149ffda87cf6865e4e515c53 Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 25 Nov 2015 21:33:06 +0100 Subject: [PATCH 086/103] Use debug description in combinator selectors --- HTMLKit/CSSCombinatorSelector.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/HTMLKit/CSSCombinatorSelector.m b/HTMLKit/CSSCombinatorSelector.m index d26e340..2da580d 100644 --- a/HTMLKit/CSSCombinatorSelector.m +++ b/HTMLKit/CSSCombinatorSelector.m @@ -78,7 +78,7 @@ - (NSString *)debugDescription { - return [NSString stringWithFormat:@"%@ > ", self.selector]; + return [NSString stringWithFormat:@"%@ > ", self.selector.debugDescription]; } @end @@ -103,7 +103,7 @@ - (NSString *)debugDescription { - return [NSString stringWithFormat:@"%@ ", self.selector]; + return [NSString stringWithFormat:@"%@ ", self.selector.debugDescription]; } @end @@ -123,7 +123,7 @@ - (NSString *)debugDescription { - return [NSString stringWithFormat:@"%@ + ", self.selector]; + return [NSString stringWithFormat:@"%@ + ", self.selector.debugDescription]; } @end @@ -148,7 +148,7 @@ - (NSString *)debugDescription { - return [NSString stringWithFormat:@"%@ ~ ", self.selector]; + return [NSString stringWithFormat:@"%@ ~ ", self.selector.debugDescription]; } @end From 7ec90d6470bcc830423026b0360674be7ebeaebb Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 25 Nov 2015 21:34:43 +0100 Subject: [PATCH 087/103] Fix escaped-code-point consuming in CSS input stream --- HTMLKit/CSSInputStream.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HTMLKit/CSSInputStream.m b/HTMLKit/CSSInputStream.m index 661ab6f..f9336be 100644 --- a/HTMLKit/CSSInputStream.m +++ b/HTMLKit/CSSInputStream.m @@ -38,8 +38,8 @@ break; } else if (isName(codePoint)) { AppendCodePoint(value, codePoint); - } else if (isValidEscape(self.nextInputCharacter, [self inputCharacterPointAtOffset:1])) { - UTF32Char escapedCodePoint = [self consumeNextInputCharacter]; + } else if (isValidEscape(codePoint, [self inputCharacterPointAtOffset:1])) { + UTF32Char escapedCodePoint = [self consumeEscapedCodePoint]; AppendCodePoint(value, escapedCodePoint); } else { [self reconsumeCurrentInputCharacter]; From 8cb088367d70b84cf673f394eef7537923867de0 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 27 Nov 2015 00:46:57 +0100 Subject: [PATCH 088/103] Add Node methods to handle child elements' indices --- HTMLKit/HTMLNode.h | 4 ++++ HTMLKit/HTMLNode.m | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/HTMLKit/HTMLNode.h b/HTMLKit/HTMLNode.h index 9d753a5..6eaa8b3 100644 --- a/HTMLKit/HTMLNode.h +++ b/HTMLKit/HTMLNode.h @@ -84,6 +84,10 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition) - (NSUInteger)indexOfChildNode:(HTMLNode *)node; +- (HTMLElement *)childElementAtIndex:(NSUInteger)index; + +- (NSUInteger)indexOfChildElement:(HTMLElement *)element; + - (HTMLNode *)prependNode:(HTMLNode *)node; - (void)prependNodes:(NSArray *)nodes; diff --git a/HTMLKit/HTMLNode.m b/HTMLKit/HTMLNode.m index bcfcfaa..74d3093 100644 --- a/HTMLKit/HTMLNode.m +++ b/HTMLKit/HTMLNode.m @@ -146,6 +146,34 @@ return [self.childNodes indexOfObject:node]; } +- (HTMLElement *)childElementAtIndex:(NSUInteger)index +{ + NSUInteger counter = 0; + for (HTMLNode *node in self.childNodes) { + if (node.nodeType == HTMLNodeElement) { + if (counter == index) { + return node.asElement; + } + counter++; + } + } + return nil; +} + +- (NSUInteger)indexOfChildElement:(HTMLElement *)element +{ + NSUInteger counter = 0; + for (HTMLNode *node in self.childNodes) { + if (node.nodeType == HTMLNodeElement) { + if (node == element) { + return counter; + } + counter++; + } + } + return NSNotFound; +} + - (HTMLNode *)prependNode:(HTMLNode *)node { return [self insertNode:node beforeChildNode:self.firstChild]; From 5a3c1063e743ea29022fcea5da39277a5758bd35 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 27 Nov 2015 00:47:24 +0100 Subject: [PATCH 089/103] Fix Nth-Expression selector's compute-index methods --- HTMLKit/CSSNthExpressionSelector.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HTMLKit/CSSNthExpressionSelector.m b/HTMLKit/CSSNthExpressionSelector.m index e6a29c8..9b93bc5 100644 --- a/HTMLKit/CSSNthExpressionSelector.m +++ b/HTMLKit/CSSNthExpressionSelector.m @@ -72,14 +72,14 @@ NSInteger computeIndex(NSEnumerator *enumerator, HTMLElement *element) + (instancetype)nthChildSelector:(CSSNthExpression)expression { return [[self alloc] initWithClassName:@"nth-child" expression:expression block:^NSInteger(HTMLElement *element) { - return [element.parentElement indexOfChildNode:element] + 1; + return [element.parentElement indexOfChildElement:element] + 1; }]; } + (instancetype)nthLastChildSelector:(CSSNthExpression)expression { return [[self alloc] initWithClassName:@"nth-last-child" expression:expression block:^NSInteger(HTMLElement *element) { - return element.parentElement.childNodesCount - [element.parentElement indexOfChildNode:element]; + return element.parentElement.childNodesCount - [element.parentElement indexOfChildElement:element]; }]; } From f735fcdfd6cb6c640f6d3ce0947fd19f03638cbe Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 27 Nov 2015 00:47:45 +0100 Subject: [PATCH 090/103] Treat nil attribute value as an empty string in the Attribute selector --- HTMLKit/CSSAttributeSelector.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTMLKit/CSSAttributeSelector.m b/HTMLKit/CSSAttributeSelector.m index ccd9c55..b8d49f7 100644 --- a/HTMLKit/CSSAttributeSelector.m +++ b/HTMLKit/CSSAttributeSelector.m @@ -43,7 +43,7 @@ if (self) { self.type = type; _name = [name copy]; - _value = [value copy]; + _value = value ? [value copy]: @""; } return self; } From 09991a149f3652e1b43a94a7263b2c626990fc14 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 27 Nov 2015 01:01:02 +0100 Subject: [PATCH 091/103] Fix :disabled selector's check for disabled form elements Should've used or- instead of all-combinator --- HTMLKit/CSSStructuralPseudoSelectors.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTMLKit/CSSStructuralPseudoSelectors.m b/HTMLKit/CSSStructuralPseudoSelectors.m index e217a7a..6414c83 100644 --- a/HTMLKit/CSSStructuralPseudoSelectors.m +++ b/HTMLKit/CSSStructuralPseudoSelectors.m @@ -198,7 +198,7 @@ CSSSelector * disabledSelector() // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled CSSSelector *disabledForm = anyOf(@[ - allOf(@[ + anyOf(@[ allOf(@[typeSelector(@"button"), disabledAttribute]), allOf(@[typeSelector(@"input"), disabledAttribute]), allOf(@[typeSelector(@"select"), disabledAttribute]), From c09adc2f96ec0b86b127bcda7089245149ca8f68 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 27 Nov 2015 01:10:07 +0100 Subject: [PATCH 092/103] Add Node properties for previous and next sibling elements --- HTMLKit/HTMLNode.h | 4 ++++ HTMLKit/HTMLNode.m | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/HTMLKit/HTMLNode.h b/HTMLKit/HTMLNode.h index 6eaa8b3..1549d30 100644 --- a/HTMLKit/HTMLNode.h +++ b/HTMLKit/HTMLNode.h @@ -62,6 +62,10 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition) @property (nonatomic, strong, readonly) HTMLNode *nextSibling; +@property (nonatomic, strong, readonly) HTMLElement *previousSiblingElement; + +@property (nonatomic, strong, readonly) HTMLElement *nextSiblingElement; + @property (nonatomic, copy) NSString *textContent; @property (nonatomic, strong, readonly) NSString *outerHTML; diff --git a/HTMLKit/HTMLNode.m b/HTMLKit/HTMLNode.m index 74d3093..ebedf36 100644 --- a/HTMLKit/HTMLNode.m +++ b/HTMLKit/HTMLNode.m @@ -99,6 +99,24 @@ return [_parentNode childNodeAtIndex:index + 1]; } +- (HTMLElement *)previousSiblingElement +{ + HTMLNode *node = self.previousSibling; + while (node && node.nodeType != HTMLNodeElement) { + node = node.previousSibling; + } + return node.asElement; +} + +- (HTMLElement *)nextSiblingElement +{ + HTMLNode *node = self.previousSibling; + while (node && node.nodeType != HTMLNodeElement) { + node = node.nextSibling; + } + return node.asElement; +} + - (NSString *)textContent { return nil; From 0cb374681c46e6c1e4b2b74ac84922665980b8fd Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 27 Nov 2015 01:10:27 +0100 Subject: [PATCH 093/103] Fix sibling combinator selectors --- HTMLKit/CSSCombinatorSelector.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HTMLKit/CSSCombinatorSelector.m b/HTMLKit/CSSCombinatorSelector.m index 2da580d..d3f866d 100644 --- a/HTMLKit/CSSCombinatorSelector.m +++ b/HTMLKit/CSSCombinatorSelector.m @@ -114,7 +114,7 @@ - (BOOL)acceptElement:(HTMLElement *)element { - HTMLNode *previous = element.previousSibling; + HTMLNode *previous = element.previousSiblingElement; if (previous == nil || previous.nodeType != HTMLNodeElement) { return NO; } @@ -134,7 +134,7 @@ - (BOOL)acceptElement:(HTMLElement *)element { - HTMLNode *previous = element.previousSibling; + HTMLNode *previous = element.previousSiblingElement; while (previous != nil && previous.nodeType == HTMLNodeElement) { if ([self.selector acceptElement:previous.asElement]) { From 50ae2c5283a4355825f4e8289b096777ecf19168 Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 27 Nov 2015 19:41:09 +0100 Subject: [PATCH 094/103] Fix :root selector --- HTMLKit/CSSStructuralPseudoSelectors.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTMLKit/CSSStructuralPseudoSelectors.m b/HTMLKit/CSSStructuralPseudoSelectors.m index 6414c83..a5ec15d 100644 --- a/HTMLKit/CSSStructuralPseudoSelectors.m +++ b/HTMLKit/CSSStructuralPseudoSelectors.m @@ -16,7 +16,7 @@ CSSSelector * rootSelector() { return namedBlockSelector(@"root", ^BOOL(HTMLElement * element) { - return !!element.parentElement; + return element.parentElement == nil; }); } From 621dbe36d64c156fe74a7927118f7905aaaa5dbf Mon Sep 17 00:00:00 2001 From: iska Date: Fri, 27 Nov 2015 19:44:57 +0100 Subject: [PATCH 095/103] Fix pseudo selectors' names --- HTMLKit/CSSStructuralPseudoSelectors.m | 39 ++++++++++++++------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/HTMLKit/CSSStructuralPseudoSelectors.m b/HTMLKit/CSSStructuralPseudoSelectors.m index a5ec15d..0b4bd43 100644 --- a/HTMLKit/CSSStructuralPseudoSelectors.m +++ b/HTMLKit/CSSStructuralPseudoSelectors.m @@ -15,14 +15,14 @@ CSSSelector * rootSelector() { - return namedBlockSelector(@"root", ^BOOL(HTMLElement * element) { + return namedBlockSelector(@":root", ^BOOL(HTMLElement * element) { return element.parentElement == nil; }); } CSSSelector * emptySelector() { - return namedBlockSelector(@"empty", ^BOOL(HTMLElement * element) { + return namedBlockSelector(@":empty", ^BOOL(HTMLElement * element) { for (HTMLNode *child in element.childNodes) { if (child.nodeType == HTMLNodeElement) { return NO; @@ -36,14 +36,14 @@ CSSSelector * emptySelector() CSSSelector * parentSelector() { - return namedBlockSelector(@"parent", ^BOOL(HTMLElement * element) { + return namedBlockSelector(@":parent", ^BOOL(HTMLElement * element) { return element.childNodesCount > 0; }); } CSSSelector * buttonSelector() { - return namedBlockSelector(@"button", ^BOOL(HTMLElement * _Nonnull element) { + return namedBlockSelector(@":button", ^BOOL(HTMLElement * _Nonnull element) { if ([element.tagName isEqualToString:@"button"]) { return YES; } @@ -56,7 +56,7 @@ CSSSelector * buttonSelector() CSSSelector * checkboxSelector() { - return namedBlockSelector(@"checkbox", ^BOOL(HTMLElement * _Nonnull element) { + return namedBlockSelector(@":checkbox", ^BOOL(HTMLElement * _Nonnull element) { if ([element[@"type"] isEqualToString:@"checkbox"]) { return YES; } @@ -66,7 +66,7 @@ CSSSelector * checkboxSelector() CSSSelector * fileSelector() { - return namedBlockSelector(@"file", ^BOOL(HTMLElement * _Nonnull element) { + return namedBlockSelector(@":file", ^BOOL(HTMLElement * _Nonnull element) { if ([element[@"type"] isEqualToString:@"file"]) { return YES; } @@ -76,7 +76,7 @@ CSSSelector * fileSelector() CSSSelector * headerSelector() { - return namedBlockSelector(@"header", ^BOOL(HTMLElement * _Nonnull element) { + return namedBlockSelector(@":header", ^BOOL(HTMLElement * _Nonnull element) { if ([element.tagName isEqualToAny:@"h1", @"h2", @"h3", @"h4", @"h5", @"h6", nil]) { return YES; } @@ -86,7 +86,7 @@ CSSSelector * headerSelector() CSSSelector * imageSelector() { - return namedBlockSelector(@"image", ^BOOL(HTMLElement * _Nonnull element) { + return namedBlockSelector(@":image", ^BOOL(HTMLElement * _Nonnull element) { if ([element[@"type"] isEqualToString:@"image"]) { return YES; } @@ -96,7 +96,7 @@ CSSSelector * imageSelector() CSSSelector * inputSelector() { - return namedBlockSelector(@"input", ^BOOL(HTMLElement * _Nonnull element) { + return namedBlockSelector(@":input", ^BOOL(HTMLElement * _Nonnull element) { if ([element.tagName isEqualToAny:@"button", @"input", @"select", @"textarea", nil]) { return YES; } @@ -107,7 +107,7 @@ CSSSelector * inputSelector() CSSSelector * linkSelector() { // https://html.spec.whatwg.org/multipage/scripting.html#selector-link - return namedBlockSelector(@"root", ^BOOL(HTMLElement * element) { + return namedBlockSelector(@":link", ^BOOL(HTMLElement * element) { if ([element hasAttribute:@"href"]) { return [element.tagName isEqualToAny:@"a", @"area", @"link", nil]; } @@ -117,7 +117,7 @@ CSSSelector * linkSelector() CSSSelector * passwordSelector() { - return namedBlockSelector(@"password", ^BOOL(HTMLElement * _Nonnull element) { + return namedBlockSelector(@":password", ^BOOL(HTMLElement * _Nonnull element) { if ([element[@"type"] isEqualToString:@"password"]) { return YES; } @@ -127,7 +127,7 @@ CSSSelector * passwordSelector() CSSSelector * radioSelector() { - return namedBlockSelector(@"radio", ^BOOL(HTMLElement * _Nonnull element) { + return namedBlockSelector(@":radio", ^BOOL(HTMLElement * _Nonnull element) { if ([element[@"type"] isEqualToString:@"radio"]) { return YES; } @@ -137,7 +137,7 @@ CSSSelector * radioSelector() CSSSelector * resetSelector() { - return namedBlockSelector(@"reset", ^BOOL(HTMLElement * _Nonnull element) { + return namedBlockSelector(@":reset", ^BOOL(HTMLElement * _Nonnull element) { if ([element[@"type"] isEqualToString:@"reset"]) { return YES; } @@ -147,7 +147,7 @@ CSSSelector * resetSelector() CSSSelector * submitSelector() { - return namedBlockSelector(@"submit", ^BOOL(HTMLElement * _Nonnull element) { + return namedBlockSelector(@":submit", ^BOOL(HTMLElement * _Nonnull element) { if ([element.tagName isEqualToString:@"input"] && [element[@"type"] isEqualToString:@"submit"]) { return YES; } @@ -160,7 +160,7 @@ CSSSelector * submitSelector() CSSSelector * textSelector() { - return namedBlockSelector(@"text", ^BOOL(HTMLElement * _Nonnull element) { + return namedBlockSelector(@":text", ^BOOL(HTMLElement * _Nonnull element) { if ([element[@"type"] isEqualToString:@"text"]) { return YES; } @@ -272,21 +272,24 @@ CSSSelector * requiredSelector() CSSSelector * ltSelector(NSUInteger index) { - return namedBlockSelector(@"lt", ^BOOL(HTMLElement * _Nonnull element) { + NSString *name = [NSString stringWithFormat:@":lt(%lu)", (unsigned long)index]; + return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) { return [element.parentElement indexOfChildNode:element] < index; }); } CSSSelector * gtSelector(NSUInteger index) { - return namedBlockSelector(@"gt", ^BOOL(HTMLElement * _Nonnull element) { + NSString *name = [NSString stringWithFormat:@":gt(%lu)", (unsigned long)index]; + return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) { return [element.parentElement indexOfChildNode:element] > index; }); } CSSSelector * eqSelector(NSInteger index) { - return namedBlockSelector(@"eq", ^BOOL(HTMLElement * _Nonnull element) { + NSString *name = [NSString stringWithFormat:@":eq(%lu)", (unsigned long)index]; + return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) { NSUInteger elementIndex = [element.parentElement indexOfChildNode:element]; if (index > 0) { From 60a5821a2cae48199b6055ce301d7e95a8c87677 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 28 Nov 2015 21:06:52 +0100 Subject: [PATCH 096/103] Fix general sibling combinator selector --- HTMLKit/CSSCombinatorSelector.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTMLKit/CSSCombinatorSelector.m b/HTMLKit/CSSCombinatorSelector.m index d3f866d..847ae7f 100644 --- a/HTMLKit/CSSCombinatorSelector.m +++ b/HTMLKit/CSSCombinatorSelector.m @@ -140,7 +140,7 @@ if ([self.selector acceptElement:previous.asElement]) { return YES; } - previous = previous.previousSibling; + previous = previous.previousSiblingElement; } return NO; From 60dc6bfc4329a5636078aa40bd7b1b476b0ce263 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 28 Nov 2015 21:07:10 +0100 Subject: [PATCH 097/103] Fix nth-last-child selector --- HTMLKit/CSSNthExpressionSelector.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTMLKit/CSSNthExpressionSelector.m b/HTMLKit/CSSNthExpressionSelector.m index 9b93bc5..0ef6e5e 100644 --- a/HTMLKit/CSSNthExpressionSelector.m +++ b/HTMLKit/CSSNthExpressionSelector.m @@ -79,7 +79,7 @@ NSInteger computeIndex(NSEnumerator *enumerator, HTMLElement *element) + (instancetype)nthLastChildSelector:(CSSNthExpression)expression { return [[self alloc] initWithClassName:@"nth-last-child" expression:expression block:^NSInteger(HTMLElement *element) { - return element.parentElement.childNodesCount - [element.parentElement indexOfChildElement:element]; + return element.parentElement.childElementsCount - [element.parentElement indexOfChildElement:element]; }]; } From 3443321459caa09512ef309baf26cf4fc41f084c Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 28 Nov 2015 21:08:39 +0100 Subject: [PATCH 098/103] Add missing check in cosnume-character HTML stream method Should only advance location if not reconsuming previous character --- HTMLKit/HTMLInputStreamReader.m | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/HTMLKit/HTMLInputStreamReader.m b/HTMLKit/HTMLInputStreamReader.m index 2493b44..3df5f8d 100644 --- a/HTMLKit/HTMLInputStreamReader.m +++ b/HTMLKit/HTMLInputStreamReader.m @@ -130,9 +130,11 @@ { UTF32Char nextInputCharacter = [self nextInputCharacter]; if (nextInputCharacter == character) { - _location += _consume; - _scanner.scanLocation = _location; - _currentInputCharacter = nextInputCharacter; + if (!_reconsume) { + _location += _consume; + _scanner.scanLocation = _location; + _currentInputCharacter = nextInputCharacter; + } _reconsume = NO; return YES; } From badf070907812b27ec12477d31c929b7ff9182f3 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 28 Nov 2015 21:09:16 +0100 Subject: [PATCH 099/103] Add HTMLKit error domain header --- HTMLKit.xcodeproj/project.pbxproj | 4 ++++ HTMLKit/HTMLKit.h | 1 + HTMLKit/HTMLKitErrorDomain.h | 23 +++++++++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 HTMLKit/HTMLKitErrorDomain.h diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index c404383..83580f1 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -108,6 +108,7 @@ 625A150319C783E200AD0C32 /* HTMLKit.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 625A14BC19C7829400AD0C32 /* HTMLKit.h */; }; 625A150919C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */; }; 625A150A19C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */; }; + 626652F91C03D7AC00C3F121 /* HTMLKitErrorDomain.h in Headers */ = {isa = PBXBuildFile; fileRef = 626652F81C03D30F00C3F121 /* HTMLKitErrorDomain.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6279F87519E1808D00F12EE5 /* HTMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6279F87319E1808D00F12EE5 /* HTMLElement.m */; }; 6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6279F87319E1808D00F12EE5 /* HTMLElement.m */; }; 628AF62F1BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */; }; @@ -331,6 +332,7 @@ 625A14EC19C7834100AD0C32 /* HTMLKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HTMLKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 625A150619C78ABA00AD0C32 /* HTMLInputStreamReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLInputStreamReader.h; sourceTree = ""; }; 625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLInputStreamReader.m; sourceTree = ""; }; + 626652F81C03D30F00C3F121 /* HTMLKitErrorDomain.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLKitErrorDomain.h; sourceTree = ""; }; 6279F87119E17DC700F12EE5 /* HTMLParserInsertionModes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLParserInsertionModes.h; sourceTree = ""; }; 6279F87219E1808D00F12EE5 /* HTMLElement.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = HTMLElement.h; sourceTree = ""; }; 6279F87319E1808D00F12EE5 /* HTMLElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLElement.m; sourceTree = ""; }; @@ -578,6 +580,7 @@ isa = PBXGroup; children = ( 625A14BC19C7829400AD0C32 /* HTMLKit.h */, + 626652F81C03D30F00C3F121 /* HTMLKitErrorDomain.h */, 62AE593219F97CCA0043F069 /* Tokenizing */, 628E16EC1ADAE71700B15A06 /* Parsing */, 623719441AA1472B002E03C8 /* DOM */, @@ -707,6 +710,7 @@ buildActionMask = 2147483647; files = ( 629AA0EA1BDD9C2900D5CC98 /* HTMLKit.h in Headers */, + 626652F91C03D7AC00C3F121 /* HTMLKitErrorDomain.h in Headers */, 629AA0EB1BDD9C2900D5CC98 /* HTMLParser.h in Headers */, 629AA0EC1BDD9C2900D5CC98 /* HTMLDOM.h in Headers */, 629AA0ED1BDD9C2900D5CC98 /* HTMLNode.h in Headers */, diff --git a/HTMLKit/HTMLKit.h b/HTMLKit/HTMLKit.h index debd2df..5d85025 100644 --- a/HTMLKit/HTMLKit.h +++ b/HTMLKit/HTMLKit.h @@ -9,3 +9,4 @@ #import "HTMLParser.h" #import "HTMLDOM.h" #import "CSSSelectors.h" +#import "HTMLKitErrorDomain.h" diff --git a/HTMLKit/HTMLKitErrorDomain.h b/HTMLKit/HTMLKitErrorDomain.h new file mode 100644 index 0000000..98ca6f8 --- /dev/null +++ b/HTMLKit/HTMLKitErrorDomain.h @@ -0,0 +1,23 @@ +// +// HTMLKitErrorDomain.h +// HTMLKit +// +// Created by Iska on 24/11/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#ifndef HTMLKitErrorDomain_h +#define HTMLKitErrorDomain_h + +static NSString *const HTMLKitErrorDomain = @"HTMLKit"; +static NSString *const HTMLKitSelectorErrorDomain = @"HTMLKitSelector"; + +static NSString *const CSSSelectorStringKey = @"CSSSelectorString"; +static NSString *const CSSSelectorErrorLocationKey = @"CSSSelectorErrorLocation"; + +NS_ENUM(NSInteger) +{ + HTMLKitSelectorParseError = 4200 +}; + +#endif /* HTMLKitErrorDomain_h */ From 30dc6cf3439303a11c13dde65af20a7abd08f14c Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 28 Nov 2015 21:09:44 +0100 Subject: [PATCH 100/103] Add HTML Node method to count child elements --- HTMLKit/HTMLNode.h | 2 ++ HTMLKit/HTMLNode.m | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/HTMLKit/HTMLNode.h b/HTMLKit/HTMLNode.h index 1549d30..e5fac40 100644 --- a/HTMLKit/HTMLNode.h +++ b/HTMLKit/HTMLNode.h @@ -88,6 +88,8 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition) - (NSUInteger)indexOfChildNode:(HTMLNode *)node; +- (NSUInteger)childElementsCount; + - (HTMLElement *)childElementAtIndex:(NSUInteger)index; - (NSUInteger)indexOfChildElement:(HTMLElement *)element; diff --git a/HTMLKit/HTMLNode.m b/HTMLKit/HTMLNode.m index ebedf36..c630665 100644 --- a/HTMLKit/HTMLNode.m +++ b/HTMLKit/HTMLNode.m @@ -159,6 +159,13 @@ return [self.childNodes objectAtIndex:index]; } +- (NSUInteger)childElementsCount +{ + return [self.childNodes indexesOfObjectsPassingTest:^BOOL(HTMLNode * _Nonnull node, NSUInteger idx, BOOL * _Nonnull stop) { + return node.nodeType == HTMLNodeElement; + }].count; +} + - (NSUInteger)indexOfChildNode:(HTMLNode *)node { return [self.childNodes indexOfObject:node]; From 94fed8afa13e07800174eafa6a918574ec3934a5 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 28 Nov 2015 21:10:08 +0100 Subject: [PATCH 101/103] Add CSS test fixtures Tests are adapted from the official suite: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/static/flat/ Test file format: Each test file is a HTML fragment with: +
+
    +
  • The background of this list item should be green
  • +
  • The background of this second list item should be also green
  • +
+

The background of this paragraph should be green.

+
diff --git a/HTMLKitTests/css-tests/10.html b/HTMLKitTests/css-tests/10.html new file mode 100644 index 0000000..4cac7d8 --- /dev/null +++ b/HTMLKitTests/css-tests/10.html @@ -0,0 +1,9 @@ + +
+

This paragraph should have a green background because its title attribute ends with "bar"

+
diff --git a/HTMLKitTests/css-tests/11.html b/HTMLKitTests/css-tests/11.html new file mode 100644 index 0000000..e324c90 --- /dev/null +++ b/HTMLKitTests/css-tests/11.html @@ -0,0 +1,9 @@ + +
+

This paragraph should have a green background because its title attribute contains "bar"

+
diff --git a/HTMLKitTests/css-tests/13.html b/HTMLKitTests/css-tests/13.html new file mode 100644 index 0000000..ff0776a --- /dev/null +++ b/HTMLKitTests/css-tests/13.html @@ -0,0 +1,23 @@ + +
+
    +
  • This list item should have green background because its class is "t1"
  • +
  • This list item should have green background because its class is "t2"
  • +
  • + This list item should have green background because the inner SPAN does not match SPAN.t3 +
  • +
+
diff --git a/HTMLKitTests/css-tests/14.html b/HTMLKitTests/css-tests/14.html new file mode 100644 index 0000000..9746a50 --- /dev/null +++ b/HTMLKitTests/css-tests/14.html @@ -0,0 +1,30 @@ + +
+

This paragraph should have a green background and a green thick solid border because it carries both classes t1 and t2.

+
This line should be green.
+
diff --git a/HTMLKitTests/css-tests/144.html b/HTMLKitTests/css-tests/144.html new file mode 100644 index 0000000..255ea3d --- /dev/null +++ b/HTMLKitTests/css-tests/144.html @@ -0,0 +1,11 @@ + +
+
+

This paragraph should have a green background.

+
+
diff --git a/HTMLKitTests/css-tests/148.html b/HTMLKitTests/css-tests/148.html new file mode 100644 index 0000000..87d2a6a --- /dev/null +++ b/HTMLKitTests/css-tests/148.html @@ -0,0 +1,9 @@ + +
+

This line should have a green background.

+
diff --git a/HTMLKitTests/css-tests/149.html b/HTMLKitTests/css-tests/149.html new file mode 100644 index 0000000..c5bdb92 --- /dev/null +++ b/HTMLKitTests/css-tests/149.html @@ -0,0 +1,10 @@ + +
+
+
This line should have a green background.
+
diff --git a/HTMLKitTests/css-tests/14b.html b/HTMLKitTests/css-tests/14b.html new file mode 100644 index 0000000..de12356 --- /dev/null +++ b/HTMLKitTests/css-tests/14b.html @@ -0,0 +1,22 @@ + +
+

This line should be green.

+

This line should be green.

+
diff --git a/HTMLKitTests/css-tests/14c.html b/HTMLKitTests/css-tests/14c.html new file mode 100644 index 0000000..26c5459 --- /dev/null +++ b/HTMLKitTests/css-tests/14c.html @@ -0,0 +1,19 @@ + +
+

This line should be green.

+
This line should be green.
+
This line should be green.
+
diff --git a/HTMLKitTests/css-tests/14d.html b/HTMLKitTests/css-tests/14d.html new file mode 100644 index 0000000..ef67d2d --- /dev/null +++ b/HTMLKitTests/css-tests/14d.html @@ -0,0 +1,21 @@ + +
+

This line should be green.

+
diff --git a/HTMLKitTests/css-tests/14e.html b/HTMLKitTests/css-tests/14e.html new file mode 100644 index 0000000..90ec981 --- /dev/null +++ b/HTMLKitTests/css-tests/14e.html @@ -0,0 +1,19 @@ + +
+

This line should be green.

+
This line should be green.
+
This line should be green.
+
diff --git a/HTMLKitTests/css-tests/15.html b/HTMLKitTests/css-tests/15.html new file mode 100644 index 0000000..40ccf78 --- /dev/null +++ b/HTMLKitTests/css-tests/15.html @@ -0,0 +1,27 @@ + +
+
    +
  • This list item should have a green background. because its ID is "t1"
  • +
  • This list item should have a green background. because its ID is "t2"
  • +
  • + This list item should have a green background. because the inner SPAN does not match "#t4" +
  • +
+
diff --git a/HTMLKitTests/css-tests/150.html b/HTMLKitTests/css-tests/150.html new file mode 100644 index 0000000..209522a --- /dev/null +++ b/HTMLKitTests/css-tests/150.html @@ -0,0 +1,11 @@ + +
+
+
This line should have a green background.
+

(Note: This test is based on unpublished errata.)

+
diff --git a/HTMLKitTests/css-tests/151.html b/HTMLKitTests/css-tests/151.html new file mode 100644 index 0000000..5f267e2 --- /dev/null +++ b/HTMLKitTests/css-tests/151.html @@ -0,0 +1,10 @@ + +
+
+
This line should have a green background.
+
diff --git a/HTMLKitTests/css-tests/152.html b/HTMLKitTests/css-tests/152.html new file mode 100644 index 0000000..83c251f --- /dev/null +++ b/HTMLKitTests/css-tests/152.html @@ -0,0 +1,10 @@ + +
+
+
This line should have a green background.
+
diff --git a/HTMLKitTests/css-tests/154.html b/HTMLKitTests/css-tests/154.html new file mode 100644 index 0000000..ad60662 --- /dev/null +++ b/HTMLKitTests/css-tests/154.html @@ -0,0 +1,10 @@ + +
+

This line should have a green background.

+
diff --git a/HTMLKitTests/css-tests/155.html b/HTMLKitTests/css-tests/155.html new file mode 100644 index 0000000..5c6b222 --- /dev/null +++ b/HTMLKitTests/css-tests/155.html @@ -0,0 +1,10 @@ + +
+

This line should have a green background.

+
diff --git a/HTMLKitTests/css-tests/155a.html b/HTMLKitTests/css-tests/155a.html new file mode 100644 index 0000000..df6b43b --- /dev/null +++ b/HTMLKitTests/css-tests/155a.html @@ -0,0 +1,9 @@ + +
+

This line should have a green background.

+
diff --git a/HTMLKitTests/css-tests/155b.html b/HTMLKitTests/css-tests/155b.html new file mode 100644 index 0000000..7cc185e --- /dev/null +++ b/HTMLKitTests/css-tests/155b.html @@ -0,0 +1,9 @@ + +
+

This line should have a green background.

+
diff --git a/HTMLKitTests/css-tests/155c.html b/HTMLKitTests/css-tests/155c.html new file mode 100644 index 0000000..12ecc98 --- /dev/null +++ b/HTMLKitTests/css-tests/155c.html @@ -0,0 +1,9 @@ + +
+

This line should have a green background.

+
diff --git a/HTMLKitTests/css-tests/155d.html b/HTMLKitTests/css-tests/155d.html new file mode 100644 index 0000000..bbcf40b --- /dev/null +++ b/HTMLKitTests/css-tests/155d.html @@ -0,0 +1,9 @@ + +
+

This line should have a green background.

+
diff --git a/HTMLKitTests/css-tests/156.html b/HTMLKitTests/css-tests/156.html new file mode 100644 index 0000000..2349293 --- /dev/null +++ b/HTMLKitTests/css-tests/156.html @@ -0,0 +1,10 @@ + +
+

This line should have a green background.

+
diff --git a/HTMLKitTests/css-tests/157.html b/HTMLKitTests/css-tests/157.html new file mode 100644 index 0000000..75df363 --- /dev/null +++ b/HTMLKitTests/css-tests/157.html @@ -0,0 +1,10 @@ + +
+

This line should have a green background.

+
diff --git a/HTMLKitTests/css-tests/158.html b/HTMLKitTests/css-tests/158.html new file mode 100644 index 0000000..51ae49a --- /dev/null +++ b/HTMLKitTests/css-tests/158.html @@ -0,0 +1,10 @@ + +
+

This line should have a green background.

+
diff --git a/HTMLKitTests/css-tests/15b.html b/HTMLKitTests/css-tests/15b.html new file mode 100644 index 0000000..6420813 --- /dev/null +++ b/HTMLKitTests/css-tests/15b.html @@ -0,0 +1,22 @@ + +
+

This line should be green.

+
This line should be green.
+
diff --git a/HTMLKitTests/css-tests/16.html b/HTMLKitTests/css-tests/16.html new file mode 100644 index 0000000..dc2ffbe --- /dev/null +++ b/HTMLKitTests/css-tests/16.html @@ -0,0 +1,15 @@ + +
+

+ This link should have green background. (Don't follow this link.) +

+
diff --git a/HTMLKitTests/css-tests/160.html b/HTMLKitTests/css-tests/160.html new file mode 100644 index 0000000..e8400a3 --- /dev/null +++ b/HTMLKitTests/css-tests/160.html @@ -0,0 +1,10 @@ + +
+

This line should have a green background.

+
diff --git a/HTMLKitTests/css-tests/170.html b/HTMLKitTests/css-tests/170.html new file mode 100644 index 0000000..7ed4a5e --- /dev/null +++ b/HTMLKitTests/css-tests/170.html @@ -0,0 +1,9 @@ + +
+

This line should be green.

+
diff --git a/HTMLKitTests/css-tests/170a.html b/HTMLKitTests/css-tests/170a.html new file mode 100644 index 0000000..d4de3c7 --- /dev/null +++ b/HTMLKitTests/css-tests/170a.html @@ -0,0 +1,9 @@ + +
+

This line should be green.

+
diff --git a/HTMLKitTests/css-tests/170b.html b/HTMLKitTests/css-tests/170b.html new file mode 100644 index 0000000..6829742 --- /dev/null +++ b/HTMLKitTests/css-tests/170b.html @@ -0,0 +1,9 @@ + +
+

This line should be green.

+
diff --git a/HTMLKitTests/css-tests/170c.html b/HTMLKitTests/css-tests/170c.html new file mode 100644 index 0000000..d063fb4 --- /dev/null +++ b/HTMLKitTests/css-tests/170c.html @@ -0,0 +1,9 @@ + +
+

This line should be green.

+
diff --git a/HTMLKitTests/css-tests/170d.html b/HTMLKitTests/css-tests/170d.html new file mode 100644 index 0000000..1487f3a --- /dev/null +++ b/HTMLKitTests/css-tests/170d.html @@ -0,0 +1,9 @@ + +
+

This line should be green.

+
diff --git a/HTMLKitTests/css-tests/175a.html b/HTMLKitTests/css-tests/175a.html new file mode 100644 index 0000000..40f60bb --- /dev/null +++ b/HTMLKitTests/css-tests/175a.html @@ -0,0 +1,10 @@ + +
+

This line should be green.

+
diff --git a/HTMLKitTests/css-tests/175b.html b/HTMLKitTests/css-tests/175b.html new file mode 100644 index 0000000..264e958 --- /dev/null +++ b/HTMLKitTests/css-tests/175b.html @@ -0,0 +1,9 @@ + +
+

This line should be green.

+
diff --git a/HTMLKitTests/css-tests/175c.html b/HTMLKitTests/css-tests/175c.html new file mode 100644 index 0000000..2b39faf --- /dev/null +++ b/HTMLKitTests/css-tests/175c.html @@ -0,0 +1,9 @@ + +
+

This line should be green.

+
diff --git a/HTMLKitTests/css-tests/176.html b/HTMLKitTests/css-tests/176.html new file mode 100644 index 0000000..698d05f --- /dev/null +++ b/HTMLKitTests/css-tests/176.html @@ -0,0 +1,30 @@ + +
+

This line should be green.

+
This line should be green.
+
diff --git a/HTMLKitTests/css-tests/177b.html b/HTMLKitTests/css-tests/177b.html new file mode 100644 index 0000000..df37984 --- /dev/null +++ b/HTMLKitTests/css-tests/177b.html @@ -0,0 +1,12 @@ + +
+
+

This line should be green.

+
+
diff --git a/HTMLKitTests/css-tests/181.html b/HTMLKitTests/css-tests/181.html new file mode 100644 index 0000000..a6ba620 --- /dev/null +++ b/HTMLKitTests/css-tests/181.html @@ -0,0 +1,26 @@ + +
+
+ + +
+

This line should be green.

+

This line should be green.

+

This line should be green.

+
+ +
+
diff --git a/HTMLKitTests/css-tests/183.html b/HTMLKitTests/css-tests/183.html new file mode 100644 index 0000000..582fee1 --- /dev/null +++ b/HTMLKitTests/css-tests/183.html @@ -0,0 +1,25 @@ + +
+

This text should be green.

+

This text should be green.

+

This text should be green.

+

This text should be green.

+

This text should be green.

+

This text should be green.

+
diff --git a/HTMLKitTests/css-tests/184a.html b/HTMLKitTests/css-tests/184a.html new file mode 100644 index 0000000..cc43a72 --- /dev/null +++ b/HTMLKitTests/css-tests/184a.html @@ -0,0 +1,10 @@ + +
+

This text should be green.

+

This text should be green.

+
diff --git a/HTMLKitTests/css-tests/184b.html b/HTMLKitTests/css-tests/184b.html new file mode 100644 index 0000000..f92d416 --- /dev/null +++ b/HTMLKitTests/css-tests/184b.html @@ -0,0 +1,10 @@ + +
+

This text should be green.

+

This text should be green.

+
diff --git a/HTMLKitTests/css-tests/184c.html b/HTMLKitTests/css-tests/184c.html new file mode 100644 index 0000000..8d25e8a --- /dev/null +++ b/HTMLKitTests/css-tests/184c.html @@ -0,0 +1,10 @@ + +
+

This text should be green.

+

This text should be green.

+
diff --git a/HTMLKitTests/css-tests/184d.html b/HTMLKitTests/css-tests/184d.html new file mode 100644 index 0000000..dfc0f97 --- /dev/null +++ b/HTMLKitTests/css-tests/184d.html @@ -0,0 +1,10 @@ + +
+

This text should be green.

+

This text should be green.

+
diff --git a/HTMLKitTests/css-tests/184e.html b/HTMLKitTests/css-tests/184e.html new file mode 100644 index 0000000..45c3433 --- /dev/null +++ b/HTMLKitTests/css-tests/184e.html @@ -0,0 +1,10 @@ + +
+

This text should be green.

+

This text should be green.

+
diff --git a/HTMLKitTests/css-tests/184f.html b/HTMLKitTests/css-tests/184f.html new file mode 100644 index 0000000..d669805 --- /dev/null +++ b/HTMLKitTests/css-tests/184f.html @@ -0,0 +1,10 @@ + +
+

This text should be green.

+

This text should be green.

+
diff --git a/HTMLKitTests/css-tests/2.html b/HTMLKitTests/css-tests/2.html new file mode 100644 index 0000000..c1efff3 --- /dev/null +++ b/HTMLKitTests/css-tests/2.html @@ -0,0 +1,9 @@ + +
+
This address element should have a green background.
+
diff --git a/HTMLKitTests/css-tests/23.html b/HTMLKitTests/css-tests/23.html new file mode 100644 index 0000000..5ffbae0 --- /dev/null +++ b/HTMLKitTests/css-tests/23.html @@ -0,0 +1,17 @@ + +
+

+ +
+ +

+
diff --git a/HTMLKitTests/css-tests/24.html b/HTMLKitTests/css-tests/24.html new file mode 100644 index 0000000..4455e33 --- /dev/null +++ b/HTMLKitTests/css-tests/24.html @@ -0,0 +1,17 @@ + +
+

+ +
+ +

+
diff --git a/HTMLKitTests/css-tests/25.html b/HTMLKitTests/css-tests/25.html new file mode 100644 index 0000000..11d0372 --- /dev/null +++ b/HTMLKitTests/css-tests/25.html @@ -0,0 +1,20 @@ + +
+

+ + Everything in this paragraph should have a green background +

+
diff --git a/HTMLKitTests/css-tests/27a.html b/HTMLKitTests/css-tests/27a.html new file mode 100644 index 0000000..f8be676 --- /dev/null +++ b/HTMLKitTests/css-tests/27a.html @@ -0,0 +1,61 @@ + +
+

This line should be green (there should be no red on this page).

+
diff --git a/HTMLKitTests/css-tests/27b.html b/HTMLKitTests/css-tests/27b.html new file mode 100644 index 0000000..3c189ed --- /dev/null +++ b/HTMLKitTests/css-tests/27b.html @@ -0,0 +1,13 @@ + +
+

This line should be green (there should be no red on this page).

+
diff --git a/HTMLKitTests/css-tests/28.html b/HTMLKitTests/css-tests/28.html new file mode 100644 index 0000000..7769632 --- /dev/null +++ b/HTMLKitTests/css-tests/28.html @@ -0,0 +1,103 @@ + +
+
    +
  • This first list item should have a green background
  • +
  • Second list item
  • +
  • This third list item should have a green background
  • +
  • Fourth list item
  • +
  • This fifth list item should have a green background
  • +
  • Sixth list item
  • +
+
    +
  1. First list item
  2. +
  3. This second list item should have a green background
  4. +
  5. Third list item
  6. +
  7. This fourth list item should have a green background
  8. +
  9. Fifth list item
  10. +
  11. This sixth list item should have a green background
  12. +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Green row : 1.11.21.3
Green row : 2.12.22.3
Green row : 3.13.23.3
Green row : 4.14.24.3
5.15.25.3
6.16.26.3
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
green cell1.21.3green cell1.51.6green cell1.8
green cell2.22.3green cell2.52.6green cell2.8
green cell3.23.3green cell3.53.6green cell3.8
+
+
diff --git a/HTMLKitTests/css-tests/29.html b/HTMLKitTests/css-tests/29.html new file mode 100644 index 0000000..845fb64 --- /dev/null +++ b/HTMLKitTests/css-tests/29.html @@ -0,0 +1,103 @@ + +
+
    +
  • First list item
  • +
  • This second list item should have a green background
  • +
  • Third list item
  • +
  • This fourth list item should have a green background
  • +
  • Fifth list item
  • +
  • This sixth list item should have a green background
  • +
+
    +
  1. This first list item should have a green background
  2. +
  3. Second list item
  4. +
  5. This third list item should have a green background
  6. +
  7. Fourth list item
  8. +
  9. This fifth list item should have a green background
  10. +
  11. Sixth list item
  12. +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1.11.21.3
2.12.22.3
Green row : 3.13.23.3
Green row : 4.14.24.3
Green row : 5.15.25.3
Green row : 6.16.26.3
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1.1green cell1.31.4green cell1.61.7green cell
2.1green cell2.32.4green cell2.62.7green cell
3.1green cell3.33.4green cell3.63.7green cell
+
+
diff --git a/HTMLKitTests/css-tests/3.html b/HTMLKitTests/css-tests/3.html new file mode 100644 index 0000000..c0aa613 --- /dev/null +++ b/HTMLKitTests/css-tests/3.html @@ -0,0 +1,18 @@ + +
+

+ This paragraph, and all textual contents in the document, should be green. +

+
    +
  • This item should be green.
  • +
+
diff --git a/HTMLKitTests/css-tests/30.html b/HTMLKitTests/css-tests/30.html new file mode 100644 index 0000000..9d22198 --- /dev/null +++ b/HTMLKitTests/css-tests/30.html @@ -0,0 +1,30 @@ + +
+

This paragraph is here only to fill space in the DOM

+
And this address too..
+

So does this paragraph !

+

But this one should have green background

+
+
First definition term that should have green background
+
First definition that should have green background
+
Second definition term
+
Second definition
+
Third definition term
+
Third definition
+
Fourth definition term that should have green background
+
Fourth definition that should have green background
+
Fifth definition term
+
Fifth definition
+
Sixth definition term
+
Sixth definition
+
+
diff --git a/HTMLKitTests/css-tests/31.html b/HTMLKitTests/css-tests/31.html new file mode 100644 index 0000000..57c516b --- /dev/null +++ b/HTMLKitTests/css-tests/31.html @@ -0,0 +1,30 @@ + +
+

This paragraph should have green background

+
But this address is here only to fill space in the dom..
+

So does this paragraph !

+

And so does this one too.

+
+
First definition term
+
First definition
+
Second definition term
+
Second definition
+
Third definition term that should have green background
+
Third definition that should have green background
+
Fourth definition term
+
Fourth definition
+
Fifth definition term
+
Fifth definition
+
Sixth definition term that should have green background
+
Sixth definition that should have green background
+
+
diff --git a/HTMLKitTests/css-tests/32.html b/HTMLKitTests/css-tests/32.html new file mode 100644 index 0000000..f310ef7 --- /dev/null +++ b/HTMLKitTests/css-tests/32.html @@ -0,0 +1,34 @@ + +
+
+ + + + + + + + + + + + + + + + +
green cell1.21.3
green cell2.22.3
green cell3.23.3
+
+

This paragraph contains some text + and a span that should have a green background +

+
diff --git a/HTMLKitTests/css-tests/33.html b/HTMLKitTests/css-tests/33.html new file mode 100644 index 0000000..6b2d3e1 --- /dev/null +++ b/HTMLKitTests/css-tests/33.html @@ -0,0 +1,34 @@ + +
+
+ + + + + + + + + + + + + + + + +
1.11.2green cell
2.12.2green cell
3.13.2green cell
+
+

+ This paragraph contains a span that should + have a green background and some text after it.

+
diff --git a/HTMLKitTests/css-tests/34.html b/HTMLKitTests/css-tests/34.html new file mode 100644 index 0000000..0d4952a --- /dev/null +++ b/HTMLKitTests/css-tests/34.html @@ -0,0 +1,13 @@ + +
+
This div contains 3 addresses: +
A first address that should have a green background
+
A second address with normal background
+
A third address with normal background
+
+
diff --git a/HTMLKitTests/css-tests/35.html b/HTMLKitTests/css-tests/35.html new file mode 100644 index 0000000..9720100 --- /dev/null +++ b/HTMLKitTests/css-tests/35.html @@ -0,0 +1,14 @@ + +
+
+
A first address with normal background
+
A second address with normal background
+
A third address that should have a green background
+ This div contains 3 addresses above this sentence. +
+
diff --git a/HTMLKitTests/css-tests/36.html b/HTMLKitTests/css-tests/36.html new file mode 100644 index 0000000..acadf0f --- /dev/null +++ b/HTMLKitTests/css-tests/36.html @@ -0,0 +1,16 @@ + +
+

This paragraph should have normal background

+
This div contains only one paragraph +

This paragraph should have green background

+
+
diff --git a/HTMLKitTests/css-tests/37.html b/HTMLKitTests/css-tests/37.html new file mode 100644 index 0000000..f482dc0 --- /dev/null +++ b/HTMLKitTests/css-tests/37.html @@ -0,0 +1,13 @@ + +
+
+

This paragraph should have normal background

+
But this address should have green background
+

This paragraph should have normal background

+
+
diff --git a/HTMLKitTests/css-tests/4.html b/HTMLKitTests/css-tests/4.html new file mode 100644 index 0000000..0f69206 --- /dev/null +++ b/HTMLKitTests/css-tests/4.html @@ -0,0 +1,9 @@ + +
+

This paragraph should have a green background

+
diff --git a/HTMLKitTests/css-tests/43.html b/HTMLKitTests/css-tests/43.html new file mode 100644 index 0000000..83ac030 --- /dev/null +++ b/HTMLKitTests/css-tests/43.html @@ -0,0 +1,29 @@ + +
+
+

This paragraph should have a green background

+ + + + + + +
+

This paragraph should have a green background

+
+
+ + + + + + +
+

This paragraph should be unstyled.

+
+
diff --git a/HTMLKitTests/css-tests/44.html b/HTMLKitTests/css-tests/44.html new file mode 100644 index 0000000..076b4b2 --- /dev/null +++ b/HTMLKitTests/css-tests/44.html @@ -0,0 +1,23 @@ + +
+
+

This paragraph should have a green background

+
+

This paragraph should have a green background

+
+
+ + + + + + +
+

This paragraph should be unstyled.

+
+
diff --git a/HTMLKitTests/css-tests/44c.html b/HTMLKitTests/css-tests/44c.html new file mode 100644 index 0000000..5c6007b --- /dev/null +++ b/HTMLKitTests/css-tests/44c.html @@ -0,0 +1,10 @@ + +
+
This should be unstyled.
+
This should have a green background.
+
diff --git a/HTMLKitTests/css-tests/44d.html b/HTMLKitTests/css-tests/44d.html new file mode 100644 index 0000000..3d6e5c9 --- /dev/null +++ b/HTMLKitTests/css-tests/44d.html @@ -0,0 +1,10 @@ + +
+
This should be unstyled.
+

This should have a green background.

+
diff --git a/HTMLKitTests/css-tests/45.html b/HTMLKitTests/css-tests/45.html new file mode 100644 index 0000000..4d84ec7 --- /dev/null +++ b/HTMLKitTests/css-tests/45.html @@ -0,0 +1,15 @@ + +
+
+

This paragraph should be unstyled.

+

But this one should have a green background.

+

And this one should also have a green background.

+
This address is only here to fill some space between two paragraphs.
+

This paragraph should be unstyled.

+
+
diff --git a/HTMLKitTests/css-tests/45c.html b/HTMLKitTests/css-tests/45c.html new file mode 100644 index 0000000..ca52954 --- /dev/null +++ b/HTMLKitTests/css-tests/45c.html @@ -0,0 +1,10 @@ + +
+
This should be unstyled.
+
This should have a green background.
+
diff --git a/HTMLKitTests/css-tests/46.html b/HTMLKitTests/css-tests/46.html new file mode 100644 index 0000000..863ea22 --- /dev/null +++ b/HTMLKitTests/css-tests/46.html @@ -0,0 +1,15 @@ + +
+
+

This paragraph should be unstyled.

+

But this one should have a green background

+

And this one should also have a green background

+
This address is only here to fill some space between two paragraphs
+

This paragraph should have a green background

+
+
diff --git a/HTMLKitTests/css-tests/5.html b/HTMLKitTests/css-tests/5.html new file mode 100644 index 0000000..6ce6434 --- /dev/null +++ b/HTMLKitTests/css-tests/5.html @@ -0,0 +1,9 @@ + +
+

This paragraph should have a green background because its TITLE attribute is set.

+
diff --git a/HTMLKitTests/css-tests/54.html b/HTMLKitTests/css-tests/54.html new file mode 100644 index 0000000..4c36daf --- /dev/null +++ b/HTMLKitTests/css-tests/54.html @@ -0,0 +1,19 @@ + +
+
+

This paragraph should be in green characters.

+

This paragraph should be in green characters.

+

+ This paragraph should be in green characters. +

+
+
diff --git a/HTMLKitTests/css-tests/55.html b/HTMLKitTests/css-tests/55.html new file mode 100644 index 0000000..ebe5406 --- /dev/null +++ b/HTMLKitTests/css-tests/55.html @@ -0,0 +1,19 @@ + +
+
+

This paragraph should be in green characters.

+

This paragraph should be in green characters.

+

+ This paragraph should be in green characters. +

+
+
diff --git a/HTMLKitTests/css-tests/56.html b/HTMLKitTests/css-tests/56.html new file mode 100644 index 0000000..8bd5345 --- /dev/null +++ b/HTMLKitTests/css-tests/56.html @@ -0,0 +1,19 @@ + +
+
+

This paragraph should be in green characters.

+

This paragraph should be in green characters.

+

+ This paragraph should be in green characters. +

+
+
diff --git a/HTMLKitTests/css-tests/59.html b/HTMLKitTests/css-tests/59.html new file mode 100644 index 0000000..2c0d5ab --- /dev/null +++ b/HTMLKitTests/css-tests/59.html @@ -0,0 +1,19 @@ + +
+
+

This paragraph should be in green characters.

+

This paragraph should be in green characters.

+

+ This paragraph should be in green characters. +

+
+
diff --git a/HTMLKitTests/css-tests/6.html b/HTMLKitTests/css-tests/6.html new file mode 100644 index 0000000..d2ec421 --- /dev/null +++ b/HTMLKitTests/css-tests/6.html @@ -0,0 +1,21 @@ + +
+
+ This line should + have a green background. + +
+
diff --git a/HTMLKitTests/css-tests/60.html b/HTMLKitTests/css-tests/60.html new file mode 100644 index 0000000..0b74f40 --- /dev/null +++ b/HTMLKitTests/css-tests/60.html @@ -0,0 +1,19 @@ + +
+
+

This paragraph should be in green characters.

+

This paragraph should be in green characters.

+

+ This paragraph should be in green characters. +

+
+
diff --git a/HTMLKitTests/css-tests/68.html b/HTMLKitTests/css-tests/68.html new file mode 100644 index 0000000..856c58e --- /dev/null +++ b/HTMLKitTests/css-tests/68.html @@ -0,0 +1,17 @@ + +
+

+ +
+ +

+
diff --git a/HTMLKitTests/css-tests/69.html b/HTMLKitTests/css-tests/69.html new file mode 100644 index 0000000..0e77724 --- /dev/null +++ b/HTMLKitTests/css-tests/69.html @@ -0,0 +1,17 @@ + +
+

+ +
+ +

+
diff --git a/HTMLKitTests/css-tests/7.html b/HTMLKitTests/css-tests/7.html new file mode 100644 index 0000000..08bd82e --- /dev/null +++ b/HTMLKitTests/css-tests/7.html @@ -0,0 +1,21 @@ + +
+

This paragraph should have green background because CLASS contains "b"

+
+ This address should also + have green background because the selector in the last rule does not apply to the inner SPANs. +
+
diff --git a/HTMLKitTests/css-tests/70.html b/HTMLKitTests/css-tests/70.html new file mode 100644 index 0000000..596b63e --- /dev/null +++ b/HTMLKitTests/css-tests/70.html @@ -0,0 +1,18 @@ + +
+

+ Everything in this paragraph should have a green background

+
diff --git a/HTMLKitTests/css-tests/72.html b/HTMLKitTests/css-tests/72.html new file mode 100644 index 0000000..7b4d261 --- /dev/null +++ b/HTMLKitTests/css-tests/72.html @@ -0,0 +1,11 @@ + +
+
+

This paragraph should have a green background and there should be no red anywhere.

+
+
diff --git a/HTMLKitTests/css-tests/72b.html b/HTMLKitTests/css-tests/72b.html new file mode 100644 index 0000000..c1b2cbb --- /dev/null +++ b/HTMLKitTests/css-tests/72b.html @@ -0,0 +1,11 @@ + +
+
+

This paragraph should have a green background and there should be no red anywhere.

+
+
diff --git a/HTMLKitTests/css-tests/73.html b/HTMLKitTests/css-tests/73.html new file mode 100644 index 0000000..fbd1b61 --- /dev/null +++ b/HTMLKitTests/css-tests/73.html @@ -0,0 +1,103 @@ + +
+
    +
  • First list item
  • +
  • This second list item should have a green background
  • +
  • Third list
  • +
  • This fourth list item should have a green background
  • +
  • Fifth list item
  • +
  • This sixth list item should have a green background
  • +
+
    +
  1. This first list item should have a green background
  2. +
  3. Second list item
  4. +
  5. This third list item should have a green background
  6. +
  7. Fourth list item
  8. +
  9. This fifth list item should have a green background
  10. +
  11. Sixth list item
  12. +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1.11.21.3
2.12.22.3
3.13.23.3
4.14.24.3
Green row : 5.15.25.3
Green row : 6.16.26.3
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1.1green cellgreen cell1.4green cellgreen cell1.7green cell
2.1green cellgreen cell2.4green cellgreen cell2.7green cell
3.1green cellgreen cell3.4green cellgreen cell3.7green cell
+
+
diff --git a/HTMLKitTests/css-tests/74.html b/HTMLKitTests/css-tests/74.html new file mode 100644 index 0000000..11789d9 --- /dev/null +++ b/HTMLKitTests/css-tests/74.html @@ -0,0 +1,103 @@ + +
+
    +
  • This first list item should have a green background
  • +
  • Second list item
  • +
  • This third list item should have a green background
  • +
  • Fourth list item
  • +
  • This fifth list item should have a green background
  • +
  • Sixth list item
  • +
+
    +
  1. First list item
  2. +
  3. This second list item should have a green background
  4. +
  5. Third list item
  6. +
  7. This fourth list item should have a green background
  8. +
  9. Fifth list item
  10. +
  11. This sixth list item should have a green background
  12. +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Green row : 1.11.21.3
Green row : 2.12.22.3
3.13.23.3
4.14.24.3
5.15.25.3
6.16.26.3
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
green cell1.2green cellgreen cell1.5green cellgreen cell1.8
green cell2.2green cellgreen cell2.5green cellgreen cell2.8
green cell3.2green cellgreen cell3.5green cellgreen cell3.8
+
+
diff --git a/HTMLKitTests/css-tests/75.html b/HTMLKitTests/css-tests/75.html new file mode 100644 index 0000000..868e05e --- /dev/null +++ b/HTMLKitTests/css-tests/75.html @@ -0,0 +1,30 @@ + +
+

This paragraph should have green background

+
And this address should be unstyled.
+

This paragraph should also have green background!

+

But this one should be unstyled again.

+
+
First definition term
+
First definition
+
Second definition term that should have green background
+
Second definition that should have green background
+
Third definition term that should have green background
+
Third definition that should have green background
+
Fourth definition term
+
Fourth definition
+
Fifth definition term that should have green background
+
Fifth definition that should have green background
+
Sixth definition term that should have green background
+
Sixth definition that should have green background
+
+
diff --git a/HTMLKitTests/css-tests/76.html b/HTMLKitTests/css-tests/76.html new file mode 100644 index 0000000..5791a6e --- /dev/null +++ b/HTMLKitTests/css-tests/76.html @@ -0,0 +1,30 @@ + +
+

This paragraph should be unstyled.

+
This address should be unstyled.
+

This paragraph should have green background.

+

This paragraph should have green background.

+
+
First definition term that should have green background.
+
First definition that should also have a green background.
+
Second definition term that should have green background.
+
Second definition that should have green background.
+
Third definition term.
+
Third definition.
+
Fourth definition term that should have green background.
+
Fourth definition that should have green background.
+
Fifth definition term that should have green background.
+
Fifth definition that should have green background.
+
Sixth definition term.
+
Sixth definition.
+
+
diff --git a/HTMLKitTests/css-tests/77.html b/HTMLKitTests/css-tests/77.html new file mode 100644 index 0000000..149bf72 --- /dev/null +++ b/HTMLKitTests/css-tests/77.html @@ -0,0 +1,32 @@ + +
+
+ + + + + + + + + + + + + + + + +
1.1green cellgreen cell
2.1green cellgreen cell
3.1green cellgreen cell
+
+

This paragraph should be unstyled.

+
diff --git a/HTMLKitTests/css-tests/78.html b/HTMLKitTests/css-tests/78.html new file mode 100644 index 0000000..0e7cb69 --- /dev/null +++ b/HTMLKitTests/css-tests/78.html @@ -0,0 +1,32 @@ + +
+
+ + + + + + + + + + + + + + + + +
green cellgreen cell1.3
green cellgreen cell2.3
green cellgreen cell3.3
+
+

This paragraph should be unstyled.

+
diff --git a/HTMLKitTests/css-tests/79.html b/HTMLKitTests/css-tests/79.html new file mode 100644 index 0000000..36dbf48 --- /dev/null +++ b/HTMLKitTests/css-tests/79.html @@ -0,0 +1,13 @@ + +
+
This div contains 3 addresses : +
A first address with normal background
+
A second address that should have a green background
+
A third address that should have a green background
+
+
diff --git a/HTMLKitTests/css-tests/7b.html b/HTMLKitTests/css-tests/7b.html new file mode 100644 index 0000000..6e629a6 --- /dev/null +++ b/HTMLKitTests/css-tests/7b.html @@ -0,0 +1,9 @@ + +
+

This line should have a green background.

+
diff --git a/HTMLKitTests/css-tests/8.html b/HTMLKitTests/css-tests/8.html new file mode 100644 index 0000000..741f5b6 --- /dev/null +++ b/HTMLKitTests/css-tests/8.html @@ -0,0 +1,21 @@ + +
+

This paragraph should have green background because its language is "en-gb"

+
+ This address should also + have green background because the language of the inner SPANs id="" is not French. +
+
diff --git a/HTMLKitTests/css-tests/80.html b/HTMLKitTests/css-tests/80.html new file mode 100644 index 0000000..20d0cc8 --- /dev/null +++ b/HTMLKitTests/css-tests/80.html @@ -0,0 +1,14 @@ + +
+
+
A first address that should have a green background
+
A second address that should have a green background
+
A third address with normal background
+ This div should have three addresses above it. +
+
diff --git a/HTMLKitTests/css-tests/81.html b/HTMLKitTests/css-tests/81.html new file mode 100644 index 0000000..9568093 --- /dev/null +++ b/HTMLKitTests/css-tests/81.html @@ -0,0 +1,16 @@ + +
+

This paragraph should have a green background.

+
This div contains only one paragraph. +

This paragraph should be unstyled.

+
+
diff --git a/HTMLKitTests/css-tests/82.html b/HTMLKitTests/css-tests/82.html new file mode 100644 index 0000000..f1149ce --- /dev/null +++ b/HTMLKitTests/css-tests/82.html @@ -0,0 +1,13 @@ + +
+
+

This paragraph should have green background.

+
But this address should be unstyled.
+

This paragraph should have green background.

+
+
diff --git a/HTMLKitTests/css-tests/83.html b/HTMLKitTests/css-tests/83.html new file mode 100644 index 0000000..74f32da --- /dev/null +++ b/HTMLKitTests/css-tests/83.html @@ -0,0 +1,9 @@ + +
+

This paragraph should have a green background

+
diff --git a/HTMLKitTests/css-tests/86.html b/HTMLKitTests/css-tests/86.html new file mode 100644 index 0000000..659e073 --- /dev/null +++ b/HTMLKitTests/css-tests/86.html @@ -0,0 +1,15 @@ + +
+
+
+
+

This text should be green.

+
+
+
+
diff --git a/HTMLKitTests/css-tests/87.html b/HTMLKitTests/css-tests/87.html new file mode 100644 index 0000000..c3be690 --- /dev/null +++ b/HTMLKitTests/css-tests/87.html @@ -0,0 +1,12 @@ + +
+
This text should be unstyled.
+
This text should be unstyled.
+
This text should be unstyled.
+

This text should be green.

+
diff --git a/HTMLKitTests/css-tests/88.html b/HTMLKitTests/css-tests/88.html new file mode 100644 index 0000000..4b3b73e --- /dev/null +++ b/HTMLKitTests/css-tests/88.html @@ -0,0 +1,14 @@ + +
+
This text should be unstyled.
+
+
+

This text should be green.

+
+
+
diff --git a/HTMLKitTests/css-tests/89.html b/HTMLKitTests/css-tests/89.html new file mode 100644 index 0000000..35f9d52 --- /dev/null +++ b/HTMLKitTests/css-tests/89.html @@ -0,0 +1,15 @@ + +
+
+
+
+

This text should be green.

+
+
+
+
diff --git a/HTMLKitTests/css-tests/9.html b/HTMLKitTests/css-tests/9.html new file mode 100644 index 0000000..40204f2 --- /dev/null +++ b/HTMLKitTests/css-tests/9.html @@ -0,0 +1,9 @@ + +
+

This paragraph should have a green background
because its title attribute begins with "foo"

+
diff --git a/HTMLKitTests/css-tests/90.html b/HTMLKitTests/css-tests/90.html new file mode 100644 index 0000000..6344b6b --- /dev/null +++ b/HTMLKitTests/css-tests/90.html @@ -0,0 +1,12 @@ + +
+
This text should be unstyled.
+
This text should be unstyled.
+
This text should be unstyled.
+

This text should be green.

+
From 13b8fe78087e1681a86eb4755cfaac7f71428287 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 28 Nov 2015 21:11:16 +0100 Subject: [PATCH 102/103] Add CSS Selectors Parser implementation --- HTMLKit/CSSSelectorParser.h | 17 ++ HTMLKit/CSSSelectorParser.m | 367 ++++++++++++++++++++++++++++++++++++ 2 files changed, 384 insertions(+) create mode 100644 HTMLKit/CSSSelectorParser.h create mode 100644 HTMLKit/CSSSelectorParser.m diff --git a/HTMLKit/CSSSelectorParser.h b/HTMLKit/CSSSelectorParser.h new file mode 100644 index 0000000..1d55788 --- /dev/null +++ b/HTMLKit/CSSSelectorParser.h @@ -0,0 +1,17 @@ +// +// CSSSelectorParser.h +// HTMLKit +// +// Created by Iska on 02/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import + +@class CSSSelector; + +@interface CSSSelectorParser : NSObject + ++ (CSSSelector *)parseSelector:(NSString *)string error:(NSError **)error; + +@end diff --git a/HTMLKit/CSSSelectorParser.m b/HTMLKit/CSSSelectorParser.m new file mode 100644 index 0000000..c550351 --- /dev/null +++ b/HTMLKit/CSSSelectorParser.m @@ -0,0 +1,367 @@ +// +// CSSSelectorParser.m +// HTMLKit +// +// Created by Iska on 02/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelectorParser.h" +#import "CSSInputStream.h" +#import "CSSCodePoints.h" +#import "CSSSelectors.h" +#import "NSString+HTMLKit.h" +#import "NSCharacterSet+HTMLKit.h" +#import "CSSNthExpressionParser.h" +#import "CSSCompoundSelector.h" +#import "HTMLKitErrorDomain.h" + +@interface CSSSelectorParser () +{ + NSString *_string; + CSSInputStream *_inputStream; + NSUInteger _location; + + NSMutableArray *_selectors; +} +@end + +@implementation CSSSelectorParser + ++ (CSSSelector *)parseSelector:(NSString *)string error:(NSError * __autoreleasing *)error +{ + CSSSelectorParser *parser = [[CSSSelectorParser alloc] initWithString:string]; + CSSSelector *selector = [parser parse:error]; + + return selector; +} + +#pragma mark - Init + +- (instancetype)initWithString:(NSString *)string +{ + self = [super init]; + if (self) { + _string = [self preprocessInput:string]; + _location = 0; + } + return self; +} + +- (NSString *)preprocessInput:(NSString *)string +{ + string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + 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 - Errors + +- (void)emitError:(NSError * __autoreleasing *)error reason:(NSString *)reason location:(NSUInteger)location +{ + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: @"Error parsing selector", + NSLocalizedFailureReasonErrorKey: reason, + CSSSelectorStringKey: _string, + CSSSelectorErrorLocationKey: @(location) + }; + + if(error) { + *error = [NSError errorWithDomain:HTMLKitSelectorErrorDomain code:HTMLKitSelectorParseError userInfo:userInfo]; + } +} + +#pragma mark - Parsing + +- (CSSSelector *)parse:(NSError * __autoreleasing *)error +{ + if (_string.length == 0) { + [self emitError:error reason:@"Empty selector" location:0]; + return nil; + } + + NSArray *allSubSelectors = [_string componentsSeparatedByString:@","]; + NSMutableArray *parsed = [NSMutableArray array]; + + for (NSString *subSelector in allSubSelectors) { + if ([subSelector isEqualToString:@""]) { + [self emitError:error reason:@"Empty selector" location:_location]; + break; + } + + CSSSelector *selector = [self parseSelector:subSelector error:error]; + if (selector == nil) { + break; + } + [parsed addObject:selector]; + + _location += subSelector.length; + } + + if (*error != nil) { + return nil; + } + + if (parsed.count > 1) { + return anyOf(parsed); + } + + return parsed.firstObject; +} + +- (CSSSelector *)parseSelector:(NSString *)selectorString error:(NSError * __autoreleasing *)error +{ + _inputStream = [[CSSInputStream alloc] initWithString:selectorString]; + [_inputStream consumeWhitespace]; + + CSSSelector *result = nil; + + while (YES) { + CSSSelector *selector = [self parseSequenceOfSimpleSelectors:error]; + if (selector == nil) { + break; + } + + result = result ? allOf(@[result, selector]) : selector; + + UTF32Char next = _inputStream.nextInputCharacter; + + if (isCombinator(next)) { + NSString *combinator = [_inputStream consumeCombinator]; + + if ([combinator isEqualToString:@""]) { + result = descendantOfElementSelector(result); + } else if ([combinator isEqualToString:@">"]) { + result = childOfElementSelector(result); + } else if ([combinator isEqualToString:@"+"]) { + result = adjacentSiblingSelector(result); + } else if ([combinator isEqualToString:@"~"]) { + result = generalSiblingSelector(result); + } + } + } + + return result; +} + +- (CSSSelector *)parseSequenceOfSimpleSelectors:(NSError * __autoreleasing *)error +{ + NSMutableArray *selectors = [NSMutableArray array]; + + CSSSelector *typeSelector = [self parseTypeSelector:error]; + if (typeSelector != nil) { + [selectors addObject:typeSelector]; + } + + while (YES) { + UTF32Char next = _inputStream.nextInputCharacter; + if (next == EOF || isCombinator(next)) { + break; + } + + CSSSelector *simpleSelector = [self parseSimpleSelector:error]; + if (simpleSelector == nil) { + return nil; + } + [selectors addObject:simpleSelector]; + } + + if (selectors.count > 1) { + return allOf(selectors); + } + + return selectors.firstObject; +} + +- (CSSSelector *)parseTypeSelector:(NSError * __autoreleasing *)error +{ + NSString *identifier = [_inputStream consumeIdentifier]; + if (identifier != nil) { + return typeSelector(identifier); + } + + if ([_inputStream consumeCharacter:ASTERIX]) { + return universalSelector(); + } + + return nil; +} + +- (CSSSelector *)parseSimpleSelector:(NSError * __autoreleasing *)error +{ + CSSSelector *typeSelector = [self parseTypeSelector:error]; + if (typeSelector != nil) { + return typeSelector; + } + + UTF32Char codePoint = [_inputStream consumeNextInputCharacter]; + switch (codePoint) { + case NUMBER_SIGN: + { + NSString *elementId = [_inputStream consumeIdentifier]; + if (elementId == nil) { + [self emitError:error reason:@"Invalid character" location:_location + _inputStream.currentLocation]; + return nil; + } + return idSelector(elementId); + } + case FULL_STOP: + { + NSString *className = [_inputStream consumeIdentifier]; + if (className == nil) { + [self emitError:error reason:@"Invalid character" location:_location + _inputStream.currentLocation]; + return nil; + } + return classSelector(className); + } + case LEFT_SQUARE_BRACKET: + { + return [self parseAttributeSelector:error]; + } + case COLON: + { + return [self parsePseudoSelector:error]; + } + default: + { + [self emitError:error reason:@"Invalid character" location:_location + _inputStream.currentLocation]; + return nil; + } + } +} + +- (CSSSelector *)parseAttributeSelector:(NSError * __autoreleasing *)error +{ + NSString *attribute = [_inputStream consumeIdentifier]; + if (attribute == nil) { + [self emitError:error reason:@"Invalid character" location:_location + _inputStream.currentLocation + 1]; + return nil; + } + [_inputStream consumeWhitespace]; + + CSSAttributeSelectorType type = CSSAttributeSelectorExists; + + NSString *operator = [_inputStream consumeCharactersInString:@"=~|^$*!"]; + + if ([operator isEqualToString:@"="]) { + type = CSSAttributeSelectorExactMatch; + } else if ([operator isEqualToString:@"~="]) { + type = CSSAttributeSelectorIncludes; + } else if ([operator isEqualToString:@"|="]) { + type = CSSAttributeSelectorHyphen; + } else if ([operator isEqualToString:@"^="]) { + type = CSSAttributeSelectorBegins; + } else if ([operator isEqualToString:@"$="]) { + type = CSSAttributeSelectorEnds; + } else if ([operator isEqualToString:@"*="]) { + type = CSSAttributeSelectorContains; + } else if ([operator isEqualToString:@"!="]) { + type = CSSAttributeSelectorNot; + } + + NSString *value = nil; + [_inputStream consumeWhitespace]; + + UTF32Char next = _inputStream.nextInputCharacter; + if (isQuote(next)) { + UTF32Char quote = [_inputStream consumeNextInputCharacter]; + value = [_inputStream consumeStringWithEndingCodePoint:quote]; + } else { + value = [_inputStream consumeIdentifier]; + } + + [_inputStream consumeWhitespace]; + + // Consume RIGHT_SQUARE_BRACKET + if (![_inputStream consumeCharacter:RIGHT_SQUARE_BRACKET]) { + [self emitError:error reason:@"Expected closing right square bracket ']'" location:_location + _inputStream.currentLocation]; + } + + if (type == CSSAttributeSelectorExists) { + return hasAttributeSelector(attribute); + } + + return attributeSelector(type, attribute, value); +} + +- (CSSSelector *)parsePseudoSelector:(NSError * __autoreleasing *)error +{ + NSString *pseudoClass = [_inputStream consumeIdentifier]; + + if ([pseudoClass hasPrefix:@"nth"]) { + [_inputStream consumeWhitespace]; + if (![_inputStream consumeCharacter:LEFT_PARENTHESIS]) { + [self emitError:error reason:@"Expected opening left parenthesis '('" location:_location + _inputStream.currentLocation]; + } + + NSString *functionExpression = [_inputStream consumeCharactersUpToString:@")"]; + CSSNthExpression expression = [CSSNthExpressionParser parseExpression:functionExpression]; + + [_inputStream consumeWhitespace]; + if (![_inputStream consumeCharacter:RIGHT_PARENTHESIS]) { + [self emitError:error reason:@"Expected closing right parenthesis ')'" location:_location + _inputStream.currentLocation]; + } + + if ([pseudoClass isEqualToString:@"nth-child"]) { + return nthChildSelector(expression); + } else if ([pseudoClass isEqualToString:@"nth-last-child"]) { + return nthLastChildSelector(expression); + } else if ([pseudoClass isEqualToString:@"nth-of-type"]) { + return nthOfTypeSelector(expression); + } else if ([pseudoClass isEqualToString:@"nth-last-of-type"]) { + return nthLastOfTypeSelector(expression); + } + } else if ([pseudoClass isEqualToString:@"not"]) { + [_inputStream consumeWhitespace]; + if (![_inputStream consumeCharacter:LEFT_PARENTHESIS]) { + [self emitError:error reason:@"Expected opening left parenthesis '('" location:_location + _inputStream.currentLocation]; + } + + CSSSelector *subSelector = [self parseSimpleSelector:error]; + [_inputStream consumeWhitespace]; + if (![_inputStream consumeCharacter:RIGHT_PARENTHESIS]) { + [self emitError:error reason:@"Expected closing right parenthesis ')'" location:_location + _inputStream.currentLocation]; + } + + return nay(subSelector); + } else { + if ([pseudoClass isEqualToString:@"even"]) { + return evenSlector(); + } else if ([pseudoClass isEqualToString:@"odd"]) { + return oddSelector(); + } else if ([pseudoClass isEqualToString:@"first-child"]) { + return firstChildSelector(); + } else if ([pseudoClass isEqualToString:@"last-child"]) { + return lastChildSelector(); + } else if ([pseudoClass isEqualToString:@"first-of-type"]) { + return firstOfTypeSelector(); + } else if ([pseudoClass isEqualToString:@"last-of-type"]) { + return lastOfTypeSelector(); + } else if ([pseudoClass isEqualToString:@"only-child"]) { + return onlyChildSelector(); + } else if ([pseudoClass isEqualToString:@"only-of-type"]) { + return onlyOfTypeSelector(); + } else if ([pseudoClass isEqualToString:@"root"]) { + return rootSelector(); + } else if ([pseudoClass isEqualToString:@"empty"]) { + return emptySelector(); + } else if ([pseudoClass isEqualToString:@"link"]) { + return linkSelector(); + } else if ([pseudoClass isEqualToString:@"enabled"]) { + return enabledSelector(); + } else if ([pseudoClass isEqualToString:@"disabled"]) { + return disabledSelector(); + } else if ([pseudoClass isEqualToString:@"checked"]) { + return checkedSelector(); + } + } + NSString *reason = [NSString stringWithFormat:@"Unknown pseudo class: %@", pseudoClass]; + [self emitError:error reason:reason location:_location + _inputStream.currentLocation]; + return nil; +} + +@end From 6b81d6e46547f99dbdeb81fd4077a25107816aa2 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 28 Nov 2015 21:11:48 +0100 Subject: [PATCH 103/103] Add tests for the CSS Selector Parser --- HTMLKit.xcodeproj/project.pbxproj | 8 ++ HTMLKitTests/CSSSelectorParserTests.m | 104 ++++++++++++++++++++++++++ HTMLKitTests/CSSSelectorTest.h | 21 ++++++ HTMLKitTests/CSSSelectorTest.m | 60 +++++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 HTMLKitTests/CSSSelectorParserTests.m create mode 100644 HTMLKitTests/CSSSelectorTest.h create mode 100644 HTMLKitTests/CSSSelectorTest.m diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 7ce55fc..27284ab 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -13,6 +13,8 @@ 620C877F1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */; }; 620EE94A1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; }; 620EE94B1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; }; + 62132E591C01F83200084175 /* CSSSelectorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62132E581C01F83200084175 /* CSSSelectorTest.m */; }; + 62132E5A1C01F83200084175 /* CSSSelectorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62132E581C01F83200084175 /* CSSSelectorTest.m */; }; 62132E5C1C021FF200084175 /* css-tests in Resources */ = {isa = PBXBuildFile; fileRef = 62132E5B1C021FF200084175 /* css-tests */; }; 62132E5D1C021FF200084175 /* css-tests in Resources */ = {isa = PBXBuildFile; fileRef = 62132E5B1C021FF200084175 /* css-tests */; }; 621FBE5A1BDAD68700BC9555 /* CSSSelectorParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE591BDAD68700BC9555 /* CSSSelectorParserTests.m */; }; @@ -241,6 +243,8 @@ 620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSCompoundSelector.m; sourceTree = ""; }; 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPseudoClassSelector.h; sourceTree = ""; }; 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSPseudoClassSelector.m; sourceTree = ""; }; + 62132E571C01F83200084175 /* CSSSelectorTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelectorTest.h; sourceTree = ""; }; + 62132E581C01F83200084175 /* CSSSelectorTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectorTest.m; sourceTree = ""; }; 62132E5B1C021FF200084175 /* css-tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "css-tests"; sourceTree = ""; }; 621FBE591BDAD68700BC9555 /* CSSSelectorParserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectorParserTests.m; sourceTree = ""; }; 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSCombinatorSelectorTests.m; sourceTree = ""; }; @@ -615,6 +619,8 @@ 624B9FB81AE072D500646C4C /* Categories */, 624E1A2D1B1D1C8A00E66AAC /* Structures */, 625A14CB19C7829400AD0C32 /* Supporting Files */, + 62132E571C01F83200084175 /* CSSSelectorTest.h */, + 62132E581C01F83200084175 /* CSSSelectorTest.m */, 621FBE591BDAD68700BC9555 /* CSSSelectorParserTests.m */, 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */, 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */, @@ -970,6 +976,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 62132E5A1C01F83200084175 /* CSSSelectorTest.m in Sources */, 6239755B1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */, 62F658711BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */, 623CAF9E1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */, @@ -1046,6 +1053,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 62132E591C01F83200084175 /* CSSSelectorTest.m in Sources */, 6239755A1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */, 62F658701BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */, 623CAF9D1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */, diff --git a/HTMLKitTests/CSSSelectorParserTests.m b/HTMLKitTests/CSSSelectorParserTests.m new file mode 100644 index 0000000..1966e44 --- /dev/null +++ b/HTMLKitTests/CSSSelectorParserTests.m @@ -0,0 +1,104 @@ +// +// CSSSelectorParserTests.m +// HTMLKit +// +// Created by Iska on 23/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import +#import +#import "CSSSelectorTest.h" +#import "CSSSelectorParser.h" + +@interface CSSSelectorParserTests : XCTestCase +@property (nonatomic, strong) CSSSelectorTest *testCase; +@end + +@implementation CSSSelectorParserTests + ++ (XCTestSuite *)defaultTestSuite +{ + XCTestSuite *suite = [[XCTestSuite alloc] initWithName:NSStringFromClass(self)]; + + NSArray *tests = [CSSSelectorTest loadCSSSelectorTests]; + for (CSSSelectorTest *test in tests) { + [self addSelectorTest:test toTestSuite:suite]; + } + + return suite; +} + ++ (void)addSelectorTest:(CSSSelectorTest *)selectorTest toTestSuite:(XCTestSuite *)suite +{ + NSArray *allInvocations = [self testInvocations]; + for (NSInvocation *invocation in allInvocations) { + XCTestCase *testCase = [[self alloc] initWithInvocation:invocation + testCase:selectorTest]; + [suite addTest:testCase]; + } +} + +#pragma mark - Instance + +- (instancetype)initWithInvocation:(NSInvocation *)invocation + testCase:(CSSSelectorTest *)testCase +{ + self = [super initWithInvocation:invocation]; + if (self) { + _testCase = testCase; + } + return self; +} + +- (NSString *)name +{ + NSInvocation *invocation = [self invocation]; + NSString *title = self.testCase.testName.stringByDeletingPathExtension; + return [NSString stringWithFormat:@"-[%@ %@_%@]", self.class, NSStringFromSelector(invocation.selector), title]; +} + +- (NSString *)description +{ + return self.name; +} + +#pragma mark - Tests + +- (void)testParser +{ + for (NSDictionary *testDescription in self.testCase.selectors) { + NSString *selectorString = testDescription[@"selector"]; + NSArray *expectedMatches = testDescription[@"match"]; + NSNumber *expectedError = testDescription[@"error"]; + HTMLElement *testDOM = self.testCase.testDOM; + + NSError *error = nil; + CSSSelector *parsedSelector = [CSSSelectorParser parseSelector:selectorString error:&error]; + + if (expectedError) { + XCTAssertNotNil(error); + XCTAssertNil(parsedSelector); + + NSUInteger errorLocation = [error.userInfo[CSSSelectorErrorLocationKey] unsignedIntegerValue]; + XCTAssertEqual(errorLocation, expectedError.unsignedIntegerValue); + } else { + XCTAssertNil(error); + XCTAssertNotNil(parsedSelector); + + NSArray *matchedElements = [testDOM elementsMatchingSelector:parsedSelector]; + NSArray *matchedIds = [matchedElements valueForKeyPath:@"attributes.id"]; + + NSString *message = [NSString stringWithFormat:@"CSS test: \'%@\'\nInput:\n%@\nDOM:\n%@\nExpected:\n%@\nActual:\n%@\n", + self.name, + selectorString, + testDOM.outerHTML, + expectedMatches, + matchedIds]; + + XCTAssertEqualObjects(matchedIds, expectedMatches, @"IDs mismatch:\n%@", message); + } + } +} + +@end diff --git a/HTMLKitTests/CSSSelectorTest.h b/HTMLKitTests/CSSSelectorTest.h new file mode 100644 index 0000000..6bb9821 --- /dev/null +++ b/HTMLKitTests/CSSSelectorTest.h @@ -0,0 +1,21 @@ +// +// CSSSelectorTest.h +// HTMLKit +// +// Created by Iska on 22/11/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import + +@class HTMLElement; + +@interface CSSSelectorTest : NSObject + +@property (nonatomic, copy) NSString *testName; +@property (nonatomic, strong) NSArray *selectors; +@property (nonatomic, strong) HTMLElement *testDOM; + ++ (NSArray *)loadCSSSelectorTests; + +@end diff --git a/HTMLKitTests/CSSSelectorTest.m b/HTMLKitTests/CSSSelectorTest.m new file mode 100644 index 0000000..a85191e --- /dev/null +++ b/HTMLKitTests/CSSSelectorTest.m @@ -0,0 +1,60 @@ +// +// CSSSelectorTest.m +// HTMLKit +// +// Created by Iska on 22/11/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelectorTest.h" +#import "HTMLParser.h" +#import "HTMLDocument.h" +#import "HTMLElement.h" +#import "CSSSelectors.h" + +static NSString * const CSSTests = @"css-tests"; + +@implementation CSSSelectorTest + ++ (NSArray *)loadCSSSelectorTests +{ + NSString *path = [[NSBundle bundleForClass:self.class] resourcePath]; + path = [path stringByAppendingPathComponent:CSSTests]; + + NSMutableArray *tests = [NSMutableArray array]; + NSArray *testFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil]; + + for (NSString *testFile in testFiles) { + if (![testFile.pathExtension isEqualToString:@"html"]) { + continue; + } + + NSString *testFilePath = [path stringByAppendingPathComponent:testFile]; + CSSSelectorTest *test = [CSSSelectorTest testWithFileAtPath:testFilePath]; + [tests addObject:test]; + } + + return tests; +} + ++ (instancetype)testWithFileAtPath:(NSString *)filePath +{ + NSString *testName = filePath.lastPathComponent.stringByDeletingPathExtension; + + NSString *html = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; + + HTMLDocument *document = [HTMLDocument documentWithString:html]; + + HTMLElement *domElement = [document firstElementMatchingSelector:idSelector(@"testDOM")]; + HTMLElement *scriptElement = [document firstElementMatchingSelector:idSelector(@"selectors")]; + NSData *data = [scriptElement.textContent dataUsingEncoding:NSUTF8StringEncoding]; + NSArray *selectors = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; + + CSSSelectorTest *instance = [CSSSelectorTest new]; + instance.testName = testName; + instance.selectors = selectors; + instance.testDOM = domElement; + return instance; +} + +@end