html_attrs 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 81f6299891fbc21d5780803b427e30dfb8e07b6280e518ff974e1e5d9f5d5bbc
4
+ data.tar.gz: 58442fc06a5a775c197aba3ad445e23f15f7f68c3a9f69a07e9900b22640193f
5
+ SHA512:
6
+ metadata.gz: 4cd21bb1474c4ce8be233580048c8dd604e7249ab40d84e55e4eddbda1a3f2f1a2deb9ca7ecc74e665905a61dcab2df23f76341834845ba4ed9e7a9a3ab58e6a
7
+ data.tar.gz: 492c60112a6c93c069f5e93ef43203d2a0f75b61456e40714d027c9604c45dec847dd1ea4fece6b91ceb1ae6025bac1e7ea1b2c65764299897e10ec87f141762
data/.standard.yml ADDED
@@ -0,0 +1,3 @@
1
+ # For available configuration options, see:
2
+ # https://github.com/testdouble/standard
3
+ ruby_version: 2.6
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in html_attrs.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "minitest", "~> 5.0"
11
+
12
+ gem "standard", "~> 1.3"
data/Gemfile.lock ADDED
@@ -0,0 +1,107 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ html_attrs (0.1.0)
5
+ actionview (>= 6.0)
6
+ activesupport (>= 6.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actionview (7.1.3.2)
12
+ activesupport (= 7.1.3.2)
13
+ builder (~> 3.1)
14
+ erubi (~> 1.11)
15
+ rails-dom-testing (~> 2.2)
16
+ rails-html-sanitizer (~> 1.6)
17
+ activesupport (7.1.3.2)
18
+ base64
19
+ bigdecimal
20
+ concurrent-ruby (~> 1.0, >= 1.0.2)
21
+ connection_pool (>= 2.2.5)
22
+ drb
23
+ i18n (>= 1.6, < 2)
24
+ minitest (>= 5.1)
25
+ mutex_m
26
+ tzinfo (~> 2.0)
27
+ ast (2.4.2)
28
+ base64 (0.2.0)
29
+ bigdecimal (3.1.6)
30
+ builder (3.2.4)
31
+ concurrent-ruby (1.2.3)
32
+ connection_pool (2.4.1)
33
+ crass (1.0.6)
34
+ drb (2.2.1)
35
+ erubi (1.12.0)
36
+ i18n (1.14.4)
37
+ concurrent-ruby (~> 1.0)
38
+ json (2.7.1)
39
+ language_server-protocol (3.17.0.3)
40
+ lint_roller (1.1.0)
41
+ loofah (2.22.0)
42
+ crass (~> 1.0.2)
43
+ nokogiri (>= 1.12.0)
44
+ minitest (5.22.2)
45
+ mutex_m (0.2.0)
46
+ nokogiri (1.16.2-arm64-darwin)
47
+ racc (~> 1.4)
48
+ parallel (1.24.0)
49
+ parser (3.3.0.5)
50
+ ast (~> 2.4.1)
51
+ racc
52
+ racc (1.7.3)
53
+ rails-dom-testing (2.2.0)
54
+ activesupport (>= 5.0.0)
55
+ minitest
56
+ nokogiri (>= 1.6)
57
+ rails-html-sanitizer (1.6.0)
58
+ loofah (~> 2.21)
59
+ nokogiri (~> 1.14)
60
+ rainbow (3.1.1)
61
+ rake (13.1.0)
62
+ regexp_parser (2.9.0)
63
+ rexml (3.2.6)
64
+ rubocop (1.62.0)
65
+ json (~> 2.3)
66
+ language_server-protocol (>= 3.17.0)
67
+ parallel (~> 1.10)
68
+ parser (>= 3.3.0.2)
69
+ rainbow (>= 2.2.2, < 4.0)
70
+ regexp_parser (>= 1.8, < 3.0)
71
+ rexml (>= 3.2.5, < 4.0)
72
+ rubocop-ast (>= 1.31.1, < 2.0)
73
+ ruby-progressbar (~> 1.7)
74
+ unicode-display_width (>= 2.4.0, < 3.0)
75
+ rubocop-ast (1.31.2)
76
+ parser (>= 3.3.0.4)
77
+ rubocop-performance (1.20.2)
78
+ rubocop (>= 1.48.1, < 2.0)
79
+ rubocop-ast (>= 1.30.0, < 2.0)
80
+ ruby-progressbar (1.13.0)
81
+ standard (1.34.0)
82
+ language_server-protocol (~> 3.17.0.2)
83
+ lint_roller (~> 1.0)
84
+ rubocop (~> 1.60)
85
+ standard-custom (~> 1.0.0)
86
+ standard-performance (~> 1.3)
87
+ standard-custom (1.0.2)
88
+ lint_roller (~> 1.0)
89
+ rubocop (~> 1.50)
90
+ standard-performance (1.3.1)
91
+ lint_roller (~> 1.1)
92
+ rubocop-performance (~> 1.20.2)
93
+ tzinfo (2.0.6)
94
+ concurrent-ruby (~> 1.0)
95
+ unicode-display_width (2.5.0)
96
+
97
+ PLATFORMS
98
+ arm64-darwin-22
99
+
100
+ DEPENDENCIES
101
+ html_attrs!
102
+ minitest (~> 5.0)
103
+ rake (~> 13.0)
104
+ standard (~> 1.3)
105
+
106
+ BUNDLED WITH
107
+ 2.4.13
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Owais
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # HtmlAttrs
2
+
3
+ A simple gem to merge HTML attributes in Ruby. It's incredibly useful when you're working with HTML attributes in a Rails app.
4
+
5
+ For example, you're accepting arguments in a component or partial from somewhere else that you then need to merge smartly (can be tailwind classes, data attributes for stimulus controllers, etc)
6
+
7
+ ## Installation
8
+
9
+ Install the gem and add to the application's Gemfile by executing:
10
+ ```shell
11
+ $ bundle add html_attrs
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ```ruby
17
+ html_attrs = {
18
+ class: 'bg-primary-500', data: { controller: 'popover', action: 'click->popover#toggle' }
19
+ }.as_html_attrs
20
+
21
+ html_attrs = html_attrs.smart_merge(
22
+ class: 'border border-primary-500', data: { controller: 'slideover' }, href: '#'
23
+ )
24
+
25
+ # Will produce:
26
+ {
27
+ class: 'bg-primary-500 border border-primary-500',
28
+ data: { controller: 'popover slideover', action: 'click->popover#toggle' },
29
+ href: '#'
30
+ }
31
+ ```
32
+
33
+ You can use this in helpers that accept HTML attributes as a hash, e.g:
34
+ ```erb
35
+ <%= content_tag(:a, 'Hello', html_attrs) %>
36
+
37
+ <%# Will produce: %>
38
+ <a
39
+ class="bg-primary-500 border border-primary-500"
40
+ data-controller="popover slideover"
41
+ data-action="click->popover#toggle"
42
+ href="#"
43
+ >
44
+ Hello
45
+ </a>
46
+ ```
47
+
48
+
49
+ You can also use the `to_s` method to get the string representation of the HTML attributes, if you need to use it in a string context.
50
+ ```erb
51
+ <a <%= html_attrs.to_s %> id='home'>Hello</a>
52
+
53
+ <%# Will produce: %>
54
+ <a
55
+ class="bg-primary-500 border border-primary-500"
56
+ data-controller="popover slideover"
57
+ data-action="click->popover#toggle"
58
+ href="#"
59
+ id='home'
60
+ >
61
+ Hello
62
+ </a>
63
+ ```
64
+
65
+
66
+ Alternative, you can use the `HtmlAttrs` class directly, e.g:
67
+ ```ruby
68
+ HtmlAttrs.smart_merge(
69
+ { class: 'bg-primary-500', data: { controller: 'popover' } },
70
+ { id: 'test', class: 'border' }
71
+ )
72
+ # => { class: 'bg-primary-500 border', data: { controller: 'popover' }, id: 'test' }
73
+ ```
74
+
75
+ Or, you can also instantiate a new `HtmlAttrs` object and use the `smart_merge` method, e.g:
76
+ ```ruby
77
+ html_attrs = HtmlAttrs.new(class: 'bg-primary-500', data: { controller: 'popover' })
78
+ # => { class: 'bg-primary-500', id: 'test', aria_label: 'Help', download: 'test.jpeg' }
79
+
80
+ html_attrs.smart_merge( id: 'test', class: 'border')
81
+ # => { class: 'bg-primary-500 border', data: { controller: 'popover' }, id: 'test' }
82
+ ```
83
+
84
+ Under the hood, `HtmlAttrs` is a simple wrapper around `ActiveSupport::HashWithIndifferentAccess`, so you can use it just like any other hash. The only difference is `#smart_merge` and `to_s`.
85
+
86
+ Merging is done recursively. Strings are merged by concatenating them with a space. Arrays are merged with simple concatenation. Hashes are merged recursively using the above rules. Everything else is merged normally, just like with `Hash#merge`. Super simple, but super powerful.
87
+
88
+ ## Configuring mergeable attributes
89
+
90
+ By default, this gem merges `class`, `style` and `data` attributes recursively. Which should usually be more than enough. You can easily customize this by specifying `mergeable_attributes:` when calling `smart_merge`. e.g:
91
+ ```ruby
92
+ HtmlAttrs.new(class: 'bg-primary-500', id: 'test', aria_label: 'Help')
93
+ .smart_merge(aria_label: 'Another', href: '/test', mergeable_attributes: [:aria_label])
94
+ # => { class: 'bg-primary-500', id: 'test', aria_label: 'Help Another', href: '/test' }
95
+ ```
96
+
97
+ ## Development
98
+
99
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
100
+
101
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
102
+
103
+ ## Contributing
104
+
105
+ Bug reports and pull requests are welcome on GitHub at https://github.com/owaiswiz/html_attrs.
106
+
107
+ ## License
108
+
109
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/**/test_*.rb"]
10
+ end
11
+
12
+ require "standard/rake"
13
+
14
+ task default: %i[test standard]
data/lib/html_attrs.rb ADDED
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view'
4
+ require 'active_support/core_ext/hash/indifferent_access'
5
+
6
+ class HtmlAttrs < HashWithIndifferentAccess
7
+ VERSION = '1.0.0'
8
+ DEFAULT_MERGEABLE_ATTRIBUTES = %i[class style data].to_set
9
+
10
+ def smart_merge(other)
11
+ mergeable_attributes = other.delete(:mergeable_attributes) if other.is_a?(Hash) && other.key?(:mergeable_attributes)
12
+ mergeable_attributes ||= DEFAULT_MERGEABLE_ATTRIBUTES
13
+ self.class.smart_merge(self, other, mergeable_attributes: mergeable_attributes)
14
+ end
15
+
16
+ def to_s
17
+ self.class.attributes(self)
18
+ end
19
+
20
+ def self.smart_merge(other, target, mergeable_attributes: DEFAULT_MERGEABLE_ATTRIBUTES)
21
+ other = other.with_indifferent_access if other.is_a?(Hash) && !other.is_a?(HashWithIndifferentAccess)
22
+ target = target.with_indifferent_access if target.is_a?(Hash) && !target.is_a?(HashWithIndifferentAccess)
23
+
24
+ return other if target.nil?
25
+ return target if other.nil?
26
+
27
+ if target.is_a?(Hash) || other.is_a?(Hash)
28
+ raise 'Expected target to be a hash or nil' if !target.nil? && !target.is_a?(Hash)
29
+ raise 'Expected other to be a hash or nil' if !other.nil? && !other.is_a?(Hash)
30
+
31
+ target.each do |key, value|
32
+ other[key] =
33
+ if other.key?(key) && attribute_mergeable?(key, mergeable_attributes)
34
+ smart_merge(other[key], value, mergeable_attributes: :all)
35
+ else
36
+ value
37
+ end
38
+ end
39
+ return other
40
+ end
41
+
42
+ if target.is_a?(Array) || other.is_a?(Array)
43
+ raise 'Expected target to be an array or nil' if !target.nil? && !target.is_a?(Array)
44
+ raise 'Expected other to be an array or nil' if !other.nil? && !other.is_a?(Array)
45
+
46
+ return (other || []).concat(target || [])
47
+ end
48
+
49
+ if target.is_a?(String) || other.is_a?(String)
50
+ raise 'Expected target to be a string or nil' if !target.nil? && !target.is_a?(String)
51
+ raise 'Expected other to be a string or nil' if !other.nil? && !other.is_a?(String)
52
+
53
+ return [other.presence, target.presence].compact.join(' ')
54
+ end
55
+
56
+ target
57
+ end
58
+
59
+ def self.attribute_mergeable?(attribute, mergeable_attributes)
60
+ return true if mergeable_attributes == :all
61
+
62
+ mergeable_attributes.include?(attribute.to_sym)
63
+ end
64
+
65
+ def self.attributes(hash)
66
+ tag_helper.tag_options(hash).to_s.strip.html_safe
67
+ end
68
+
69
+ def self.tag_helper
70
+ @tag_helper ||= ActionView::Helpers::TagBuilder.new(nil)
71
+ end
72
+ end
73
+
74
+ class Hash
75
+ def as_html_attrs
76
+ HtmlAttrs.new(self)
77
+ end
78
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: html_attrs
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Owais
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-03-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: actionview
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '6.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '6.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '6.0'
41
+ description: A gem that provides a way to smartly merge HTML attributes
42
+ email:
43
+ - owaiswiz@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".standard.yml"
49
+ - Gemfile
50
+ - Gemfile.lock
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - lib/html_attrs.rb
55
+ homepage: https://github.com/owaiswiz/html_attrs
56
+ licenses:
57
+ - MIT
58
+ metadata:
59
+ homepage_uri: https://github.com/owaiswiz/html_attrs
60
+ source_code_uri: https://github.com/owaiswiz/html_attrs
61
+ changelog_uri: https://github.com/owaiswiz/html_attrs/releases
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 2.6.0
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubygems_version: 3.4.10
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: A gem that provides a way to smartly merge HTML attributes
81
+ test_files: []