Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
5ce304af
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5ce304af
编写于
6月 27, 2016
作者:
K
Kasper Timm Hansen
提交者:
GitHub
6月 27, 2016
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #25543 from marekkirejczyk/tag_builder_25195
New syntax for tag helpers i.e. tag.br instead of tag('br') #25195
上级
ffded19f
a65a3bde
变更
6
显示空白变更内容
内联
并排
Showing
6 changed file
with
364 addition
and
63 deletion
+364
-63
actionview/CHANGELOG.md
actionview/CHANGELOG.md
+25
-0
actionview/lib/action_view/helpers/form_options_helper.rb
actionview/lib/action_view/helpers/form_options_helper.rb
+1
-1
actionview/lib/action_view/helpers/tag_helper.rb
actionview/lib/action_view/helpers/tag_helper.rb
+173
-56
actionview/lib/action_view/helpers/tags/base.rb
actionview/lib/action_view/helpers/tags/base.rb
+2
-2
actionview/test/fixtures/test/_builder_tag_nested_in_content_tag.erb
...test/fixtures/test/_builder_tag_nested_in_content_tag.erb
+3
-0
actionview/test/template/tag_helper_test.rb
actionview/test/template/tag_helper_test.rb
+160
-4
未找到文件。
actionview/CHANGELOG.md
浏览文件 @
5ce304af
*
New syntax for tag helpers. Avoid positional parameters and support HTML5 by default.
Example usage of tag helpers before:
```ruby
tag(:br, nil, true)
content_tag(:div, content_tag(:p, "Hello world!"), class: "strong")
<%= content_tag :div, class: "strong" do -%>
Hello world!
<% end -%>
```
Example usage of tag helpers after:
```ruby
tag.br
tag.div tag.p("Hello world!"), class: "strong"
<%= tag.div class: "strong" do %>
Hello world!
<% end %>
```
*Marek Kirejczyk*, *Kasper Timm Hansen*
*
Change
`datetime_field`
and
`datetime_field_tag`
to generate
`datetime-local`
fields.
As a new specification of the HTML 5 the text field type `datetime` will no longer exist
...
...
actionview/lib/action_view/helpers/form_options_helper.rb
浏览文件 @
5ce304af
...
...
@@ -363,7 +363,7 @@ def options_for_select(container, selected = nil)
html_attributes
[
:disabled
]
||=
disabled
&&
option_value_selected?
(
value
,
disabled
)
html_attributes
[
:value
]
=
value
content_tag_string
(
:option
,
text
,
html_attributes
)
tag_builder
.
content_tag_string
(
:option
,
text
,
html_attributes
)
end
.
join
(
"
\n
"
).
html_safe
end
...
...
actionview/lib/action_view/helpers/tag_helper.rb
浏览文件 @
5ce304af
...
...
@@ -4,8 +4,8 @@
module
ActionView
# = Action View Tag Helpers
module
Helpers
#:nodoc:
# Provides methods to generate HTML tags programmatically
when you can't use
#
a Builder. By default, they output
XHTML compliant tags.
# Provides methods to generate HTML tags programmatically
both as a modern
#
HTML5 compliant builder style and legacy
XHTML compliant tags.
module
TagHelper
extend
ActiveSupport
::
Concern
include
CaptureHelper
...
...
@@ -26,7 +26,167 @@ module TagHelper
PRE_CONTENT_STRINGS
[
:textarea
]
=
"
\n
"
PRE_CONTENT_STRINGS
[
"textarea"
]
=
"
\n
"
class
TagBuilder
#:nodoc:
include
CaptureHelper
include
OutputSafetyHelper
VOID_ELEMENTS
=
%i(base br col embed hr img input keygen link meta param source track wbr)
.
to_set
def
initialize
(
view_context
)
@view_context
=
view_context
end
def
tag_string
(
name
,
content
=
nil
,
escape_attributes:
true
,
**
options
,
&
block
)
content
=
@view_context
.
capture
(
self
,
&
block
)
if
block_given?
if
VOID_ELEMENTS
.
include?
(
name
)
&&
content
.
nil?
"<
#{
name
.
to_s
.
dasherize
}#{
tag_options
(
options
,
escape_attributes
)
}
>"
.
html_safe
else
content_tag_string
(
name
.
to_s
.
dasherize
,
content
||
''
,
options
,
escape_attributes
)
end
end
def
content_tag_string
(
name
,
content
,
options
,
escape
=
true
)
tag_options
=
tag_options
(
options
,
escape
)
if
options
content
=
ERB
::
Util
.
unwrapped_html_escape
(
content
)
if
escape
"<
#{
name
}#{
tag_options
}
>
#{
PRE_CONTENT_STRINGS
[
name
]
}#{
content
}
</
#{
name
}
>"
.
html_safe
end
def
tag_options
(
options
,
escape
=
true
)
return
if
options
.
blank?
output
=
""
sep
=
" "
.
freeze
options
.
each_pair
do
|
key
,
value
|
if
TAG_PREFIXES
.
include?
(
key
)
&&
value
.
is_a?
(
Hash
)
value
.
each_pair
do
|
k
,
v
|
next
if
v
.
nil?
output
<<
sep
output
<<
prefix_tag_option
(
key
,
k
,
v
,
escape
)
end
elsif
BOOLEAN_ATTRIBUTES
.
include?
(
key
)
if
value
output
<<
sep
output
<<
boolean_tag_option
(
key
)
end
elsif
!
value
.
nil?
output
<<
sep
output
<<
tag_option
(
key
,
value
,
escape
)
end
end
output
unless
output
.
empty?
end
def
boolean_tag_option
(
key
)
%(#{key}="#{key}")
end
def
tag_option
(
key
,
value
,
escape
)
if
value
.
is_a?
(
Array
)
value
=
escape
?
safe_join
(
value
,
" "
.
freeze
)
:
value
.
join
(
" "
.
freeze
)
else
value
=
escape
?
ERB
::
Util
.
unwrapped_html_escape
(
value
)
:
value
end
%(#{key}="#{value}")
end
private
def
prefix_tag_option
(
prefix
,
key
,
value
,
escape
)
key
=
"
#{
prefix
}
-
#{
key
.
to_s
.
dasherize
}
"
unless
value
.
is_a?
(
String
)
||
value
.
is_a?
(
Symbol
)
||
value
.
is_a?
(
BigDecimal
)
value
=
value
.
to_json
end
tag_option
(
key
,
value
,
escape
)
end
def
respond_to_missing?
(
*
args
)
true
end
def
method_missing
(
called
,
*
args
,
&
block
)
tag_string
(
called
,
*
args
,
&
block
)
end
end
# Returns an HTML tag.
#
# === Building HTML tags
# Builds HTML5 compliant tags with a tag proxy. Every tag can be built with:
#
# tag.<tag name>(optional content, options)
#
# where tag name can be e.g. br, div, section, article, or any tag really.
#
# ==== Passing content
# Tags can pass content to embed within it:
#
# tag.h1 'All shit fit to print' # => <h1>All shit fit to print</h1>
#
# tag.div tag.p('Hello world!') # => <div><p>Hello world!</p></div>
#
# Content can also be captured with a block. Great for ERB templates:
#
# <%= tag.p do %>
# The next great American novel starts here.
# <% end %>
# # => <p>The next great American novel starts here.</p>
#
# ==== Options
# Any passed options becomes attributes on the generated tag.
#
# tag.section class: %w( kitties puppies )
# # => <section class="kitties puppies"></section>
#
# tag.section id: dom_id(@post)
# # => <section id="<generated dom id>"></section>
#
# Pass true for any attributes that can render with no values like +disabled+.
#
# tag.input type: 'text', disabled: true
# # => <input type="text" disabled="disabled">
#
# HTML5 <tt>data-*</tt> attributes can be set with a single +data+ key
# pointing to a hash of sub-attributes.
#
# To play nicely with JavaScript conventions sub-attributes are dasherized.
#
# tag.article data: { user_id: 123 }
# # => <article data-user-id="123"></article>
#
# Thus <tt>data-user-id</tt> can be accessed as <tt>dataset.userId</tt>.
#
# Data attribute values are encoded to JSON, with the exception of strings, symbols and
# BigDecimals.
# This may come in handy when using jQuery's HTML5-aware <tt>.data()</tt>
# from 1.4.3.
#
# tag.div data: { city_state: %w( Chigaco IL ) }
# # => <div data-city-state="["Chicago","IL"]"></div>
#
# The generated attributes are escaped by default, but it can be turned off with
# +escape_attributes+.
#
# tag.img src: 'open & shut.png'
# # => <img src="open & shut.png">
#
# tag.img src: 'open & shut.png', escape_attributes: false
# # => <img src="open & shut.png">
#
# The tag builder respects
# [HTML5 void elements](https://www.w3.org/TR/html5/syntax.html#void-elements)
# if no content is passed, and omits closing tags for those elements.
#
# # A standard element:
# tag.div # => <div></div>
#
# # A void element:
# tag.br # => <br>
#
# === Legacy syntax
# Following format is legacy syntax. It will be deprecated in future versions of rails.
#
# tag(tag_name, options)
#
# === Building HTML tags
# Returns an empty HTML tag of type +name+ which by default is XHTML
# compliant. Set +open+ to true to create an open tag compatible
# with HTML 4.0 and below. Add HTML attributes by passing an attributes
...
...
@@ -72,8 +232,12 @@ module TagHelper
#
# tag("div", data: {name: 'Stephen', city_state: %w(Chicago IL)})
# # => <div data-name="Stephen" data-city-state="["Chicago","IL"]" />
def
tag
(
name
,
options
=
nil
,
open
=
false
,
escape
=
true
)
"<
#{
name
}#{
tag_options
(
options
,
escape
)
if
options
}#{
open
?
">"
:
" />"
}
"
.
html_safe
def
tag
(
name
=
nil
,
options
=
nil
,
open
=
false
,
escape
=
true
)
if
name
.
nil?
tag_builder
else
"<
#{
name
}#{
tag_builder
.
tag_options
(
options
,
escape
)
if
options
}#{
open
?
">"
:
" />"
}
"
.
html_safe
end
end
# Returns an HTML block tag of type +name+ surrounding the +content+. Add
...
...
@@ -81,6 +245,7 @@ def tag(name, options = nil, open = false, escape = true)
# Instead of passing the content as an argument, you can also use a block
# in which case, you pass your +options+ as the second parameter.
# Set escape to false to disable attribute value escaping.
# Note: this is legacy syntax, see +tag+ method description for details.
#
# ==== Options
# The +options+ hash can be used with attributes with no value like (<tt>disabled</tt> and
...
...
@@ -104,9 +269,9 @@ def tag(name, options = nil, open = false, escape = true)
def
content_tag
(
name
,
content_or_options_with_block
=
nil
,
options
=
nil
,
escape
=
true
,
&
block
)
if
block_given?
options
=
content_or_options_with_block
if
content_or_options_with_block
.
is_a?
(
Hash
)
content_tag_string
(
name
,
capture
(
&
block
),
options
,
escape
)
tag_builder
.
content_tag_string
(
name
,
capture
(
&
block
),
options
,
escape
)
else
content_tag_string
(
name
,
content_or_options_with_block
,
options
,
escape
)
tag_builder
.
content_tag_string
(
name
,
content_or_options_with_block
,
options
,
escape
)
end
end
...
...
@@ -140,56 +305,8 @@ def escape_once(html)
end
private
def
content_tag_string
(
name
,
content
,
options
,
escape
=
true
)
tag_options
=
tag_options
(
options
,
escape
)
if
options
content
=
ERB
::
Util
.
unwrapped_html_escape
(
content
)
if
escape
"<
#{
name
}#{
tag_options
}
>
#{
PRE_CONTENT_STRINGS
[
name
]
}#{
content
}
</
#{
name
}
>"
.
html_safe
end
def
tag_options
(
options
,
escape
=
true
)
return
if
options
.
blank?
output
=
""
sep
=
" "
.
freeze
options
.
each_pair
do
|
key
,
value
|
if
TAG_PREFIXES
.
include?
(
key
)
&&
value
.
is_a?
(
Hash
)
value
.
each_pair
do
|
k
,
v
|
next
if
v
.
nil?
output
<<
sep
output
<<
prefix_tag_option
(
key
,
k
,
v
,
escape
)
end
elsif
BOOLEAN_ATTRIBUTES
.
include?
(
key
)
if
value
output
<<
sep
output
<<
boolean_tag_option
(
key
)
end
elsif
!
value
.
nil?
output
<<
sep
output
<<
tag_option
(
key
,
value
,
escape
)
end
end
output
unless
output
.
empty?
end
def
prefix_tag_option
(
prefix
,
key
,
value
,
escape
)
key
=
"
#{
prefix
}
-
#{
key
.
to_s
.
dasherize
}
"
unless
value
.
is_a?
(
String
)
||
value
.
is_a?
(
Symbol
)
||
value
.
is_a?
(
BigDecimal
)
value
=
value
.
to_json
end
tag_option
(
key
,
value
,
escape
)
end
def
boolean_tag_option
(
key
)
%(#{key}="#{key}")
end
def
tag_option
(
key
,
value
,
escape
)
if
value
.
is_a?
(
Array
)
value
=
escape
?
safe_join
(
value
,
" "
.
freeze
)
:
value
.
join
(
" "
.
freeze
)
else
value
=
escape
?
ERB
::
Util
.
unwrapped_html_escape
(
value
)
:
value
end
%(#{key}="#{value}")
def
tag_builder
@tag_builder
||=
TagBuilder
.
new
(
self
)
end
end
end
...
...
actionview/lib/action_view/helpers/tags/base.rb
浏览文件 @
5ce304af
...
...
@@ -143,10 +143,10 @@ def placeholder_required?(html_options)
def
add_options
(
option_tags
,
options
,
value
=
nil
)
if
options
[
:include_blank
]
option_tags
=
content_tag_string
(
'option'
,
options
[
:include_blank
].
kind_of?
(
String
)
?
options
[
:include_blank
]
:
nil
,
:value
=>
''
)
+
"
\n
"
+
option_tags
option_tags
=
tag_builder
.
content_tag_string
(
'option'
,
options
[
:include_blank
].
kind_of?
(
String
)
?
options
[
:include_blank
]
:
nil
,
:value
=>
''
)
+
"
\n
"
+
option_tags
end
if
value
.
blank?
&&
options
[
:prompt
]
option_tags
=
content_tag_string
(
'option'
,
prompt_text
(
options
[
:prompt
]),
:value
=>
''
)
+
"
\n
"
+
option_tags
option_tags
=
tag_builder
.
content_tag_string
(
'option'
,
prompt_text
(
options
[
:prompt
]),
:value
=>
''
)
+
"
\n
"
+
option_tags
end
option_tags
end
...
...
actionview/test/fixtures/test/_builder_tag_nested_in_content_tag.erb
0 → 100644
浏览文件 @
5ce304af
<%=
tag
.
p
do
%>
<%=
tag
.
b
'Hello'
%>
<%
end
%>
actionview/test/template/tag_helper_test.rb
浏览文件 @
5ce304af
...
...
@@ -11,6 +11,24 @@ def test_tag
assert_equal
"<br>"
,
tag
(
"br"
,
nil
,
true
)
end
def
test_tag_builder
assert_equal
"<span></span>"
,
tag
.
span
assert_equal
"<span class=
\"
bookmark
\"
></span>"
,
tag
.
span
(
class:
"bookmark"
)
end
def
test_tag_builder_void_tag
assert_equal
"<br>"
,
tag
.
br
assert_equal
"<br class=
\"
some_class
\"
>"
,
tag
.
br
(
class:
'some_class'
)
end
def
test_tag_builder_void_tag_with_forced_content
assert_equal
"<br>some content</br>"
,
tag
.
br
(
"some content"
)
end
def
test_tag_builder_is_singleton
assert_equal
tag
,
tag
end
def
test_tag_options
str
=
tag
(
"p"
,
"class"
=>
"show"
,
:class
=>
"elsewhere"
)
assert_match
(
/class="show"/
,
str
)
...
...
@@ -21,19 +39,36 @@ def test_tag_options_rejects_nil_option
assert_equal
"<p />"
,
tag
(
"p"
,
:ignored
=>
nil
)
end
def
test_tag_builder_options_rejects_nil_option
assert_equal
"<p></p>"
,
tag
.
p
(
ignored:
nil
)
end
def
test_tag_options_accepts_false_option
assert_equal
"<p value=
\"
false
\"
/>"
,
tag
(
"p"
,
:value
=>
false
)
end
def
test_tag_builder_options_accepts_false_option
assert_equal
"<p value=
\"
false
\"
></p>"
,
tag
.
p
(
value:
false
)
end
def
test_tag_options_accepts_blank_option
assert_equal
"<p included=
\"\"
/>"
,
tag
(
"p"
,
:included
=>
''
)
end
def
test_tag_builder_options_accepts_blank_option
assert_equal
"<p included=
\"\"
></p>"
,
tag
.
p
(
included:
''
)
end
def
test_tag_options_converts_boolean_option
assert_dom_equal
'<p disabled="disabled" itemscope="itemscope" multiple="multiple" readonly="readonly" allowfullscreen="allowfullscreen" seamless="seamless" typemustmatch="typemustmatch" sortable="sortable" default="default" inert="inert" truespeed="truespeed" />'
,
tag
(
"p"
,
:disabled
=>
true
,
:itemscope
=>
true
,
:multiple
=>
true
,
:readonly
=>
true
,
:allowfullscreen
=>
true
,
:seamless
=>
true
,
:typemustmatch
=>
true
,
:sortable
=>
true
,
:default
=>
true
,
:inert
=>
true
,
:truespeed
=>
true
)
end
def
test_tag_builder_options_converts_boolean_option
assert_dom_equal
'<p disabled="disabled" itemscope="itemscope" multiple="multiple" readonly="readonly" allowfullscreen="allowfullscreen" seamless="seamless" typemustmatch="typemustmatch" sortable="sortable" default="default" inert="inert" truespeed="truespeed" />'
,
tag
.
p
(
disabled:
true
,
itemscope:
true
,
multiple:
true
,
readonly:
true
,
allowfullscreen:
true
,
seamless:
true
,
typemustmatch:
true
,
sortable:
true
,
default:
true
,
inert:
true
,
truespeed:
true
)
end
def
test_content_tag
assert_equal
"<a href=
\"
create
\"
>Create</a>"
,
content_tag
(
"a"
,
"Create"
,
"href"
=>
"create"
)
assert
content_tag
(
"a"
,
"Create"
,
"href"
=>
"create"
).
html_safe?
...
...
@@ -45,43 +80,96 @@ def test_content_tag
content_tag
(
:p
,
'<script>evil_js</script>'
,
nil
,
false
)
end
def
test_tag_builder_with_content
assert_equal
"<div id=
\"
post_1
\"
>Content</div>"
,
tag
.
div
(
"Content"
,
id:
"post_1"
)
assert
tag
.
div
(
"Content"
,
id:
"post_1"
).
html_safe?
assert_equal
tag
.
div
(
"Content"
,
id:
"post_1"
),
tag
.
div
(
"Content"
,
"id"
:
"post_1"
)
assert_equal
"<p><script>evil_js</script></p>"
,
tag
.
p
(
"<script>evil_js</script>"
)
assert_equal
"<p><script>evil_js</script></p>"
,
tag
.
p
(
'<script>evil_js</script>'
,
escape_attributes:
false
)
end
def
test_tag_builder_nested
assert_equal
"<div>content</div>"
,
tag
.
div
{
"content"
}
assert_equal
"<div id=
\"
header
\"
><span>hello</span></div>"
,
tag
.
div
(
id:
'header'
)
{
|
tag
|
tag
.
span
'hello'
}
assert_equal
"<div id=
\"
header
\"
><div class=
\"
world
\"
><span>hello</span></div></div>"
,
tag
.
div
(
id:
'header'
)
{
|
tag
|
tag
.
div
(
class:
'world'
)
{
tag
.
span
'hello'
}
}
end
def
test_content_tag_with_block_in_erb
buffer
=
render_erb
(
"<%= content_tag(:div) do %>Hello world!<% end %>"
)
assert_dom_equal
"<div>Hello world!</div>"
,
buffer
end
def
test_tag_builder_with_block_in_erb
buffer
=
render_erb
(
"<%= tag.div do %>Hello world!<% end %>"
)
assert_dom_equal
"<div>Hello world!</div>"
,
buffer
end
def
test_content_tag_with_block_in_erb_containing_non_displayed_erb
buffer
=
render_erb
(
"<%= content_tag(:p) do %><% 1 %><% end %>"
)
assert_dom_equal
"<p></p>"
,
buffer
end
def
test_tag_builder_with_block_in_erb_containing_non_displayed_erb
buffer
=
render_erb
(
"<%= tag.p do %><% 1 %><% end %>"
)
assert_dom_equal
"<p></p>"
,
buffer
end
def
test_content_tag_with_block_and_options_in_erb
buffer
=
render_erb
(
"<%= content_tag(:div, :class => 'green') do %>Hello world!<% end %>"
)
assert_dom_equal
%(<div class="green">Hello world!</div>)
,
buffer
end
def
test_tag_builder_with_block_and_options_in_erb
buffer
=
render_erb
(
"<%= tag.div(class: 'green') do %>Hello world!<% end %>"
)
assert_dom_equal
%(<div class="green">Hello world!</div>)
,
buffer
end
def
test_content_tag_with_block_and_options_out_of_erb
assert_dom_equal
%(<div class="green">Hello world!</div>)
,
content_tag
(
:div
,
:class
=>
"green"
)
{
"Hello world!"
}
end
def
test_tag_builder_with_block_and_options_out_of_erb
assert_dom_equal
%(<div class="green">Hello world!</div>)
,
tag
.
div
(
class:
"green"
)
{
"Hello world!"
}
end
def
test_content_tag_with_block_and_options_outside_out_of_erb
assert_equal
content_tag
(
"a"
,
"Create"
,
:href
=>
"create"
),
content_tag
(
"a"
,
"href"
=>
"create"
)
{
"Create"
}
end
def
test_tag_builder_with_block_and_options_outside_out_of_erb
assert_equal
tag
.
a
(
"Create"
,
href:
"create"
),
tag
.
a
(
"href"
:
"create"
)
{
"Create"
}
end
def
test_content_tag_with_block_and_non_string_outside_out_of_erb
assert_equal
content_tag
(
"p"
),
content_tag
(
"p"
)
{
3
.
times
{
"do_something"
}
}
end
def
test_tag_builder_with_block_and_non_string_outside_out_of_erb
assert_equal
tag
.
p
,
tag
.
p
{
3
.
times
{
"do_something"
}
}
end
def
test_content_tag_nested_in_content_tag_out_of_erb
assert_equal
content_tag
(
"p"
,
content_tag
(
"b"
,
"Hello"
)),
content_tag
(
"p"
)
{
content_tag
(
"b"
,
"Hello"
)
},
output_buffer
assert_equal
tag
.
p
(
tag
.
b
(
"Hello"
)),
tag
.
p
{
tag
.
b
(
"Hello"
)
},
output_buffer
end
def
test_content_tag_nested_in_content_tag_in_erb
assert_equal
"<p>
\n
<b>Hello</b>
\n
</p>"
,
view
.
render
(
"test/content_tag_nested_in_content_tag"
)
assert_equal
"<p>
\n
<b>Hello</b>
\n
</p>"
,
view
.
render
(
"test/builder_tag_nested_in_content_tag"
)
end
def
test_content_tag_with_escaped_array_class
...
...
@@ -95,6 +183,17 @@ def test_content_tag_with_escaped_array_class
assert_equal
"<p class=
\"
song play
\"
>limelight</p>"
,
str
end
def
test_tag_builder_with_escaped_array_class
str
=
tag
.
p
"limelight"
,
class:
[
"song"
,
"play>"
]
assert_equal
"<p class=
\"
song play>
\"
>limelight</p>"
,
str
str
=
tag
.
p
"limelight"
,
class:
[
"song"
,
"play"
]
assert_equal
"<p class=
\"
song play
\"
>limelight</p>"
,
str
str
=
tag
.
p
"limelight"
,
class:
[
"song"
,
[
"play"
]]
assert_equal
"<p class=
\"
song play
\"
>limelight</p>"
,
str
end
def
test_content_tag_with_unescaped_array_class
str
=
content_tag
(
'p'
,
"limelight"
,
{
:class
=>
[
"song"
,
"play>"
]},
false
)
assert_equal
"<p class=
\"
song play>
\"
>limelight</p>"
,
str
...
...
@@ -103,21 +202,43 @@ def test_content_tag_with_unescaped_array_class
assert_equal
"<p class=
\"
song play>
\"
>limelight</p>"
,
str
end
def
test_tag_builder_with_unescaped_array_class
str
=
tag
.
p
"limelight"
,
class:
[
"song"
,
"play>"
],
escape_attributes:
false
assert_equal
"<p class=
\"
song play>
\"
>limelight</p>"
,
str
str
=
tag
.
p
"limelight"
,
class:
[
"song"
,
[
"play>"
]],
escape_attributes:
false
assert_equal
"<p class=
\"
song play>
\"
>limelight</p>"
,
str
end
def
test_content_tag_with_empty_array_class
str
=
content_tag
(
'p'
,
'limelight'
,
{
:class
=>
[]})
assert_equal
'<p class="">limelight</p>'
,
str
end
def
test_tag_builder_with_empty_array_class
assert_equal
'<p class="">limelight</p>'
,
tag
.
p
(
'limelight'
,
class:
[])
end
def
test_content_tag_with_unescaped_empty_array_class
str
=
content_tag
(
'p'
,
'limelight'
,
{
:class
=>
[]},
false
)
assert_equal
'<p class="">limelight</p>'
,
str
end
def
test_tag_builder_with_unescaped_empty_array_class
str
=
tag
.
p
'limelight'
,
class:
[],
escape_attributes:
false
assert_equal
'<p class="">limelight</p>'
,
str
end
def
test_content_tag_with_data_attributes
assert_dom_equal
'<p data-number="1" data-string="hello" data-string-with-quotes="double"quote"party"">limelight</p>'
,
content_tag
(
'p'
,
"limelight"
,
data:
{
number:
1
,
string:
'hello'
,
string_with_quotes:
'double"quote"party"'
})
end
def
test_tag_builder_with_data_attributes
assert_dom_equal
'<p data-number="1" data-string="hello" data-string-with-quotes="double"quote"party"">limelight</p>'
,
tag
.
p
(
"limelight"
,
data:
{
number:
1
,
string:
'hello'
,
string_with_quotes:
'double"quote"party"'
})
end
def
test_cdata_section
assert_equal
"<![CDATA[<hello world>]]>"
,
cdata_section
(
"<hello world>"
)
end
...
...
@@ -139,20 +260,24 @@ def test_escape_once
def
test_tag_honors_html_safe_for_param_values
[
'1&2'
,
'1 < 2'
,
'“test“'
].
each
do
|
escaped
|
assert_equal
%(<a href="#{escaped}" />)
,
tag
(
'a'
,
:href
=>
escaped
.
html_safe
)
assert_equal
%(<a href="#{escaped}"></a>)
,
tag
.
a
(
href:
escaped
.
html_safe
)
end
end
def
test_tag_honors_html_safe_with_escaped_array_class
str
=
tag
(
'p'
,
:class
=>
[
'song>'
,
raw
(
'play>'
)])
assert_equal
'<p class="song> play>" />'
,
str
assert_equal
'<p class="song> play>" />'
,
tag
(
'p'
,
:class
=>
[
'song>'
,
raw
(
'play>'
)])
assert_equal
'<p class="song> play>" />'
,
tag
(
'p'
,
:class
=>
[
raw
(
'song>'
),
'play>'
])
end
str
=
tag
(
'p'
,
:class
=>
[
raw
(
'song>'
),
'play>'
])
assert_equal
'<p class="song> play>" />'
,
str
def
test_tag_builder_honors_html_safe_with_escaped_array_class
assert_equal
'<p class="song> play>"></p>'
,
tag
.
p
(
class:
[
'song>'
,
raw
(
'play>'
)])
assert_equal
'<p class="song> play>"></p>'
,
tag
.
p
(
class:
[
raw
(
'song>'
),
'play>'
])
end
def
test_skip_invalid_escaped_attributes
[
'&1;'
,
'dfa3;'
,
'& #123;'
].
each
do
|
escaped
|
assert_equal
%(<a href="#{escaped.gsub(/&/, '&')}" />)
,
tag
(
'a'
,
:href
=>
escaped
)
assert_equal
%(<a href="#{escaped.gsub(/&/, '&')}"></a>)
,
tag
.
a
(
href:
escaped
)
end
end
...
...
@@ -160,10 +285,20 @@ def test_disable_escaping
assert_equal
'<a href="&" />'
,
tag
(
'a'
,
{
:href
=>
'&'
},
false
,
false
)
end
def
test_tag_builder_disable_escaping
assert_equal
'<a href="&"></a>'
,
tag
.
a
(
href:
'&'
,
escape_attributes:
false
)
assert_equal
'<a href="&">cnt</a>'
,
tag
.
a
(
href:
'&'
,
escape_attributes:
false
)
{
"cnt"
}
assert_equal
'<br data-hidden="&">'
,
tag
.
br
(
"data-hidden"
:
'&'
,
escape_attributes:
false
)
assert_equal
'<a href="&">content</a>'
,
tag
.
a
(
"content"
,
href:
'&'
,
escape_attributes:
false
)
assert_equal
'<a href="&">content</a>'
,
tag
.
a
(
href:
'&'
,
escape_attributes:
false
)
{
"content"
}
end
def
test_data_attributes
[
'data'
,
:data
].
each
{
|
data
|
assert_dom_equal
'<a data-a-float="3.14" data-a-big-decimal="-123.456" data-a-number="1" data-array="[1,2,3]" data-hash="{"key":"value"}" data-string-with-quotes="double"quote"party"" data-string="hello" data-symbol="foo" />'
,
tag
(
'a'
,
{
data
=>
{
a_float:
3.14
,
a_big_decimal:
BigDecimal
.
new
(
"-123.456"
),
a_number:
1
,
string:
'hello'
,
symbol: :foo
,
array:
[
1
,
2
,
3
],
hash:
{
key:
'value'
},
string_with_quotes:
'double"quote"party"'
}
})
assert_dom_equal
'<a data-a-float="3.14" data-a-big-decimal="-123.456" data-a-number="1" data-array="[1,2,3]" data-hash="{"key":"value"}" data-string-with-quotes="double"quote"party"" data-string="hello" data-symbol="foo" />'
,
tag
.
a
(
data:
{
a_float:
3.14
,
a_big_decimal:
BigDecimal
.
new
(
"-123.456"
),
a_number:
1
,
string:
'hello'
,
symbol: :foo
,
array:
[
1
,
2
,
3
],
hash:
{
key:
'value'
},
string_with_quotes:
'double"quote"party"'
})
}
end
...
...
@@ -171,6 +306,8 @@ def test_aria_attributes
[
'aria'
,
:aria
].
each
{
|
aria
|
assert_dom_equal
'<a aria-a-float="3.14" aria-a-big-decimal="-123.456" aria-a-number="1" aria-array="[1,2,3]" aria-hash="{"key":"value"}" aria-string-with-quotes="double"quote"party"" aria-string="hello" aria-symbol="foo" />'
,
tag
(
'a'
,
{
aria
=>
{
a_float:
3.14
,
a_big_decimal:
BigDecimal
.
new
(
"-123.456"
),
a_number:
1
,
string:
'hello'
,
symbol: :foo
,
array:
[
1
,
2
,
3
],
hash:
{
key:
'value'
},
string_with_quotes:
'double"quote"party"'
}
})
assert_dom_equal
'<a aria-a-float="3.14" aria-a-big-decimal="-123.456" aria-a-number="1" aria-array="[1,2,3]" aria-hash="{"key":"value"}" aria-string-with-quotes="double"quote"party"" aria-string="hello" aria-symbol="foo" />'
,
tag
.
a
(
aria:
{
a_float:
3.14
,
a_big_decimal:
BigDecimal
.
new
(
"-123.456"
),
a_number:
1
,
string:
'hello'
,
symbol: :foo
,
array:
[
1
,
2
,
3
],
hash:
{
key:
'value'
},
string_with_quotes:
'double"quote"party"'
})
}
end
...
...
@@ -179,4 +316,23 @@ def test_link_to_data_nil_equal
div_type2
=
content_tag
(
:div
,
'test'
,
{
data:
{
tooltip:
nil
}
})
assert_dom_equal
div_type1
,
div_type2
end
def
test_tag_builder_link_to_data_nil_equal
div_type1
=
tag
.
div
'test'
,
{
'data-tooltip'
:
nil
}
div_type2
=
tag
.
div
'test'
,
{
data:
{
tooltip:
nil
}
}
assert_dom_equal
div_type1
,
div_type2
end
def
test_tag_builder_allow_call_via_method_object
assert_equal
"<foo></foo>"
,
tag
.
method
(
:foo
).
call
end
def
test_tag_builder_dasherize_names
assert_equal
"<img-slider></img-slider>"
,
tag
.
img_slider
end
def
test_respond_to
assert_respond_to
tag
,
:any_tag
end
end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录