style_train 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/style_train/sheet.rb +43 -8
- data/lib/style_train/style.rb +35 -4
- data/spec/sheet_spec.rb +110 -11
- data/spec/style_spec.rb +30 -2
- data/style_train.gemspec +2 -3
- metadata +4 -5
- data/spec/integration.css +0 -89
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
data/lib/style_train/sheet.rb
CHANGED
@@ -15,15 +15,18 @@ module StyleTrain
|
|
15
15
|
else
|
16
16
|
send render_method
|
17
17
|
end
|
18
|
+
|
19
|
+
render_array(opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
def render_array opts={}
|
18
23
|
if opts[:type]
|
19
24
|
render_type = opts[:type]
|
20
|
-
joiner = "\n"
|
21
25
|
else
|
22
26
|
render_type = :full
|
23
|
-
joiner = "\n\n"
|
24
27
|
end
|
25
28
|
|
26
|
-
output.map{|s| s.is_a?(String) ? s : s.render( render_type ) }.join(
|
29
|
+
output.map{|s| s.is_a?(String) ? s : s.render( render_type ) }.join("\n")
|
27
30
|
end
|
28
31
|
|
29
32
|
def header
|
@@ -34,8 +37,40 @@ module StyleTrain
|
|
34
37
|
CSS
|
35
38
|
end
|
36
39
|
|
37
|
-
def
|
38
|
-
|
40
|
+
def style_options
|
41
|
+
{:level => level, :context => context}
|
42
|
+
end
|
43
|
+
|
44
|
+
def style(*selectors, &block)
|
45
|
+
s = Style.new( style_options.merge(:selectors => selectors) )
|
46
|
+
add_style_to_queue(s, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
alias :c :style
|
50
|
+
|
51
|
+
def id(*selectors, &block)
|
52
|
+
selectors = selectors.map{|s| "##{s}"}
|
53
|
+
style(*selectors, &block)
|
54
|
+
end
|
55
|
+
|
56
|
+
def concat(*selectors, &block)
|
57
|
+
s = Style.new( style_options.merge(:selectors => selectors, :concat => true ) )
|
58
|
+
add_style_to_queue(s, &block)
|
59
|
+
end
|
60
|
+
|
61
|
+
alias :cat :concat
|
62
|
+
|
63
|
+
def child(*selectors, &block)
|
64
|
+
s = Style.new( style_options.merge(:selectors => selectors, :child => true))
|
65
|
+
add_style_to_queue(s, &block)
|
66
|
+
end
|
67
|
+
|
68
|
+
def attr(*selector, &block)
|
69
|
+
selector = selector.map{|s| "[#{s}]"}
|
70
|
+
concat(*selector, &block)
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_style_to_queue(s, &block)
|
39
74
|
self.output << s
|
40
75
|
self.contexts.unshift( s )
|
41
76
|
if block_given?
|
@@ -50,15 +85,15 @@ CSS
|
|
50
85
|
contexts.first
|
51
86
|
end
|
52
87
|
|
53
|
-
alias :c :style
|
54
|
-
|
55
88
|
TAGS = StyleTrain::Style::TAGS
|
56
89
|
|
57
90
|
TAGS.each do |tag|
|
58
91
|
class_eval <<-RUBY
|
59
92
|
def #{tag}(*selectors, &block)
|
60
93
|
if selectors.size > 0
|
61
|
-
selectors = selectors.map
|
94
|
+
selectors = selectors.map do |e|
|
95
|
+
'#{tag}' + StyleTrain::Style.selector(e, :exclude_tags => true)
|
96
|
+
end
|
62
97
|
style( *selectors, &block )
|
63
98
|
else
|
64
99
|
style( '#{tag}', &block )
|
data/lib/style_train/style.rb
CHANGED
@@ -1,19 +1,24 @@
|
|
1
1
|
module StyleTrain
|
2
2
|
class Style
|
3
|
-
attr_accessor :selectors, :level, :properties
|
3
|
+
attr_accessor :selectors, :level, :properties, :opts
|
4
4
|
|
5
5
|
def initialize(opts)
|
6
|
+
self.opts = opts
|
6
7
|
self.level = opts[:level].to_i
|
7
8
|
self.selectors = []
|
8
9
|
self.properties = []
|
9
10
|
set_selectors opts[:selectors], opts[:context] && opts[:context].selectors
|
10
11
|
end
|
11
12
|
|
13
|
+
def spacing(value)
|
14
|
+
PSUEDOS.include?(value) || opts[:concat] ? '' : ' '
|
15
|
+
end
|
16
|
+
|
12
17
|
def set_selectors values, contexts
|
13
18
|
if contexts
|
14
19
|
contexts.each do |context|
|
15
20
|
values.each do |value|
|
16
|
-
self.selectors << "#{context}
|
21
|
+
self.selectors << "#{context}#{spacing(value)}#{make_selector(value)}"
|
17
22
|
end
|
18
23
|
end
|
19
24
|
else
|
@@ -37,18 +42,44 @@ module StyleTrain
|
|
37
42
|
:tr, :tt, :u, :ul, :var
|
38
43
|
]
|
39
44
|
|
45
|
+
PSUEDOS = [
|
46
|
+
:link, :visited, :hover, :active, :target, :before, :after,
|
47
|
+
:enabled, :disabled, :checked, :focus
|
48
|
+
]
|
49
|
+
|
40
50
|
def make_selector(value)
|
41
|
-
|
51
|
+
self.class.selector(value, opts)
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.selector(value, opts={})
|
55
|
+
value = if value.is_a?(String) || (!opts[:exclude_tags] && TAGS.include?(value))
|
56
|
+
value.to_s
|
57
|
+
elsif PSUEDOS.include?(value)
|
58
|
+
":#{value}"
|
59
|
+
else
|
60
|
+
".#{value}"
|
61
|
+
end
|
62
|
+
opts[:child] ? "> #{value}" : value
|
42
63
|
end
|
43
64
|
|
44
65
|
INDENT = ' '
|
45
66
|
|
46
67
|
def render(type=:full)
|
47
|
-
|
68
|
+
if properties.empty?
|
69
|
+
render_empty
|
70
|
+
elsif type == :full
|
71
|
+
render_full
|
72
|
+
else
|
73
|
+
render_linear
|
74
|
+
end
|
48
75
|
end
|
49
76
|
|
50
77
|
alias :to_s :render
|
51
78
|
|
79
|
+
def render_empty
|
80
|
+
"#{indent}/* #{selectors.join(', ')} {} */"
|
81
|
+
end
|
82
|
+
|
52
83
|
def render_full
|
53
84
|
str = ""
|
54
85
|
|
data/spec/sheet_spec.rb
CHANGED
@@ -79,7 +79,7 @@ CSS
|
|
79
79
|
@sheet.output = ["bar", "baz"]
|
80
80
|
@sheet.stub(:output=)
|
81
81
|
@sheet.stub(:content)
|
82
|
-
@sheet.render.should == "bar\
|
82
|
+
@sheet.render.should == "bar\nbaz"
|
83
83
|
end
|
84
84
|
|
85
85
|
it 'joins with one line break when a render type is specified' do
|
@@ -135,9 +135,19 @@ CSS
|
|
135
135
|
|
136
136
|
it "should add a style for '#{tag}'" do
|
137
137
|
@sheet.send(tag)
|
138
|
-
@sheet.output.first.render.should include "#{tag} {
|
138
|
+
@sheet.output.first.render.should include "#{tag} {}"
|
139
139
|
end
|
140
140
|
end
|
141
|
+
|
142
|
+
it 'should correctly concatenate the selector' do
|
143
|
+
@sheet.div(:hover)
|
144
|
+
@sheet.div(:foo)
|
145
|
+
@sheet.div(:p)
|
146
|
+
str = @sheet.render_array
|
147
|
+
str.should match /div:hover/
|
148
|
+
str.should match /div.foo/
|
149
|
+
str.should match /div.p/
|
150
|
+
end
|
141
151
|
end
|
142
152
|
|
143
153
|
describe 'properties' do
|
@@ -762,12 +772,10 @@ CSS
|
|
762
772
|
background-color: #666;
|
763
773
|
font-family: verdana;
|
764
774
|
}
|
765
|
-
|
766
775
|
#wrapper {
|
767
776
|
background-color: white;
|
768
777
|
margin: 1em auto;
|
769
778
|
}
|
770
|
-
|
771
779
|
.foo {
|
772
780
|
color: red;
|
773
781
|
}"
|
@@ -816,6 +824,10 @@ CSS
|
|
816
824
|
div( :next, :again ){
|
817
825
|
color :red
|
818
826
|
}
|
827
|
+
|
828
|
+
id(:wrapper) {
|
829
|
+
margin 1.em, :auto
|
830
|
+
}
|
819
831
|
end
|
820
832
|
end
|
821
833
|
|
@@ -824,7 +836,7 @@ CSS
|
|
824
836
|
end
|
825
837
|
|
826
838
|
it 'aliases #style to #s' do
|
827
|
-
@sheet.render.should match
|
839
|
+
@sheet.render.should match /.abridged_syntax \{/
|
828
840
|
end
|
829
841
|
|
830
842
|
it 'assigns multiple arguments to comma separated' do
|
@@ -845,6 +857,10 @@ div.again {
|
|
845
857
|
}"
|
846
858
|
end
|
847
859
|
|
860
|
+
it 'makes id selectors' do
|
861
|
+
@sheet.render.should include '#wrapper {'
|
862
|
+
end
|
863
|
+
|
848
864
|
describe 'nesting' do
|
849
865
|
class Nested < Sheet
|
850
866
|
def content
|
@@ -887,8 +903,8 @@ div.again {
|
|
887
903
|
end
|
888
904
|
|
889
905
|
it 'should indent the nested style to the right level' do
|
890
|
-
@output.should match /^\W{2}
|
891
|
-
@output.should match /^\W{4}
|
906
|
+
@output.should match /^\W{2}form label \{$/
|
907
|
+
@output.should match /^\W{4}form label input \{$/
|
892
908
|
end
|
893
909
|
|
894
910
|
it 'puts property declarations after a nested style in the right place' do
|
@@ -907,10 +923,93 @@ form {
|
|
907
923
|
end
|
908
924
|
end
|
909
925
|
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
926
|
+
describe 'joining/concatenating' do
|
927
|
+
class Joiner < Sheet
|
928
|
+
def content
|
929
|
+
c(:foo) {
|
930
|
+
background :color => :blue
|
931
|
+
concat(:bar){
|
932
|
+
color :white
|
933
|
+
}
|
934
|
+
concat(:hover){
|
935
|
+
background :color => :lightyellow
|
936
|
+
}
|
937
|
+
c(:focus){
|
938
|
+
background :color => :gold
|
939
|
+
}
|
940
|
+
}
|
941
|
+
end
|
942
|
+
end
|
943
|
+
|
944
|
+
it 'should make a style for the concatenated selectors' do
|
945
|
+
Joiner.render.should include ".foo.bar {"
|
946
|
+
end
|
947
|
+
|
948
|
+
it 'should make a concatenated selector for psuedo selectors with concat' do
|
949
|
+
Joiner.render.should include '.foo:hover {'
|
950
|
+
end
|
951
|
+
|
952
|
+
it 'should make a concatenated selector for psuedo selectors regardless' do
|
953
|
+
Joiner.render.should include '.foo:focus {'
|
954
|
+
end
|
955
|
+
end
|
956
|
+
|
957
|
+
describe 'child direct descendant' do
|
958
|
+
class Childish < Sheet
|
959
|
+
def content
|
960
|
+
c(:foo) {
|
961
|
+
background :color => :blue
|
962
|
+
child(:bar, :p) {
|
963
|
+
background :color => :red
|
964
|
+
}
|
965
|
+
}
|
966
|
+
end
|
967
|
+
end
|
968
|
+
|
969
|
+
before :all do
|
970
|
+
@str = Childish.render
|
971
|
+
end
|
972
|
+
|
973
|
+
it 'correctly builds selectors for classes' do
|
974
|
+
@str.should include '.foo > .bar'
|
975
|
+
end
|
976
|
+
|
977
|
+
it 'correctly builds selectors for tags' do
|
978
|
+
@str.should include '.foo > p'
|
979
|
+
end
|
980
|
+
|
981
|
+
it 'should render embedded properties' do
|
982
|
+
@str.should include "background-color: red"
|
983
|
+
end
|
984
|
+
end
|
985
|
+
|
986
|
+
describe 'attribute' do
|
987
|
+
class Attr < Sheet
|
988
|
+
def content
|
989
|
+
c(:input) {
|
990
|
+
background :color => :blue
|
991
|
+
attr(:disabled) {
|
992
|
+
color :grey
|
993
|
+
}
|
994
|
+
}
|
995
|
+
end
|
996
|
+
end
|
997
|
+
|
998
|
+
before :all do
|
999
|
+
@str = Attr.render
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
|
1003
|
+
it 'should concatenate the selector' do
|
1004
|
+
@str.should include "input[disabled]"
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
it 'should render embedded properties' do
|
1008
|
+
@str.should include "color: grey"
|
1009
|
+
end
|
1010
|
+
end
|
1011
|
+
|
1012
|
+
|
914
1013
|
# #css method on objects that allows instance eval of blocks globally
|
915
1014
|
end
|
916
1015
|
end
|
data/spec/style_spec.rb
CHANGED
@@ -26,6 +26,28 @@ describe Style do
|
|
26
26
|
it 'takes into account the context' do
|
27
27
|
Style.new(:selectors => @selectors, :context => @context).selectors.should == ['a.special p', 'a.special .classy']
|
28
28
|
end
|
29
|
+
|
30
|
+
it 'makes the correct selectors with the :concat option' do
|
31
|
+
Style.new(:selectors => [:hover, :classy], :context => @context, :concat => :true).selectors.should == [
|
32
|
+
'a.special:hover', 'a.special.classy'
|
33
|
+
]
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'makes the correct selectors with the :child option' do
|
37
|
+
Style.new(:selectors => [:bar, :p], :context => @context, :child => :true).selectors.should == [
|
38
|
+
'a.special > .bar', 'a.special > p'
|
39
|
+
]
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'concatenates psuedo selectors automatically' do
|
43
|
+
Style.new(:selectors => [:hover, :classy], :context => @context).selectors.should == [
|
44
|
+
'a.special:hover', 'a.special .classy'
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'excludes tags when requested' do
|
49
|
+
Style.selector(:p, :exclude_tags => :true)
|
50
|
+
end
|
29
51
|
end
|
30
52
|
|
31
53
|
describe 'properties' do
|
@@ -43,19 +65,25 @@ describe Style do
|
|
43
65
|
|
44
66
|
describe 'rendering' do
|
45
67
|
describe 'types' do
|
46
|
-
before
|
47
|
-
@style = Style.new(:selectors => @selectors)
|
68
|
+
before do
|
69
|
+
@style = Style.new(:selectors => @selectors, :level => 2)
|
48
70
|
end
|
49
71
|
|
50
72
|
it 'renders full by default' do
|
73
|
+
@style.properties << "foo:bar"
|
51
74
|
@style.should_receive(:render_full)
|
52
75
|
@style.render
|
53
76
|
end
|
54
77
|
|
55
78
|
it 'renders minimized if an argument is passed in' do
|
79
|
+
@style.properties << "foo:bar"
|
56
80
|
@style.should_receive(:render_linear)
|
57
81
|
@style.render(:something_else)
|
58
82
|
end
|
83
|
+
|
84
|
+
it 'renders a commented line if the declaration is empty' do
|
85
|
+
@style.render.should == " /* p, .classy {} */"
|
86
|
+
end
|
59
87
|
end
|
60
88
|
|
61
89
|
describe 'full' do
|
data/style_train.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{style_train}
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Kane Baccigalupi"]
|
12
|
-
s.date = %q{2011-02
|
12
|
+
s.date = %q{2011-03-02}
|
13
13
|
s.description = %q{style_train builds CSS using pure Ruby, not a DSL interpreted via Ruby. This allows inheritance, modules, instance level calculations and all the goodness Ruby can offer.}
|
14
14
|
s.email = %q{baccigalupi@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -44,7 +44,6 @@ Gem::Specification.new do |s|
|
|
44
44
|
"spec/color/keyword_color_spec.rb",
|
45
45
|
"spec/color/rgb_color_spec.rb",
|
46
46
|
"spec/generated_files/.gitkeep",
|
47
|
-
"spec/integration.css",
|
48
47
|
"spec/integration_spec.rb",
|
49
48
|
"spec/numbers_spec.rb",
|
50
49
|
"spec/sheet_spec.rb",
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: style_train
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 1
|
10
|
+
version: 0.3.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Kane Baccigalupi
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02
|
18
|
+
date: 2011-03-02 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -69,7 +69,6 @@ files:
|
|
69
69
|
- spec/color/keyword_color_spec.rb
|
70
70
|
- spec/color/rgb_color_spec.rb
|
71
71
|
- spec/generated_files/.gitkeep
|
72
|
-
- spec/integration.css
|
73
72
|
- spec/integration_spec.rb
|
74
73
|
- spec/numbers_spec.rb
|
75
74
|
- spec/sheet_spec.rb
|
data/spec/integration.css
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
Generated by StlyeTrain CSS generator via the class Cohuman
|
3
|
-
*/
|
4
|
-
body {
|
5
|
-
font-family: Verdana Sans;
|
6
|
-
font-size: 13px;
|
7
|
-
line-height: 1.5;
|
8
|
-
}
|
9
|
-
|
10
|
-
h1 {
|
11
|
-
font-size: 25px;
|
12
|
-
}
|
13
|
-
|
14
|
-
h2 {
|
15
|
-
font-size: 23px;
|
16
|
-
}
|
17
|
-
|
18
|
-
h3 {
|
19
|
-
font-size: 18px;
|
20
|
-
}
|
21
|
-
|
22
|
-
h3 {
|
23
|
-
margin-left: 0;
|
24
|
-
margin-top: 0;
|
25
|
-
margin-bottom: 0;
|
26
|
-
margin-right: 0;
|
27
|
-
}
|
28
|
-
|
29
|
-
h4 {
|
30
|
-
font-size: 16px;
|
31
|
-
}
|
32
|
-
|
33
|
-
h5 {
|
34
|
-
font-size: 11px;
|
35
|
-
}
|
36
|
-
|
37
|
-
h6 {
|
38
|
-
font-size: 10px;
|
39
|
-
}
|
40
|
-
|
41
|
-
hr {
|
42
|
-
border: none;
|
43
|
-
height: 1px;
|
44
|
-
color: gray;
|
45
|
-
background-color: gray;
|
46
|
-
}
|
47
|
-
|
48
|
-
.create_button {
|
49
|
-
font-weight: bold;
|
50
|
-
font-size: 8em;
|
51
|
-
border: 1px solid black;
|
52
|
-
color: gray;
|
53
|
-
cursor: pointer;
|
54
|
-
padding: 0 0.5em;
|
55
|
-
}
|
56
|
-
|
57
|
-
.activity_button {
|
58
|
-
display: inline-block;
|
59
|
-
position: relative;
|
60
|
-
overflow: visible;
|
61
|
-
padding-left: 0;
|
62
|
-
padding-top: 0;
|
63
|
-
padding-bottom: 0;
|
64
|
-
padding-right: 0;
|
65
|
-
font-weight: bold;
|
66
|
-
font-size: 0.8em;
|
67
|
-
cursor: pointer;
|
68
|
-
color: gray;
|
69
|
-
border: 1px solid black;
|
70
|
-
}
|
71
|
-
|
72
|
-
.user_info {
|
73
|
-
padding: 10px 10px 0px 10px;
|
74
|
-
width: 500px;
|
75
|
-
overflow-x: hidden;
|
76
|
-
}
|
77
|
-
|
78
|
-
.user_info h1 {
|
79
|
-
margin: -4px 0 -2px 0;
|
80
|
-
font-size: 1.5em;
|
81
|
-
}
|
82
|
-
|
83
|
-
.user_info .my_class {
|
84
|
-
padding: 2em;
|
85
|
-
}
|
86
|
-
|
87
|
-
.user_info < p {
|
88
|
-
padding: 1em;
|
89
|
-
}
|