stylesheet 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/.gitignore +20 -0
  2. data/Gemfile +4 -0
  3. data/Guardfile +9 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +63 -0
  6. data/Rakefile +22 -0
  7. data/features/document_styles.feature +15 -0
  8. data/features/rule_declarations.feature +9 -0
  9. data/features/step_definitions/document_steps.rb +39 -0
  10. data/features/step_definitions/rule_declaration_steps.rb +13 -0
  11. data/features/step_definitions/style_rule_steps.rb +31 -0
  12. data/features/style_rules.feature +15 -0
  13. data/features/support/env.rb +6 -0
  14. data/lib/stylesheet.rb +35 -0
  15. data/lib/stylesheet/css_charset_rule.rb +24 -0
  16. data/lib/stylesheet/css_font_face_rule.rb +26 -0
  17. data/lib/stylesheet/css_import_rule.rb +41 -0
  18. data/lib/stylesheet/css_media_rule.rb +30 -0
  19. data/lib/stylesheet/css_rule.rb +57 -0
  20. data/lib/stylesheet/css_rule_list.rb +30 -0
  21. data/lib/stylesheet/css_style_declaration.rb +41 -0
  22. data/lib/stylesheet/css_style_rule.rb +29 -0
  23. data/lib/stylesheet/css_style_sheet.rb +100 -0
  24. data/lib/stylesheet/document.rb +63 -0
  25. data/lib/stylesheet/errors.rb +5 -0
  26. data/lib/stylesheet/inflector.rb +11 -0
  27. data/lib/stylesheet/location.rb +113 -0
  28. data/lib/stylesheet/media_list.rb +26 -0
  29. data/lib/stylesheet/request.rb +23 -0
  30. data/lib/stylesheet/style_sheet_list.rb +15 -0
  31. data/lib/stylesheet/version.rb +3 -0
  32. data/spec/css_charset_rule_spec.rb +39 -0
  33. data/spec/css_font_face_rule_spec.rb +47 -0
  34. data/spec/css_import_rule_spec.rb +178 -0
  35. data/spec/css_media_rule_spec.rb +57 -0
  36. data/spec/css_rule_list_spec.rb +74 -0
  37. data/spec/css_rule_spec.rb +102 -0
  38. data/spec/css_style_declaration_spec.rb +71 -0
  39. data/spec/css_style_rule_spec.rb +53 -0
  40. data/spec/css_style_sheet_spec.rb +157 -0
  41. data/spec/document_spec.rb +99 -0
  42. data/spec/fixtures/css/absolute_path.html +14 -0
  43. data/spec/fixtures/css/charset.html +13 -0
  44. data/spec/fixtures/css/font_face.html +13 -0
  45. data/spec/fixtures/css/full_url.html +14 -0
  46. data/spec/fixtures/css/html4.html +15 -0
  47. data/spec/fixtures/css/html5.html +14 -0
  48. data/spec/fixtures/css/inline.html +33 -0
  49. data/spec/fixtures/css/inline_import.html +15 -0
  50. data/spec/fixtures/css/invalid.html +14 -0
  51. data/spec/fixtures/css/media.html +13 -0
  52. data/spec/fixtures/css/relative_path.html +14 -0
  53. data/spec/fixtures/css/stylesheets/charset.css +5 -0
  54. data/spec/fixtures/css/stylesheets/colors.css +0 -0
  55. data/spec/fixtures/css/stylesheets/font_face.css +6 -0
  56. data/spec/fixtures/css/stylesheets/fonts.css +0 -0
  57. data/spec/fixtures/css/stylesheets/media.css +3 -0
  58. data/spec/fixtures/css/stylesheets/print.css +3 -0
  59. data/spec/fixtures/css/stylesheets/screen.css +16 -0
  60. data/spec/fixtures/css_import/index.html +14 -0
  61. data/spec/fixtures/css_import/stylesheets/import1.css +3 -0
  62. data/spec/fixtures/css_import/stylesheets/import2.css +3 -0
  63. data/spec/fixtures/css_import/stylesheets/import3.css +3 -0
  64. data/spec/fixtures/css_import/stylesheets/import4.css +3 -0
  65. data/spec/fixtures/css_import/stylesheets/import5.css +3 -0
  66. data/spec/fixtures/css_import/stylesheets/import6.css +3 -0
  67. data/spec/fixtures/css_import/stylesheets/import7.css +3 -0
  68. data/spec/fixtures/css_import/stylesheets/import8.css +3 -0
  69. data/spec/fixtures/css_import/stylesheets/import9.css +3 -0
  70. data/spec/fixtures/css_import/stylesheets/print.css +3 -0
  71. data/spec/fixtures/css_import/stylesheets/screen.css +15 -0
  72. data/spec/fixtures/fonts/VeraSeBd.ttf +0 -0
  73. data/spec/inflector_spec.rb +17 -0
  74. data/spec/location_spec.rb +260 -0
  75. data/spec/media_list_spec.rb +108 -0
  76. data/spec/spec_helper.rb +10 -0
  77. data/spec/stubs/fake_request.rb +19 -0
  78. data/spec/style_sheet_list_spec.rb +53 -0
  79. data/spec/version_spec.rb +9 -0
  80. data/stylesheet.gemspec +34 -0
  81. metadata +294 -0
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Stylesheet</title>
7
+
8
+ <link rel="stylesheet" href="/css/stylesheets/screen.css" media="screen" type="text/css" />
9
+ <link rel="stylesheet" href="/css/stylesheets/print.css" media="print" type="text/css" />
10
+ </head>
11
+ <body>
12
+ <div></div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Stylesheet</title>
7
+
8
+ <link rel="stylesheet" href="stylesheets/charset.css" media="screen" type="text/css" />
9
+ </head>
10
+ <body>
11
+ <div></div>
12
+ </body>
13
+ </html>
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Stylesheet</title>
7
+
8
+ <link rel="stylesheet" href="stylesheets/font_face.css" media="screen" type="text/css" />
9
+ </head>
10
+ <body>
11
+ <div></div>
12
+ </body>
13
+ </html>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Stylesheet</title>
7
+
8
+ <link rel="stylesheet" href="http://example.com/css/stylesheets/screen.css" media="screen" type="text/css" />
9
+ <link rel="stylesheet" href="http://example.com/css/stylesheets/print.css" media="print" type="text/css" />
10
+ </head>
11
+ <body>
12
+ <div></div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
4
+
5
+ <head>
6
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
7
+ <title>Color Parser</title>
8
+
9
+ <link rel="stylesheet" href="http://example.com/css/stylesheets/screen.css" media="screen" type="text/css" />
10
+ <link rel="stylesheet" href="http://example.com/css/stylesheets/print.css" media="print" type="text/css" />
11
+ </head>
12
+ <body>
13
+ <div></div>
14
+ </body>
15
+ </html>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Stylesheet</title>
7
+
8
+ <link rel="stylesheet" href="http://example.com/css/stylesheets/screen.css" media="screen" type="text/css" />
9
+ <link rel="stylesheet" href="http://example.com/css/stylesheets/print.css" media="print" type="text/css" />
10
+ </head>
11
+ <body>
12
+ <div></div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,33 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Stylesheet</title>
7
+ <style>
8
+ body {
9
+ color: #444;
10
+ background-color: #535353;
11
+ }
12
+ a:link {
13
+ color: #357ad1;
14
+ }
15
+ a:visited {
16
+ color: #77abf0;
17
+ }
18
+ a:hover {
19
+ color: #333;
20
+ }
21
+ </style>
22
+ </head>
23
+ <body>
24
+ <style>
25
+ div {
26
+ background-color: #aaa;
27
+ border: 1px solid #ccc;
28
+ }
29
+ </style>
30
+
31
+ <div></div>
32
+ </body>
33
+ </html>
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Stylesheet</title>
7
+ <style>
8
+ @import "stylesheets/print.css";@import url "stylesheets/fonts.css"
9
+ @import url("stylesheets/colors.css")
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div></div>
14
+ </body>
15
+ </html>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Stylesheet</title>
7
+
8
+ <link rel="stylesheet" href="stylesheets/asdf.css" media="screen" type="text/css" />
9
+ <link rel="stylesheet" href="stylesheets/screen.css" media="screen" type="text/css" />
10
+ </head>
11
+ <body>
12
+ <div></div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Stylesheet</title>
7
+
8
+ <link rel="stylesheet" href="stylesheets/media.css" media="screen" type="text/css" />
9
+ </head>
10
+ <body>
11
+ <div></div>
12
+ </body>
13
+ </html>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Stylesheet</title>
7
+
8
+ <link rel="stylesheet" href="stylesheets/screen.css" media="screen" type="text/css" />
9
+ <link rel="stylesheet" href="stylesheets/print.css" media="print" type="text/css" />
10
+ </head>
11
+ <body>
12
+ <div></div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,5 @@
1
+ @charset "UTF-8";
2
+
3
+ body {
4
+ font-weight: bold;
5
+ }
File without changes
@@ -0,0 +1,6 @@
1
+ @font-face {
2
+ font-family: "Bitstream Vera Serif Bold";
3
+ src: url("http://example.com/fonts/VeraSeBd.ttf");
4
+ }
5
+
6
+ body { font-family: "Bitstream Vera Serif Bold", serif }
File without changes
@@ -0,0 +1,3 @@
1
+ @media only screen and (max-width: 850px) {
2
+ font-weight: bold;
3
+ }
@@ -0,0 +1,3 @@
1
+ body {
2
+ margin: 0;
3
+ }
@@ -0,0 +1,16 @@
1
+ body {
2
+ color: #444;
3
+ background-color: #535353;
4
+ }
5
+ a:link {
6
+ color: #357ad1;
7
+ }
8
+ a:visited {
9
+ color: #77abf0;
10
+ }
11
+ a:hover {
12
+ color: #333;
13
+ }
14
+ .shade {
15
+ background-color: #f5f5f5;
16
+ }
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
6
+ <title>Stylesheet</title>
7
+
8
+ <link rel="stylesheet" href="stylesheets/screen.css" media="screen" type="text/css" />
9
+ <link rel="stylesheet" href="stylesheets/print.css" media="screen" type="text/css" />
10
+ </head>
11
+ <body>
12
+ <div></div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,3 @@
1
+ .style1 {
2
+ border: 1px solid red;
3
+ }
@@ -0,0 +1,3 @@
1
+ .style2 {
2
+ border: 1px solid blue;
3
+ }
@@ -0,0 +1,3 @@
1
+ .style3 {
2
+ border: 1px solid blue;
3
+ }
@@ -0,0 +1,3 @@
1
+ .style4 {
2
+ border: 1px solid yellow;
3
+ }
@@ -0,0 +1,3 @@
1
+ .style5 {
2
+ border: 1px solid orange;
3
+ }
@@ -0,0 +1,3 @@
1
+ .style6 {
2
+ border: 1px solid pink;
3
+ }
@@ -0,0 +1,3 @@
1
+ .style7 {
2
+ border: 1px solid black;
3
+ }
@@ -0,0 +1,3 @@
1
+ .style8 {
2
+ border: 1px solid purple;
3
+ }
@@ -0,0 +1,3 @@
1
+ .style9 {
2
+ border: 1px solid teal;
3
+ }
@@ -0,0 +1,3 @@
1
+ body {
2
+ margin: 0;
3
+ }
@@ -0,0 +1,15 @@
1
+ @import url("import1.css");
2
+ @import url('/css_import/stylesheets/import2.css');
3
+ @import url(http://example.com/css_import/stylesheets/import3.css);
4
+ @import "import4.css";
5
+ @import "import5.css" screen;
6
+ @import "import6.css" screen, projection;
7
+ @import url("import7.css") print;
8
+ @import url("import8.css") screen and (orientation:landscape);
9
+ @import url("invalid.css");
10
+
11
+ body {
12
+ color: #444;
13
+ background-color: #535353;
14
+ }
15
+
Binary file
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Inflector do
4
+ describe ".camelize" do
5
+ it "should camelize a dashed css property" do
6
+ dashed = "background-color"
7
+ expect(Inflector.camelize(dashed)).to eq "backgroundColor"
8
+ end
9
+ end
10
+
11
+ describe ".dasherize" do
12
+ it "should dasherize camelized css property" do
13
+ camelized = "backgroundColor"
14
+ expect(Inflector.dasherize(camelized)).to eq "background-color"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,260 @@
1
+ require 'spec_helper'
2
+
3
+ describe Location do
4
+ let(:url) { "http://initvisual.com:80/services?foo=bar#abc" }
5
+
6
+ describe "#new without parent" do
7
+ it "should parse out parts of url" do
8
+ location = Location.new(url)
9
+ expect(location.host).to eq "initvisual.com"
10
+ end
11
+
12
+ it "should accept relative urls" do
13
+ location = Location.new("/some/path.html")
14
+ expect(location.to_s).to eq "/some/path.html"
15
+ end
16
+
17
+ it "should throw error for invalid host" do
18
+ expect { Location.new("http://") }.to raise_error(InvalidLocationError)
19
+ end
20
+ end
21
+
22
+
23
+ describe "#new with parent" do
24
+ it "should not expand a full url" do
25
+ parent = Location.new("http://example.com/css/url.html")
26
+ location = Location.new("http://example.com/css/stylesheets/screen.css", parent)
27
+
28
+ expect(location.to_s).to eq "http://example.com/css/stylesheets/screen.css"
29
+ end
30
+
31
+ it "should expand a relative path into a full path given the parent" do
32
+ parent = Location.new("http://example.com/css/relative.html")
33
+ location = Location.new("stylesheets/screen.css", parent)
34
+
35
+ expect(location.to_s).to eq "http://example.com/css/stylesheets/screen.css"
36
+ end
37
+
38
+ it "should expand a absolute path into a full path given the parent" do
39
+ parent = Location.new("http://example.com/css/absolute.html")
40
+ location = Location.new("/css/stylesheets/screen.css", parent)
41
+
42
+ expect(location.to_s).to eq "http://example.com/css/stylesheets/screen.css"
43
+ end
44
+ end
45
+
46
+
47
+ describe "#host" do
48
+ it "should parse out the url host" do
49
+ location = Location.new(url)
50
+ expect(location.host).to eq "initvisual.com"
51
+ end
52
+ end
53
+
54
+ describe "#host=" do
55
+ it "should assign host to url" do
56
+ location = Location.new(url)
57
+
58
+ location.host = "derekdevries.com"
59
+ expect(location.host).to eq "derekdevries.com"
60
+ end
61
+ end
62
+
63
+ describe "#hostname" do
64
+ it "should parse out the url hostname" do
65
+ location = Location.new(url)
66
+ expect(location.hostname).to eq "initvisual.com"
67
+ end
68
+ end
69
+
70
+ describe "#hostname=" do
71
+ it "should assign hostname to url" do
72
+ location = Location.new(url)
73
+
74
+ location.hostname = "derekdevries.com"
75
+ expect(location.hostname).to eq "derekdevries.com"
76
+ end
77
+ end
78
+
79
+ describe "#pathname" do
80
+ it "should parse out the url pathname" do
81
+ location = Location.new(url)
82
+ expect(location.pathname).to eq "/services"
83
+ end
84
+ end
85
+
86
+ describe "#pathname=" do
87
+ it "should assign path to url" do
88
+ location = Location.new(url)
89
+
90
+ location.pathname = "/work"
91
+ expect(location.pathname).to eq "/work"
92
+ end
93
+
94
+ it "add initial forward-slash if not given" do
95
+ location = Location.new(url)
96
+
97
+ location.pathname = "work"
98
+ expect(location.pathname).to eq "/work"
99
+ end
100
+ end
101
+
102
+ describe "#hash" do
103
+ it "should parse out the url hash" do
104
+ location = Location.new(url)
105
+ expect(location.hash).to eq "#abc"
106
+ end
107
+ end
108
+
109
+ describe "#hash=" do
110
+ it "should assign hash to url" do
111
+ location = Location.new(url)
112
+
113
+ location.hash = "#def"
114
+ expect(location.hash).to eq "#def"
115
+ end
116
+
117
+ it "add hash character if not given" do
118
+ location = Location.new(url)
119
+
120
+ location.hash = "def"
121
+ expect(location.hash).to eq "#def"
122
+ end
123
+ end
124
+
125
+ describe "#protocol" do
126
+ it "should parse out the url protocol" do
127
+ location = Location.new(url)
128
+ expect(location.protocol).to eq "http:"
129
+ end
130
+ end
131
+
132
+ describe "#protocol=" do
133
+ it "should assign protocol to url" do
134
+ location = Location.new(url)
135
+
136
+ location.protocol = "https:"
137
+ expect(location.protocol).to eq "https:"
138
+ end
139
+
140
+ it "add colon character if not given" do
141
+ location = Location.new(url)
142
+
143
+ location.protocol = "https"
144
+ expect(location.protocol).to eq "https:"
145
+ end
146
+ end
147
+
148
+ describe "#search" do
149
+ it "should parse out the url query string" do
150
+ location = Location.new(url)
151
+ expect(location.search).to eq "?foo=bar"
152
+ end
153
+ end
154
+
155
+ describe "#search=" do
156
+ it "should assign query string to url" do
157
+ location = Location.new(url)
158
+
159
+ location.search = "?bar=baz"
160
+ expect(location.search).to eq "?bar=baz"
161
+ end
162
+
163
+ it "add question mark to query string if not given" do
164
+ location = Location.new(url)
165
+
166
+ location.search = "bar=baz"
167
+ expect(location.search).to eq "?bar=baz"
168
+ end
169
+ end
170
+
171
+ describe "#href" do
172
+ it "should show the stringified version of the url" do
173
+ location = Location.new(url)
174
+ expect(location.href).to eq "http://initvisual.com/services?foo=bar#abc"
175
+ end
176
+ end
177
+
178
+ describe "#port" do
179
+ it "should parse out the url port" do
180
+ url = "http://initvisual.com:8080/services?foo=bar#abc"
181
+ location = Location.new(url)
182
+ expect(location.port).to eq "8080"
183
+ end
184
+
185
+ it "should ignore port 80 on http" do
186
+ url = "http://initvisual.com:80/services?foo=bar#abc"
187
+ location = Location.new(url)
188
+ expect(location.port).to eq ""
189
+ end
190
+
191
+ it "should show port 80 on https" do
192
+ url = "https://initvisual.com:80/services?foo=bar#abc"
193
+ location = Location.new(url)
194
+ expect(location.port).to eq "80"
195
+ end
196
+
197
+ it "should ignore port 443 on https" do
198
+ url = "https://initvisual.com:443/services?foo=bar#abc"
199
+ location = Location.new(url)
200
+ expect(location.port).to eq ""
201
+ end
202
+
203
+ it "should show port 443 on http" do
204
+ url = "http://initvisual.com:443/services?foo=bar#abc"
205
+ location = Location.new(url)
206
+ expect(location.port).to eq "443"
207
+ end
208
+ end
209
+
210
+ describe "#to_s" do
211
+ it "should rebuild url from parts" do
212
+ u = "http://initvisual.com:8080/services?foo=bar#abc"
213
+ location = Location.new(u)
214
+ expect(location.to_s).to eq u
215
+ end
216
+
217
+ it "should ignore hash if no hash present" do
218
+ url = "http://initvisual.com/services?foo=bar#abc"
219
+ location = Location.new(url)
220
+ location.hash = ""
221
+ expect(location.to_s).to eq "http://initvisual.com/services?foo=bar"
222
+ end
223
+
224
+ it "should ignore port if no port present" do
225
+ url = "https://initvisual.com/services?foo=bar#abc"
226
+ location = Location.new(url)
227
+ expect(location.to_s).to eq url
228
+ end
229
+
230
+ it "should ignore query string if no query string present" do
231
+ url = "https://initvisual.com/services"
232
+ location = Location.new(url)
233
+ expect(location.to_s).to eq url
234
+ end
235
+
236
+ it "should ignore scheme if no protocol is present" do
237
+ url = "/services"
238
+ location = Location.new(url)
239
+ expect(location.to_s).to eq url
240
+ end
241
+ end
242
+
243
+ describe "#valid?" do
244
+ it "should be true with a valid host and protocol" do
245
+ location = Location.new("http://initvisual.com")
246
+ expect(location.valid?).to be_true
247
+ end
248
+
249
+ it "should be false for an invalid host" do
250
+ location = Location.new("/asdf")
251
+ expect(location.valid?).to be_false
252
+ end
253
+
254
+ it "should be false for an invalid protocol" do
255
+ location = Location.new("foo.com/asdf")
256
+ expect(location.valid?).to be_false
257
+ end
258
+ end
259
+
260
+ end