stylesheet 0.1.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 (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