tag_options 0.9.0 → 0.9.1

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: a5fb04a9c092cabe732ee9a7807861f8a2587b22e9221836d42bf9c2400856be
4
- data.tar.gz: 229782a164b543562f6f988a7afb486c26715d55f825862bd4a32b0dfd33e42c
3
+ metadata.gz: 83e261e9adfa9aeb2c3dff7ea1a96feef6b879643232d84135739204bbac2eb1
4
+ data.tar.gz: 4f5017d33651e2274f6a28200c402e840ec044c5c33e9458f73720177cbf6cc1
5
5
  SHA512:
6
- metadata.gz: 484238573bfd185df2f607efff78d33258c2dbbeff55498ebf1d5d39e9610e374676d8e0a0ebafc32b39bf942717c21e843290d724b3f3ec129a5936ccaf7bb7
7
- data.tar.gz: 5705a6389364ef3d5761e77b96d41dec2ac225f7deaefcf3995a462221f09aaf65037c3f38b7f838d42021731d1ed82630e0393326f4e023201c87755a599b16
6
+ metadata.gz: abd1baed79e11a1ecbf6bef278a4d607400e2aaedbe5b3d6d62b9b7480ff2acb4b47091f476c199cffd40ead699be7edcb18f4e5f4e68d90e2fc16e35618c073
7
+ data.tar.gz: 3606249e0673f84f8f00a407c2fe9f73eea3286e1309f10fca238ca906ff3aef8da4e20114eba04e097622317ba5cf74c534f032cb3367e8b2936ec94dac977d
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
- ## [0.9.0] - 2021-11-03
5
+ ## [0.9.0] - 2021-11-04
6
6
 
7
7
  - Initial release
8
+
9
+ ## [0.9.1] - 2021-11-08
10
+
11
+ - Implement property handling
data/README.md CHANGED
@@ -31,12 +31,14 @@ Would render:
31
31
  ## Table of Contents
32
32
 
33
33
  - [Installation](#installation)
34
+ - [Configuration](#configuration)
34
35
  - [General Usage](#general-usage)
35
36
  - [combine_with!](#combinewith)
36
37
  - [override!](#override)
37
38
  - [Conditional Usage](#conditional-usage)
38
39
  - [Development](#development)
39
40
  - [Contributing](#contributing)
41
+ - [To Do](#to-do)
40
42
  - [License](#license)
41
43
 
42
44
  ## Installation
@@ -53,6 +55,14 @@ And then execute:
53
55
  bundle install
54
56
  ```
55
57
 
58
+ ## Configuration
59
+
60
+ Generate an initializer to customize the default configuration:
61
+
62
+ ```sh
63
+ rails generate arc_options:install
64
+ ```
65
+
56
66
  ## General Usage
57
67
 
58
68
  Initialize a `TagOptions::Hash` directly or by passing an existing `Hash`.
@@ -0,0 +1,9 @@
1
+ Description:
2
+ Creates a new initializer containing the default settings of the gem.
3
+
4
+ Examples:
5
+ `rails generate tag_options:install`
6
+
7
+ Creates the following:
8
+
9
+ Initializer: config/tag_options.rb
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TagOptions
4
+ class InstallGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('templates', __dir__)
6
+
7
+ def copy_initializer
8
+ copy_file 'tag_options.rb', 'config/initializers/tag_options.rb'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ TagOptions.configure do |config|
4
+ # fallback_property_handler
5
+ #
6
+ # Defines the default behavior of how values are treated on HTML properties. `TagOptions::PropertyHandler::Generic`
7
+ # allows for multiple, unique, values seperated by spaces.
8
+ config.fallback_property_handler = 'TagOptions::PropertyHandler::Generic'
9
+
10
+ # property_handlers
11
+ #
12
+ # Allows of the custom handling of HTML properties that match the defined property handler. Properties are handled by
13
+ # the first matching property handler.
14
+ config.property_handlers = [
15
+ 'TagOptions::PropertyHandler::Singular',
16
+ 'TagOptions::PropertyHandler::Style'
17
+ ]
18
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TagOptions
4
+ class << self
5
+ attr_writer :configuration
6
+
7
+ def configuration
8
+ @configuration ||= TagOptions::Configuration.new
9
+ end
10
+
11
+ def configure
12
+ yield(configuration)
13
+ end
14
+ end
15
+
16
+ class Configuration
17
+ attr_writer :fallback_property_handler, :property_handlers
18
+
19
+ def fallback_property_handler
20
+ @fallback_property_handler ||= 'TagOptions::PropertyHandler::Generic'
21
+ end
22
+
23
+ def property_handlers
24
+ @property_handlers ||= [
25
+ 'TagOptions::PropertyHandler::Singular',
26
+ 'TagOptions::PropertyHandler::Style'
27
+ ]
28
+ end
29
+ end
30
+ end
@@ -2,49 +2,50 @@
2
2
 
3
3
  require 'active_support/core_ext/string'
4
4
  require 'forwardable'
5
+ require 'tag_options/property_handler/resolve_value'
5
6
 
6
7
  module TagOptions
7
8
  class Hash
8
9
  extend Forwardable
9
10
 
10
- def_delegators :@data, :inspect, :to_s, :stringify_keys, :<, :<=, :==, :>, :>=
11
+ def_delegators :@data, :inspect, :to_h, :to_hash, :to_s, :stringify_keys, :<, :<=, :==, :>, :>=
11
12
 
12
13
  # Hashes passed into the initializer are automatically flattened, with nested keys seperated by dashes. For example,
13
14
  # `data: { controller: 'dropdown' }`` becomes `'data-controller': 'dropdown'`.
14
15
  def initialize(hash={})
15
16
  @data = {}
16
- flatten_hash(hash).each do |key, value|
17
- self[key] = value
17
+ flatten_hash(hash).each do |property, value|
18
+ self[property] = value
18
19
  end
19
20
  end
20
21
 
21
22
  # []
22
- # Underscores in a key name is automatically coverted to dashes. Keys can be specified as strings or symbols, both
23
- # return the same value.
24
- def [](key)
25
- @data[normalize_key(key)]
23
+ # Underscores in a property name is automatically coverted to dashes. Properties can be specified as strings or
24
+ # symbols, both return the same value.
25
+ def [](property)
26
+ @data[normalize_property(property)]
26
27
  end
27
28
 
28
29
  # []=
29
- # Hashes assigned to a key are automatically flatten, with nested keys seperated by dashes. Underscores in a key
30
- # name is automatically converted to dashes. Keys can be specified as strings or symbols, both will assign the value
31
- # to the same key.
32
- def []=(key, value)
30
+ # Hashes assigned to a property are automatically flatten, with nested keys seperated by dashes. Underscores in a
31
+ # property name are automatically converted to dashes. Propertiess can be specified as strings or symbols, both will
32
+ # assign the value to the same property.
33
+ def []=(property, value)
33
34
  if value.is_a?(::Hash)
34
- flatten_hash({ key => value }).each do |flat_key, flat_value|
35
- @data[normalize_key(flat_key)] = flat_value
35
+ flatten_hash({ property => value }).each do |flat_property, flat_value|
36
+ store(flat_property, flat_value)
36
37
  end
37
38
  else
38
- @data[normalize_key(key)] = value
39
+ store(property, value)
39
40
  end
40
41
  end
41
42
 
42
43
  # combine_with!
43
44
  # Allows you to combine values with multiple HTML attributes in one operation. Passed keys should be the HTML
44
- # attributes to combine the values with. The values can be passed as single value (e.g. `class: 'flex'`) or as an
45
+ # property to combine the values with. The values can be specified as single string (e.g. `class: 'flex'`) or as an
45
46
  # argument array (e.g. `class: ['flex', 'mt-2', 'flex-col': layout_column?]`). Hashes in an argument array have
46
47
  # their keys combined only their value is true. Nested keys will automatically be flattened and combine with the
47
- # associated key (e.g. `data: { controller: 'dropdown' }` would be combined with `data-controller`).
48
+ # associated property (e.g. `data: { controller: 'dropdown' }` would be combined with `data-controller`).
48
49
  #
49
50
  # #combine_with!(
50
51
  # class: ['flex', 'mt-2', 'flex-col': layout_column?],
@@ -58,18 +59,18 @@ module TagOptions
58
59
  # attribute is converted to dashes, for example: `combine_with_data_controller!` will result in the argument array
59
60
  # being combined with existing values in `data-controller`.
60
61
  def combine_with!(hash={})
61
- flatten_hash(hash).each do |key, args|
62
- self[key] = combine_values(self[key], *args)
62
+ flatten_hash(hash).each do |property, args|
63
+ store(property, self[property], *args)
63
64
  end
64
65
  self
65
66
  end
66
67
 
67
68
  # override!
68
- # Allows you to override values on multiple HTML attributes in one operation. Passed keys should be the HTML
69
- # attributes to override the values of. The values can be passed as single string (e.g. `class: 'flex'`) or as an
69
+ # Allows you to override values on multiple HTML properties in one operation. Passed keys should be the HTML
70
+ # properties to override the values of. The values can be passed as single string (e.g. `class: 'flex'`) or as an
70
71
  # argument array (e.g. `class: ['flex', 'mt-2', 'flex-col': layout_column?]`). Hashes in an argument array have
71
72
  # their keys added only if their value is true. Nested keys will automatically be flattened and override the value
72
- # at the associated key (e.g. `data: { controller: 'dropdown' }` would override values at `data-controller`).
73
+ # at the associated property (e.g. `data: { controller: 'dropdown' }` would override values at `data-controller`).
73
74
  #
74
75
  # #override!(
75
76
  # class: ['flex', 'mt-2', 'flex-col': layout_column?],
@@ -83,35 +84,26 @@ module TagOptions
83
84
  # attribute is automatically nested, for example `override_data_controller!` will result in the argument array
84
85
  # overriding the existing values in `data-controller`.
85
86
  def override!(hash={})
86
- flatten_hash(hash).each do |key, args|
87
- self[key] = combine_values(*args)
87
+ flatten_hash(hash).each do |property, args|
88
+ store(property, *args)
88
89
  end
89
90
  self
90
91
  end
91
92
 
92
- def to_h
93
- @data.transform_values { |value| value.is_a?(::TagOptions::Hash) ? value.to_h : value }
94
- end
95
- alias to_hash to_h
96
-
97
93
  private
98
94
 
99
95
  def action_matcher
100
- /\A(?<action>combine_with|override)_(?<key>.*)!\z/
101
- end
102
-
103
- def combine_values(*values, **conditions)
104
- [*values, *resolve_conditions(conditions.to_h)].map { |v| v.to_s.split }.flatten.compact.uniq.join(' ')
96
+ /\A(?<action>combine_with|override)_(?<property>.*)!\z/
105
97
  end
106
98
 
107
99
  def flatten_hash(hash)
108
- hash.each_with_object({}) do |(key, value), result|
100
+ hash.each_with_object({}) do |(property, value), result|
109
101
  if value.is_a?(::Hash)
110
- flatten_hash(value).map do |nested_key, nested_value|
111
- result["#{key}-#{nested_key}".to_sym] = nested_value
102
+ flatten_hash(value).map do |nested_property, nested_value|
103
+ result["#{property}-#{nested_property}".to_sym] = nested_value
112
104
  end
113
105
  else
114
- result[key] = value
106
+ result[property] = value
115
107
  end
116
108
  end
117
109
  end
@@ -119,18 +111,24 @@ module TagOptions
119
111
  def method_missing(method_name, *args, &block)
120
112
  match_data = action_matcher.match(method_name.to_s)
121
113
  if match_data
122
- public_send("#{match_data['action']}!", { match_data['key'] => args }, &block)
114
+ public_send("#{match_data['action']}!", { match_data['property'] => args }, &block)
123
115
  else
124
116
  super
125
117
  end
126
118
  end
127
119
 
128
- def normalize_key(key)
129
- key.to_s.downcase.dasherize.to_sym
120
+ def store(property, *values, **conditions)
121
+ property = normalize_property(property)
122
+ value = resolve_value(property, *values, **conditions)
123
+ value.empty? ? @data.delete(property) : @data[property] = value
124
+ end
125
+
126
+ def resolve_value(property, *values, **conditions)
127
+ TagOptions::PropertyHandler::ResolveValue.call(property, *values, **conditions)
130
128
  end
131
129
 
132
- def resolve_conditions(conditions)
133
- conditions.select { |_key, value| value }.keys
130
+ def normalize_property(property)
131
+ property.to_s.downcase.dasherize.to_sym
134
132
  end
135
133
 
136
134
  def respond_to_missing?(method_name, include_private=false)
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TagOptions
4
+ module PropertyHandler
5
+ class Base
6
+ attr_reader :values, :conditions
7
+
8
+ def initialize(*values, **conditions)
9
+ @values = values
10
+ @conditions = conditions
11
+ end
12
+
13
+ def self.call(...)
14
+ new(...).call
15
+ end
16
+
17
+ def self.handler_for?(property_name)
18
+ self::MATCHER.match?(property_name.to_s)
19
+ end
20
+
21
+ private
22
+
23
+ def combine_values(*values, **conditions)
24
+ resolve_uniq_values(*values, **conditions).join(' ')
25
+ end
26
+
27
+ def resolve_uniq_values(*values, **conditions)
28
+ [*values, *resolve_conditions(conditions)].map { |v| v.to_s.split }.flatten.compact.uniq
29
+ end
30
+
31
+ def resolve_conditions(conditions)
32
+ conditions.select { |_key, value| value }.keys
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tag_options/property_handler/base'
4
+
5
+ module TagOptions
6
+ module PropertyHandler
7
+ class Generic < Base
8
+ MATCHER = /\A.*\z/.freeze
9
+
10
+ def call
11
+ combine_values(*values, **conditions)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tag_options/configuration'
4
+
5
+ module TagOptions
6
+ module PropertyHandler
7
+ class ResolveValue
8
+ attr_reader :property
9
+
10
+ def initialize(property)
11
+ @property = property
12
+ end
13
+
14
+ def call(...)
15
+ handler.call(...)
16
+ end
17
+
18
+ def self.call(property, *values, **conditions)
19
+ new(property).call(*values, **conditions)
20
+ end
21
+
22
+ private
23
+
24
+ def handler
25
+ TagOptions.configuration.property_handlers.each do |handler_string|
26
+ handler = handler_string.constantize
27
+ return handler if handler.handler_for?(property)
28
+ end
29
+ TagOptions.configuration.fallback_property_handler.constantize
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tag_options/property_handler/base'
4
+
5
+ module TagOptions
6
+ module PropertyHandler
7
+ class Singular < Base
8
+ MATCHER = /\Aid|role|aria-.+\z/.freeze
9
+
10
+ def call
11
+ resolve_uniq_values(*values, **conditions).last.to_s
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tag_options/property_handler/base'
4
+
5
+ module TagOptions
6
+ module PropertyHandler
7
+ class Style < Base
8
+ MATCHER = /\Astyle\z/.freeze
9
+
10
+ def call
11
+ styles.map { |p, v| "#{p}: #{v};" }.join(' ')
12
+ end
13
+
14
+ private
15
+
16
+ def styles
17
+ styles_from_values.merge(styles_from_conditions)
18
+ end
19
+
20
+ def styles_from_values
21
+ style_hash_from(values)
22
+ end
23
+
24
+ def styles_from_conditions
25
+ style_hash_from(resolve_conditions(conditions))
26
+ end
27
+
28
+ def style_hash_from(strings)
29
+ {}.tap do |result|
30
+ Array(strings).each do |string|
31
+ string.to_s.split(';').compact.each do |property_value_pair|
32
+ property, value = property_value_pair.split(':')
33
+ next unless property && value
34
+
35
+ result[property.strip.downcase.to_sym] = value.strip
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TagOptions
4
- VERSION = '0.9.0'
4
+ VERSION = '0.9.1'
5
5
  end
data/lib/tag_options.rb CHANGED
@@ -1,5 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'tag_options/property_handler/base'
4
+ require 'tag_options/property_handler/generic'
5
+ require 'tag_options/property_handler/resolve_value'
6
+ require 'tag_options/property_handler/singular'
7
+ require 'tag_options/property_handler/style'
8
+ require 'tag_options/configuration'
3
9
  require 'tag_options/hash'
4
10
  require 'tag_options/railtie'
5
11
  require 'tag_options/version'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tag_options
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Monroe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-04 00:00:00.000000000 Z
11
+ date: 2021-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: debug
@@ -161,8 +161,17 @@ files:
161
161
  - MIT-LICENSE
162
162
  - README.md
163
163
  - Rakefile
164
+ - lib/generators/tag_options/install/USAGE
165
+ - lib/generators/tag_options/install/install_generator.rb
166
+ - lib/generators/tag_options/install/templates/tag_options.rb
164
167
  - lib/tag_options.rb
168
+ - lib/tag_options/configuration.rb
165
169
  - lib/tag_options/hash.rb
170
+ - lib/tag_options/property_handler/base.rb
171
+ - lib/tag_options/property_handler/generic.rb
172
+ - lib/tag_options/property_handler/resolve_value.rb
173
+ - lib/tag_options/property_handler/singular.rb
174
+ - lib/tag_options/property_handler/style.rb
166
175
  - lib/tag_options/railtie.rb
167
176
  - lib/tag_options/version.rb
168
177
  homepage: https://github.com/wamonroe/tag_options