hanami-helpers 1.1.2 → 1.2.0.beta1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -3
- data/hanami-helpers.gemspec +1 -1
- data/lib/hanami/helpers/form_helper.rb +40 -4
- data/lib/hanami/helpers/form_helper/form_builder.rb +18 -35
- data/lib/hanami/helpers/html_helper/empty_html_node.rb +16 -1
- data/lib/hanami/helpers/html_helper/html_node.rb +3 -3
- data/lib/hanami/helpers/version.rb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e45f7f598ca31c583c6c23bc8c5462caba3c2ef912ec92d28902681fcade042f
|
4
|
+
data.tar.gz: 1471aee67afbf749bc146f0127de2c40bb08f8973bf133832251b939142a5d33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
5
|
-
|
6
|
-
- [Luca Guidi]
|
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
|
data/hanami-helpers.gemspec
CHANGED
@@ -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', '
|
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
|
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
|
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
|
-
|
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,
|
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
|
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
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
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,
|
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
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
(
|
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 =
|
26
|
-
when Hash
|
25
|
+
@content = if content.is_a?(Hash)
|
27
26
|
@attributes = content
|
28
27
|
nil
|
29
28
|
else
|
30
|
-
|
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
|
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.
|
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-
|
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:
|
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:
|
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:
|
128
|
+
version: 1.3.1
|
129
129
|
requirements: []
|
130
130
|
rubyforge_project:
|
131
131
|
rubygems_version: 2.7.5
|