effigy 0.3.2 → 0.4.0
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/Rakefile +7 -0
- data/VERSION +1 -1
- data/lib/effigy/view.rb +26 -13
- data/spec/effigy/view_spec.rb +62 -35
- metadata +18 -9
data/Rakefile
CHANGED
@@ -31,6 +31,13 @@ begin
|
|
31
31
|
end
|
32
32
|
|
33
33
|
task :spec => :rails_root
|
34
|
+
|
35
|
+
desc "Run all specs individually to ensure that requires are correct"
|
36
|
+
task :check_requires do
|
37
|
+
Dir["spec/**/*_spec.rb"].each do |spec_file|
|
38
|
+
system("spec -cfp #{spec_file}") or raise "Failed while running #{spec_file}"
|
39
|
+
end
|
40
|
+
end
|
34
41
|
rescue LoadError => exception
|
35
42
|
puts "Missing dependencies for specs"
|
36
43
|
task :spec do
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/lib/effigy/view.rb
CHANGED
@@ -85,7 +85,7 @@ module Effigy
|
|
85
85
|
#
|
86
86
|
# @return [String] the resulting document
|
87
87
|
def render(template)
|
88
|
-
@current_context = Nokogiri::
|
88
|
+
@current_context = Nokogiri::HTML.fragment(template)
|
89
89
|
yield if block_given?
|
90
90
|
transform
|
91
91
|
output
|
@@ -136,13 +136,13 @@ module Effigy
|
|
136
136
|
#
|
137
137
|
# @param [String] selector a CSS or XPath string describing the element to
|
138
138
|
# transform
|
139
|
-
# @param [String]
|
139
|
+
# @param [String] inner_html the new contents of the selected element. Markup is
|
140
140
|
# not escaped.
|
141
141
|
# @example
|
142
142
|
# html('p', '<b>Welcome!</b>')
|
143
143
|
# find('p').html('<b>Welcome!</b>')
|
144
|
-
def html(selector,
|
145
|
-
select(selector).inner_html =
|
144
|
+
def html(selector, inner_html)
|
145
|
+
select(selector).inner_html = inner_html
|
146
146
|
end
|
147
147
|
|
148
148
|
# Replaces the selected element with live markup.
|
@@ -151,10 +151,23 @@ module Effigy
|
|
151
151
|
#
|
152
152
|
# @param [String] selector a CSS or XPath string describing the element to
|
153
153
|
# transform
|
154
|
-
# @param [String]
|
154
|
+
# @param [String] html the new markup to replace the selected element. Markup is
|
155
155
|
# not escaped.
|
156
|
-
def replace_with(selector,
|
157
|
-
select(selector).after(
|
156
|
+
def replace_with(selector, html)
|
157
|
+
select(selector).after(html).unlink
|
158
|
+
end
|
159
|
+
|
160
|
+
# Adds the given markup to the end of the selected element.
|
161
|
+
#
|
162
|
+
# @param [String] selector a CSS or XPath string describing the element to
|
163
|
+
# which this HTML should be appended
|
164
|
+
# @param [String] html_to_append the new markup to append to the selected
|
165
|
+
# element. Markup is not escaped.
|
166
|
+
def append(selector, html_to_append)
|
167
|
+
node = select(selector)
|
168
|
+
current_context.fragment(html_to_append).children.each do |child|
|
169
|
+
node << child
|
170
|
+
end
|
158
171
|
end
|
159
172
|
|
160
173
|
# Selects an element or elements for chained transformation.
|
@@ -220,10 +233,10 @@ module Effigy
|
|
220
233
|
# Returns the first node that matches the given selection, or the nodes
|
221
234
|
# themselves if given a set of nodes.
|
222
235
|
#
|
223
|
-
# @param nodes [String,Nokogiri::
|
236
|
+
# @param nodes [String,Nokogiri::HTML::NodeSet] if a String, the selector to
|
224
237
|
# use when determining the current context. When a NodeSet, the set of
|
225
238
|
# nodes that should be returned.
|
226
|
-
# @return [Nokogiri::
|
239
|
+
# @return [Nokogiri::HTML::NodeSet] the nodes selected by the given selector
|
227
240
|
# or node set.
|
228
241
|
# @raise [ElementNotFound] if no nodes match the given selector
|
229
242
|
def select(nodes)
|
@@ -238,7 +251,7 @@ module Effigy
|
|
238
251
|
# Returns a set of nodes matching the given selector.
|
239
252
|
#
|
240
253
|
# @param selector [String] the selctor to use when finding nodes
|
241
|
-
# @return [Nokogiri::
|
254
|
+
# @return [Nokogiri::HTML::NodeSet] the nodes selected by the given selector
|
242
255
|
# @raise [ElementNotFound] if no nodes match the given selector
|
243
256
|
def select_all(selector)
|
244
257
|
result = current_context.search(selector)
|
@@ -249,10 +262,10 @@ module Effigy
|
|
249
262
|
# Clones an element, sets it as the current context, and yields to the
|
250
263
|
# given block with the given item.
|
251
264
|
#
|
252
|
-
# @param [Nokogiri::
|
265
|
+
# @param [Nokogiri::HTML::Element] the element to clone
|
253
266
|
# @param [Object] item the item that should be yielded to the block
|
254
267
|
# @yield [Object] the item passed as item
|
255
|
-
# @return [Nokogiri::
|
268
|
+
# @return [Nokogiri::HTML::Element] the clone of the original element
|
256
269
|
def clone_element_with_item(original_element, item, &block)
|
257
270
|
item_element = original_element.dup
|
258
271
|
find(item_element) { yield(item) }
|
@@ -269,7 +282,7 @@ module Effigy
|
|
269
282
|
#
|
270
283
|
# @return [String] the transformed document as a string
|
271
284
|
def output
|
272
|
-
current_context.
|
285
|
+
current_context.to_html
|
273
286
|
end
|
274
287
|
|
275
288
|
end
|
data/spec/effigy/view_spec.rb
CHANGED
@@ -7,130 +7,157 @@ module Effigy
|
|
7
7
|
template = %{<test><element one="abc">something</element></test>}
|
8
8
|
|
9
9
|
view = Effigy::View.new
|
10
|
-
|
10
|
+
html = view.render(template) do
|
11
11
|
view.text 'element', 'expected'
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
html.should have_selector(:element, :contents => 'expected', :one => 'abc')
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should replace element attributes" do
|
18
18
|
template = %{<test><element one="abc">something</element></test>}
|
19
19
|
|
20
20
|
view = Effigy::View.new
|
21
|
-
|
21
|
+
html = view.render(template) do
|
22
22
|
view.attr 'element', :one => '123', :two => '234'
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
html.should have_selector(:element, :contents => 'something', :one => '123', :two => '234')
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should replace one attribute" do
|
29
29
|
template = %{<test><element one="abc">something</element></test>}
|
30
30
|
|
31
31
|
view = Effigy::View.new
|
32
|
-
|
32
|
+
html = view.render(template) do
|
33
33
|
view.attr 'element', :one, '123'
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
html.should have_selector(:element, :contents => 'something', :one => '123')
|
37
37
|
end
|
38
38
|
|
39
39
|
it "should replace an element with a clone for each item in a collection" do
|
40
40
|
template = %{<test><element><value>original</value></element></test>}
|
41
41
|
|
42
42
|
view = Effigy::View.new
|
43
|
-
|
43
|
+
html = view.render(template) do
|
44
44
|
view.replace_each('element', %w(one two)) do |value|
|
45
45
|
view.text('value', value)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
49
|
+
html.should have_selector('element value', :contents => 'one')
|
50
|
+
html.should have_selector('element value', :contents => 'two')
|
51
|
+
html.should_not have_selector('element value', :contents => 'original')
|
52
|
+
html.should =~ /one.*two/m
|
53
53
|
end
|
54
54
|
|
55
55
|
it "should replace within a context" do
|
56
56
|
template = %{<test><element><value>original</value></element></test>}
|
57
57
|
|
58
58
|
view = Effigy::View.new
|
59
|
-
|
59
|
+
html = view.render(template) do
|
60
60
|
view.find('element') do
|
61
61
|
view.text('value', 'expected')
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
|
65
|
+
html.should have_selector('element value', :contents => 'expected')
|
66
66
|
end
|
67
67
|
|
68
68
|
it "should remove all matching elements" do
|
69
69
|
template = %{<test><first class="yes"/><other class="yes"/><last class="no"/></test>}
|
70
70
|
|
71
71
|
view = Effigy::View.new
|
72
|
-
|
72
|
+
html = view.render(template) do
|
73
73
|
view.remove('.yes')
|
74
74
|
end
|
75
75
|
|
76
|
-
|
77
|
-
|
76
|
+
html.should have_selector('.no')
|
77
|
+
html.should_not have_selector('.yes')
|
78
78
|
end
|
79
79
|
|
80
80
|
it "should add the given class names" do
|
81
81
|
template = %{<test class="original"/>}
|
82
82
|
|
83
83
|
view = Effigy::View.new
|
84
|
-
|
84
|
+
html = view.render(template) do
|
85
85
|
view.add_class('test', 'one', 'two')
|
86
86
|
end
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
88
|
+
html.should have_selector('test.original')
|
89
|
+
html.should have_selector('test.one')
|
90
|
+
html.should have_selector('test.two')
|
91
91
|
end
|
92
92
|
|
93
93
|
it "should remove the given class names" do
|
94
94
|
template = %{<test class="one two three"/>}
|
95
95
|
|
96
96
|
view = Effigy::View.new
|
97
|
-
|
97
|
+
html = view.render(template) do
|
98
98
|
view.remove_class('test', 'one', 'two')
|
99
99
|
end
|
100
100
|
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
html.should have_selector('test.three')
|
102
|
+
html.should_not have_selector('test.one')
|
103
|
+
html.should_not have_selector('test.two')
|
104
104
|
end
|
105
105
|
|
106
106
|
it "should replace an element's inner markup" do
|
107
107
|
template = %{<test><original>contents</original></test>}
|
108
108
|
|
109
109
|
view = Effigy::View.new
|
110
|
-
|
110
|
+
html = view.render(template) do
|
111
111
|
view.html 'test', '<new>replaced</new>'
|
112
112
|
end
|
113
113
|
|
114
|
-
|
115
|
-
|
114
|
+
html.should have_selector('test new', :contents => 'replaced')
|
115
|
+
html.should_not have_selector('original')
|
116
116
|
end
|
117
117
|
|
118
118
|
it "should replace an element's outer markup" do
|
119
119
|
template = %{<test><original>contents</original></test>}
|
120
120
|
|
121
121
|
view = Effigy::View.new
|
122
|
-
|
122
|
+
html = view.render(template) do
|
123
123
|
view.replace_with 'test', '<new>replaced</new>'
|
124
124
|
end
|
125
125
|
|
126
|
-
|
127
|
-
|
126
|
+
html.should have_selector('new', :contents => 'replaced')
|
127
|
+
html.should_not have_selector('test')
|
128
128
|
end
|
129
129
|
|
130
|
-
it "should
|
130
|
+
it "should append text to an element" do
|
131
|
+
template = %{<test>start</test>}
|
132
|
+
|
133
|
+
view = Effigy::View.new
|
134
|
+
html = view.render(template) do
|
135
|
+
view.append 'test', '<p>middle</p><p>end</p>'
|
136
|
+
end
|
137
|
+
|
138
|
+
html.should include("<test>start")
|
139
|
+
html.should have_selector('test p', :contents => 'middle')
|
140
|
+
html.should have_selector('test p', :contents => 'end')
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should render html by default" do
|
131
144
|
template = %{<html/>}
|
132
|
-
|
133
|
-
|
145
|
+
html = Effigy::View.new.render(template)
|
146
|
+
html.should_not include('<?xml')
|
147
|
+
html.should_not include('xmlns')
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should keep multiple top-level elements" do
|
151
|
+
template = %{<p>fragment one</p><p>fragment two</p>}
|
152
|
+
html = Effigy::View.new.render(template)
|
153
|
+
html.should include('one')
|
154
|
+
html.should include('two')
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should handle html fragments" do
|
158
|
+
template = %{<h1>hello</h1>}
|
159
|
+
html = Effigy::View.new.render(template)
|
160
|
+
html.should == template
|
134
161
|
end
|
135
162
|
|
136
163
|
%w(find f).each do |chain_method|
|
@@ -138,11 +165,11 @@ module Effigy
|
|
138
165
|
template = %{<test><element one="abc">something</element></test>}
|
139
166
|
|
140
167
|
view = Effigy::View.new
|
141
|
-
|
168
|
+
html = view.render(template) do
|
142
169
|
view.send(chain_method, 'element').text('expected')
|
143
170
|
end
|
144
171
|
|
145
|
-
|
172
|
+
html.should have_selector(:element, :contents => 'expected', :one => 'abc')
|
146
173
|
end
|
147
174
|
end
|
148
175
|
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effigy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Joe Ferris
|
@@ -9,19 +14,21 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-03-30 00:00:00 -04:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: nokogiri
|
17
|
-
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
24
|
requirements:
|
21
25
|
- - ">="
|
22
26
|
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
23
29
|
version: "0"
|
24
|
-
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
25
32
|
description: Define views in Ruby and templates in HTML. Avoid code interpolation or ugly templating languages. Use ids, class names, and semantic structures already present in your documents to produce content.
|
26
33
|
email: jferris@thoughtbot.com
|
27
34
|
executables: []
|
@@ -76,18 +83,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
83
|
requirements:
|
77
84
|
- - ">="
|
78
85
|
- !ruby/object:Gem::Version
|
86
|
+
segments:
|
87
|
+
- 0
|
79
88
|
version: "0"
|
80
|
-
version:
|
81
89
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
90
|
requirements:
|
83
91
|
- - ">="
|
84
92
|
- !ruby/object:Gem::Version
|
93
|
+
segments:
|
94
|
+
- 0
|
85
95
|
version: "0"
|
86
|
-
version:
|
87
96
|
requirements: []
|
88
97
|
|
89
98
|
rubyforge_project:
|
90
|
-
rubygems_version: 1.3.
|
99
|
+
rubygems_version: 1.3.6
|
91
100
|
signing_key:
|
92
101
|
specification_version: 3
|
93
102
|
summary: Effigy provides a view and template framework without a templating language.
|