html-attributes-utils 0.9.0
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 +7 -0
- data/README.md +3 -0
- data/lib/html_attributes_utils.rb +132 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a383443446570cb37c2c67e608c4bcde35ecf1b255eca392cbcc263d5a36ae76
|
4
|
+
data.tar.gz: 2b81b3e7929301ee349b330dae54131b79f93afe417db7e57b934cc4c8a96615
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9c2568b9c1a67be8cad3df9ccd4eb5f11a9e612c27da3438acddc2587eaaee2d12138adf9397aeb43bb0d05e57b3fa3735df9caf0437a8cb6d53b8eddc937e59
|
7
|
+
data.tar.gz: ce81b1c86dcbf9e464a9268d02e595a60ee6eb30ba5fd0e5fa829a5f8ed233bee252da1a06716ba9ff0a06a565a70010d71d372acc42796e7c104c6ab222d98f
|
data/README.md
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
require "active_support/core_ext/hash/keys"
|
2
|
+
|
3
|
+
module HTMLAttributesUtils
|
4
|
+
refine Hash do
|
5
|
+
# Merge the incoming hash into the current one in a way that suits
|
6
|
+
# HTML attributes.
|
7
|
+
#
|
8
|
+
# @param custom [Hash] the incoming hash
|
9
|
+
# @param parents [Array] used to keep track of the keys that have already been
|
10
|
+
# merged, *don't supply this unless the method is called during recursion*
|
11
|
+
# @mergeable_attributes [Array<Array<Symbol>>] Mergeable attributes are
|
12
|
+
# HTML attributes can contain lists made from space-separated strings. We
|
13
|
+
# convert them to arrays so they can be cleanly merged. Rails accepts them
|
14
|
+
# as arrays so there's no need to convert back to strings.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# original = { class: "red", data: { size: "medium", controller: "comment" } }
|
18
|
+
# incoming = { class: "blue", data: { controller: "reply" } }
|
19
|
+
#
|
20
|
+
# original.deep_merge_html_attributes(incoming)
|
21
|
+
#
|
22
|
+
# => { class: "blue", data: { size: "medium", controller: "reply" } }
|
23
|
+
#
|
24
|
+
def deep_merge_html_attributes(custom, parents = [], mergeable_attributes: default_mergeable_attributes)
|
25
|
+
return custom unless custom.is_a?(Hash)
|
26
|
+
|
27
|
+
overrides = custom.deep_symbolize_keys
|
28
|
+
|
29
|
+
deep_symbolize_keys.each_with_object(deep_symbolize_keys) { |(key, value), merged|
|
30
|
+
next unless overrides.key?(key)
|
31
|
+
|
32
|
+
merged[key] = combine_values(
|
33
|
+
value,
|
34
|
+
overrides[key],
|
35
|
+
parents: parents << key,
|
36
|
+
mergeable_attributes: mergeable_attributes
|
37
|
+
)
|
38
|
+
|
39
|
+
overrides.delete(key)
|
40
|
+
}.merge(overrides)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Remove unwanted attributes from a the hash and any values that are hashes
|
44
|
+
# recursively. In particular we don't care for empty hashes, arrays,
|
45
|
+
# strings that are empty or just contain spaces and nils.
|
46
|
+
#
|
47
|
+
# It preserves +true+ and +false+.
|
48
|
+
#
|
49
|
+
# @return [Hash] the tidied hash
|
50
|
+
# @example
|
51
|
+
# { class: "blue", title: nil, lang: "", aria: { describedby: [] } }.deep_tidy_html_attributes
|
52
|
+
#
|
53
|
+
# => { class: "blue" }
|
54
|
+
#
|
55
|
+
def deep_tidy_html_attributes
|
56
|
+
each_with_object({}) do |(key, value), tidy|
|
57
|
+
(tidy[key] = tidy_value(value)) unless skippable_value?(value)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def tidy_value(value)
|
64
|
+
case value
|
65
|
+
when Hash
|
66
|
+
value.deep_tidy_html_attributes.presence
|
67
|
+
when Array
|
68
|
+
value.reject(&:blank?).presence
|
69
|
+
when String
|
70
|
+
value.strip.presence
|
71
|
+
else
|
72
|
+
value
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Identiy attribute values we don't care about.
|
77
|
+
#
|
78
|
+
# We can't check for this using Rails' `#presence` because we want `false` to be
|
79
|
+
# included so some HTML attributes that default to on can be disabled, like
|
80
|
+
# `autocomplete: false`
|
81
|
+
#
|
82
|
+
# FIXME: there is probably a nicer way of doing this...
|
83
|
+
def skippable_value?(value)
|
84
|
+
return false if [true, false].include?(value)
|
85
|
+
|
86
|
+
value.blank?
|
87
|
+
end
|
88
|
+
|
89
|
+
def combine_values(value, override, **kwargs)
|
90
|
+
case split_attribute_list(value, **kwargs)
|
91
|
+
when Array
|
92
|
+
combine_array(value, override, **kwargs)
|
93
|
+
when Hash
|
94
|
+
combine_hash(value, override, **kwargs)
|
95
|
+
else
|
96
|
+
split_attribute_list(override, **kwargs)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def combine_array(originals, overrides, parents:, mergeable_attributes:)
|
101
|
+
return overrides if overrides.nil?
|
102
|
+
return overrides unless mergeable_attributes.include?(parents)
|
103
|
+
|
104
|
+
(try_split(originals) + try_split(overrides)).uniq
|
105
|
+
end
|
106
|
+
|
107
|
+
def try_split(value)
|
108
|
+
value.is_a?(String) ? value.split : value
|
109
|
+
end
|
110
|
+
|
111
|
+
def combine_hash(originals, overrides, parents:, mergeable_attributes:)
|
112
|
+
originals.deep_merge_html_attributes(overrides, parents, mergeable_attributes: mergeable_attributes)
|
113
|
+
end
|
114
|
+
|
115
|
+
def split_attribute_list(value, parents:, mergeable_attributes:)
|
116
|
+
return value.split if value.is_a?(String) && mergeable_attributes.include?(parents)
|
117
|
+
|
118
|
+
value
|
119
|
+
end
|
120
|
+
|
121
|
+
def default_mergeable_attributes
|
122
|
+
[
|
123
|
+
%i(class),
|
124
|
+
%i(aria controls),
|
125
|
+
%i(aria describedby),
|
126
|
+
%i(aria flowto),
|
127
|
+
%i(aria labelledby),
|
128
|
+
%i(aria owns),
|
129
|
+
]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: html-attributes-utils
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter Yates
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-03-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.1.4.4
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 6.1.4.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: debug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.11.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.11.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop-govuk
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 4.3.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 4.3.0
|
69
|
+
description: A small collection of utilities to ease working with hashes of HTML attributes
|
70
|
+
email:
|
71
|
+
- peter.yates@graphia.co.uk
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- README.md
|
77
|
+
- lib/html_attributes_utils.rb
|
78
|
+
homepage: https://github.com/DFE-Digital/html-attributes-utils
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata:
|
82
|
+
bug_tracker_uri: https://github.com/DFE-Digital/html-attributes-utils/issues
|
83
|
+
changelog_uri: https://github.com/DFE-Digital/html-attributes-utils/releases
|
84
|
+
homepage_uri: https://govuk-form-builder.netlify.app
|
85
|
+
source_code_uri: https://github.com/DFE-Digital/html-attributes-utils
|
86
|
+
github_repo: https://github.com/DFE-Digital/html-attributes-utils
|
87
|
+
documentation_uri: https://www.rubydoc.info/gems/html-attributes-utils/
|
88
|
+
rubygems_mfa_required: 'true'
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
requirements: []
|
104
|
+
rubygems_version: 3.3.7
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: HTML attribute hash utilities
|
108
|
+
test_files: []
|