stylesheet 0.1.0 → 0.1.1
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/README.md +33 -19
- data/lib/stylesheet/css_import_rule.rb +3 -1
- data/lib/stylesheet/css_rule_list.rb +5 -2
- data/lib/stylesheet/css_style_declaration.rb +8 -7
- data/lib/stylesheet/css_style_sheet.rb +26 -17
- data/lib/stylesheet/request.rb +2 -2
- data/lib/stylesheet/version.rb +1 -1
- data/spec/css_import_rule_spec.rb +2 -2
- data/spec/css_rule_list_spec.rb +20 -1
- data/spec/css_style_declaration_spec.rb +11 -0
- data/spec/css_style_sheet_spec.rb +36 -5
- data/spec/request_spec.rb +12 -0
- data/stylesheet.gemspec +1 -1
- metadata +6 -4
data/README.md
CHANGED
@@ -8,52 +8,66 @@ Get styles from a document:
|
|
8
8
|
|
9
9
|
```ruby
|
10
10
|
document = Stylesheet::Document.new("http://sportspyder.com")
|
11
|
+
=> #<Document location:http://sportspyder.com/>
|
12
|
+
|
11
13
|
document.style_sheets
|
14
|
+
=> [#<Stylesheet::CssStyleSheet:0x007fa905c58c20>,
|
15
|
+
#<Stylesheet::CssStyleSheet:0x007fa905c5f430>,
|
16
|
+
#<Stylesheet::CssStyleSheet:0x007fa905c5e968>]
|
12
17
|
```
|
13
18
|
|
14
19
|
Get attributes of a stylesheet:
|
15
20
|
|
16
21
|
```ruby
|
17
22
|
sheet = document.style_sheets[0]
|
18
|
-
|
19
|
-
|
23
|
+
=> #<Stylesheet::CssStyleSheet:0x007fa905c58c20>
|
24
|
+
|
25
|
+
sheet.href
|
26
|
+
=> "http://sportspyder.com/assets/application-26ff2c8d54ab9cd8e74af60fc650390e.css"
|
27
|
+
|
28
|
+
sheet.type
|
29
|
+
=> "text/css"
|
20
30
|
```
|
21
31
|
|
22
32
|
Get stylesheet media definitions:
|
23
33
|
|
24
34
|
```ruby
|
25
|
-
sheet
|
26
|
-
|
27
|
-
puts media
|
28
|
-
end
|
35
|
+
sheet.media.map {|medium| medium }
|
36
|
+
=> ["screen"]
|
29
37
|
```
|
30
38
|
|
31
39
|
Get rules defined in a stylesheet:
|
32
40
|
|
33
41
|
```ruby
|
34
42
|
sheet = Stylesheet::CssStyleSheet.new("http://sportspyder.com/stylesheets/screen.css")
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
43
|
+
=> #<Stylesheet::CssStyleSheet:0x007fa905c58c20>
|
44
|
+
|
45
|
+
rule = sheet.css_rules[0]
|
46
|
+
=> #<Stylesheet::CssStyleRule>
|
47
|
+
|
48
|
+
rule.css_text
|
49
|
+
=> "iframe.editor{width:580px;height:150px;border:1px solid #ccc;background-color:#fff}"
|
50
|
+
|
51
|
+
rule.selector_text
|
52
|
+
=> "iframe.editor"
|
39
53
|
```
|
40
54
|
|
41
55
|
Get declarations defined in a style rules:
|
42
56
|
|
43
57
|
```ruby
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
58
|
+
rule.style[0]
|
59
|
+
=> "width:580px"
|
60
|
+
|
61
|
+
rule.style.border
|
62
|
+
=> "1px solid #ccc"
|
48
63
|
```
|
49
64
|
|
50
65
|
## Installation
|
51
66
|
|
52
|
-
|
53
|
-
|
54
|
-
```
|
55
|
-
|
56
|
-
gem "stylesheet"
|
67
|
+
To install Stylesheet, add the gem to your Gemfile:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
gem "stylesheet", "~> 0.1.0"
|
57
71
|
```
|
58
72
|
|
59
73
|
## LICENSE
|
@@ -12,7 +12,9 @@ module Stylesheet
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def style_sheet
|
15
|
-
@style_sheet ||= CssStyleSheet.new(location.href
|
15
|
+
@style_sheet ||= CssStyleSheet.new(:href => location.href,
|
16
|
+
:owner_rule => self,
|
17
|
+
:parent => parent_style_sheet)
|
16
18
|
end
|
17
19
|
|
18
20
|
def self.matches_rule?(text)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Stylesheet
|
2
2
|
class CssRuleList
|
3
3
|
extend Forwardable
|
4
|
-
def_delegators :@rules, :length, :size, :[], :each, :to_s
|
4
|
+
def_delegators :@rules, :length, :size, :[], :each, :insert, :delete_at, :to_s
|
5
5
|
include Enumerable
|
6
6
|
|
7
7
|
def initialize(rules, parent = nil)
|
@@ -11,10 +11,13 @@ module Stylesheet
|
|
11
11
|
def item(index)
|
12
12
|
@rules[index]
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
private
|
16
16
|
|
17
17
|
def parse(rules, parent)
|
18
|
+
# clean out comments
|
19
|
+
rules = rules.gsub(/\/\*[\s\S]*?\*\//, '')
|
20
|
+
|
18
21
|
# clean extraneous whitespace
|
19
22
|
rules = rules.to_s.gsub(/\s+/m, " ").gsub(/([\};])\s/, '\1')
|
20
23
|
|
@@ -1,35 +1,36 @@
|
|
1
1
|
module Stylesheet
|
2
2
|
class CssStyleDeclaration
|
3
3
|
extend Forwardable
|
4
|
-
def_delegators :@
|
4
|
+
def_delegators :@declarations_list, :length, :size, :[], :each, :<<, :push, :delete, :to_s
|
5
5
|
include Enumerable
|
6
6
|
|
7
|
-
attr_reader :parent_rule
|
7
|
+
attr_reader :declarations, :parent_rule
|
8
8
|
|
9
9
|
def initialize(options={})
|
10
|
+
@declarations = Hash.new("")
|
10
11
|
@parent_rule = options[:parent_rule]
|
11
12
|
self.css_text = options[:css_text]
|
12
13
|
end
|
13
14
|
|
14
15
|
def css_text=(css_text)
|
15
|
-
@
|
16
|
+
@declarations_list = []
|
16
17
|
|
17
18
|
css_text.to_s.strip.chomp(";").split(";").each do |declaration|
|
18
19
|
property, value = declaration.split(":", 2)
|
19
|
-
@
|
20
|
-
@
|
20
|
+
@declarations_list << declaration.strip
|
21
|
+
@declarations[property.strip] = parse_value(value.strip)
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
25
|
def css_text
|
25
|
-
css_text = @
|
26
|
+
css_text = @declarations_list.join("; ")
|
26
27
|
css_text += ";" if css_text != ""
|
27
28
|
end
|
28
29
|
|
29
30
|
alias_method :to_s, :css_text
|
30
31
|
|
31
32
|
def method_missing(name, *args)
|
32
|
-
@
|
33
|
+
@declarations[Inflector.dasherize(name.to_s)]
|
33
34
|
end
|
34
35
|
|
35
36
|
private
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module Stylesheet
|
2
2
|
class CssStyleSheet
|
3
3
|
attr_accessor :parent, :title
|
4
|
-
attr_reader :href, :media
|
4
|
+
attr_reader :href, :media, :owner_rule
|
5
5
|
attr_writer :disabled, :type
|
6
|
-
|
6
|
+
|
7
7
|
def initialize(args)
|
8
8
|
if args.kind_of?(String)
|
9
9
|
init_with_url(args)
|
@@ -11,18 +11,19 @@ module Stylesheet
|
|
11
11
|
init_with_hash(args)
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def init_with_url(url)
|
16
16
|
self.href = url
|
17
17
|
self.media = ""
|
18
18
|
self.content = nil
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def init_with_hash(args)
|
22
|
-
@parent
|
23
|
-
@title
|
24
|
-
@type
|
25
|
-
|
22
|
+
@parent = args[:parent]
|
23
|
+
@title = args[:title]
|
24
|
+
@type = args[:type]
|
25
|
+
@owner_rule = args[:owner_rule]
|
26
|
+
|
26
27
|
self.href = args[:href]
|
27
28
|
self.location = args[:location]
|
28
29
|
self.media = args[:media]
|
@@ -32,25 +33,25 @@ module Stylesheet
|
|
32
33
|
def disabled?
|
33
34
|
@disabled || false
|
34
35
|
end
|
35
|
-
|
36
|
+
|
36
37
|
def type
|
37
38
|
@type || "text/css"
|
38
39
|
end
|
39
|
-
|
40
|
+
|
40
41
|
def href=(url)
|
41
42
|
return unless url
|
42
43
|
@url = url
|
43
44
|
@href = location.to_s
|
44
45
|
end
|
45
|
-
|
46
|
+
|
46
47
|
def media=(media)
|
47
48
|
@media ||= MediaList.new(media)
|
48
49
|
end
|
49
|
-
|
50
|
+
|
50
51
|
def content=(content)
|
51
52
|
@content = content if content != ""
|
52
53
|
end
|
53
|
-
|
54
|
+
|
54
55
|
def content
|
55
56
|
@content ||= request_content
|
56
57
|
end
|
@@ -62,14 +63,22 @@ module Stylesheet
|
|
62
63
|
alias_method :rules, :css_rules
|
63
64
|
|
64
65
|
def parent_style_sheet
|
65
|
-
parent
|
66
|
+
@parent if @owner_rule
|
67
|
+
end
|
68
|
+
|
69
|
+
def delete_rule(index)
|
70
|
+
@css_rules.delete_at(index)
|
71
|
+
end
|
72
|
+
|
73
|
+
def insert_rule(rule, index)
|
74
|
+
@css_rules.insert(index, rule)
|
66
75
|
end
|
67
|
-
|
76
|
+
|
68
77
|
def location
|
69
78
|
return if inline_css?
|
70
79
|
@location ||= Location.new(@url, parent && parent.location)
|
71
80
|
end
|
72
|
-
|
81
|
+
|
73
82
|
def location=(location)
|
74
83
|
return unless location
|
75
84
|
|
@@ -83,7 +92,7 @@ module Stylesheet
|
|
83
92
|
def standalone_css?
|
84
93
|
!parent
|
85
94
|
end
|
86
|
-
|
95
|
+
|
87
96
|
def inline_css?
|
88
97
|
!@url || @url == ""
|
89
98
|
end
|
data/lib/stylesheet/request.rb
CHANGED
@@ -8,12 +8,12 @@ module Stylesheet
|
|
8
8
|
|
9
9
|
curl.body_str
|
10
10
|
|
11
|
-
rescue
|
11
|
+
rescue Stylesheet::Error
|
12
12
|
raise
|
13
13
|
|
14
14
|
# re-raise external library errors in our namespace
|
15
15
|
rescue => error
|
16
|
-
raise
|
16
|
+
raise Stylesheet::Error.new("#{error.class}: #{error.message}")
|
17
17
|
end
|
18
18
|
|
19
19
|
def user_agent
|
data/lib/stylesheet/version.rb
CHANGED
@@ -21,9 +21,9 @@ describe CssImportRule do
|
|
21
21
|
let(:parent) do
|
22
22
|
CssStyleSheet.new("http://example.com/css_import/stylesheets/screen.css")
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
let(:rule_url) { "http://example.com/css_import/stylesheets/import1.css" }
|
26
|
-
|
26
|
+
|
27
27
|
it "parses an url from the style rule" do
|
28
28
|
css_text = "@import url(\"http://example.com/css_import/stylesheets/import1.css\");"
|
29
29
|
|
data/spec/css_rule_list_spec.rb
CHANGED
@@ -23,7 +23,19 @@ describe CssRuleList do
|
|
23
23
|
src: url(\"http://example.com/fonts/VeraSeBd.ttf\");
|
24
24
|
}"
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
|
+
let(:style_w_comments) do
|
28
|
+
"body {
|
29
|
+
color: #444;
|
30
|
+
background-color: #535353;
|
31
|
+
}
|
32
|
+
|
33
|
+
/* style paragraphs */
|
34
|
+
p {
|
35
|
+
font-size: 90%;
|
36
|
+
}"
|
37
|
+
end
|
38
|
+
|
27
39
|
describe ".new" do
|
28
40
|
it "parses charset rules" do
|
29
41
|
rules = CssRuleList.new(styles)
|
@@ -49,6 +61,13 @@ describe CssRuleList do
|
|
49
61
|
rules = CssRuleList.new(styles)
|
50
62
|
expect(rules[4]).to be_kind_of(CssFontFaceRule)
|
51
63
|
end
|
64
|
+
|
65
|
+
it "removes comments" do
|
66
|
+
rules = CssRuleList.new(style_w_comments)
|
67
|
+
expect(rules.length).to eq 2
|
68
|
+
expect(rules[0].css_text).to eq "body { color: #444;background-color: #535353;}"
|
69
|
+
expect(rules[1].css_text).to eq "p { font-size: 90%;}"
|
70
|
+
end
|
52
71
|
end
|
53
72
|
|
54
73
|
describe "#[]" do
|
@@ -51,6 +51,17 @@ describe CssStyleDeclaration do
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
describe "rules" do
|
55
|
+
it "returns a hash of rules" do
|
56
|
+
expected = {"color" => "#444",
|
57
|
+
"font-size" => "12px",
|
58
|
+
"font-family" => "Arial, Verdana",
|
59
|
+
"border-left" => "1px solid red",
|
60
|
+
"border-right-width" => "1px",
|
61
|
+
"background-color" => "#535353"}
|
62
|
+
expect(declaration.declarations).to eq expected
|
63
|
+
end
|
64
|
+
end
|
54
65
|
|
55
66
|
describe "#parent_rule" do
|
56
67
|
it "returns the parent css style rule" do
|
@@ -90,15 +90,20 @@ describe CssStyleSheet do
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
describe "#
|
94
|
-
|
93
|
+
describe "#parent_style_sheet" do
|
94
|
+
let(:parent) do
|
95
|
+
CssStyleSheet.new("http://example.com/css_import/stylesheets/screen.css")
|
96
|
+
end
|
95
97
|
|
98
|
+
it "should be nil for non-imported sheets" do
|
99
|
+
expect(parent.parent_style_sheet).to be_nil
|
96
100
|
end
|
97
|
-
|
98
|
-
|
99
|
-
describe "#parent_style_sheet" do
|
101
|
+
|
100
102
|
it "references parent style sheet" do
|
103
|
+
text = "@import url(\"import1.css\");"
|
104
|
+
rule = CssImportRule.new(:css_text => text, :parent_style_sheet => parent)
|
101
105
|
|
106
|
+
expect(rule.style_sheet.parent_style_sheet).to eq parent
|
102
107
|
end
|
103
108
|
end
|
104
109
|
|
@@ -138,20 +143,46 @@ describe CssStyleSheet do
|
|
138
143
|
end
|
139
144
|
|
140
145
|
describe "#owner_rule" do
|
146
|
+
let(:parent) do
|
147
|
+
CssStyleSheet.new("http://example.com/css_import/stylesheets/screen.css")
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should be nil for non-imported sheets" do
|
151
|
+
expect(parent.owner_rule).to be_nil
|
152
|
+
end
|
153
|
+
|
141
154
|
it "references the owner rule" do
|
155
|
+
text = "@import url(\"import1.css\");"
|
156
|
+
rule = CssImportRule.new(:css_text => text, :parent_style_sheet => parent)
|
142
157
|
|
158
|
+
expect(rule.style_sheet.owner_rule).to eq rule
|
143
159
|
end
|
144
160
|
end
|
145
161
|
|
146
162
|
describe "#delete_rule" do
|
147
163
|
it "deletes a rule from the css rules" do
|
164
|
+
css = "div {\n background-color: #aaa;\n} span {\n color: #444; \n}"
|
165
|
+
sheet = CssStyleSheet.new(:content => css)
|
148
166
|
|
167
|
+
sheet.css_rules
|
168
|
+
expect(sheet.css_rules.length).to eq 2
|
169
|
+
|
170
|
+
sheet.delete_rule(0)
|
171
|
+
expect(sheet.css_rules.length).to eq 1
|
172
|
+
expect(sheet.css_rules[0].css_text).to eq "span { color: #444;}"
|
149
173
|
end
|
150
174
|
end
|
151
175
|
|
152
176
|
describe "#insert_rule" do
|
153
177
|
it "adds a rule to the css rules" do
|
178
|
+
css = "div {\n background-color: #aaa;\n} span {\n color: #444; \n}"
|
179
|
+
sheet = CssStyleSheet.new(:content => css)
|
180
|
+
|
181
|
+
expect(sheet.css_rules.length).to eq 2
|
154
182
|
|
183
|
+
sheet.insert_rule("#blanc { color: white }", 0);
|
184
|
+
expect(sheet.css_rules.length).to eq 3
|
185
|
+
|
155
186
|
end
|
156
187
|
end
|
157
188
|
end
|
data/stylesheet.gemspec
CHANGED
@@ -6,7 +6,7 @@ require 'stylesheet/version'
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "stylesheet"
|
8
8
|
gem.version = Stylesheet::VERSION
|
9
|
-
gem.summary = %q{
|
9
|
+
gem.summary = %q{A CSS parser based on the DOM API}
|
10
10
|
gem.description = gem.summary
|
11
11
|
|
12
12
|
gem.required_ruby_version = '>= 1.9.3'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stylesheet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-05-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: curb
|
@@ -123,7 +123,7 @@ dependencies:
|
|
123
123
|
- - ~>
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0.9'
|
126
|
-
description:
|
126
|
+
description: A CSS parser based on the DOM API
|
127
127
|
email:
|
128
128
|
- derek@sportspyder.com
|
129
129
|
executables: []
|
@@ -205,6 +205,7 @@ files:
|
|
205
205
|
- spec/inflector_spec.rb
|
206
206
|
- spec/location_spec.rb
|
207
207
|
- spec/media_list_spec.rb
|
208
|
+
- spec/request_spec.rb
|
208
209
|
- spec/spec_helper.rb
|
209
210
|
- spec/stubs/fake_request.rb
|
210
211
|
- spec/style_sheet_list_spec.rb
|
@@ -234,7 +235,7 @@ rubyforge_project:
|
|
234
235
|
rubygems_version: 1.8.25
|
235
236
|
signing_key:
|
236
237
|
specification_version: 3
|
237
|
-
summary:
|
238
|
+
summary: A CSS parser based on the DOM API
|
238
239
|
test_files:
|
239
240
|
- features/document_styles.feature
|
240
241
|
- features/rule_declarations.feature
|
@@ -287,6 +288,7 @@ test_files:
|
|
287
288
|
- spec/inflector_spec.rb
|
288
289
|
- spec/location_spec.rb
|
289
290
|
- spec/media_list_spec.rb
|
291
|
+
- spec/request_spec.rb
|
290
292
|
- spec/spec_helper.rb
|
291
293
|
- spec/stubs/fake_request.rb
|
292
294
|
- spec/style_sheet_list_spec.rb
|