hanami-helpers 1.1.2 → 1.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2240795ff1bddb8305850e8473c60580701e7175528edcc25f83bad073a49fc9
4
- data.tar.gz: 704af3c5d22e74509806c87c17bb368b0935dafe6ff276d2532bbc010c59eba2
3
+ metadata.gz: e45f7f598ca31c583c6c23bc8c5462caba3c2ef912ec92d28902681fcade042f
4
+ data.tar.gz: 1471aee67afbf749bc146f0127de2c40bb08f8973bf133832251b939142a5d33
5
5
  SHA512:
6
- metadata.gz: 94778d91a095e8e7e41d58c0fa9477de162960fab463f2c8eb593b03f27ba2ac3dc7041d6fdab42b7f46783838510f0532191d678c4d5cd2225b454251b0c499
7
- data.tar.gz: 6a5c35fd9efdc2c5db4d763398e10bc51de1cf2b429e28bfcfc5b2694e2dc3a68d24d6b22658965e85e5b85202a3c1f206d920badc5bf6e70ae75335dd4d8410
6
+ metadata.gz: f894fd9f04c7e0e9ab8829f14caac0c3589345224c88bf02cda2aca4c48817c8bdf0773ab0de489a45eada4f4892eb5a494d730a1a0e616180f7f7b9347c0221
7
+ data.tar.gz: 8fbcfe52c12a78b6b7e26b2e8d7a35533b7558bbd2742466c5d79d87472306751db6f93b0eda4300b48cffb8bbda29f56a042bdc42426ffa3117604445bdd3a2
data/CHANGELOG.md CHANGED
@@ -1,9 +1,11 @@
1
1
  # Hanami::Helpers
2
2
  View helpers for Ruby web applications
3
3
 
4
- ## v1.1.2 - 2018-04-05
5
- ### Fixed
6
- - [Luca Guidi] Ensure correct arity of `#form_for`, to be used in conjuction with `Hanami::Helpers::FormHelper::Form` (eg. `<%= form_for(form) { ... } %>`)
4
+ ## v1.2.0.beta1 - 2018-02-28
5
+ ## Added
6
+ - [Luca Guidi] Introduced `csrf_meta_tags` helper to print meta tags for CSRF protection
7
+ - [Luca Guidi] Added support for `form_for(..., remote: true)` which translates to `<form ... data-remote="true">`
8
+ - [Sean Collins] Allow HTML attributes to be specified as an array of strings or symbols (eg `<%= html.span("foo", class: %w(ui form)) %>`)
7
9
 
8
10
  ## v1.1.1 - 2018-02-27
9
11
  ### Fixed
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ['lib']
21
21
  spec.required_ruby_version = '>= 2.3.0'
22
22
 
23
- spec.add_dependency 'hanami-utils', '~> 1.1'
23
+ spec.add_dependency 'hanami-utils', '1.2.0.beta1'
24
24
 
25
25
  spec.add_development_dependency 'bundler', '~> 1.6'
26
26
  spec.add_development_dependency 'dry-struct', '~> 0.3'
@@ -1,4 +1,5 @@
1
1
  require 'hanami/helpers/form_helper/form_builder'
2
+ require 'hanami/helpers/html_helper'
2
3
 
3
4
  module Hanami
4
5
  module Helpers
@@ -97,6 +98,8 @@ module Hanami
97
98
  # @api private
98
99
  CSRF_TOKEN = :_csrf_token
99
100
 
101
+ include HtmlHelper
102
+
100
103
  # Form object
101
104
  #
102
105
  # @since 0.2.0
@@ -229,7 +232,7 @@ module Hanami
229
232
  # @option options [Hash] :values An optional payload of objects to pass
230
233
  # @param blk [Proc] A block that describes the contents of the form
231
234
  #
232
- # @overload form_for(form, attributes = {}, &blk)
235
+ # @overload form_for(form, attributes, &blk)
233
236
  # Use Form
234
237
  # @param form [Hanami::Helpers::FormHelper::Form] a form object
235
238
  # @param attributes [Hash] HTML attributes to pass to the form tag and form values
@@ -406,15 +409,18 @@ module Hanami
406
409
  #
407
410
  # <button type="submit">Create</button>
408
411
  # </form>
409
- def form_for(name, url = nil, options = {}, &blk)
412
+ def form_for(name, url, options = {}, &blk)
410
413
  form = if name.is_a?(Form)
411
- options = url || {}
414
+ options = url
412
415
  name
413
416
  else
414
417
  Form.new(name, url, options.delete(:values))
415
418
  end
416
419
 
417
- attributes = { action: form.url, method: form.verb, 'accept-charset': DEFAULT_CHARSET, id: "#{form.name}-form" }.merge(options)
420
+ opts = options.dup
421
+ opts[:"data-remote"] = opts.delete(:remote) if opts.key?(:remote)
422
+ attributes = { action: form.url, method: form.verb, 'accept-charset': DEFAULT_CHARSET, id: "#{form.name}-form" }.merge(opts)
423
+
418
424
  FormBuilder.new(form, attributes, self, &blk)
419
425
  end
420
426
 
@@ -432,6 +438,36 @@ module Hanami
432
438
  locals[:session][CSRF_TOKEN]
433
439
  end
434
440
  end
441
+
442
+ # Prints CSRF meta tags for Unobtrusive JavaScript (UJS) purposes.
443
+ #
444
+ # @return [Hanami::Helpers::HtmlHelper::HtmlBuilder,NilClass] the tags if `csrf_token` is not `nil`
445
+ #
446
+ # @since 1.2.0
447
+ #
448
+ # @example
449
+ # <html>
450
+ # <head>
451
+ # <!-- ... -->
452
+ # <%= csrf_meta_tags %>
453
+ # </head>
454
+ # <!-- ... -->
455
+ # </html>
456
+ #
457
+ # <html>
458
+ # <head>
459
+ # <!-- ... -->
460
+ # <meta name="csrf-param" value="_csrf_token">
461
+ # <meta name="csrf-token" value="4a038be85b7603c406dcbfad4b9cdf91ec6ca138ed6441163a07bb0fdfbe25b5">
462
+ # </head>
463
+ # <!-- ... -->
464
+ # </html>
465
+ def csrf_meta_tags
466
+ return if csrf_token.nil?
467
+
468
+ html.meta(name: "csrf-param", value: CSRF_TOKEN) +
469
+ html.meta(name: "csrf-token", value: csrf_token)
470
+ end
435
471
  end
436
472
  end
437
473
  end
@@ -81,11 +81,11 @@ module Hanami
81
81
 
82
82
  # Instantiate a form builder
83
83
  #
84
- # @overload initialize(form, attributes, context, &blk)
84
+ # @overload initialize(form, attributes, params, &blk)
85
85
  # Top level form
86
86
  # @param form [Hanami::Helpers:FormHelper::Form] the form
87
87
  # @param attributes [::Hash] a set of HTML attributes
88
- # @param context [Hanami::Helpers::FormHelper]
88
+ # @param params [Hanami::Action::Params] request params
89
89
  # @param blk [Proc] a block that describes the contents of the form
90
90
  #
91
91
  # @overload initialize(form, attributes, params, &blk)
@@ -1225,19 +1225,17 @@ module Hanami
1225
1225
  # <option value="zw">Zimbabwe</option>
1226
1226
  # </select>
1227
1227
  def select(name, values, attributes = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
1228
- options = attributes.delete(:options) { {} }
1229
- multiple = attributes[:multiple]
1230
- attributes = { name: _select_input_name(name, multiple), id: _input_id(name) }.merge(attributes)
1231
- prompt = options.delete(:prompt)
1232
- selected = options.delete(:selected)
1233
- input_value = _value(name)
1228
+ options = attributes.delete(:options) { {} }
1229
+ attributes = { name: _select_input_name(name, attributes[:multiple]), id: _input_id(name) }.merge(attributes)
1230
+ prompt = options.delete(:prompt)
1231
+ selected = options.delete(:selected)
1234
1232
 
1235
1233
  super(attributes) do
1236
1234
  option(prompt) unless prompt.nil?
1237
1235
 
1238
1236
  already_selected = nil
1239
1237
  values.each do |content, value|
1240
- if (multiple || !already_selected) && (already_selected = _select_option_selected?(value, selected, input_value, multiple))
1238
+ if (attributes[:multiple] || !already_selected) && (already_selected = _select_option_selected?(value, selected, _value(name), attributes[:multiple]))
1241
1239
  option(content, { value: value, selected: SELECTED }.merge(options))
1242
1240
  else
1243
1241
  option(content, { value: value }.merge(options))
@@ -1570,35 +1568,20 @@ module Hanami
1570
1568
  select_name
1571
1569
  end
1572
1570
 
1571
+ # TODO: this has to be refactored
1572
+ #
1573
1573
  # @api private
1574
+ #
1575
+ # rubocop:disable Metrics/CyclomaticComplexity
1576
+ # rubocop:disable Metrics/PerceivedComplexity
1574
1577
  def _select_option_selected?(value, selected, input_value, multiple)
1575
- if input_value && selected.nil?
1576
- value.to_s == input_value
1577
- else
1578
- (value == selected) ||
1579
- _is_in_selected_values?(multiple, selected, value) ||
1580
- _is_current_value?(input_value, value) ||
1581
- _is_in_input_values?(multiple, input_value, value)
1582
- end
1583
- end
1584
-
1585
- # @api private
1586
- def _is_current_value?(input_value, value)
1587
- return unless input_value
1588
- value.to_s == input_value.to_s
1589
- end
1590
-
1591
- # @api private
1592
- def _is_in_selected_values?(multiple, selected, value)
1593
- return unless multiple && selected.is_a?(Array)
1594
- selected.include?(value)
1595
- end
1596
-
1597
- # @api private
1598
- def _is_in_input_values?(multiple, input_value, value)
1599
- return unless multiple && input_value.is_a?(Array)
1600
- input_value.include?(value)
1578
+ value == selected ||
1579
+ (multiple && (selected.is_a?(Array) && selected.include?(value))) ||
1580
+ (!input_value.nil? && (value.to_s == input_value.to_s)) ||
1581
+ (multiple && (input_value.is_a?(Array) && input_value.include?(value)))
1601
1582
  end
1583
+ # rubocop:enable Metrics/PerceivedComplexity
1584
+ # rubocop:enable Metrics/CyclomaticComplexity
1602
1585
 
1603
1586
  # @api private
1604
1587
  def _check_box_checked?(value, input_value)
@@ -78,7 +78,7 @@ module Hanami
78
78
  # @api private
79
79
  def initialize(name, attributes)
80
80
  @name = name
81
- @attributes = attributes
81
+ @attributes = prepare_html_attributes(attributes)
82
82
  end
83
83
 
84
84
  # Resolve and return the output
@@ -129,6 +129,21 @@ module Hanami
129
129
  def attribute(attribute_name, value)
130
130
  %(#{ATTRIBUTES_SEPARATOR}#{attribute_name}="#{value}")
131
131
  end
132
+
133
+ # Changes any attributes values that are arrays into a string joined by
134
+ # a space, as HTML expects it.
135
+ #
136
+ # @param attributes [Hash] the attributes with values to be HTMLified
137
+ #
138
+ # @return [Hash] the attributes transformed into HTML friendly values, i.e space separated strings
139
+ #
140
+ # @since 1.2.0
141
+ def prepare_html_attributes(attributes)
142
+ attributes&.inject({}) do |attrs, (key, value)|
143
+ attrs[key] = value.is_a?(Array) ? value.join(ATTRIBUTES_SEPARATOR) : value
144
+ attrs
145
+ end
146
+ end
132
147
  end
133
148
  end
134
149
  end
@@ -22,12 +22,12 @@ module Hanami
22
22
  def initialize(name, content, attributes, _options = {})
23
23
  @builder = HtmlBuilder.new
24
24
  @name = name
25
- @content = case content
26
- when Hash
25
+ @content = if content.is_a?(Hash)
27
26
  @attributes = content
28
27
  nil
29
28
  else
30
- @attributes = attributes.to_h if attributes.respond_to?(:to_h)
29
+ attributes_hash = attributes.to_h if attributes.respond_to?(:to_h)
30
+ @attributes = prepare_html_attributes(attributes_hash)
31
31
  content
32
32
  end
33
33
  end
@@ -3,6 +3,6 @@ module Hanami
3
3
  # Define version
4
4
  #
5
5
  # @since 0.1.0
6
- VERSION = '1.1.2'.freeze
6
+ VERSION = '1.2.0.beta1'.freeze
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-05 00:00:00.000000000 Z
11
+ date: 2018-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hanami-utils
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: '1.1'
19
+ version: 1.2.0.beta1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: '1.1'
26
+ version: 1.2.0.beta1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -123,9 +123,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
123
  version: 2.3.0
124
124
  required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  requirements:
126
- - - ">="
126
+ - - ">"
127
127
  - !ruby/object:Gem::Version
128
- version: '0'
128
+ version: 1.3.1
129
129
  requirements: []
130
130
  rubyforge_project:
131
131
  rubygems_version: 2.7.5