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 CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.3.1
@@ -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(joiner)
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 style(*selectors)
38
- s = Style.new(:selectors => selectors, :level => level, :context => context)
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{ |e| '#{tag}' + '.' + e.to_s }
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 )
@@ -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} #{make_selector(value)}"
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
- value.is_a?(String) || TAGS.include?(value) ? "#{value}" : ".#{value}"
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
- type == :full ? render_full : render_linear
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\n\nbaz"
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} {\n}"
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 /^\.abridged_syntax/
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}*form label \{$/
891
- @output.should match /^\W{4}*form label \{$/
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
- # input[:readonly]{ ... }
911
- # input['type=text']{ ... }
912
- # how to handle :hover and other psuedo selectors
913
- # p.classy < a
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 :all do
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.0"
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-28}
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: 19
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 0
10
- version: 0.3.0
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-28 00:00:00 -08:00
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
- }