csspool 3.0.2 → 4.0.0.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +4 -4
- data/Manifest.txt +13 -0
- data/README.rdoc +1 -1
- data/lib/csspool/css/document.rb +6 -0
- data/lib/csspool/css/document_handler.rb +41 -7
- data/lib/csspool/css/document_query.rb +14 -0
- data/lib/csspool/css/import_rule.rb +8 -4
- data/lib/csspool/css/keyframes_block.rb +14 -0
- data/lib/csspool/css/keyframes_rule.rb +14 -0
- data/lib/csspool/css/media.rb +5 -3
- data/lib/csspool/css/namespace_rule.rb +13 -0
- data/lib/csspool/css/parser.rb +970 -425
- data/lib/csspool/css/parser.y +227 -30
- data/lib/csspool/css/tokenizer.rb +31 -7
- data/lib/csspool/css/tokenizer.rex +36 -7
- data/lib/csspool/css.rb +4 -0
- data/lib/csspool/selector.rb +5 -1
- data/lib/csspool/selectors/attribute.rb +6 -1
- data/lib/csspool/selectors/pseudo.rb +17 -0
- data/lib/csspool/selectors/pseudo_element.rb +13 -0
- data/lib/csspool/selectors/simple.rb +0 -4
- data/lib/csspool/selectors/type.rb +7 -0
- data/lib/csspool/selectors/universal.rb +7 -0
- data/lib/csspool/selectors.rb +1 -1
- data/lib/csspool/terms/math.rb +18 -0
- data/lib/csspool/terms.rb +1 -0
- data/lib/csspool/visitors/children.rb +1 -1
- data/lib/csspool/visitors/comparable.rb +8 -2
- data/lib/csspool/visitors/iterator.rb +1 -1
- data/lib/csspool/visitors/to_css.rb +41 -21
- data/lib/csspool.rb +1 -1
- data/test/_local_helper.rb +2 -0
- data/test/css/test_document_query.rb +76 -0
- data/test/css/test_import_rule.rb +1 -1
- data/test/css/test_keyframes_rule.rb +93 -0
- data/test/css/test_namespace_rule.rb +54 -0
- data/test/css/test_parser.rb +46 -1
- data/test/css/test_tokenizer.rb +0 -45
- data/test/helper.rb +6 -1
- data/test/sac/test_parser.rb +16 -3
- data/test/test_declaration.rb +39 -0
- data/test/test_parser.rb +26 -13
- data/test/test_selector.rb +205 -5
- data/test/test_term.rb +23 -0
- data/test/visitors/test_to_css.rb +34 -23
- metadata +136 -118
    
        data/lib/csspool/css/parser.y
    CHANGED
    
    | @@ -3,7 +3,15 @@ class CSSPool::CSS::Parser | |
| 3 3 | 
             
            token CHARSET_SYM IMPORT_SYM STRING SEMI IDENT S COMMA LBRACE RBRACE STAR HASH
         | 
| 4 4 | 
             
            token LSQUARE RSQUARE EQUAL INCLUDES DASHMATCH RPAREN FUNCTION GREATER PLUS
         | 
| 5 5 | 
             
            token SLASH NUMBER MINUS LENGTH PERCENTAGE EMS EXS ANGLE TIME FREQ URI
         | 
| 6 | 
            +
            token IMPORTANT_SYM MEDIA_SYM NTH_PSEUDO_CLASS
         | 
| 7 | 
            +
            token IMPORTANT_SYM MEDIA_SYM DOCUMENT_QUERY_SYM FUNCTION_NO_QUOTE
         | 
| 6 8 | 
             
            token IMPORTANT_SYM MEDIA_SYM
         | 
| 9 | 
            +
            token NAMESPACE_SYM TILDE
         | 
| 10 | 
            +
            token NAMESPACE_SYM PREFIXMATCH SUFFIXMATCH SUBSTRINGMATCH
         | 
| 11 | 
            +
            token NAMESPACE_SYM NOT_PSEUDO_CLASS
         | 
| 12 | 
            +
            token NAMESPACE_SYM KEYFRAMES_SYM
         | 
| 13 | 
            +
            token NAMESPACE_SYM MATCHES_PSEUDO_CLASS
         | 
| 14 | 
            +
            token NAMESPACE_SYM MATH
         | 
| 7 15 |  | 
| 8 16 | 
             
            rule
         | 
| 9 17 | 
             
              document
         | 
| @@ -14,8 +22,10 @@ rule | |
| 14 22 | 
             
              stylesheet
         | 
| 15 23 | 
             
                : charset stylesheet
         | 
| 16 24 | 
             
                | import stylesheet
         | 
| 25 | 
            +
                | namespace stylesheet
         | 
| 17 26 | 
             
                | charset
         | 
| 18 27 | 
             
                | import
         | 
| 28 | 
            +
                | namespace
         | 
| 19 29 | 
             
                | body
         | 
| 20 30 | 
             
                ;
         | 
| 21 31 | 
             
              charset
         | 
| @@ -34,6 +44,14 @@ rule | |
| 34 44 | 
             
                | STRING { result = Terms::String.new interpret_string val.first }
         | 
| 35 45 | 
             
                | URI { result = Terms::URI.new interpret_uri val.first }
         | 
| 36 46 | 
             
                ;
         | 
| 47 | 
            +
              namespace
         | 
| 48 | 
            +
                : NAMESPACE_SYM ident import_location SEMI {
         | 
| 49 | 
            +
                    @handler.namespace val[1], val[2]
         | 
| 50 | 
            +
                  }
         | 
| 51 | 
            +
                | NAMESPACE_SYM import_location SEMI {
         | 
| 52 | 
            +
                    @handler.namespace nil, val[1]
         | 
| 53 | 
            +
                  }
         | 
| 54 | 
            +
                ;
         | 
| 37 55 | 
             
              medium
         | 
| 38 56 | 
             
                : medium COMMA IDENT {
         | 
| 39 57 | 
             
                    result = [val.first, Terms::Ident.new(interpret_identifier val.last)]
         | 
| @@ -44,9 +62,15 @@ rule | |
| 44 62 | 
             
                ;
         | 
| 45 63 | 
             
              body
         | 
| 46 64 | 
             
                : ruleset body
         | 
| 47 | 
            -
                |  | 
| 65 | 
            +
                | conditional_rule body
         | 
| 66 | 
            +
                | keyframes_rule body
         | 
| 48 67 | 
             
                | ruleset
         | 
| 49 | 
            -
                |  | 
| 68 | 
            +
                | conditional_rule
         | 
| 69 | 
            +
                | keyframes_rule
         | 
| 70 | 
            +
                ;
         | 
| 71 | 
            +
              conditional_rule
         | 
| 72 | 
            +
                : media
         | 
| 73 | 
            +
                | document_query
         | 
| 50 74 | 
             
                ;
         | 
| 51 75 | 
             
              media
         | 
| 52 76 | 
             
                : start_media body RBRACE { @handler.end_media val.first }
         | 
| @@ -58,6 +82,60 @@ rule | |
| 58 82 | 
             
                  }
         | 
| 59 83 | 
             
                | MEDIA_SYM LBRACE { result = [] }
         | 
| 60 84 | 
             
                ;
         | 
| 85 | 
            +
              document_query
         | 
| 86 | 
            +
                : start_document_query body RBRACE { @handler.end_document_query }
         | 
| 87 | 
            +
                | start_document_query RBRACE { @handler.end_document_query }
         | 
| 88 | 
            +
                ;
         | 
| 89 | 
            +
              start_document_query
         | 
| 90 | 
            +
                : DOCUMENT_QUERY_SYM url_match_fns LBRACE {
         | 
| 91 | 
            +
                    @handler.start_document_query val[1]
         | 
| 92 | 
            +
                  }
         | 
| 93 | 
            +
                ;
         | 
| 94 | 
            +
              url_match_fns
         | 
| 95 | 
            +
                : url_match_fn COMMA url_match_fns {
         | 
| 96 | 
            +
                    result = [val[0], val[2]].flatten
         | 
| 97 | 
            +
                  }
         | 
| 98 | 
            +
                | url_match_fn {
         | 
| 99 | 
            +
                    result = val
         | 
| 100 | 
            +
                  }
         | 
| 101 | 
            +
                ;
         | 
| 102 | 
            +
              url_match_fn
         | 
| 103 | 
            +
                : function_no_quote
         | 
| 104 | 
            +
                | function
         | 
| 105 | 
            +
                | uri
         | 
| 106 | 
            +
                ;
         | 
| 107 | 
            +
              keyframes_rule
         | 
| 108 | 
            +
                : start_keyframes_rule keyframes_blocks RBRACE
         | 
| 109 | 
            +
                | start_keyframes_rule RBRACE
         | 
| 110 | 
            +
                ;
         | 
| 111 | 
            +
              start_keyframes_rule
         | 
| 112 | 
            +
                : KEYFRAMES_SYM IDENT LBRACE {
         | 
| 113 | 
            +
                    @handler.start_keyframes_rule val[1]
         | 
| 114 | 
            +
                  }
         | 
| 115 | 
            +
                ;
         | 
| 116 | 
            +
              keyframes_blocks
         | 
| 117 | 
            +
                : keyframes_block keyframes_blocks
         | 
| 118 | 
            +
                | keyframes_block
         | 
| 119 | 
            +
                ;
         | 
| 120 | 
            +
              keyframes_block
         | 
| 121 | 
            +
                : start_keyframes_block declarations RBRACE { @handler.end_keyframes_block }
         | 
| 122 | 
            +
                | start_keyframes_block RBRACE { @handler.end_keyframes_block }
         | 
| 123 | 
            +
                ;
         | 
| 124 | 
            +
              start_keyframes_block
         | 
| 125 | 
            +
                : keyframes_selectors LBRACE {
         | 
| 126 | 
            +
                    @handler.start_keyframes_block val[0]
         | 
| 127 | 
            +
                  }
         | 
| 128 | 
            +
                ;
         | 
| 129 | 
            +
              keyframes_selectors
         | 
| 130 | 
            +
                | keyframes_selector COMMA keyframes_selectors {
         | 
| 131 | 
            +
                     result = val[0] + ', ' + val[2]
         | 
| 132 | 
            +
                  }
         | 
| 133 | 
            +
                | keyframes_selector
         | 
| 134 | 
            +
                ;
         | 
| 135 | 
            +
              keyframes_selector
         | 
| 136 | 
            +
                : IDENT
         | 
| 137 | 
            +
                | PERCENTAGE { result = val[0].strip }
         | 
| 138 | 
            +
                ;
         | 
| 61 139 | 
             
              ruleset
         | 
| 62 140 | 
             
                : start_selector declarations RBRACE {
         | 
| 63 141 | 
             
                    @handler.end_selector val.first
         | 
| @@ -97,6 +175,7 @@ rule | |
| 97 175 | 
             
                : S       { result = :s }
         | 
| 98 176 | 
             
                | GREATER { result = :> }
         | 
| 99 177 | 
             
                | PLUS    { result = :+ }
         | 
| 178 | 
            +
                | TILDE   { result = :~ }
         | 
| 100 179 | 
             
                ;
         | 
| 101 180 | 
             
              simple_selector
         | 
| 102 181 | 
             
                : element_name hcap {
         | 
| @@ -112,9 +191,22 @@ rule | |
| 112 191 | 
             
                    result = [ss]
         | 
| 113 192 | 
             
                  }
         | 
| 114 193 | 
             
                ;
         | 
| 194 | 
            +
              simple_selectors
         | 
| 195 | 
            +
                : simple_selector COMMA simple_selectors { result = [val[0], val[2]].flatten }
         | 
| 196 | 
            +
                | simple_selector
         | 
| 197 | 
            +
                ;
         | 
| 198 | 
            +
              ident_with_namespace
         | 
| 199 | 
            +
                : IDENT { result = [interpret_identifier(val[0]), nil] }
         | 
| 200 | 
            +
                | IDENT '|' IDENT { result = [interpret_identifier(val[2]), interpret_identifier(val[0])] }
         | 
| 201 | 
            +
                | '|' IDENT { result = [interpret_identifier(val[1]), nil] }
         | 
| 202 | 
            +
                | STAR '|' IDENT { result = [interpret_identifier(val[2]), '*'] }
         | 
| 203 | 
            +
                ;
         | 
| 115 204 | 
             
              element_name
         | 
| 116 | 
            -
                :  | 
| 117 | 
            -
                | STAR | 
| 205 | 
            +
                : ident_with_namespace { result = Selectors::Type.new val.first[0], nil, val.first[1] }
         | 
| 206 | 
            +
                | STAR { result = Selectors::Universal.new val.first }
         | 
| 207 | 
            +
                | '|' STAR { result = Selectors::Universal.new val[1] }
         | 
| 208 | 
            +
                | STAR '|' STAR { result = Selectors::Universal.new val[2], nil, val[0] }
         | 
| 209 | 
            +
                | IDENT '|' STAR { result = Selectors::Universal.new val[2], nil, interpret_identifier(val[0]) }
         | 
| 118 210 | 
             
                ;
         | 
| 119 211 | 
             
              hcap
         | 
| 120 212 | 
             
                : hash        { result = val }
         | 
| @@ -136,60 +228,118 @@ rule | |
| 136 228 | 
             
                  }
         | 
| 137 229 | 
             
                ;
         | 
| 138 230 | 
             
              attrib
         | 
| 139 | 
            -
                : LSQUARE  | 
| 231 | 
            +
                : LSQUARE ident_with_namespace EQUAL IDENT RSQUARE {
         | 
| 140 232 | 
             
                    result = Selectors::Attribute.new(
         | 
| 141 | 
            -
                       | 
| 233 | 
            +
                      val[1][0],
         | 
| 142 234 | 
             
                      interpret_identifier(val[3]),
         | 
| 143 | 
            -
                      Selectors::Attribute::EQUALS
         | 
| 235 | 
            +
                      Selectors::Attribute::EQUALS,
         | 
| 236 | 
            +
                      val[1][1]
         | 
| 144 237 | 
             
                    )
         | 
| 145 238 | 
             
                  }
         | 
| 146 | 
            -
                | LSQUARE  | 
| 239 | 
            +
                | LSQUARE ident_with_namespace EQUAL STRING RSQUARE {
         | 
| 147 240 | 
             
                    result = Selectors::Attribute.new(
         | 
| 148 | 
            -
                       | 
| 241 | 
            +
                      val[1][0],
         | 
| 149 242 | 
             
                      interpret_string(val[3]),
         | 
| 150 | 
            -
                      Selectors::Attribute::EQUALS
         | 
| 243 | 
            +
                      Selectors::Attribute::EQUALS,
         | 
| 244 | 
            +
                      val[1][1]
         | 
| 151 245 | 
             
                    )
         | 
| 152 246 | 
             
                  }
         | 
| 153 | 
            -
                | LSQUARE  | 
| 247 | 
            +
                | LSQUARE ident_with_namespace INCLUDES STRING RSQUARE {
         | 
| 154 248 | 
             
                    result = Selectors::Attribute.new(
         | 
| 155 | 
            -
                       | 
| 249 | 
            +
                      val[1][0],
         | 
| 156 250 | 
             
                      interpret_string(val[3]),
         | 
| 157 | 
            -
                      Selectors::Attribute::INCLUDES
         | 
| 251 | 
            +
                      Selectors::Attribute::INCLUDES,
         | 
| 252 | 
            +
                      val[1][1]
         | 
| 158 253 | 
             
                    )
         | 
| 159 254 | 
             
                  }
         | 
| 160 | 
            -
                | LSQUARE  | 
| 255 | 
            +
                | LSQUARE ident_with_namespace INCLUDES IDENT RSQUARE {
         | 
| 161 256 | 
             
                    result = Selectors::Attribute.new(
         | 
| 162 | 
            -
                       | 
| 257 | 
            +
                      val[1][0],
         | 
| 163 258 | 
             
                      interpret_identifier(val[3]),
         | 
| 164 | 
            -
                      Selectors::Attribute::INCLUDES
         | 
| 259 | 
            +
                      Selectors::Attribute::INCLUDES,
         | 
| 260 | 
            +
                      val[1][1]
         | 
| 165 261 | 
             
                    )
         | 
| 166 262 | 
             
                  }
         | 
| 167 | 
            -
                | LSQUARE  | 
| 263 | 
            +
                | LSQUARE ident_with_namespace DASHMATCH IDENT RSQUARE {
         | 
| 168 264 | 
             
                    result = Selectors::Attribute.new(
         | 
| 169 | 
            -
                       | 
| 265 | 
            +
                      val[1][0],
         | 
| 170 266 | 
             
                      interpret_identifier(val[3]),
         | 
| 171 | 
            -
                      Selectors::Attribute::DASHMATCH
         | 
| 267 | 
            +
                      Selectors::Attribute::DASHMATCH,
         | 
| 268 | 
            +
                      val[1][1]
         | 
| 172 269 | 
             
                    )
         | 
| 173 270 | 
             
                  }
         | 
| 174 | 
            -
                | LSQUARE  | 
| 271 | 
            +
                | LSQUARE ident_with_namespace DASHMATCH STRING RSQUARE {
         | 
| 175 272 | 
             
                    result = Selectors::Attribute.new(
         | 
| 176 | 
            -
                       | 
| 273 | 
            +
                      val[1][0],
         | 
| 177 274 | 
             
                      interpret_string(val[3]),
         | 
| 178 | 
            -
                      Selectors::Attribute::DASHMATCH
         | 
| 275 | 
            +
                      Selectors::Attribute::DASHMATCH,
         | 
| 276 | 
            +
                      val[1][1]
         | 
| 179 277 | 
             
                    )
         | 
| 180 278 | 
             
                  }
         | 
| 181 | 
            -
                | LSQUARE IDENT RSQUARE {
         | 
| 279 | 
            +
                | LSQUARE ident_with_namespace PREFIXMATCH IDENT RSQUARE {
         | 
| 182 280 | 
             
                    result = Selectors::Attribute.new(
         | 
| 183 | 
            -
                       | 
| 281 | 
            +
                      val[1][0],
         | 
| 282 | 
            +
                      interpret_identifier(val[3]),
         | 
| 283 | 
            +
                      Selectors::Attribute::PREFIXMATCH,
         | 
| 284 | 
            +
                      val[1][1]
         | 
| 285 | 
            +
                    )
         | 
| 286 | 
            +
                  }
         | 
| 287 | 
            +
                | LSQUARE ident_with_namespace PREFIXMATCH STRING RSQUARE {
         | 
| 288 | 
            +
                    result = Selectors::Attribute.new(
         | 
| 289 | 
            +
                      val[1][0],
         | 
| 290 | 
            +
                      interpret_string(val[3]),
         | 
| 291 | 
            +
                      Selectors::Attribute::PREFIXMATCH,
         | 
| 292 | 
            +
                      val[1][1]
         | 
| 293 | 
            +
                    )
         | 
| 294 | 
            +
                  }
         | 
| 295 | 
            +
                | LSQUARE ident_with_namespace SUFFIXMATCH IDENT RSQUARE {
         | 
| 296 | 
            +
                    result = Selectors::Attribute.new(
         | 
| 297 | 
            +
                      val[1][0],
         | 
| 298 | 
            +
                      interpret_identifier(val[3]),
         | 
| 299 | 
            +
                      Selectors::Attribute::SUFFIXMATCH,
         | 
| 300 | 
            +
                      val[1][1]
         | 
| 301 | 
            +
                    )
         | 
| 302 | 
            +
                  }
         | 
| 303 | 
            +
                | LSQUARE ident_with_namespace SUFFIXMATCH STRING RSQUARE {
         | 
| 304 | 
            +
                    result = Selectors::Attribute.new(
         | 
| 305 | 
            +
                      val[1][0],
         | 
| 306 | 
            +
                      interpret_string(val[3]),
         | 
| 307 | 
            +
                      Selectors::Attribute::SUFFIXMATCH,
         | 
| 308 | 
            +
                      val[1][1]
         | 
| 309 | 
            +
                    )
         | 
| 310 | 
            +
                  }
         | 
| 311 | 
            +
                | LSQUARE ident_with_namespace SUBSTRINGMATCH IDENT RSQUARE {
         | 
| 312 | 
            +
                    result = Selectors::Attribute.new(
         | 
| 313 | 
            +
                      val[1][0],
         | 
| 314 | 
            +
                      interpret_identifier(val[3]),
         | 
| 315 | 
            +
                      Selectors::Attribute::SUBSTRINGMATCH,
         | 
| 316 | 
            +
                      val[1][1]
         | 
| 317 | 
            +
                    )
         | 
| 318 | 
            +
                  }
         | 
| 319 | 
            +
                | LSQUARE ident_with_namespace SUBSTRINGMATCH STRING RSQUARE {
         | 
| 320 | 
            +
                    result = Selectors::Attribute.new(
         | 
| 321 | 
            +
                      val[1][0],
         | 
| 322 | 
            +
                      interpret_string(val[3]),
         | 
| 323 | 
            +
                      Selectors::Attribute::SUBSTRINGMATCH,
         | 
| 324 | 
            +
                      val[1][1]
         | 
| 325 | 
            +
                    )
         | 
| 326 | 
            +
                  }
         | 
| 327 | 
            +
                | LSQUARE ident_with_namespace RSQUARE {
         | 
| 328 | 
            +
                    result = Selectors::Attribute.new(
         | 
| 329 | 
            +
                      val[1][0],
         | 
| 184 330 | 
             
                      nil,
         | 
| 185 | 
            -
                      Selectors::Attribute::SET
         | 
| 331 | 
            +
                      Selectors::Attribute::SET,
         | 
| 332 | 
            +
                      val[1][1]
         | 
| 186 333 | 
             
                    )
         | 
| 187 334 | 
             
                  }
         | 
| 188 335 | 
             
                ;
         | 
| 189 336 | 
             
              pseudo
         | 
| 190 337 | 
             
                : ':' IDENT {
         | 
| 191 | 
            -
                    result = Selectors:: | 
| 192 | 
            -
             | 
| 338 | 
            +
                    result = Selectors::pseudo interpret_identifier(val[1])
         | 
| 339 | 
            +
                  }
         | 
| 340 | 
            +
                | ':' ':' IDENT {
         | 
| 341 | 
            +
                    result = Selectors::PseudoElement.new(
         | 
| 342 | 
            +
                      interpret_identifier(val[2])
         | 
| 193 343 | 
             
                    )
         | 
| 194 344 | 
             
                  }
         | 
| 195 345 | 
             
                | ':' FUNCTION RPAREN {
         | 
| @@ -204,11 +354,36 @@ rule | |
| 204 354 | 
             
                      interpret_identifier(val[2])
         | 
| 205 355 | 
             
                    )
         | 
| 206 356 | 
             
                  }
         | 
| 357 | 
            +
                | ':' NOT_PSEUDO_CLASS simple_selector RPAREN {
         | 
| 358 | 
            +
                    result = Selectors::PseudoClass.new(
         | 
| 359 | 
            +
                      'not',
         | 
| 360 | 
            +
                      val[2].first.to_s
         | 
| 361 | 
            +
                    )
         | 
| 362 | 
            +
                  }
         | 
| 363 | 
            +
                | ':' NTH_PSEUDO_CLASS {
         | 
| 364 | 
            +
                    result = Selectors::PseudoClass.new(
         | 
| 365 | 
            +
                      interpret_identifier(val[1].sub(/\(.*/, '')),
         | 
| 366 | 
            +
                      interpret_identifier(val[1].sub(/.*\(/, '').sub(/\).*/, ''))
         | 
| 367 | 
            +
                    )
         | 
| 368 | 
            +
                  }
         | 
| 369 | 
            +
                | ':' MATCHES_PSEUDO_CLASS simple_selectors RPAREN {
         | 
| 370 | 
            +
                    result = Selectors::PseudoClass.new(
         | 
| 371 | 
            +
                      val[1].split('(').first.strip,
         | 
| 372 | 
            +
                      val[2].join(', ')
         | 
| 373 | 
            +
                    )
         | 
| 374 | 
            +
                  }
         | 
| 375 | 
            +
                ;
         | 
| 376 | 
            +
              # declarations can be separated by one *or more* semicolons. semi-colons at the start or end of a ruleset are also allowed
         | 
| 377 | 
            +
              one_or_more_semis
         | 
| 378 | 
            +
                : SEMI
         | 
| 379 | 
            +
                | SEMI one_or_more_semis
         | 
| 207 380 | 
             
                ;
         | 
| 208 381 | 
             
              declarations
         | 
| 209 | 
            -
                : declaration  | 
| 210 | 
            -
                |  | 
| 382 | 
            +
                : declaration one_or_more_semis declarations
         | 
| 383 | 
            +
                | one_or_more_semis declarations
         | 
| 384 | 
            +
                | declaration one_or_more_semis
         | 
| 211 385 | 
             
                | declaration
         | 
| 386 | 
            +
                | one_or_more_semis
         | 
| 212 387 | 
             
                ;
         | 
| 213 388 | 
             
              declaration
         | 
| 214 389 | 
             
                : property ':' expr prio
         | 
| @@ -247,6 +422,7 @@ rule | |
| 247 422 | 
             
                | string
         | 
| 248 423 | 
             
                | uri
         | 
| 249 424 | 
             
                | hexcolor
         | 
| 425 | 
            +
                | math
         | 
| 250 426 | 
             
                | function
         | 
| 251 427 | 
             
                ;
         | 
| 252 428 | 
             
              function
         | 
| @@ -260,6 +436,22 @@ rule | |
| 260 436 | 
             
                    end
         | 
| 261 437 | 
             
                  }
         | 
| 262 438 | 
             
                ;
         | 
| 439 | 
            +
              function_no_quote
         | 
| 440 | 
            +
                : function_no_quote S { result = val.first }
         | 
| 441 | 
            +
                | FUNCTION_NO_QUOTE {
         | 
| 442 | 
            +
                    parts = val.first.split('(')
         | 
| 443 | 
            +
                    name = interpret_identifier parts.first
         | 
| 444 | 
            +
                    result = Terms::Function.new(name, [Terms::String.new(interpret_string_no_quote(parts.last))])
         | 
| 445 | 
            +
                  }
         | 
| 446 | 
            +
                ;
         | 
| 447 | 
            +
              math
         | 
| 448 | 
            +
                : MATH {
         | 
| 449 | 
            +
                    parts = val.first.split('(', 2)
         | 
| 450 | 
            +
                    name = parts[0].strip
         | 
| 451 | 
            +
                    expression = parts[1][0..parts[1].rindex(')')-1].strip
         | 
| 452 | 
            +
                    result = Terms::Math.new(name, expression)
         | 
| 453 | 
            +
                  }
         | 
| 454 | 
            +
                ;
         | 
| 263 455 | 
             
              hexcolor
         | 
| 264 456 | 
             
                : hexcolor S { result = val.first }
         | 
| 265 457 | 
             
                | HASH { result = Terms::Hash.new val.first.sub(/^#/, '') }
         | 
| @@ -267,6 +459,7 @@ rule | |
| 267 459 | 
             
              uri
         | 
| 268 460 | 
             
                : uri S { result = val.first }
         | 
| 269 461 | 
             
                | URI { result = Terms::URI.new interpret_uri val.first }
         | 
| 462 | 
            +
                ;
         | 
| 270 463 | 
             
              string
         | 
| 271 464 | 
             
                : string S { result = val.first }
         | 
| 272 465 | 
             
                | STRING { result = Terms::String.new interpret_string val.first }
         | 
| @@ -326,7 +519,11 @@ def interpret_identifier s | |
| 326 519 | 
             
            end
         | 
| 327 520 |  | 
| 328 521 | 
             
            def interpret_uri s
         | 
| 329 | 
            -
              interpret_escapes s.match(/^url\((.*)\)$/ | 
| 522 | 
            +
              interpret_escapes s.match(/^url\((.*)\)$/mui)[1].strip.match(/^(['"]?)((?:\\.|.)*)\1$/mu)[2]
         | 
| 523 | 
            +
            end
         | 
| 524 | 
            +
             | 
| 525 | 
            +
            def interpret_string_no_quote s
         | 
| 526 | 
            +
              interpret_escapes s.match(/^(.*)\)$/mu)[1].strip.match(/^(['"]?)((?:\\.|.)*)\1$/mu)[2]
         | 
| 330 527 | 
             
            end
         | 
| 331 528 |  | 
| 332 529 | 
             
            def interpret_string s
         | 
| @@ -58,7 +58,7 @@ class Tokenizer < Parser | |
| 58 58 | 
             
                token = case @state
         | 
| 59 59 | 
             
                when nil
         | 
| 60 60 | 
             
                  case
         | 
| 61 | 
            -
                  when (text = @ss.scan(/url\([\s]*("([^\n\r\f\\"] | 
| 61 | 
            +
                  when (text = @ss.scan(/url\([\s]*("([^\n\r\f\\"]|\\(\n|\r\n|\r|\f)|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*"|'([^\n\r\f\\']|\\(\n|\r\n|\r|\f)|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*')[\s]*\)/i))
         | 
| 62 62 | 
             
                     action { [:URI, st(text)] }
         | 
| 63 63 |  | 
| 64 64 | 
             
                  when (text = @ss.scan(/url\([\s]*([!#\$%&*-~]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*[\s]*\)/i))
         | 
| @@ -70,6 +70,24 @@ class Tokenizer < Parser | |
| 70 70 | 
             
                  when (text = @ss.scan(/[\s]*\/\*(.|[\s]*)*?\*\/[\s]*/i))
         | 
| 71 71 | 
             
                     action { next_token }
         | 
| 72 72 |  | 
| 73 | 
            +
                  when (text = @ss.scan(/not\(\s*/i))
         | 
| 74 | 
            +
                     action { [:NOT_PSEUDO_CLASS, st(text)] }
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  when (text = @ss.scan(/(nth\-child|nth\-last\-child|nth\-of\-type|nth\-last\-of\-type)\([\s]*([\+\-]?[0-9]*n([\s]*[\+\-][\s]*[0-9]+)?|[\+\-]?[0-9]+|odd|even)[\s]*\)/i))
         | 
| 77 | 
            +
                     action { [:NTH_PSEUDO_CLASS, st(text)] }
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                  when (text = @ss.scan(/(\-[A-Za-z]+\-)?(matches|any)\(\s*/i))
         | 
| 80 | 
            +
                     action { [:MATCHES_PSEUDO_CLASS, st(text)] }
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  when (text = @ss.scan(/(domain|url\-prefix)\([\s]*("([^\n\r\f\\"]|\\(\n|\r\n|\r|\f)|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*"|'([^\n\r\f\\']|\\(\n|\r\n|\r|\f)|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*')[\s]*\)/i))
         | 
| 83 | 
            +
                     action { [:FUNCTION_NO_QUOTE, st(text)] }
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  when (text = @ss.scan(/(domain|url\-prefix)\([\s]*([!#\$%&*-~]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*[\s]*\)/i))
         | 
| 86 | 
            +
                     action { [:FUNCTION_NO_QUOTE, st(text)] }
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                  when (text = @ss.scan(/[\s]*(\-[A-Za-z]+\-)?calc\([\s]*(([0-9]*\.[0-9]+|[0-9]+)|([0-9]*\.[0-9]+|[0-9]+)(px|cm|mm|in|pt|pc)|([0-9]*\.[0-9]+|[0-9]+)%|([0-9]*\.[0-9]+|[0-9]+)em|([0-9]*\.[0-9]+|[0-9]+)ex)([\s]*(\*[\s]*(([0-9]*\.[0-9]+|[0-9]+)|([0-9]*\.[0-9]+|[0-9]+)(px|cm|mm|in|pt|pc)|([0-9]*\.[0-9]+|[0-9]+)%|([0-9]*\.[0-9]+|[0-9]+)em|([0-9]*\.[0-9]+|[0-9]+)ex)|\/[\s]*([0-9]*\.[0-9]+|[0-9]+)))*([\s]+[\+\-][\s]+(([0-9]*\.[0-9]+|[0-9]+)|([0-9]*\.[0-9]+|[0-9]+)(px|cm|mm|in|pt|pc)|([0-9]*\.[0-9]+|[0-9]+)%|([0-9]*\.[0-9]+|[0-9]+)em|([0-9]*\.[0-9]+|[0-9]+)ex)([\s]*(\*[\s]*(([0-9]*\.[0-9]+|[0-9]+)|([0-9]*\.[0-9]+|[0-9]+)(px|cm|mm|in|pt|pc)|([0-9]*\.[0-9]+|[0-9]+)%|([0-9]*\.[0-9]+|[0-9]+)em|([0-9]*\.[0-9]+|[0-9]+)ex)|\/[\s]*([0-9]*\.[0-9]+|[0-9]+)))*)*[\s]*\)[\s]*[\s]*/i))
         | 
| 89 | 
            +
                     action { [:MATH, st(text)] }
         | 
| 90 | 
            +
             | 
| 73 91 | 
             
                  when (text = @ss.scan(/[-@]?([_A-Za-z]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])([_A-Za-z0-9-]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f]|[.])*\(\s*/i))
         | 
| 74 92 | 
             
                     action { [:FUNCTION, st(text)] }
         | 
| 75 93 |  | 
| @@ -85,6 +103,15 @@ class Tokenizer < Parser | |
| 85 103 | 
             
                  when (text = @ss.scan(/[\s]*@media[\s]*/i))
         | 
| 86 104 | 
             
                     action { [:MEDIA_SYM, st(text)] }
         | 
| 87 105 |  | 
| 106 | 
            +
                  when (text = @ss.scan(/[\s]*@(\-[A-Za-z]+\-)?document[\s]*/i))
         | 
| 107 | 
            +
                     action { [:DOCUMENT_QUERY_SYM, st(text)] }
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                  when (text = @ss.scan(/[\s]*@namespace[\s]*/i))
         | 
| 110 | 
            +
                     action { [:NAMESPACE_SYM, st(text)] }
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  when (text = @ss.scan(/[\s]*@(\-[A-Za-z]+\-)?keyframes[\s]*/i))
         | 
| 113 | 
            +
                     action { [:KEYFRAMES_SYM, st(text)] }
         | 
| 114 | 
            +
             | 
| 88 115 | 
             
                  when (text = @ss.scan(/[\s]*!([\s]*|[\s]*\/\*(.|[\s]*)*?\*\/[\s]*)important[\s]*/i))
         | 
| 89 116 | 
             
                     action { [:IMPORTANT_SYM, st(text)] }
         | 
| 90 117 |  | 
| @@ -118,7 +145,7 @@ class Tokenizer < Parser | |
| 118 145 | 
             
                  when (text = @ss.scan(/[\s]*\)/i))
         | 
| 119 146 | 
             
                     action { [:RPAREN, st(text)] }
         | 
| 120 147 |  | 
| 121 | 
            -
                  when (text = @ss.scan( | 
| 148 | 
            +
                  when (text = @ss.scan(/\[[\s]*/i))
         | 
| 122 149 | 
             
                     action { [:LSQUARE, st(text)] }
         | 
| 123 150 |  | 
| 124 151 | 
             
                  when (text = @ss.scan(/[\s]*\]/i))
         | 
| @@ -148,9 +175,6 @@ class Tokenizer < Parser | |
| 148 175 | 
             
                  when (text = @ss.scan(/[\s]*~[\s]*/i))
         | 
| 149 176 | 
             
                     action { [:TILDE, st(text)] }
         | 
| 150 177 |  | 
| 151 | 
            -
                  when (text = @ss.scan(/\:not\([\s]*/i))
         | 
| 152 | 
            -
                     action { [:NOT, st(text)]  }
         | 
| 153 | 
            -
             | 
| 154 178 | 
             
                  when (text = @ss.scan(/[\s]*([0-9]*\.[0-9]+|[0-9]+)em[\s]*/i))
         | 
| 155 179 | 
             
                     action { [:EMS, st(text)] }
         | 
| 156 180 |  | 
| @@ -196,10 +220,10 @@ class Tokenizer < Parser | |
| 196 220 | 
             
                  when (text = @ss.scan(/[\s]+/i))
         | 
| 197 221 | 
             
                     action { [:S, st(text)] }
         | 
| 198 222 |  | 
| 199 | 
            -
                  when (text = @ss.scan(/("([^\n\r\f\\"] | 
| 223 | 
            +
                  when (text = @ss.scan(/("([^\n\r\f\\"]|\\(\n|\r\n|\r|\f)|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*"|'([^\n\r\f\\']|\\(\n|\r\n|\r|\f)|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*')/i))
         | 
| 200 224 | 
             
                     action { [:STRING, st(text)] }
         | 
| 201 225 |  | 
| 202 | 
            -
                  when (text = @ss.scan(/("([^\n\r\f\\"] | 
| 226 | 
            +
                  when (text = @ss.scan(/("([^\n\r\f\\"]|\\(\n|\r\n|\r|\f)|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*|'([^\n\r\f\\']|\\(\n|\r\n|\r|\f)|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*)/i))
         | 
| 203 227 | 
             
                     action { [:INVALID, st(text)] }
         | 
| 204 228 |  | 
| 205 229 | 
             
                  when (text = @ss.scan(/./i))
         | 
| @@ -3,11 +3,17 @@ module CSS | |
| 3 3 | 
             
            class Tokenizer < Parser
         | 
| 4 4 |  | 
| 5 5 | 
             
            macro
         | 
| 6 | 
            -
              nl        \n|\r\n|\r|\f
         | 
| 6 | 
            +
              nl        (\n|\r\n|\r|\f)
         | 
| 7 7 | 
             
              w         [\s]*
         | 
| 8 8 | 
             
              nonascii  [^\0-\177]
         | 
| 9 9 | 
             
              num       ([0-9]*\.[0-9]+|[0-9]+)
         | 
| 10 | 
            +
              length    {num}(px|cm|mm|in|pt|pc)
         | 
| 11 | 
            +
              percentage {num}%
         | 
| 12 | 
            +
              ems       {num}em
         | 
| 13 | 
            +
              exs       {num}ex
         | 
| 10 14 | 
             
              unicode   \\[0-9A-Fa-f]{1,6}(\r\n|[\s])?
         | 
| 15 | 
            +
              nth       ([\+\-]?[0-9]*n({w}[\+\-]{w}[0-9]+)?|[\+\-]?[0-9]+|odd|even)
         | 
| 16 | 
            +
              vendorprefix \-[A-Za-z]+\-
         | 
| 11 17 |  | 
| 12 18 | 
             
              escape    {unicode}|\\[^\n\r\f0-9A-Fa-f]
         | 
| 13 19 | 
             
              nmchar    [_A-Za-z0-9-]|{nonascii}|{escape}
         | 
| @@ -23,6 +29,12 @@ macro | |
| 23 29 | 
             
              invalid   ({invalid1}|{invalid2})
         | 
| 24 30 | 
             
              comment   \/\*(.|{w})*?\*\/
         | 
| 25 31 |  | 
| 32 | 
            +
              unit      ({num}|{length}|{percentage}|{ems}|{exs})
         | 
| 33 | 
            +
              product   {unit}({w}(\*{w}{unit}|\/{w}{num}))*
         | 
| 34 | 
            +
              sum       {product}([\s]+[\+\-][\s]+{product})*
         | 
| 35 | 
            +
              calc      ({vendorprefix})?calc\({w}{sum}{w}\)
         | 
| 36 | 
            +
              math      {calc}{w}
         | 
| 37 | 
            +
             | 
| 26 38 | 
             
            rule
         | 
| 27 39 |  | 
| 28 40 | 
             
            # [:state]  pattern  [actions]
         | 
| @@ -32,11 +44,29 @@ rule | |
| 32 44 | 
             
                        U\+[0-9a-fA-F?]{1,6}(-[0-9a-fA-F]{1,6})?  {[:UNICODE_RANGE, st(text)] }
         | 
| 33 45 | 
             
                        {w}{comment}{w}  { next_token }
         | 
| 34 46 |  | 
| 47 | 
            +
                        # this one takes a selector as a parameter
         | 
| 48 | 
            +
                        not\(\s*         { [:NOT_PSEUDO_CLASS, st(text)] }
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                        # this one takes an "nth" value
         | 
| 51 | 
            +
                        (nth\-child|nth\-last\-child|nth\-of\-type|nth\-last\-of\-type)\({w}{nth}{w}\) { [:NTH_PSEUDO_CLASS, st(text)] }
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                        # this one takes a comma-separated list of simple selectors as a parameter
         | 
| 54 | 
            +
                        ({vendorprefix})?(matches|any)\(\s* { [:MATCHES_PSEUDO_CLASS, st(text)] }
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                        # functions that can take an unquoted string parameter
         | 
| 57 | 
            +
                        (domain|url\-prefix)\({w}{string}{w}\) { [:FUNCTION_NO_QUOTE, st(text)] }
         | 
| 58 | 
            +
                        (domain|url\-prefix)\({w}([!#\$%&*-~]|{nonascii}|{escape})*{w}\) { [:FUNCTION_NO_QUOTE, st(text)] }
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                        {w}{math}{w}     { [:MATH, st(text)] }
         | 
| 61 | 
            +
             | 
| 35 62 | 
             
                        {func}\(\s*      { [:FUNCTION, st(text)] }
         | 
| 36 63 | 
             
                        {w}@import{w}    { [:IMPORT_SYM, st(text)] }
         | 
| 37 64 | 
             
                        {w}@page{w}      { [:PAGE_SYM, st(text)] }
         | 
| 38 65 | 
             
                        {w}@charset{w}   { [:CHARSET_SYM, st(text)] }
         | 
| 39 66 | 
             
                        {w}@media{w}     { [:MEDIA_SYM, st(text)] }
         | 
| 67 | 
            +
                        {w}@({vendorprefix})?document{w} { [:DOCUMENT_QUERY_SYM, st(text)] }
         | 
| 68 | 
            +
                        {w}@namespace{w} { [:NAMESPACE_SYM, st(text)] }
         | 
| 69 | 
            +
                        {w}@({vendorprefix})?keyframes{w} { [:KEYFRAMES_SYM, st(text)] }
         | 
| 40 70 | 
             
                        {w}!({w}|{w}{comment}{w})important{w}  { [:IMPORTANT_SYM, st(text)] }
         | 
| 41 71 | 
             
                        {ident}          { [:IDENT, st(text)] }
         | 
| 42 72 | 
             
                        \#{name}         { [:HASH, st(text)] }
         | 
| @@ -48,7 +78,7 @@ rule | |
| 48 78 | 
             
                        {w}!={w}         { [:NOT_EQUAL, st(text)] }
         | 
| 49 79 | 
             
                        {w}={w}          { [:EQUAL, st(text)] }
         | 
| 50 80 | 
             
                        {w}\)            { [:RPAREN, st(text)] }
         | 
| 51 | 
            -
                         | 
| 81 | 
            +
                        \[{w}            { [:LSQUARE, st(text)] }
         | 
| 52 82 | 
             
                        {w}\]            { [:RSQUARE, st(text)] }
         | 
| 53 83 | 
             
                        {w}\+{w}         { [:PLUS, st(text)] }
         | 
| 54 84 | 
             
                        {w}\{{w}         { [:LBRACE, st(text)] }
         | 
| @@ -58,16 +88,15 @@ rule | |
| 58 88 | 
             
                        {w};{w}          { [:SEMI, st(';')] }
         | 
| 59 89 | 
             
                        \*               { [:STAR, st(text)] }
         | 
| 60 90 | 
             
                        {w}~{w}          { [:TILDE, st(text)] }
         | 
| 61 | 
            -
                         | 
| 62 | 
            -
                        {w}{ | 
| 63 | 
            -
                        {w}{num}ex{w}    { [:EXS, st(text)] }
         | 
| 91 | 
            +
                        {w}{ems}{w}      { [:EMS, st(text)] }
         | 
| 92 | 
            +
                        {w}{exs}{w}      { [:EXS, st(text)] }
         | 
| 64 93 |  | 
| 65 | 
            -
                        {w}{ | 
| 94 | 
            +
                        {w}{length}{w}   { [:LENGTH, st(text)] }
         | 
| 66 95 | 
             
                        {w}{num}(deg|rad|grad){w} { [:ANGLE, st(text)] }
         | 
| 67 96 | 
             
                        {w}{num}(ms|s){w} { [:TIME, st(text)] }
         | 
| 68 97 | 
             
                        {w}{num}[k]?hz{w} { [:FREQ, st(text)] }
         | 
| 69 98 |  | 
| 70 | 
            -
                        {w}{ | 
| 99 | 
            +
                        {w}{percentage}{w} { [:PERCENTAGE, st(text)] }
         | 
| 71 100 | 
             
                        {w}{num}{w}      { [:NUMBER, st(text)] }
         | 
| 72 101 | 
             
                        {w}\/\/{w}       { [:DOUBLESLASH, st(text)] }
         | 
| 73 102 | 
             
                        {w}\/{w}         { [:SLASH, st('/')] }
         | 
    
        data/lib/csspool/css.rb
    CHANGED
    
    | @@ -6,3 +6,7 @@ require 'csspool/css/rule_set' | |
| 6 6 | 
             
            require 'csspool/css/declaration'
         | 
| 7 7 | 
             
            require 'csspool/css/document'
         | 
| 8 8 | 
             
            require 'csspool/css/document_handler'
         | 
| 9 | 
            +
            require 'csspool/css/document_query'
         | 
| 10 | 
            +
            require 'csspool/css/namespace_rule'
         | 
| 11 | 
            +
            require 'csspool/css/keyframes_rule'
         | 
| 12 | 
            +
            require 'csspool/css/keyframes_block'
         | 
    
        data/lib/csspool/selector.rb
    CHANGED
    
    | @@ -17,10 +17,14 @@ module CSSPool | |
| 17 17 | 
             
                def specificity
         | 
| 18 18 | 
             
                  a = b = c = 0
         | 
| 19 19 | 
             
                  simple_selectors.each do |s|
         | 
| 20 | 
            -
                     | 
| 20 | 
            +
                    if !s.name.nil?
         | 
| 21 | 
            +
                      c += 1
         | 
| 22 | 
            +
                    end
         | 
| 21 23 | 
             
                    s.additional_selectors.each do |additional_selector|
         | 
| 22 24 | 
             
                      if Selectors::Id === additional_selector
         | 
| 23 25 | 
             
                        a += 1
         | 
| 26 | 
            +
                      elsif Selectors::PseudoElement === additional_selector
         | 
| 27 | 
            +
                        c += 1
         | 
| 24 28 | 
             
                      else
         | 
| 25 29 | 
             
                        b += 1
         | 
| 26 30 | 
             
                      end
         | 
| @@ -4,17 +4,22 @@ module CSSPool | |
| 4 4 | 
             
                  attr_accessor :name
         | 
| 5 5 | 
             
                  attr_accessor :value
         | 
| 6 6 | 
             
                  attr_accessor :match_way
         | 
| 7 | 
            +
                  attr_accessor :namespace
         | 
| 7 8 |  | 
| 8 9 | 
             
                  NO_MATCH  = 0
         | 
| 9 10 | 
             
                  SET       = 1
         | 
| 10 11 | 
             
                  EQUALS    = 2
         | 
| 11 12 | 
             
                  INCLUDES  = 3
         | 
| 12 13 | 
             
                  DASHMATCH = 4
         | 
| 14 | 
            +
                  PREFIXMATCH = 5
         | 
| 15 | 
            +
                  SUFFIXMATCH = 6
         | 
| 16 | 
            +
                  SUBSTRINGMATCH = 7
         | 
| 13 17 |  | 
| 14 | 
            -
                  def initialize name, value, match_way
         | 
| 18 | 
            +
                  def initialize name, value, match_way, namespace = nil
         | 
| 15 19 | 
             
                    @name = name
         | 
| 16 20 | 
             
                    @value = value
         | 
| 17 21 | 
             
                    @match_way = match_way
         | 
| 22 | 
            +
                    @namespace = namespace
         | 
| 18 23 | 
             
                  end
         | 
| 19 24 | 
             
                end
         | 
| 20 25 | 
             
              end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            require 'csspool/selectors/pseudo_class'
         | 
| 2 | 
            +
            require 'csspool/selectors/pseudo_element'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module CSSPool
         | 
| 5 | 
            +
              module Selectors
         | 
| 6 | 
            +
                def Selectors.pseudo name
         | 
| 7 | 
            +
                  # FIXME: This is a bit of an ugly solution. Should be able to handle it
         | 
| 8 | 
            +
                  # more elegantly, and without calling out css2
         | 
| 9 | 
            +
                  css2_pseudo_elements = 
         | 
| 10 | 
            +
                  if %w{after before first-letter first-line}.include? name
         | 
| 11 | 
            +
                    PseudoElement.new name, true
         | 
| 12 | 
            +
                  else
         | 
| 13 | 
            +
                    PseudoClass.new name
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
    
        data/lib/csspool/selectors.rb
    CHANGED