actionview 4.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionview might be problematic. Click here for more details.

Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +274 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +34 -0
  5. data/lib/action_view.rb +97 -0
  6. data/lib/action_view/base.rb +205 -0
  7. data/lib/action_view/buffers.rb +49 -0
  8. data/lib/action_view/context.rb +36 -0
  9. data/lib/action_view/dependency_tracker.rb +93 -0
  10. data/lib/action_view/digestor.rb +116 -0
  11. data/lib/action_view/flows.rb +76 -0
  12. data/lib/action_view/helpers.rb +64 -0
  13. data/lib/action_view/helpers/active_model_helper.rb +49 -0
  14. data/lib/action_view/helpers/asset_tag_helper.rb +322 -0
  15. data/lib/action_view/helpers/asset_url_helper.rb +355 -0
  16. data/lib/action_view/helpers/atom_feed_helper.rb +203 -0
  17. data/lib/action_view/helpers/cache_helper.rb +200 -0
  18. data/lib/action_view/helpers/capture_helper.rb +216 -0
  19. data/lib/action_view/helpers/controller_helper.rb +25 -0
  20. data/lib/action_view/helpers/csrf_helper.rb +30 -0
  21. data/lib/action_view/helpers/date_helper.rb +1075 -0
  22. data/lib/action_view/helpers/debug_helper.rb +39 -0
  23. data/lib/action_view/helpers/form_helper.rb +1876 -0
  24. data/lib/action_view/helpers/form_options_helper.rb +843 -0
  25. data/lib/action_view/helpers/form_tag_helper.rb +746 -0
  26. data/lib/action_view/helpers/javascript_helper.rb +75 -0
  27. data/lib/action_view/helpers/number_helper.rb +425 -0
  28. data/lib/action_view/helpers/output_safety_helper.rb +38 -0
  29. data/lib/action_view/helpers/record_tag_helper.rb +108 -0
  30. data/lib/action_view/helpers/rendering_helper.rb +90 -0
  31. data/lib/action_view/helpers/sanitize_helper.rb +256 -0
  32. data/lib/action_view/helpers/tag_helper.rb +176 -0
  33. data/lib/action_view/helpers/tags.rb +41 -0
  34. data/lib/action_view/helpers/tags/base.rb +148 -0
  35. data/lib/action_view/helpers/tags/check_box.rb +64 -0
  36. data/lib/action_view/helpers/tags/checkable.rb +16 -0
  37. data/lib/action_view/helpers/tags/collection_check_boxes.rb +44 -0
  38. data/lib/action_view/helpers/tags/collection_helpers.rb +85 -0
  39. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
  40. data/lib/action_view/helpers/tags/collection_select.rb +28 -0
  41. data/lib/action_view/helpers/tags/color_field.rb +25 -0
  42. data/lib/action_view/helpers/tags/date_field.rb +13 -0
  43. data/lib/action_view/helpers/tags/date_select.rb +72 -0
  44. data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
  45. data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
  46. data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
  47. data/lib/action_view/helpers/tags/email_field.rb +8 -0
  48. data/lib/action_view/helpers/tags/file_field.rb +8 -0
  49. data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
  50. data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
  51. data/lib/action_view/helpers/tags/label.rb +65 -0
  52. data/lib/action_view/helpers/tags/month_field.rb +13 -0
  53. data/lib/action_view/helpers/tags/number_field.rb +18 -0
  54. data/lib/action_view/helpers/tags/password_field.rb +12 -0
  55. data/lib/action_view/helpers/tags/radio_button.rb +31 -0
  56. data/lib/action_view/helpers/tags/range_field.rb +8 -0
  57. data/lib/action_view/helpers/tags/search_field.rb +24 -0
  58. data/lib/action_view/helpers/tags/select.rb +41 -0
  59. data/lib/action_view/helpers/tags/tel_field.rb +8 -0
  60. data/lib/action_view/helpers/tags/text_area.rb +18 -0
  61. data/lib/action_view/helpers/tags/text_field.rb +29 -0
  62. data/lib/action_view/helpers/tags/time_field.rb +13 -0
  63. data/lib/action_view/helpers/tags/time_select.rb +8 -0
  64. data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
  65. data/lib/action_view/helpers/tags/url_field.rb +8 -0
  66. data/lib/action_view/helpers/tags/week_field.rb +13 -0
  67. data/lib/action_view/helpers/text_helper.rb +447 -0
  68. data/lib/action_view/helpers/translation_helper.rb +111 -0
  69. data/lib/action_view/helpers/url_helper.rb +625 -0
  70. data/lib/action_view/layouts.rb +426 -0
  71. data/lib/action_view/locale/en.yml +56 -0
  72. data/lib/action_view/log_subscriber.rb +44 -0
  73. data/lib/action_view/lookup_context.rb +249 -0
  74. data/lib/action_view/model_naming.rb +12 -0
  75. data/lib/action_view/path_set.rb +77 -0
  76. data/lib/action_view/railtie.rb +49 -0
  77. data/lib/action_view/record_identifier.rb +84 -0
  78. data/lib/action_view/renderer/abstract_renderer.rb +47 -0
  79. data/lib/action_view/renderer/partial_renderer.rb +492 -0
  80. data/lib/action_view/renderer/renderer.rb +50 -0
  81. data/lib/action_view/renderer/streaming_template_renderer.rb +103 -0
  82. data/lib/action_view/renderer/template_renderer.rb +96 -0
  83. data/lib/action_view/rendering.rb +145 -0
  84. data/lib/action_view/routing_url_for.rb +109 -0
  85. data/lib/action_view/tasks/dependencies.rake +17 -0
  86. data/lib/action_view/template.rb +340 -0
  87. data/lib/action_view/template/error.rb +141 -0
  88. data/lib/action_view/template/handlers.rb +53 -0
  89. data/lib/action_view/template/handlers/builder.rb +26 -0
  90. data/lib/action_view/template/handlers/erb.rb +145 -0
  91. data/lib/action_view/template/handlers/raw.rb +11 -0
  92. data/lib/action_view/template/resolver.rb +329 -0
  93. data/lib/action_view/template/text.rb +34 -0
  94. data/lib/action_view/template/types.rb +57 -0
  95. data/lib/action_view/test_case.rb +272 -0
  96. data/lib/action_view/testing/resolvers.rb +50 -0
  97. data/lib/action_view/vendor/html-scanner.rb +20 -0
  98. data/lib/action_view/vendor/html-scanner/html/document.rb +68 -0
  99. data/lib/action_view/vendor/html-scanner/html/node.rb +532 -0
  100. data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +188 -0
  101. data/lib/action_view/vendor/html-scanner/html/selector.rb +830 -0
  102. data/lib/action_view/vendor/html-scanner/html/tokenizer.rb +107 -0
  103. data/lib/action_view/vendor/html-scanner/html/version.rb +11 -0
  104. data/lib/action_view/version.rb +11 -0
  105. data/lib/action_view/view_paths.rb +96 -0
  106. metadata +218 -0
@@ -0,0 +1,44 @@
1
+ require 'action_view/helpers/tags/collection_helpers'
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class CollectionCheckBoxes < Base # :nodoc:
7
+ include CollectionHelpers
8
+
9
+ class CheckBoxBuilder < Builder # :nodoc:
10
+ def check_box(extra_html_options={})
11
+ html_options = extra_html_options.merge(@input_html_options)
12
+ @template_object.check_box(@object_name, @method_name, html_options, @value, nil)
13
+ end
14
+ end
15
+
16
+ def render(&block)
17
+ rendered_collection = render_collection do |item, value, text, default_html_options|
18
+ default_html_options[:multiple] = true
19
+ builder = instantiate_builder(CheckBoxBuilder, item, value, text, default_html_options)
20
+
21
+ if block_given?
22
+ @template_object.capture(builder, &block)
23
+ else
24
+ render_component(builder)
25
+ end
26
+ end
27
+
28
+ # Append a hidden field to make sure something will be sent back to the
29
+ # server if all check boxes are unchecked.
30
+ hidden_name = @html_options[:name] || "#{tag_name}[]"
31
+ hidden = @template_object.hidden_field_tag(hidden_name, "", :id => nil)
32
+
33
+ rendered_collection + hidden
34
+ end
35
+
36
+ private
37
+
38
+ def render_component(builder)
39
+ builder.check_box + builder.label
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,85 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ module CollectionHelpers # :nodoc:
5
+ class Builder # :nodoc:
6
+ attr_reader :object, :text, :value
7
+
8
+ def initialize(template_object, object_name, method_name, object,
9
+ sanitized_attribute_name, text, value, input_html_options)
10
+ @template_object = template_object
11
+ @object_name = object_name
12
+ @method_name = method_name
13
+ @object = object
14
+ @sanitized_attribute_name = sanitized_attribute_name
15
+ @text = text
16
+ @value = value
17
+ @input_html_options = input_html_options
18
+ end
19
+
20
+ def label(label_html_options={}, &block)
21
+ html_options = @input_html_options.slice(:index, :namespace).merge(label_html_options)
22
+ @template_object.label(@object_name, @sanitized_attribute_name, @text, html_options, &block)
23
+ end
24
+ end
25
+
26
+ def initialize(object_name, method_name, template_object, collection, value_method, text_method, options, html_options)
27
+ @collection = collection
28
+ @value_method = value_method
29
+ @text_method = text_method
30
+ @html_options = html_options
31
+
32
+ super(object_name, method_name, template_object, options)
33
+ end
34
+
35
+ private
36
+
37
+ def instantiate_builder(builder_class, item, value, text, html_options)
38
+ builder_class.new(@template_object, @object_name, @method_name, item,
39
+ sanitize_attribute_name(value), text, value, html_options)
40
+ end
41
+
42
+ # Generate default options for collection helpers, such as :checked and
43
+ # :disabled.
44
+ def default_html_options_for_collection(item, value) #:nodoc:
45
+ html_options = @html_options.dup
46
+
47
+ [:checked, :selected, :disabled].each do |option|
48
+ current_value = @options[option]
49
+ next if current_value.nil?
50
+
51
+ accept = if current_value.respond_to?(:call)
52
+ current_value.call(item)
53
+ else
54
+ Array(current_value).map(&:to_s).include?(value.to_s)
55
+ end
56
+
57
+ if accept
58
+ html_options[option] = true
59
+ elsif option == :checked
60
+ html_options[option] = false
61
+ end
62
+ end
63
+
64
+ html_options[:object] = @object
65
+ html_options
66
+ end
67
+
68
+ def sanitize_attribute_name(value) #:nodoc:
69
+ "#{sanitized_method_name}_#{sanitized_value(value)}"
70
+ end
71
+
72
+ def render_collection #:nodoc:
73
+ @collection.map do |item|
74
+ value = value_for_collection(item, @value_method)
75
+ text = value_for_collection(item, @text_method)
76
+ default_html_options = default_html_options_for_collection(item, value)
77
+ additional_html_options = option_html_attributes(item)
78
+
79
+ yield item, value, text, default_html_options.merge(additional_html_options)
80
+ end.join.html_safe
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,36 @@
1
+ require 'action_view/helpers/tags/collection_helpers'
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class CollectionRadioButtons < Base # :nodoc:
7
+ include CollectionHelpers
8
+
9
+ class RadioButtonBuilder < Builder # :nodoc:
10
+ def radio_button(extra_html_options={})
11
+ html_options = extra_html_options.merge(@input_html_options)
12
+ @template_object.radio_button(@object_name, @method_name, @value, html_options)
13
+ end
14
+ end
15
+
16
+ def render(&block)
17
+ render_collection do |item, value, text, default_html_options|
18
+ builder = instantiate_builder(RadioButtonBuilder, item, value, text, default_html_options)
19
+
20
+ if block_given?
21
+ @template_object.capture(builder, &block)
22
+ else
23
+ render_component(builder)
24
+ end
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def render_component(builder)
31
+ builder.radio_button + builder.label
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,28 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class CollectionSelect < Base #:nodoc:
5
+ def initialize(object_name, method_name, template_object, collection, value_method, text_method, options, html_options)
6
+ @collection = collection
7
+ @value_method = value_method
8
+ @text_method = text_method
9
+ @html_options = html_options
10
+
11
+ super(object_name, method_name, template_object, options)
12
+ end
13
+
14
+ def render
15
+ option_tags_options = {
16
+ :selected => @options.fetch(:selected) { value(@object) },
17
+ :disabled => @options[:disabled]
18
+ }
19
+
20
+ select_content_tag(
21
+ options_from_collection_for_select(@collection, @value_method, @text_method, option_tags_options),
22
+ @options, @html_options
23
+ )
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class ColorField < TextField # :nodoc:
5
+ def render
6
+ options = @options.stringify_keys
7
+ options["value"] ||= validate_color_string(value(object))
8
+ @options = options
9
+ super
10
+ end
11
+
12
+ private
13
+
14
+ def validate_color_string(string)
15
+ regex = /#[0-9a-fA-F]{6}/
16
+ if regex.match(string)
17
+ string.downcase
18
+ else
19
+ "#000000"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class DateField < DatetimeField # :nodoc:
5
+ private
6
+
7
+ def format_date(value)
8
+ value.try(:strftime, "%Y-%m-%d")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,72 @@
1
+ require 'active_support/core_ext/time/calculations'
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class DateSelect < Base # :nodoc:
7
+ def initialize(object_name, method_name, template_object, options, html_options)
8
+ @html_options = html_options
9
+
10
+ super(object_name, method_name, template_object, options)
11
+ end
12
+
13
+ def render
14
+ error_wrapping(datetime_selector(@options, @html_options).send("select_#{select_type}").html_safe)
15
+ end
16
+
17
+ class << self
18
+ def select_type
19
+ @select_type ||= self.name.split("::").last.sub("Select", "").downcase
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def select_type
26
+ self.class.select_type
27
+ end
28
+
29
+ def datetime_selector(options, html_options)
30
+ datetime = options.fetch(:selected) { value(object) || default_datetime(options) }
31
+ @auto_index ||= nil
32
+
33
+ options = options.dup
34
+ options[:field_name] = @method_name
35
+ options[:include_position] = true
36
+ options[:prefix] ||= @object_name
37
+ options[:index] = @auto_index if @auto_index && !options.has_key?(:index)
38
+
39
+ DateTimeSelector.new(datetime, options, html_options)
40
+ end
41
+
42
+ def default_datetime(options)
43
+ return if options[:include_blank] || options[:prompt]
44
+
45
+ case options[:default]
46
+ when nil
47
+ Time.current
48
+ when Date, Time
49
+ options[:default]
50
+ else
51
+ default = options[:default].dup
52
+
53
+ # Rename :minute and :second to :min and :sec
54
+ default[:min] ||= default[:minute]
55
+ default[:sec] ||= default[:second]
56
+
57
+ time = Time.current
58
+
59
+ [:year, :month, :day, :hour, :min, :sec].each do |key|
60
+ default[key] ||= time.send(key)
61
+ end
62
+
63
+ Time.utc(
64
+ default[:year], default[:month], default[:day],
65
+ default[:hour], default[:min], default[:sec]
66
+ )
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,22 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class DatetimeField < TextField # :nodoc:
5
+ def render
6
+ options = @options.stringify_keys
7
+ options["value"] ||= format_date(value(object))
8
+ options["min"] = format_date(options["min"])
9
+ options["max"] = format_date(options["max"])
10
+ @options = options
11
+ super
12
+ end
13
+
14
+ private
15
+
16
+ def format_date(value)
17
+ value.try(:strftime, "%Y-%m-%dT%T.%L%z")
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class DatetimeLocalField < DatetimeField # :nodoc:
5
+ class << self
6
+ def field_type
7
+ @field_type ||= "datetime-local"
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def format_date(value)
14
+ value.try(:strftime, "%Y-%m-%dT%T")
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class DatetimeSelect < DateSelect # :nodoc:
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class EmailField < TextField # :nodoc:
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class FileField < TextField # :nodoc:
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,29 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class GroupedCollectionSelect < Base # :nodoc:
5
+ def initialize(object_name, method_name, template_object, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options)
6
+ @collection = collection
7
+ @group_method = group_method
8
+ @group_label_method = group_label_method
9
+ @option_key_method = option_key_method
10
+ @option_value_method = option_value_method
11
+ @html_options = html_options
12
+
13
+ super(object_name, method_name, template_object, options)
14
+ end
15
+
16
+ def render
17
+ option_tags_options = {
18
+ :selected => @options.fetch(:selected) { value(@object) },
19
+ :disabled => @options[:disabled]
20
+ }
21
+
22
+ select_content_tag(
23
+ option_groups_from_collection_for_select(@collection, @group_method, @group_label_method, @option_key_method, @option_value_method, option_tags_options), @options, @html_options
24
+ )
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,8 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class HiddenField < TextField # :nodoc:
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,65 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class Label < Base # :nodoc:
5
+ def initialize(object_name, method_name, template_object, content_or_options = nil, options = nil)
6
+ options ||= {}
7
+
8
+ content_is_options = content_or_options.is_a?(Hash)
9
+ if content_is_options
10
+ options.merge! content_or_options
11
+ @content = nil
12
+ else
13
+ @content = content_or_options
14
+ end
15
+
16
+ super(object_name, method_name, template_object, options)
17
+ end
18
+
19
+ def render(&block)
20
+ options = @options.stringify_keys
21
+ tag_value = options.delete("value")
22
+ name_and_id = options.dup
23
+
24
+ if name_and_id["for"]
25
+ name_and_id["id"] = name_and_id["for"]
26
+ else
27
+ name_and_id.delete("id")
28
+ end
29
+
30
+ add_default_name_and_id_for_value(tag_value, name_and_id)
31
+ options.delete("index")
32
+ options.delete("namespace")
33
+ options["for"] = name_and_id["id"] unless options.key?("for")
34
+
35
+ if block_given?
36
+ content = @template_object.capture(&block)
37
+ else
38
+ content = if @content.blank?
39
+ @object_name.gsub!(/\[(.*)_attributes\]\[\d\]/, '.\1')
40
+ method_and_value = tag_value.present? ? "#{@method_name}.#{tag_value}" : @method_name
41
+
42
+ if object.respond_to?(:to_model)
43
+ key = object.class.model_name.i18n_key
44
+ i18n_default = ["#{key}.#{method_and_value}".to_sym, ""]
45
+ end
46
+
47
+ i18n_default ||= ""
48
+ I18n.t("#{@object_name}.#{method_and_value}", :default => i18n_default, :scope => "helpers.label").presence
49
+ else
50
+ @content.to_s
51
+ end
52
+
53
+ content ||= if object && object.class.respond_to?(:human_attribute_name)
54
+ object.class.human_attribute_name(@method_name)
55
+ end
56
+
57
+ content ||= @method_name.humanize
58
+ end
59
+
60
+ label_tag(name_and_id["id"], content, options)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end