css_parser 1.1.1 → 1.1.2
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/lib/css_parser/parser.rb +63 -26
- data/lib/css_parser.rb +3 -1
- data/test/test_css_parser_loading.rb +18 -4
- data/test/test_css_parser_misc.rb +0 -1
- metadata +4 -4
    
        data/lib/css_parser/parser.rb
    CHANGED
    
    | @@ -23,11 +23,7 @@ module CssParser | |
| 23 23 | 
             
                # Initial parsing
         | 
| 24 24 | 
             
                RE_AT_IMPORT_RULE = /\@import\s*(?:url\s*)?(?:\()?(?:\s*)["']?([^'"\s\)]*)["']?\)?([\w\s\,^\])]*)\)?[;\n]?/
         | 
| 25 25 |  | 
| 26 | 
            -
             | 
| 27 | 
            -
                # RE_AT_IMPORT_RULE = Regexp.new('@import[\s]*(' + RE_STRING.to_s + ')([\w\s\,]*)[;]?', Regexp::IGNORECASE) -- should handle url() even though it is not allowed
         | 
| 28 | 
            -
                #++
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                # Array of CSS files that have been loaded.
         | 
| 26 | 
            +
                 # Array of CSS files that have been loaded.
         | 
| 31 27 | 
             
                attr_reader   :loaded_uris
         | 
| 32 28 |  | 
| 33 29 | 
             
                #attr_reader   :rules
         | 
| @@ -199,7 +195,7 @@ module CssParser | |
| 199 195 | 
             
                  options = {:media_types => :all}.merge(options)
         | 
| 200 196 | 
             
                  media_types = options[:media_types]
         | 
| 201 197 |  | 
| 202 | 
            -
                  in_declarations =  | 
| 198 | 
            +
                  in_declarations = 0
         | 
| 203 199 |  | 
| 204 200 | 
             
                  block_depth = 0
         | 
| 205 201 |  | 
| @@ -219,13 +215,25 @@ module CssParser | |
| 219 215 | 
             
                      in_string = !in_string
         | 
| 220 216 | 
             
                    end       
         | 
| 221 217 |  | 
| 222 | 
            -
                    if in_declarations
         | 
| 218 | 
            +
                    if in_declarations > 0
         | 
| 219 | 
            +
             | 
| 220 | 
            +
                      # too deep, malformed declaration block
         | 
| 221 | 
            +
                      if in_declarations > 1
         | 
| 222 | 
            +
                        in_declarations -= 1 if token =~ /\}/
         | 
| 223 | 
            +
                        next
         | 
| 224 | 
            +
                      end
         | 
| 225 | 
            +
                      
         | 
| 226 | 
            +
                      if token =~ /\{/
         | 
| 227 | 
            +
                        in_declarations += 1
         | 
| 228 | 
            +
                        next
         | 
| 229 | 
            +
                      end
         | 
| 230 | 
            +
                    
         | 
| 223 231 | 
             
                      current_declarations += token
         | 
| 224 232 |  | 
| 225 233 | 
             
                      if token =~ /\}/ and not in_string
         | 
| 226 234 | 
             
                        current_declarations.gsub!(/\}[\s]*$/, '')
         | 
| 227 235 |  | 
| 228 | 
            -
                        in_declarations  | 
| 236 | 
            +
                        in_declarations -= 1
         | 
| 229 237 |  | 
| 230 238 | 
             
                        unless current_declarations.strip.empty?
         | 
| 231 239 | 
             
                          #puts "SAVING #{current_selectors} -> #{current_declarations}"
         | 
| @@ -257,7 +265,7 @@ module CssParser | |
| 257 265 | 
             
                        if token =~ /\{/ and not in_string
         | 
| 258 266 | 
             
                          current_selectors.gsub!(/^[\s]*/, '')
         | 
| 259 267 | 
             
                          current_selectors.gsub!(/[\s]*$/, '')
         | 
| 260 | 
            -
                          in_declarations  | 
| 268 | 
            +
                          in_declarations += 1
         | 
| 261 269 | 
             
                        else
         | 
| 262 270 | 
             
                          current_selectors += token
         | 
| 263 271 | 
             
                        end
         | 
| @@ -267,13 +275,18 @@ module CssParser | |
| 267 275 | 
             
                end
         | 
| 268 276 |  | 
| 269 277 | 
             
                # Load a remote CSS file.
         | 
| 278 | 
            +
                #
         | 
| 279 | 
            +
                # You can also pass in file://test.css
         | 
| 270 280 | 
             
                def load_uri!(uri, base_uri = nil, media_types = :all)
         | 
| 281 | 
            +
                  uri = URI.parse(uri) unless uri.respond_to? :scheme
         | 
| 282 | 
            +
                  if uri.scheme == 'file' or uri.scheme.nil?
         | 
| 283 | 
            +
                    uri.path = File.expand_path(uri.path)
         | 
| 284 | 
            +
                    uri.scheme = 'file'
         | 
| 285 | 
            +
                  end
         | 
| 271 286 | 
             
                  base_uri = uri if base_uri.nil?
         | 
| 272 287 |  | 
| 273 288 | 
             
                  src, charset = read_remote_file(uri)
         | 
| 274 | 
            -
                   | 
| 275 | 
            -
                    add_block!(src, {:media_types => media_types, :base_uri => base_uri})
         | 
| 276 | 
            -
                  end
         | 
| 289 | 
            +
                  add_block!(src, {:media_types => media_types, :base_uri => base_uri})
         | 
| 277 290 | 
             
                end
         | 
| 278 291 |  | 
| 279 292 | 
             
                # Load a local CSS file.
         | 
| @@ -321,27 +334,51 @@ module CssParser | |
| 321 334 |  | 
| 322 335 | 
             
                  @loaded_uris << uri.to_s
         | 
| 323 336 |  | 
| 324 | 
            -
                   | 
| 325 | 
            -
                  #fh = open(uri, 'rb')
         | 
| 326 | 
            -
                    fh = open(uri, 'rb', 'User-Agent' => USER_AGENT, 'Accept-Encoding' => 'gzip')
         | 
| 337 | 
            +
                  src = '', charset = nil
         | 
| 327 338 |  | 
| 328 | 
            -
             | 
| 329 | 
            -
             | 
| 339 | 
            +
                  begin
         | 
| 340 | 
            +
                    uri = URI.parse(uri.to_s)    
         | 
| 341 | 
            +
                    http = Net::HTTP.new(uri.host, uri.port)
         | 
| 342 | 
            +
             | 
| 343 | 
            +
                    if uri.scheme == 'file'
         | 
| 344 | 
            +
                      # local file
         | 
| 345 | 
            +
                      fh = open(uri.path, 'rb')
         | 
| 346 | 
            +
                      src = fh.read
         | 
| 347 | 
            +
                      fh.close
         | 
| 330 348 | 
             
                    else
         | 
| 331 | 
            -
                       | 
| 332 | 
            -
             | 
| 349 | 
            +
                      # remote file
         | 
| 350 | 
            +
                      if uri.scheme == 'https'
         | 
| 351 | 
            +
                        http.use_ssl = true 
         | 
| 352 | 
            +
                        http.verify_mode = OpenSSL::SSL::VERIFY_NONE
         | 
| 353 | 
            +
                      end
         | 
| 333 354 |  | 
| 334 | 
            -
             | 
| 355 | 
            +
                      res, src = http.get(uri.path, {'User-Agent' => USER_AGENT, 'Accept-Encoding' => 'gzip'})
         | 
| 356 | 
            +
                      charset = fh.respond_to?(:charset) ? fh.charset : 'utf-8'
         | 
| 335 357 |  | 
| 336 | 
            -
             | 
| 337 | 
            -
             | 
| 358 | 
            +
                      if res.code.to_i >= 400
         | 
| 359 | 
            +
                        raise RemoteFileError if @options[:io_exceptions]
         | 
| 360 | 
            +
                        return '', nil
         | 
| 361 | 
            +
                      end
         | 
| 338 362 |  | 
| 339 | 
            -
             | 
| 340 | 
            -
             | 
| 341 | 
            -
             | 
| 363 | 
            +
                      case res['content-encoding']
         | 
| 364 | 
            +
                        when 'gzip'
         | 
| 365 | 
            +
                          io = Zlib::GzipReader.new(StringIO.new(res.body))
         | 
| 366 | 
            +
                          src = io.read
         | 
| 367 | 
            +
                        when 'deflate'
         | 
| 368 | 
            +
                          io = Zlib::Inflate.new
         | 
| 369 | 
            +
                          src = io.inflate(res.body)
         | 
| 370 | 
            +
                      end
         | 
| 371 | 
            +
                    end
         | 
| 372 | 
            +
             | 
| 373 | 
            +
                    if charset
         | 
| 374 | 
            +
                      ic = Iconv.new('UTF-8//IGNORE', charset)
         | 
| 375 | 
            +
                      src = ic.iconv(src)
         | 
| 376 | 
            +
                    end
         | 
| 377 | 
            +
                  rescue
         | 
| 342 378 | 
             
                    raise RemoteFileError if @options[:io_exceptions]
         | 
| 343 | 
            -
                    return '', nil
         | 
| 344 379 | 
             
                  end
         | 
| 380 | 
            +
             | 
| 381 | 
            +
                  return src, charset  
         | 
| 345 382 | 
             
                end
         | 
| 346 383 |  | 
| 347 384 | 
             
              private
         | 
    
        data/lib/css_parser.rb
    CHANGED
    
    | @@ -1,11 +1,13 @@ | |
| 1 1 | 
             
            require 'uri'
         | 
| 2 | 
            +
            require 'net/https'
         | 
| 2 3 | 
             
            require 'open-uri'
         | 
| 3 4 | 
             
            require 'digest/md5'
         | 
| 4 5 | 
             
            require 'zlib'
         | 
| 6 | 
            +
            require 'stringio'
         | 
| 5 7 | 
             
            require 'iconv'
         | 
| 6 8 |  | 
| 7 9 | 
             
            module CssParser
         | 
| 8 | 
            -
              VERSION = '1.1. | 
| 10 | 
            +
              VERSION = '1.1.2'
         | 
| 9 11 |  | 
| 10 12 | 
             
              # Merge multiple CSS RuleSets by cascading according to the CSS 2.1 cascading rules 
         | 
| 11 13 | 
             
              # (http://www.w3.org/TR/REC-CSS2/cascade.html#cascading-order).
         | 
| @@ -11,10 +11,10 @@ class CssParserLoadingTests < Test::Unit::TestCase | |
| 11 11 |  | 
| 12 12 | 
             
                @uri_base = 'http://localhost:12000'
         | 
| 13 13 |  | 
| 14 | 
            -
                www_root = File.dirname(__FILE__) + '/fixtures/'
         | 
| 14 | 
            +
                @www_root = File.dirname(__FILE__) + '/fixtures/'
         | 
| 15 15 |  | 
| 16 16 | 
             
                @server_thread = Thread.new do
         | 
| 17 | 
            -
                  s = WEBrick::HTTPServer.new(:Port => 12000, :DocumentRoot => www_root, :Logger => Log.new(nil, BasicLog::FATAL), :AccessLog => [])
         | 
| 17 | 
            +
                  s = WEBrick::HTTPServer.new(:Port => 12000, :DocumentRoot => @www_root, :Logger => Log.new(nil, BasicLog::FATAL), :AccessLog => [])
         | 
| 18 18 | 
             
                  @port = s.config[:Port]
         | 
| 19 19 | 
             
                  begin
         | 
| 20 20 | 
             
                    s.start
         | 
| @@ -25,24 +25,38 @@ class CssParserLoadingTests < Test::Unit::TestCase | |
| 25 25 |  | 
| 26 26 | 
             
                sleep 1 # ensure the server has time to load
         | 
| 27 27 | 
             
              end
         | 
| 28 | 
            -
             | 
| 28 | 
            +
             
         | 
| 29 29 | 
             
              def teardown
         | 
| 30 30 | 
             
                @server_thread.kill
         | 
| 31 31 | 
             
                @server_thread.join(5)
         | 
| 32 32 | 
             
                @server_thread = nil
         | 
| 33 33 | 
             
              end
         | 
| 34 | 
            -
             | 
| 34 | 
            +
             
         | 
| 35 35 | 
             
              def test_loading_a_local_file
         | 
| 36 36 | 
             
                file_name = File.dirname(__FILE__) + '/fixtures/simple.css'
         | 
| 37 37 | 
             
                @cp.load_file!(file_name)
         | 
| 38 38 | 
             
                assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
         | 
| 39 39 | 
             
              end
         | 
| 40 40 |  | 
| 41 | 
            +
              def test_loading_a_local_file_with_scheme
         | 
| 42 | 
            +
                file_name = 'file://' + File.dirname(__FILE__) + '/fixtures/simple.css'
         | 
| 43 | 
            +
                @cp.load_uri!(file_name)
         | 
| 44 | 
            +
                assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
             | 
| 41 47 | 
             
              def test_loading_a_remote_file
         | 
| 42 48 | 
             
                @cp.load_uri!("#{@uri_base}/simple.css")
         | 
| 43 49 | 
             
                assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
         | 
| 44 50 | 
             
              end
         | 
| 45 51 |  | 
| 52 | 
            +
              # http://github.com/alexdunae/css_parser/issues#issue/4
         | 
| 53 | 
            +
              def test_loading_a_remote_file_over_ssl
         | 
| 54 | 
            +
                # TODO: test SSL locally
         | 
| 55 | 
            +
                @cp.load_uri!("https://www.expresspardons.com/inc/screen.css")
         | 
| 56 | 
            +
                assert_match /margin\: 0\;/, @cp.find_by_selector('body').join(' ')
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
             | 
| 46 60 | 
             
              def test_following_at_import_rules_local
         | 
| 47 61 | 
             
                base_dir = File.dirname(__FILE__) + '/fixtures'
         | 
| 48 62 | 
             
                @cp.load_file!('import1.css', base_dir)
         | 
    
        metadata
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: css_parser
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              hash:  | 
| 4 | 
            +
              hash: 23
         | 
| 5 5 | 
             
              prerelease: false
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 1
         | 
| 8 8 | 
             
              - 1
         | 
| 9 | 
            -
              -  | 
| 10 | 
            -
              version: 1.1. | 
| 9 | 
            +
              - 2
         | 
| 10 | 
            +
              version: 1.1.2
         | 
| 11 11 | 
             
            platform: ruby
         | 
| 12 12 | 
             
            authors: 
         | 
| 13 13 | 
             
            - Alex Dunae
         | 
| @@ -15,7 +15,7 @@ autorequire: | |
| 15 15 | 
             
            bindir: bin
         | 
| 16 16 | 
             
            cert_chain: []
         | 
| 17 17 |  | 
| 18 | 
            -
            date: 2010-10- | 
| 18 | 
            +
            date: 2010-10-28 00:00:00 -07:00
         | 
| 19 19 | 
             
            default_executable: 
         | 
| 20 20 | 
             
            dependencies: []
         | 
| 21 21 |  |