deadweight 0.1.3 → 0.2.0

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.
Files changed (40) hide show
  1. data/README.md +123 -0
  2. data/lib/deadweight.rb +37 -11
  3. data/lib/deadweight/hijack.rb +13 -0
  4. data/lib/deadweight/hijack/rails.rb +35 -0
  5. data/lib/deadweight/rack/capturing_middleware.rb +26 -0
  6. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/lib/css_parser.rb +25 -12
  7. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/lib/css_parser/parser.rb +120 -54
  8. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/lib/css_parser/regexps.rb +1 -1
  9. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/lib/css_parser/rule_set.rb +24 -13
  10. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/fixtures/import-circular-reference.css +0 -0
  11. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/fixtures/import-with-media-types.css +0 -0
  12. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/fixtures/import1.css +0 -0
  13. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/fixtures/simple.css +0 -0
  14. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/fixtures/subdir/import2.css +0 -0
  15. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/test_css_parser_basic.rb +4 -1
  16. data/vendor/gems/css_parser-1.1.5/test/test_css_parser_loading.rb +139 -0
  17. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/test_css_parser_media_types.rb +39 -4
  18. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/test_css_parser_misc.rb +1 -2
  19. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/test_css_parser_regexps.rb +1 -1
  20. data/vendor/gems/css_parser-1.1.5/test/test_helper.rb +6 -0
  21. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/test_merging.rb +16 -1
  22. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/test_rule_set.rb +16 -1
  23. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/test_rule_set_creating_shorthand.rb +1 -1
  24. data/vendor/gems/{css_parser-1.0.0 → css_parser-1.1.5}/test/test_rule_set_expanding_shorthand.rb +1 -1
  25. metadata +79 -54
  26. data/.document +0 -5
  27. data/.gitignore +0 -6
  28. data/README.rdoc +0 -85
  29. data/Rakefile +0 -58
  30. data/VERSION +0 -1
  31. data/deadweight.gemspec +0 -84
  32. data/test/cli_test.rb +0 -21
  33. data/test/deadweight_test.rb +0 -72
  34. data/test/fixtures/index.html +0 -16
  35. data/test/fixtures/index2.html +0 -21
  36. data/test/fixtures/style.css +0 -24
  37. data/test/rake_task_test.rb +0 -26
  38. data/test/test_helper.rb +0 -47
  39. data/vendor/gems/css_parser-1.0.0/test/test_css_parser_downloading.rb +0 -81
  40. data/vendor/gems/css_parser-1.0.0/test/test_helper.rb +0 -8
@@ -16,7 +16,7 @@ module CssParser
16
16
  URI_RX = /url\(("([^"]*)"|'([^']*)'|([^)]*))\)/im
17
17
 
18
18
  # Initial parsing
19
- RE_AT_IMPORT_RULE = /\@import[\s]+(url\()?["']+(.[^'"]*)["']\)?([\w\s\,]*);?/i
19
+ RE_AT_IMPORT_RULE = /\@import[\s]+(url\()?["''"]?(.[^'"\s"']*)["''"]?\)?([\w\s\,^\])]*)\)?;?/
20
20
 
21
21
  #--
22
22
  #RE_AT_MEDIA_RULE = Regexp.new('(\"(.[^\n\r\f\\"]*|\\\\' + RE_NL.to_s + '|' + RE_ESCAPE.to_s + ')*\")')
@@ -14,6 +14,7 @@ module CssParser
14
14
  @selectors = []
15
15
  @specificity = specificity
16
16
  @declarations = {}
17
+ @order = 0
17
18
  parse_selectors!(selectors) if selectors
18
19
  parse_declarations!(block)
19
20
  end
@@ -57,7 +58,9 @@ module CssParser
57
58
  is_important = !value.gsub!(CssParser::IMPORTANT_IN_PROPERTY_RX, '').nil?
58
59
  property = property.downcase.strip
59
60
  #puts "SAVING #{property} #{value} #{is_important.inspect}"
60
- @declarations[property] = {:value => value, :is_important => is_important}
61
+ @declarations[property] = {
62
+ :value => value, :is_important => is_important, :order => @order += 1
63
+ }
61
64
  end
62
65
  alias_method :[]=, :add_declaration!
63
66
 
@@ -81,9 +84,9 @@ module CssParser
81
84
 
82
85
  # Iterate through declarations.
83
86
  def each_declaration # :yields: property, value, is_important
84
- @declarations.each do |property, data|
87
+ decs = @declarations.sort { |a,b| a[1][:order].nil? || b[1][:order].nil? ? 0 : a[1][:order] <=> b[1][:order] }
88
+ decs.each do |property, data|
85
89
  value = data[:value]
86
- #value += ' !important' if data[:is_important]
87
90
  yield property.downcase.strip, value.strip, data[:is_important]
88
91
  end
89
92
  end
@@ -95,8 +98,10 @@ module CssParser
95
98
  def declarations_to_s(options = {})
96
99
  options = {:force_important => false}.merge(options)
97
100
  str = ''
98
- importance = options[:force_important] ? ' !important' : ''
99
- each_declaration { |prop, val| str += "#{prop}: #{val}#{importance}; " }
101
+ each_declaration do |prop, val, is_important|
102
+ importance = (options[:force_important] || is_important) ? ' !important' : ''
103
+ str += "#{prop}: #{val}#{importance}; "
104
+ end
100
105
  str.gsub(/^[\s]+|[\n\r\f\t]*|[\s]+$/mx, '').strip
101
106
  end
102
107
 
@@ -154,6 +159,7 @@ public
154
159
 
155
160
  value = @declarations[property][:value]
156
161
  is_important = @declarations[property][:is_important]
162
+ order = @declarations[property][:order]
157
163
  t, r, b, l = nil
158
164
 
159
165
  matches = value.scan(CssParser::BOX_MODEL_UNITS_RX)
@@ -175,10 +181,11 @@ public
175
181
  l = matches[3][0]
176
182
  end
177
183
 
178
- @declarations["#{property}-top"] = {:value => t.to_s, :is_important => is_important}
179
- @declarations["#{property}-right"] = {:value => r.to_s, :is_important => is_important}
180
- @declarations["#{property}-bottom"] = {:value => b.to_s, :is_important => is_important}
181
- @declarations["#{property}-left"] = {:value => l.to_s, :is_important => is_important}
184
+ values = { :is_important => is_important, :order => order }
185
+ @declarations["#{property}-top"] = values.merge(:value => t.to_s)
186
+ @declarations["#{property}-right"] = values.merge(:value => r.to_s)
187
+ @declarations["#{property}-bottom"] = values.merge(:value => b.to_s)
188
+ @declarations["#{property}-left"] = values.merge(:value => l.to_s)
182
189
  @declarations.delete(property)
183
190
  end
184
191
  end
@@ -198,6 +205,7 @@ public
198
205
 
199
206
  value = @declarations['font'][:value]
200
207
  is_important = @declarations['font'][:is_important]
208
+ order = @declarations['font'][:order]
201
209
 
202
210
  in_fonts = false
203
211
 
@@ -232,7 +240,7 @@ public
232
240
  end
233
241
  end
234
242
 
235
- font_props.each { |font_prop, font_val| @declarations[font_prop] = {:value => font_val, :is_important => is_important} }
243
+ font_props.each { |font_prop, font_val| @declarations[font_prop] = {:value => font_val, :is_important => is_important, :order => order} }
236
244
 
237
245
  @declarations.delete('font')
238
246
  end
@@ -247,6 +255,7 @@ public
247
255
 
248
256
  value = @declarations['background'][:value]
249
257
  is_important = @declarations['background'][:is_important]
258
+ order = @declarations['background'][:order]
250
259
 
251
260
  bg_props = {}
252
261
 
@@ -283,7 +292,7 @@ public
283
292
  end
284
293
  end
285
294
 
286
- bg_props.each { |bg_prop, bg_val| @declarations[bg_prop] = {:value => bg_val, :is_important => is_important} }
295
+ bg_props.each { |bg_prop, bg_val| @declarations[bg_prop] = {:value => bg_val, :is_important => is_important, :order => order} }
287
296
 
288
297
  @declarations.delete('background')
289
298
  end
@@ -291,11 +300,13 @@ public
291
300
 
292
301
  # Looks for long format CSS background properties (e.g. <tt>background-color</tt>) and
293
302
  # converts them into a shorthand CSS <tt>background</tt> property.
303
+ #
304
+ # Leaves properties declared !important alone.
294
305
  def create_background_shorthand! # :nodoc:
295
306
  new_value = ''
296
307
  ['background-color', 'background-image', 'background-repeat',
297
308
  'background-position', 'background-attachment'].each do |property|
298
- if @declarations.has_key?(property)
309
+ if @declarations.has_key?(property) and not @declarations[property][:is_important]
299
310
  new_value += @declarations[property][:value] + ' '
300
311
  @declarations.delete(property)
301
312
  end
@@ -380,4 +391,4 @@ public
380
391
 
381
392
  end
382
393
  end
383
- end
394
+ end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/test_helper'
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
2
 
3
3
  # Test cases for reading and generating CSS shorthand properties
4
4
  class CssParserBasicTests < Test::Unit::TestCase
@@ -10,6 +10,7 @@ class CssParserBasicTests < Test::Unit::TestCase
10
10
  html, body, p { margin: 0px; }
11
11
  p { padding: 0px; }
12
12
  #content { font: 12px/normal sans-serif; }
13
+ .content { color: red; }
13
14
  EOT
14
15
  end
15
16
 
@@ -17,6 +18,8 @@ class CssParserBasicTests < Test::Unit::TestCase
17
18
  @cp.add_block!(@css)
18
19
  assert_equal 'margin: 0px;', @cp.find_by_selector('body').join(' ')
19
20
  assert_equal 'margin: 0px; padding: 0px;', @cp.find_by_selector('p').join(' ')
21
+ assert_equal 'font: 12px/normal sans-serif;', @cp.find_by_selector('#content').join(' ')
22
+ assert_equal 'color: red;', @cp.find_by_selector('.content').join(' ')
20
23
  end
21
24
 
22
25
  def test_adding_block
@@ -0,0 +1,139 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
+
3
+ # Test cases for the CssParser's loading functions.
4
+ class CssParserLoadingTests < Test::Unit::TestCase
5
+ include CssParser
6
+ include WEBrick
7
+
8
+ def setup
9
+ # from http://nullref.se/blog/2006/5/17/testing-with-webrick
10
+ @cp = Parser.new
11
+
12
+ @uri_base = 'http://localhost:12000'
13
+
14
+ @www_root = File.dirname(__FILE__) + '/fixtures/'
15
+
16
+ @server_thread = Thread.new do
17
+ s = WEBrick::HTTPServer.new(:Port => 12000, :DocumentRoot => @www_root, :Logger => Log.new(nil, BasicLog::FATAL), :AccessLog => [])
18
+ @port = s.config[:Port]
19
+ begin
20
+ s.start
21
+ ensure
22
+ s.shutdown
23
+ end
24
+ end
25
+
26
+ sleep 1 # ensure the server has time to load
27
+ end
28
+
29
+ def teardown
30
+ @server_thread.kill
31
+ @server_thread.join(5)
32
+ @server_thread = nil
33
+ end
34
+
35
+ def test_loading_a_local_file
36
+ file_name = File.dirname(__FILE__) + '/fixtures/simple.css'
37
+ @cp.load_file!(file_name)
38
+ assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
39
+ end
40
+
41
+ def test_loading_a_local_file_with_scheme
42
+ file_name = 'file://' + File.expand_path(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
+
47
+ def test_loading_a_remote_file
48
+ @cp.load_uri!("#{@uri_base}/simple.css")
49
+ assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
50
+ end
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
+
60
+ def test_following_at_import_rules_local
61
+ base_dir = File.dirname(__FILE__) + '/fixtures'
62
+ @cp.load_file!('import1.css', base_dir)
63
+
64
+ # from '/import1.css'
65
+ assert_equal 'color: lime;', @cp.find_by_selector('div').join(' ')
66
+
67
+ # from '/subdir/import2.css'
68
+ assert_equal 'text-decoration: none;', @cp.find_by_selector('a').join(' ')
69
+
70
+ # from '/subdir/../simple.css'
71
+ assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
72
+ end
73
+
74
+ def test_following_at_import_rules_remote
75
+ @cp.load_uri!("#{@uri_base}/import1.css")
76
+
77
+ # from '/import1.css'
78
+ assert_equal 'color: lime;', @cp.find_by_selector('div').join(' ')
79
+
80
+ # from '/subdir/import2.css'
81
+ assert_equal 'text-decoration: none;', @cp.find_by_selector('a').join(' ')
82
+
83
+ # from '/subdir/../simple.css'
84
+ assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
85
+ end
86
+
87
+ def test_following_at_import_rules_from_add_block
88
+ css_block = '@import "../simple.css";'
89
+
90
+ @cp.add_block!(css_block, :base_uri => "#{@uri_base}/subdir/")
91
+
92
+ # from 'simple.css'
93
+ assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
94
+ end
95
+
96
+ def test_importing_with_media_types
97
+ @cp.load_uri!("#{@uri_base}/import-with-media-types.css")
98
+
99
+ # from simple.css with :screen media type
100
+ assert_equal 'margin: 0px;', @cp.find_by_selector('p', :screen).join(' ')
101
+ assert_equal '', @cp.find_by_selector('p', :tty).join(' ')
102
+ end
103
+
104
+ def test_throwing_circular_reference_exception
105
+ assert_raise CircularReferenceError do
106
+ @cp.load_uri!("#{@uri_base}/import-circular-reference.css")
107
+ end
108
+
109
+ cp_without_exceptions = Parser.new(:io_exceptions => false)
110
+
111
+ assert_nothing_raised CircularReferenceError do
112
+ cp_without_exceptions.load_uri!("#{@uri_base}/import-circular-reference.css")
113
+ end
114
+
115
+ end
116
+
117
+ def test_toggling_circular_reference_exception
118
+ cp_without_exceptions = Parser.new(:io_exceptions => false)
119
+
120
+ assert_nothing_raised CircularReferenceError do
121
+ cp_without_exceptions.load_uri!("#{@uri_base}/import-circular-reference.css")
122
+ end
123
+ end
124
+
125
+ def test_toggling_not_found_exceptions
126
+ cp_with_exceptions = Parser.new(:io_exceptions => true)
127
+
128
+ assert_raise RemoteFileError do
129
+ cp_with_exceptions.load_uri!("#{@uri_base}/no-exist.xyz")
130
+ end
131
+
132
+ cp_without_exceptions = Parser.new(:io_exceptions => false)
133
+
134
+ assert_nothing_raised RemoteFileError do
135
+ cp_without_exceptions.load_uri!("#{@uri_base}/no-exist.xyz")
136
+ end
137
+ end
138
+
139
+ end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/test_helper'
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
2
 
3
3
  # Test cases for the handling of media types
4
4
  class CssParserMediaTypesTests < Test::Unit::TestCase
@@ -28,7 +28,7 @@ class CssParserMediaTypesTests < Test::Unit::TestCase
28
28
  assert_equal 'font-size: 13px; line-height: 1.2;', @cp.find_by_selector('body', :screen).join(' ')
29
29
  end
30
30
 
31
- def atest_finding_by_multiple_media_types
31
+ def test_finding_by_multiple_media_types
32
32
  css = <<-EOT
33
33
  @media print {
34
34
  body { font-size: 10pt }
@@ -55,14 +55,49 @@ class CssParserMediaTypesTests < Test::Unit::TestCase
55
55
  assert_equal 'font-size: 10pt;', @cp.find_by_selector('body', :screen).join(' ')
56
56
  assert @cp.find_by_selector('body', :handheld).empty?
57
57
  end
58
+
59
+ def test_adding_block_and_limiting_media_types1
60
+ css = <<-EOT
61
+ @import "import1.css", print
62
+ EOT
63
+
64
+ base_dir = File.dirname(__FILE__) + '/fixtures/'
65
+
66
+ @cp.add_block!(css, :only_media_types => :screen, :base_dir => base_dir)
67
+ assert @cp.find_by_selector('div').empty?
68
+
69
+ end
70
+
71
+ def test_adding_block_and_limiting_media_types2
72
+ css = <<-EOT
73
+ @import "import1.css", print
74
+ EOT
75
+
76
+ base_dir = File.dirname(__FILE__) + '/fixtures/'
77
+
78
+ @cp.add_block!(css, :only_media_types => :print, :base_dir => base_dir)
79
+ assert_match 'color: lime', @cp.find_by_selector('div').join(' ')
80
+ end
81
+
82
+ def test_adding_block_and_limiting_media_types
83
+ css = <<-EOT
84
+ @import "import1.css"
85
+ EOT
86
+
87
+ base_dir = File.dirname(__FILE__) + '/fixtures/'
88
+
89
+ @cp.add_block!(css, :only_media_types => :print, :base_dir => base_dir)
90
+ assert_match 'color: lime', @cp.find_by_selector('div').join(' ')
91
+ end
92
+
58
93
 
59
- def atest_adding_rule_set_with_media_type
94
+ def test_adding_rule_set_with_media_type
60
95
  @cp.add_rule!('body', 'color: black;', [:handheld,:tty])
61
96
  @cp.add_rule!('body', 'color: blue;', :screen)
62
97
  assert_equal 'color: black;', @cp.find_by_selector('body', :handheld).join(' ')
63
98
  end
64
99
 
65
- def atest_selecting_with_all_meda_type
100
+ def test_selecting_with_all_meda_type
66
101
  @cp.add_rule!('body', 'color: black;', [:handheld,:tty])
67
102
  assert_equal 'color: black;', @cp.find_by_selector('body', :all).join(' ')
68
103
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/test_helper'
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
2
 
3
3
  # Test cases for the CssParser.
4
4
  class CssParserTests < Test::Unit::TestCase
@@ -83,7 +83,6 @@ class CssParserTests < Test::Unit::TestCase
83
83
  end
84
84
 
85
85
  def test_ignoring_malformed_declarations
86
- flunk
87
86
  # dervived from http://www.w3.org/TR/CSS21/syndata.html#parsing-errors
88
87
  css = <<-EOT
89
88
  p { color:green }
@@ -1,5 +1,5 @@
1
1
  # coding: iso-8859-1
2
- require File.dirname(__FILE__) + '/test_helper'
2
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
3
3
 
4
4
  # Test cases for CSS regular expressions
5
5
  #
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'net/http'
4
+ require 'open-uri'
5
+ require 'WEBrick'
6
+ require File.dirname(__FILE__) + '/../lib/css_parser'
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/test_helper'
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
2
 
3
3
  class MergingTests < Test::Unit::TestCase
4
4
  include CssParser
@@ -85,4 +85,19 @@ class MergingTests < Test::Unit::TestCase
85
85
  merged = CssParser.merge(rs)
86
86
  assert_equal rs.object_id, merged.object_id
87
87
  end
88
+
89
+ def test_merging_important
90
+ rs1 = RuleSet.new(nil, 'color: black !important;')
91
+ rs2 = RuleSet.new(nil, 'color: red;')
92
+ merged = CssParser.merge(rs1, rs2)
93
+ assert_equal 'black !important;', merged['color']
94
+ end
95
+
96
+ def test_merging_shorthand_important
97
+ rs1 = RuleSet.new(nil, 'background: black none !important;')
98
+ rs2 = RuleSet.new(nil, 'background-color: red;')
99
+ merged = CssParser.merge(rs1, rs2)
100
+ assert_equal 'black !important;', merged['background-color']
101
+ end
102
+
88
103
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/test_helper'
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
2
  require "set"
3
3
 
4
4
  # Test cases for parsing CSS blocks
@@ -60,12 +60,27 @@ class RuleSetTests < Test::Unit::TestCase
60
60
  assert_equal(expected, actual)
61
61
  end
62
62
 
63
+ def test_each_declaration_respects_order
64
+ css_fragment = "margin: 0; padding: 20px; margin-bottom: 28px;"
65
+ rs = RuleSet.new(nil, css_fragment)
66
+ expected = %w(margin padding margin-bottom)
67
+ actual = []
68
+ rs.each_declaration { |prop, val, imp| actual << prop }
69
+ assert_equal(expected, actual)
70
+ end
71
+
63
72
  def test_declarations_to_s
64
73
  declarations = 'color: #fff; font-weight: bold;'
65
74
  rs = RuleSet.new('#content p, a', declarations)
66
75
  assert_equal(declarations.split(' ').sort, rs.declarations_to_s.split(' ').sort)
67
76
  end
68
77
 
78
+ def test_important_declarations_to_s
79
+ declarations = 'color: #fff; font-weight: bold !important;'
80
+ rs = RuleSet.new('#content p, a', declarations)
81
+ assert_equal(declarations.split(' ').sort, rs.declarations_to_s.split(' ').sort)
82
+ end
83
+
69
84
  def test_overriding_specificity
70
85
  rs = RuleSet.new('#content p, a', 'color: white', 1000)
71
86
  rs.each_selector do |sel, decs, spec|