arbre 1.0.0 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 30b53bbea249a4468d48f14a136eda6c20fc65b7
4
+ data.tar.gz: 17a5b69fd8d6b97bb0c4231ae675e726307044c4
5
+ SHA512:
6
+ metadata.gz: de40bce2886fe8180f32ca25fb0a6a8eae6cef04d0f8bcd9af568332241f4e5a4aec73a6064fc6af8ddb4e42a78d74b715be61aeff4925d84686f7d0e70d1a79
7
+ data.tar.gz: 789a7b6cc502b10ce1a2eb2d46fac659500727c22915c0539f511529a1f947cd5d51f6fe2990241adfe0708816831a9cbe62c6c2d4eaed21d9f5994e3161bbba
data/.gitignore CHANGED
@@ -3,6 +3,8 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  benchmarks
6
- /.rvmrc
7
- /tags
6
+ .rvmrc
7
+ .ruby-version
8
+ .ruby-gemset
9
+ tags
8
10
  .DS_Store
@@ -1,5 +1,4 @@
1
1
  script: bundle exec rake
2
2
  rvm:
3
- - ree
4
- - 1.9.2
5
3
  - 1.9.3
4
+ - 2.1.2
@@ -1,3 +1,16 @@
1
+ ## 1.0.2
2
+
3
+ * make `Element#inspect` behave correctly in Ruby 2.0 (@seanlinsley, #16)
4
+ * prevent `Arbre::Element#flatten` infinite recursion (@seanlinsley, #32)
5
+ * make `find_by_class` correctly find children by class (@kaapa, #33)
6
+
7
+ ## 1.0.1
8
+
9
+ * Template handler converts to string to satisfy Rack::Lint (@jpmckinney, #6)
10
+ * Fix to `Tag#add_class` when passing a string of classes to Tag build method
11
+ (@gregbell, #7)
12
+ * Not longer uses the default separator (@LTe, #4)
13
+
1
14
  ## 1.0.0
2
15
 
3
16
  * Added support for the use of `:for` with non Active Model objects
data/Gemfile CHANGED
@@ -1,13 +1,16 @@
1
- source "http://rubygems.org"
1
+ source 'http://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
5
  group :test do
6
- gem "rspec"
6
+ gem 'rspec'
7
+ gem 'rack'
8
+ gem 'pry'
7
9
  end
8
10
 
9
11
  group :rails do
10
- gem "rspec-rails"
11
- gem 'combustion', '0.3.2'
12
- gem "capybara"
12
+ gem 'rails'
13
+ gem 'rspec-rails'
14
+ gem 'combustion'
15
+ gem 'capybara'
13
16
  end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Greg Bell
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,110 @@
1
+ # Arbre - HTML Views in Ruby
2
+
3
+ Arbre makes it easy to generate HTML directly in Ruby. This gem was extracted from [Active Admin](https://github.com/activeadmin/active_admin).
4
+
5
+ [![Version ](http://img.shields.io/gem/v/arbre.svg) ](https://rubygems.org/gems/arbre)
6
+ [![Travis CI](http://img.shields.io/travis/activeadmin/arbre/master.svg)](https://travis-ci.org/activeadmin/arbre)
7
+
8
+ ## Simple Usage
9
+
10
+ ```ruby
11
+ html = Arbre::Context.new do
12
+ h2 "Why is Arbre awesome?"
13
+
14
+ ul do
15
+ li "The DOM is implemented in ruby"
16
+ li "You can create object oriented views"
17
+ li "Templates suck"
18
+ end
19
+ end
20
+
21
+ puts html.to_s # =>
22
+ ```
23
+
24
+ ```html
25
+ <h2>Why is Arbre awesome?</h2>
26
+ <ul>
27
+ <li>The DOM is implemented in ruby</li>
28
+ <li>You can create object oriented views</li>
29
+ <li>Templates suck</li>
30
+ </ul>
31
+ ```
32
+
33
+ ## The DOM in Ruby
34
+
35
+ The purpose of Arbre is to leave the view as ruby objects as long
36
+ as possible. This allows OO Design to be used to implement the view layer.
37
+
38
+ ```ruby
39
+ html = Arbre::Context.new do
40
+ h2 "Why Arbre is awesome?"
41
+ end
42
+
43
+ html.children.size # => 1
44
+ html.children.first # => #<Arbre::HTML::H2>
45
+ ```
46
+
47
+ ## Components
48
+
49
+ The purpose of Arbre is to be able to create shareable and extendable HTML
50
+ components. To do this, you create a subclass of Arbre::Component.
51
+
52
+ For example:
53
+
54
+ ```ruby
55
+ class Panel < Arbre::Component
56
+ builder_method :panel
57
+
58
+ def build(title, attributes = {})
59
+ super(attributes)
60
+
61
+ h3(title, :class => "panel-title")
62
+ end
63
+ end
64
+ ```
65
+
66
+ The builder_method defines the method that will be called to build this component
67
+ when using the DSL. The arguments passed into the builder_method will be passed
68
+ into the #build method for you.
69
+
70
+ You can now use this panel in any Arbre context:
71
+
72
+ ```ruby
73
+ html = Arbre::Context.new do
74
+ panel "Hello World", :id => "my-panel" do
75
+ span "Inside the panel"
76
+ end
77
+ end
78
+
79
+ puts html.to_s # =>
80
+ ```
81
+
82
+ ```html
83
+ <div class='panel' id="my-panel">
84
+ <h3 class='panel-title'>Hello World</h3>
85
+ <span>Inside the panel</span>
86
+ </div>
87
+ ```
88
+
89
+ ### Text Nodes
90
+
91
+ To insert unwrapped text nodes use `text_node`:
92
+
93
+ ```ruby
94
+ html = Arbre::Context.new do
95
+ panel "Hello World", :id => "my-panel" do
96
+ span "Inside the panel"
97
+ text_node "Plain text"
98
+ end
99
+ end
100
+
101
+ puts html.to_s # =>
102
+ ```
103
+
104
+ ```html
105
+ <div class='panel' id="my-panel">
106
+ <h3 class='panel-title'>Hello World</h3>
107
+ <span>Inside the panel</span>
108
+ Plain text
109
+ </div>
110
+ ```
data/Rakefile CHANGED
@@ -5,3 +5,14 @@ require 'rspec/core/rake_task'
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
7
  task :default => :spec
8
+
9
+ task :console do
10
+ require 'irb'
11
+ require 'irb/completion'
12
+
13
+ require 'pry'
14
+ require 'arbre'
15
+
16
+ ARGV.clear
17
+ IRB.start
18
+ end
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.homepage = ""
12
12
  s.summary = %q{An Object Oriented DOM Tree in Ruby}
13
13
  s.description = %q{An Object Oriented DOM Tree in Ruby}
14
+ s.license = "MIT"
14
15
 
15
16
  s.files = `git ls-files`.split("\n")
16
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -1,4 +1,5 @@
1
1
  require 'arbre/element/builder_methods'
2
+ require 'arbre/element/proxy'
2
3
  require 'arbre/element_collection'
3
4
 
4
5
  module Arbre
@@ -106,8 +107,8 @@ module Arbre
106
107
  def get_elements_by_class_name(class_name)
107
108
  elements = ElementCollection.new
108
109
  children.each do |child|
109
- elements << child if child.class_list =~ /#{class_name}/
110
- elements.concat(child.get_elements_by_tag_name(tag_name))
110
+ elements << child if child.class_list.include?(class_name)
111
+ elements.concat(child.get_elements_by_class_name(class_name))
111
112
  end
112
113
  elements
113
114
  end
@@ -129,6 +130,10 @@ module Arbre
129
130
  [to_s].each(&block)
130
131
  end
131
132
 
133
+ def inspect
134
+ to_s
135
+ end
136
+
132
137
  def to_str
133
138
  to_s
134
139
  end
@@ -143,11 +148,11 @@ module Arbre
143
148
  else
144
149
  element = Arbre::HTML::TextNode.from_string(element)
145
150
  end
146
- ElementCollection.new([self]) + element
151
+ to_ary + element
147
152
  end
148
153
 
149
154
  def to_ary
150
- ElementCollection.new [self]
155
+ ElementCollection.new [Proxy.new(self)]
151
156
  end
152
157
  alias_method :to_a, :to_ary
153
158
 
@@ -0,0 +1,28 @@
1
+ module Arbre
2
+ class Element
3
+ class Proxy < BasicObject
4
+ undef_method :==
5
+ undef_method :equal?
6
+
7
+ def initialize(element)
8
+ @element = element
9
+ end
10
+
11
+ def respond_to?(method, include_all = false)
12
+ if method.to_s == 'to_ary'
13
+ false
14
+ else
15
+ super || @element.respond_to?(method, include_all)
16
+ end
17
+ end
18
+
19
+ def method_missing(method, *args, &block)
20
+ if method.to_s == 'to_ary'
21
+ super
22
+ else
23
+ @element.__send__ method, *args, &block
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -18,7 +18,7 @@ module Arbre
18
18
  def to_s
19
19
  self.collect do |element|
20
20
  element.to_s
21
- end.join.html_safe
21
+ end.join('').html_safe
22
22
  end
23
23
  end
24
24
 
@@ -4,13 +4,22 @@ module Arbre
4
4
  class Attributes < Hash
5
5
 
6
6
  def to_s
7
- self.collect do |name, value|
7
+ map do |name, value|
8
+ next if value_empty?(value)
8
9
  "#{html_escape(name)}=\"#{html_escape(value)}\""
9
- end.join(" ")
10
+ end.compact.join ' '
11
+ end
12
+
13
+ def any?
14
+ super{ |k,v| !value_empty?(v) }
10
15
  end
11
16
 
12
17
  protected
13
18
 
19
+ def value_empty?(value)
20
+ value.respond_to?(:empty?) ? value.empty? : !value
21
+ end
22
+
14
23
  def html_escape(s)
15
24
  ERB::Util.html_escape(s)
16
25
  end
@@ -6,6 +6,13 @@ module Arbre
6
6
  # Holds a set of classes
7
7
  class ClassList < Set
8
8
 
9
+ def self.build_from_string(class_names)
10
+ list = new
11
+ list.add(class_names)
12
+
13
+ list
14
+ end
15
+
9
16
  def add(class_names)
10
17
  class_names.to_s.split(" ").each do |class_name|
11
18
  super(class_name)
@@ -77,7 +77,16 @@ module Arbre
77
77
  end
78
78
 
79
79
  def class_list
80
- get_attribute(:class) || set_attribute(:class, ClassList.new)
80
+ list = get_attribute(:class)
81
+
82
+ case list
83
+ when ClassList
84
+ list
85
+ when String
86
+ set_attribute(:class, ClassList.build_from_string(list))
87
+ else
88
+ set_attribute(:class, ClassList.new)
89
+ end
81
90
  end
82
91
 
83
92
  def to_s
@@ -121,7 +130,7 @@ module Arbre
121
130
  end
122
131
 
123
132
  def self_closing_tag?
124
- %w|meta link|.include?(tag_name)
133
+ %w|br link meta|.include?(tag_name)
125
134
  end
126
135
 
127
136
  def no_child?
@@ -132,9 +141,8 @@ module Arbre
132
141
  children.size == 1 && children.first.is_a?(TextNode)
133
142
  end
134
143
 
135
-
136
144
  def attributes_html
137
- attributes.any? ? " " + attributes.to_s : nil
145
+ " #{attributes}" if attributes.any?
138
146
  end
139
147
 
140
148
  def set_for_attribute(record)
@@ -22,6 +22,10 @@ module Arbre
22
22
  @content = string
23
23
  end
24
24
 
25
+ def class_list
26
+ []
27
+ end
28
+
25
29
  def tag_name
26
30
  nil
27
31
  end
@@ -1,14 +1,14 @@
1
1
  module Arbre
2
2
  module Rails
3
-
4
3
  class TemplateHandler
5
-
6
4
  def call(template)
7
- "Arbre::Context.new(assigns, self){ #{template.source} }"
5
+ <<-END
6
+ Arbre::Context.new(assigns, self) {
7
+ #{template.source}
8
+ }.to_s
9
+ END
8
10
  end
9
-
10
11
  end
11
-
12
12
  end
13
13
  end
14
14
 
@@ -1,3 +1,3 @@
1
1
  module Arbre
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.2"
3
3
  end
@@ -6,17 +6,17 @@ describe Arbre do
6
6
  let(:assigns){ {} }
7
7
 
8
8
  it "should render a single element" do
9
- arbre {
9
+ expect(arbre {
10
10
  span "Hello World"
11
- }.to_s.should == "<span>Hello World</span>\n"
11
+ }.to_s).to eq("<span>Hello World</span>\n")
12
12
  end
13
13
 
14
14
  it "should render a child element" do
15
- arbre {
15
+ expect(arbre {
16
16
  span do
17
17
  span "Hello World"
18
18
  end
19
- }.to_s.should == <<-HTML
19
+ }.to_s).to eq <<-HTML
20
20
  <span>
21
21
  <span>Hello World</span>
22
22
  </span>
@@ -24,13 +24,13 @@ HTML
24
24
  end
25
25
 
26
26
  it "should render an unordered list" do
27
- arbre {
27
+ expect(arbre {
28
28
  ul do
29
29
  li "First"
30
30
  li "Second"
31
31
  li "Third"
32
32
  end
33
- }.to_s.should == <<-HTML
33
+ }.to_s).to eq <<-HTML
34
34
  <ul>
35
35
  <li>First</li>
36
36
  <li>Second</li>
@@ -40,14 +40,14 @@ HTML
40
40
  end
41
41
 
42
42
  it "should allow local variables inside the tags" do
43
- arbre {
43
+ expect(arbre {
44
44
  first = "First"
45
45
  second = "Second"
46
46
  ul do
47
47
  li first
48
48
  li second
49
49
  end
50
- }.to_s.should == <<-HTML
50
+ }.to_s).to eq <<-HTML
51
51
  <ul>
52
52
  <li>First</li>
53
53
  <li>Second</li>
@@ -57,14 +57,14 @@ HTML
57
57
 
58
58
 
59
59
  it "should add children and nested" do
60
- arbre {
60
+ expect(arbre {
61
61
  div do
62
62
  ul
63
63
  li do
64
64
  li
65
65
  end
66
66
  end
67
- }.to_s.should == <<-HTML
67
+ }.to_s).to eq <<-HTML
68
68
  <div>
69
69
  <ul></ul>
70
70
  <li>
@@ -76,13 +76,13 @@ HTML
76
76
 
77
77
 
78
78
  it "should pass the element in to the block if asked for" do
79
- arbre {
79
+ expect(arbre {
80
80
  div do |d|
81
81
  d.ul do
82
82
  li
83
83
  end
84
84
  end
85
- }.to_s.should == <<-HTML
85
+ }.to_s).to eq <<-HTML
86
86
  <div>
87
87
  <ul>
88
88
  <li></li>
@@ -93,11 +93,11 @@ HTML
93
93
 
94
94
 
95
95
  it "should move content tags between parents" do
96
- arbre {
96
+ expect(arbre {
97
97
  div do
98
98
  span(ul(li))
99
99
  end
100
- }.to_s.should == <<-HTML
100
+ }.to_s).to eq <<-HTML
101
101
  <div>
102
102
  <span>
103
103
  <ul>
@@ -109,14 +109,14 @@ HTML
109
109
  end
110
110
 
111
111
  it "should add content to the parent if the element is passed into block" do
112
- arbre {
112
+ expect(arbre {
113
113
  div do |d|
114
114
  d.id = "my-tag"
115
115
  ul do
116
116
  li
117
117
  end
118
118
  end
119
- }.to_s.should == <<-HTML
119
+ }.to_s).to eq <<-HTML
120
120
  <div id="my-tag">
121
121
  <ul>
122
122
  <li></li>
@@ -126,42 +126,43 @@ HTML
126
126
  end
127
127
 
128
128
  it "should have the parent set on it" do
129
+ list, item = nil
129
130
  arbre {
130
- item = nil
131
131
  list = ul do
132
132
  li "Hello"
133
133
  item = li "World"
134
134
  end
135
- item.parent.should == list
136
135
  }
136
+ expect(item.parent).to eq list
137
137
  end
138
138
 
139
139
  it "should set a string content return value with no children" do
140
- arbre {
140
+ expect(arbre {
141
141
  li do
142
142
  "Hello World"
143
143
  end
144
- }.to_s.should == <<-HTML
144
+ }.to_s).to eq <<-HTML
145
145
  <li>Hello World</li>
146
146
  HTML
147
147
  end
148
148
 
149
149
  it "should turn string return values into text nodes" do
150
+ node = nil
150
151
  arbre {
151
152
  list = li do
152
153
  "Hello World"
153
154
  end
154
155
  node = list.children.first
155
- node.class.should == Arbre::HTML::TextNode
156
156
  }
157
+ expect(node).to be_a Arbre::HTML::TextNode
157
158
  end
158
159
 
159
160
  it "should not render blank arrays" do
160
- arbre {
161
+ expect(arbre {
161
162
  tbody do
162
163
  []
163
164
  end
164
- }.to_s.should == <<-HTML
165
+ }.to_s).to eq <<-HTML
165
166
  <tbody></tbody>
166
167
  HTML
167
168
  end
@@ -169,21 +170,27 @@ HTML
169
170
  describe "self-closing nodes" do
170
171
 
171
172
  it "should not self-close script tags" do
172
- arbre {
173
+ expect(arbre {
173
174
  script :type => 'text/javascript'
174
- }.to_s.should == "<script type=\"text/javascript\"></script>\n"
175
+ }.to_s).to eq("<script type=\"text/javascript\"></script>\n")
175
176
  end
176
177
 
177
178
  it "should self-close meta tags" do
178
- arbre {
179
+ expect(arbre {
179
180
  meta :content => "text/html; charset=utf-8"
180
- }.to_s.should == "<meta content=\"text/html; charset=utf-8\"/>\n"
181
+ }.to_s).to eq("<meta content=\"text/html; charset=utf-8\"/>\n")
181
182
  end
182
183
 
183
184
  it "should self-close link tags" do
184
- arbre {
185
+ expect(arbre {
185
186
  link :rel => "stylesheet"
186
- }.to_s.should == "<link rel=\"stylesheet\"/>\n"
187
+ }.to_s).to eq("<link rel=\"stylesheet\"/>\n")
188
+ end
189
+
190
+ it "should self-close br tags" do
191
+ expect(arbre {
192
+ br
193
+ }.to_s).to eq("<br/>\n")
187
194
  end
188
195
 
189
196
  end
@@ -191,23 +198,23 @@ HTML
191
198
  describe "html safe" do
192
199
 
193
200
  it "should escape the contents" do
194
- arbre {
201
+ expect(arbre {
195
202
  span("<br />")
196
- }.to_s.should == <<-HTML
203
+ }.to_s).to eq <<-HTML
197
204
  <span>&lt;br /&gt;</span>
198
205
  HTML
199
206
  end
200
207
 
201
208
  it "should return html safe strings" do
202
- arbre {
209
+ expect(arbre {
203
210
  span("<br />")
204
- }.to_s.should be_html_safe
211
+ }.to_s).to be_html_safe
205
212
  end
206
213
 
207
214
  it "should not escape html passed in" do
208
- arbre {
215
+ expect(arbre {
209
216
  span(span("<br />"))
210
- }.to_s.should == <<-HTML
217
+ }.to_s).to eq <<-HTML
211
218
  <span>
212
219
  <span>&lt;br /&gt;</span>
213
220
  </span>
@@ -215,13 +222,13 @@ HTML
215
222
  end
216
223
 
217
224
  it "should escape string contents when passed in block" do
218
- arbre {
225
+ expect(arbre {
219
226
  span {
220
227
  span {
221
228
  "<br />"
222
229
  }
223
230
  }
224
- }.to_s.should == <<-HTML
231
+ }.to_s).to eq <<-HTML
225
232
  <span>
226
233
  <span>&lt;br /&gt;</span>
227
234
  </span>
@@ -229,9 +236,9 @@ HTML
229
236
  end
230
237
 
231
238
  it "should escape the contents of attributes" do
232
- arbre {
239
+ expect(arbre {
233
240
  span(:class => "<br />")
234
- }.to_s.should == <<-HTML
241
+ }.to_s).to eq <<-HTML
235
242
  <span class="&lt;br /&gt;"></span>
236
243
  HTML
237
244
  end