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: []
         
     |