padrino-helpers 0.11.0 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,8 +5,8 @@ module Padrino
5
5
  #
6
6
  module AssetTagHelpers
7
7
  FRAGMENT_HASH = "#".html_safe.freeze
8
- # assets that require an appended extension
9
- APPEND_ASSET_EXTENSIONS = ["js", "css"]
8
+ APPEND_ASSET_EXTENSIONS = ["js", "css"] # assets that require an appended extension
9
+ ABSOLUTE_URL_PATTERN = %r{^(https?://)} # absolute url regex
10
10
 
11
11
  ##
12
12
  # Creates a div to display the flash of given type if it exists
@@ -32,7 +32,7 @@ module Padrino
32
32
  bootstrap = options.delete(:bootstrap) if options[:bootstrap]
33
33
  args.inject(''.html_safe) do |html,kind|
34
34
  flash_text = flash[kind]
35
- next if flash_text.blank?
35
+ next html if flash_text.blank?
36
36
  flash_text << safe_content_tag(:button, "&times;", {:type => :button, :class => :close, :'data-dismiss' => :alert}) if bootstrap
37
37
  html << safe_content_tag(:div, flash_text, options.reverse_merge(:class => kind))
38
38
  end
@@ -323,7 +323,7 @@ module Padrino
323
323
  # @api semipublic
324
324
  def asset_path(kind, source)
325
325
  source = asset_normalize_extension(kind, URI.escape(source.to_s))
326
- return source if source =~ %r{^(/|https?://)} # absolute source
326
+ return source if source =~ ABSOLUTE_URL_PATTERN || source =~ /^\// # absolute source
327
327
  source = File.join(asset_folder_name(kind), source)
328
328
  timestamp = asset_timestamp(source)
329
329
  result_path = uri_root_path(source)
@@ -384,7 +384,7 @@ module Padrino
384
384
  #
385
385
  def asset_normalize_extension(kind, source)
386
386
  ignore_extension = !APPEND_ASSET_EXTENSIONS.include?(kind.to_s)
387
- source << ".#{kind}" unless ignore_extension or source =~ /\.#{kind}/
387
+ source << ".#{kind}" unless ignore_extension || source =~ /\.#{kind}/ || source =~ ABSOLUTE_URL_PATTERN
388
388
  source
389
389
  end
390
390
 
@@ -37,7 +37,7 @@ module Padrino
37
37
  #
38
38
  # @api public
39
39
  def set_home(url, caption)
40
- self.home = { :url => url, :caption => caption.to_s.humanize, :name => :home }
40
+ self.home = { :url => url, :caption => caption.to_s.humanize.html_safe, :name => :home }
41
41
  reset
42
42
  end
43
43
 
@@ -85,7 +85,7 @@ module Padrino
85
85
  #
86
86
  # @api public
87
87
  def add(name, url, caption)
88
- items << { :name => name, :url => url.to_s, :caption => caption.to_s.humanize }
88
+ items << { :name => name, :url => url.to_s, :caption => caption.to_s.humanize.html_safe }
89
89
  end
90
90
 
91
91
  alias :<< :add
@@ -31,7 +31,8 @@ module Padrino
31
31
  # @api public
32
32
  def form_for(object, url, settings={}, &block)
33
33
  instance = builder_instance(object, settings)
34
- form_tag(url, settings) { capture_html(instance, &block) }
34
+ html = capture_html(instance, &block)
35
+ form_tag(url, settings) { html }
35
36
  end
36
37
 
37
38
  ##
@@ -170,7 +171,7 @@ module Padrino
170
171
  objects = objects.map { |object_name|
171
172
  object_name.is_a?(Symbol) ? instance_variable_get("@#{object_name}") : object_name
172
173
  }.compact
173
- count = objects.inject(0) { |sum, object| sum + object.errors.size }
174
+ count = objects.inject(0) { |sum, object| sum + object.errors.count }
174
175
 
175
176
  unless count.zero?
176
177
  html = {}
@@ -19,7 +19,7 @@ module Padrino
19
19
  #
20
20
  # @api public
21
21
  def escape_html(text)
22
- Rack::Utils.escape_html(text)
22
+ Rack::Utils.escape_html(text).html_safe
23
23
  end
24
24
  alias h escape_html
25
25
  alias sanitize_html escape_html
@@ -41,8 +41,8 @@ module Padrino
41
41
  #
42
42
  # @api public
43
43
  def h!(text, blank_text = '&nbsp;')
44
- return blank_text if text.nil? || text.empty?
45
- h text
44
+ return blank_text.html_safe if text.nil? || text.empty?
45
+ h(text)
46
46
  end
47
47
 
48
48
  ##
@@ -83,12 +83,13 @@ module Padrino
83
83
  def simple_format(text, options={})
84
84
  t = options.delete(:tag) || :p
85
85
  start_tag = tag(t, options, true)
86
- text = text.to_s.dup
86
+ text = escape_html(text.to_s.dup)
87
87
  text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
88
88
  text.gsub!(/\n\n+/, "</#{t}>\n\n#{start_tag}") # 2+ newline -> paragraph
89
89
  text.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
90
90
  text.insert 0, start_tag
91
91
  text << "</#{t}>"
92
+ text.html_safe
92
93
  end
93
94
 
94
95
  ##
@@ -374,7 +375,9 @@ module Padrino
374
375
  def js_escape_html(html_content)
375
376
  return '' unless html_content
376
377
  javascript_mapping = { '\\' => '\\\\', '</' => '<\/', "\r\n" => '\n', "\n" => '\n', "\r" => '\n', '"' => '\\"', "'" => "\\'" }
377
- html_content.gsub(/(\\|<\/|\r\n|[\n\r"'])/){|m| javascript_mapping[m]}
378
+ escaped_content = html_content.gsub(/(\\|<\/|\r\n|[\n\r"'])/){ |m| javascript_mapping[m] }
379
+ escaped_content = escaped_content.html_safe if html_content.html_safe?
380
+ escaped_content
378
381
  end
379
382
  alias :escape_javascript :js_escape_html
380
383
  end # FormatHelpers
@@ -14,8 +14,8 @@ zh_cn:
14
14
  currency:
15
15
  format:
16
16
  # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
17
- format: "%u %n"
18
- unit: ""
17
+ format: "%u%n"
18
+ unit: "RMB"
19
19
  # These three are to override number.format and are optional
20
20
  separator: "."
21
21
  delimiter: ","
@@ -50,12 +50,12 @@ zh_cn:
50
50
  format: "%n %u"
51
51
  units:
52
52
  byte:
53
- one: "Byte"
54
- other: "Bytes"
55
- kb: "KB"
56
- mb: "MB"
57
- gb: "GB"
58
- tb: "TB"
53
+ one: "字节"
54
+ other: "字节"
55
+ kb: "K"
56
+ mb: ""
57
+ gb: "G"
58
+ tb: "T"
59
59
 
60
60
  # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
61
61
  datetime:
@@ -92,13 +92,12 @@ zh_cn:
92
92
  one: "一年多"
93
93
  other: "%{count} 年多"
94
94
  almost_x_years:
95
- one: "接近一年"
96
- other: "接近 %{count} 年"
95
+ one: "已经一年"
96
+ other: "已经 %{count} 年"
97
97
  models:
98
98
  errors:
99
99
  template:
100
100
  header:
101
- one: "有1 个错误发生使得「%{model}」无法被储存。 "
102
- other: "有%{count} 个错误发生使得「%{model}」无法被储存。 "
103
- body: "以下栏位发生问题:"
104
-
101
+ one: "%{model} 保存时产生错误"
102
+ other: "%{model} 保存时产生了 %{count} 个错误"
103
+ body: "下列字段产生错误:"
@@ -48,12 +48,12 @@ module Padrino
48
48
  # @api semipublic
49
49
  def capture_html(*args, &block)
50
50
  handler = find_proper_handler
51
- captured_html = ""
51
+ captured_block, captured_html = nil, ""
52
52
  if handler && handler.is_type? && handler.block_is_type?(block)
53
- captured_html = handler.capture_from_template(*args, &block)
53
+ captured_html, captured_block = handler.capture_from_template(*args, &block)
54
54
  end
55
55
  # invoking the block directly if there was no template
56
- captured_html = block_given? && block.call(*args) if captured_html.blank?
56
+ captured_html = block_given? && ( captured_block || block.call(*args) ) if captured_html.blank?
57
57
  captured_html
58
58
  end
59
59
  alias :capture :capture_html
@@ -29,10 +29,10 @@ module Padrino
29
29
  #
30
30
  def capture_from_template(*args, &block)
31
31
  self.output_buffer, _buf_was = ActiveSupport::SafeBuffer.new, self.output_buffer
32
- block.call(*args)
32
+ captured_block = block.call(*args)
33
33
  ret = eval("@_out_buf", block.binding)
34
34
  self.output_buffer = _buf_was
35
- ret
35
+ [ ret, captured_block ]
36
36
  end
37
37
 
38
38
  ##
@@ -31,10 +31,10 @@ module Padrino
31
31
  #
32
32
  def capture_from_template(*args, &block)
33
33
  self.output_buffer, _buf_was = ActiveSupport::SafeBuffer.new, self.output_buffer
34
- block.call(*args)
34
+ captured_block = block.call(*args)
35
35
  ret = eval("@_out_buf", block.binding)
36
36
  self.output_buffer = _buf_was
37
- ret
37
+ [ ret, captured_block ]
38
38
  end
39
39
 
40
40
  ##
@@ -31,6 +31,10 @@ class RenderDemo < Padrino::Application
31
31
  render :explicit_engine
32
32
  end
33
33
 
34
+ get '/double_capture_:ext' do
35
+ render "double_capture_#{params[:ext]}"
36
+ end
37
+
34
38
  # partial with object
35
39
  get '/partial/object' do
36
40
  partial 'template/user', :object => RenderUser.new('John'), :locals => { :extra => "bar" }
@@ -0,0 +1,3 @@
1
+ <% form_for( :object, '/' ) do |f| %>
2
+ <%= $number_of_captures += 1 %>
3
+ <% end %>
@@ -0,0 +1,2 @@
1
+ - form_for :object, '/' do |f|
2
+ = $number_of_captures += 1
@@ -0,0 +1,2 @@
1
+ - form_for :object, '/' do |f|
2
+ = $number_of_captures += 1
@@ -23,7 +23,7 @@ describe "AssetTagHelpers" do
23
23
  should "display multiple flash tags with given attributes" do
24
24
  flash[:error] = 'wrong'
25
25
  flash[:success] = 'okey'
26
- actual_html = flash_tag(:success, :error, :id => 'area')
26
+ actual_html = flash_tag(:success, :warning, :error, :id => 'area')
27
27
  assert_has_tag('div.success#area', :content => flash[:success]) { actual_html }
28
28
  assert_has_tag('div.error#area', :content => flash[:error]) { actual_html }
29
29
  assert_has_no_tag('div.notice') { actual_html }
@@ -294,6 +294,12 @@ describe "AssetTagHelpers" do
294
294
  assert_has_tag('script', :src => "/blog/javascripts/application.js?#{time.to_i}", :type => "text/javascript") { actual_html }
295
295
  end
296
296
 
297
+ should "not append extension to absolute paths" do
298
+ time = stop_time_for_test
299
+ actual_html = javascript_include_tag('https://maps.googleapis.com/maps/api/js?key=value&sensor=false')
300
+ assert_has_tag('script', :src => "https://maps.googleapis.com/maps/api/js?key=value&sensor=false") { actual_html }
301
+ end
302
+
297
303
  should "display javascript items" do
298
304
  time = stop_time_for_test
299
305
  actual_html = javascript_include_tag('application', 'base.js', 'http://google.com/lib.js')
@@ -15,6 +15,7 @@ describe "FormatHelpers" do
15
15
  context 'for #simple_format method' do
16
16
  should "format simple text into html format" do
17
17
  actual_text = simple_format("Here is some basic text...\n...with a line break.")
18
+ assert_equal true, actual_text.html_safe?
18
19
  assert_equal "<p>Here is some basic text...\n<br />...with a line break.</p>", actual_text
19
20
  end
20
21
 
@@ -139,6 +140,11 @@ describe "FormatHelpers" do
139
140
  should "return text escaped if not empty" do
140
141
  assert_equal '&lt;h1&gt;hello&lt;&#x2F;h1&gt;', h!('<h1>hello</h1>')
141
142
  end
143
+ should "mark escaped text as safe" do
144
+ assert_equal false, '<h1>hello</h1>'.html_safe?
145
+ assert_equal true, h('<h1>hello</h1>').html_safe?
146
+ assert_equal true, h!("", "default").html_safe?
147
+ end
142
148
  end
143
149
 
144
150
  context 'for #time_ago_in_words method' do
@@ -227,5 +233,9 @@ describe "FormatHelpers" do
227
233
  assert_equal "<data-confirm=\\\"are you sure\\\">", js_escape_html("<data-confirm=\"are you sure\">")
228
234
  assert_equal "<data-confirm=\\\"are you sure\\\">", js_escape_html(ActiveSupport::SafeBuffer.new("<data-confirm=\"are you sure\">"))
229
235
  end
236
+ should "keep html_safe content html_safe" do
237
+ assert_equal false, js_escape_html('"hello"').html_safe?
238
+ assert_equal true, js_escape_html(ActiveSupport::SafeBuffer.new('"hello"')).html_safe?
239
+ end
230
240
  end
231
241
  end
@@ -72,5 +72,23 @@ describe "RenderHelpers" do
72
72
  assert_have_selector 'p.slim span', :content => "slim"
73
73
  assert_have_selector 'p.end', :content => "haml"
74
74
  end
75
+
76
+ should "capture slim template once and only once" do
77
+ $number_of_captures = 0
78
+ visit '/double_capture_slim'
79
+ assert_equal 1,$number_of_captures
80
+ end
81
+
82
+ should "capture haml template once and only once" do
83
+ $number_of_captures = 0
84
+ visit '/double_capture_haml'
85
+ assert_equal 1,$number_of_captures
86
+ end
87
+
88
+ should "capture erb template once and only once" do
89
+ $number_of_captures = 0
90
+ visit '/double_capture_erb'
91
+ assert_equal 1,$number_of_captures
92
+ end
75
93
  end
76
94
  end
metadata CHANGED
@@ -1,7 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: padrino-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.11.1
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Padrino Team
@@ -11,25 +12,28 @@ authors:
11
12
  autorequire:
12
13
  bindir: bin
13
14
  cert_chain: []
14
- date: 2013-03-22 00:00:00.000000000 Z
15
+ date: 2013-04-07 00:00:00.000000000 Z
15
16
  dependencies:
16
17
  - !ruby/object:Gem::Dependency
17
18
  name: padrino-core
18
19
  requirement: !ruby/object:Gem::Requirement
20
+ none: false
19
21
  requirements:
20
22
  - - '='
21
23
  - !ruby/object:Gem::Version
22
- version: 0.11.0
24
+ version: 0.11.1
23
25
  type: :runtime
24
26
  prerelease: false
25
27
  version_requirements: !ruby/object:Gem::Requirement
28
+ none: false
26
29
  requirements:
27
30
  - - '='
28
31
  - !ruby/object:Gem::Version
29
- version: 0.11.0
32
+ version: 0.11.1
30
33
  - !ruby/object:Gem::Dependency
31
34
  name: i18n
32
35
  requirement: !ruby/object:Gem::Requirement
36
+ none: false
33
37
  requirements:
34
38
  - - ~>
35
39
  - !ruby/object:Gem::Version
@@ -37,6 +41,7 @@ dependencies:
37
41
  type: :runtime
38
42
  prerelease: false
39
43
  version_requirements: !ruby/object:Gem::Requirement
44
+ none: false
40
45
  requirements:
41
46
  - - ~>
42
47
  - !ruby/object:Gem::Version
@@ -135,6 +140,9 @@ files:
135
140
  - test/fixtures/render_app/views/current_engines/_erb.erb
136
141
  - test/fixtures/render_app/views/current_engines/_haml.haml
137
142
  - test/fixtures/render_app/views/current_engines/_slim.slim
143
+ - test/fixtures/render_app/views/double_capture_erb.erb
144
+ - test/fixtures/render_app/views/double_capture_haml.haml
145
+ - test/fixtures/render_app/views/double_capture_slim.slim
138
146
  - test/fixtures/render_app/views/erb/test.erb
139
147
  - test/fixtures/render_app/views/explicit_engine.haml
140
148
  - test/fixtures/render_app/views/haml/test.haml
@@ -153,27 +161,31 @@ files:
153
161
  - test/test_tag_helpers.rb
154
162
  homepage: http://www.padrinorb.com
155
163
  licenses: []
156
- metadata: {}
157
164
  post_install_message:
158
165
  rdoc_options:
159
166
  - --charset=UTF-8
160
167
  require_paths:
161
168
  - lib
162
169
  required_ruby_version: !ruby/object:Gem::Requirement
170
+ none: false
163
171
  requirements:
164
- - - '>='
172
+ - - ! '>='
165
173
  - !ruby/object:Gem::Version
166
174
  version: '0'
175
+ segments:
176
+ - 0
177
+ hash: 3249284005023139295
167
178
  required_rubygems_version: !ruby/object:Gem::Requirement
179
+ none: false
168
180
  requirements:
169
- - - '>='
181
+ - - ! '>='
170
182
  - !ruby/object:Gem::Version
171
183
  version: 1.3.6
172
184
  requirements: []
173
185
  rubyforge_project: padrino-helpers
174
- rubygems_version: 2.0.3
186
+ rubygems_version: 1.8.25
175
187
  signing_key:
176
- specification_version: 4
188
+ specification_version: 3
177
189
  summary: Helpers for padrino
178
190
  test_files:
179
191
  - test/fixtures/markup_app/app.rb
@@ -218,6 +230,9 @@ test_files:
218
230
  - test/fixtures/render_app/views/current_engines/_erb.erb
219
231
  - test/fixtures/render_app/views/current_engines/_haml.haml
220
232
  - test/fixtures/render_app/views/current_engines/_slim.slim
233
+ - test/fixtures/render_app/views/double_capture_erb.erb
234
+ - test/fixtures/render_app/views/double_capture_haml.haml
235
+ - test/fixtures/render_app/views/double_capture_slim.slim
221
236
  - test/fixtures/render_app/views/erb/test.erb
222
237
  - test/fixtures/render_app/views/explicit_engine.haml
223
238
  - test/fixtures/render_app/views/haml/test.haml
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: f362f51264ab447da505f5bbaeb295b467cff819
4
- data.tar.gz: c0a4370011a89876d15d3668a82e3451e5b9b6cb
5
- SHA512:
6
- metadata.gz: c3b645ff7c6bbdafc844465cb6f78fcdea389ee27ccff8b6dabd2f7eb352ebb1f256f0cea9c67914a6d56ba74609c678a2703b7b7451558c73ef1822877a511f
7
- data.tar.gz: fafd39ce16c2639cbde4537a6b6530b2580e1c59ae9c397298dd16d8416bc9a241e7eeff8c4a91f4548609f64339162ec28ad597398a1c6a93839f11c6706652