arbre 1.0.0 → 1.0.2

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.
@@ -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