diff --git a/.rubocop.yml b/.rubocop.yml index 77aef07..e3f41d8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -25,8 +25,8 @@ AllCops: - test/fixtures/**/* - vendor/**/* -# Lint/MissingSuper: -# Enabled: false +Layout/MultilineBlockLayout: + Enabled: false Metrics/AbcSize: Exclude: @@ -40,28 +40,5 @@ Metrics/MethodLength: Exclude: - test/**/*.rb -# Style/Documentation: -# Enabled: false - -# Style/Lambda: -# Enabled: false - -# Style/LambdaCall: -# Enabled: false - -# Style/MultilineBlockChain: -# Enabled: false - -# Style/StringLiterals: -# Enabled: true -# EnforcedStyle: double_quotes - -# Style/StringLiteralsInInterpolation: -# Enabled: true -# EnforcedStyle: double_quotes - -# Style/ParallelAssignment: -# Enabled: false - Layout/LineLength: Max: 120 diff --git a/Gemfile.lock b/Gemfile.lock index 63c22ba..7d23260 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,10 @@ PATH remote: . specs: - lifeform (0.11.0) + lifeform (0.12.0) hash_with_dot_access (>= 1.2) sequel (>= 5.72) - serbea (>= 2.1) + streamlined (>= 0.2.0) zeitwerk (~> 2.5) GEM @@ -116,6 +116,9 @@ GEM thor (~> 1.0) tilt (~> 2.0) yard (~> 0.9, >= 0.9.24) + streamlined (0.2.0) + serbea (>= 2.1) + zeitwerk (~> 2.5) thor (1.3.0) tilt (2.3.0) tzinfo (2.0.6) diff --git a/lib/lifeform.rb b/lib/lifeform.rb index 53e35a6..e4b8b31 100644 --- a/lib/lifeform.rb +++ b/lib/lifeform.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true -require "serbea/helpers" # primarily just for HTML safety polyfill -require "serbea/pipeline" +require "streamlined" require "zeitwerk" loader = Zeitwerk::Loader.for_gem loader.setup diff --git a/lib/lifeform/form.rb b/lib/lifeform/form.rb index 0ecca95..cf342d5 100644 --- a/lib/lifeform/form.rb +++ b/lib/lifeform/form.rb @@ -9,7 +9,7 @@ module Lifeform # A form object which stores field definitions and can be rendered as a component class Form - include Lifeform::Renderable + include Streamlined::Renderable extend Sequel::Inflections MODEL_PATH_HELPER = :polymorphic_path @@ -192,14 +192,13 @@ def template(&block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComple form_tag = library::FORM_TAG parameters[:action] ||= url || (model ? helpers.send(self.class.const_get(:MODEL_PATH_HELPER), model) : nil) - html -> { - <<~HTML # rubocop:disable Bridgetown/HTMLEscapedHeredoc - <#{form_tag} #{html_attributes attributes}> - #{add_authenticity_token unless parameters[:method].to_s.casecmp("get").zero?} - #{@method_tag&.() || ""} - #{block ? capture(self, &block) : auto_render_fields} - - HTML + html -> { <<~HTML # rubocop:disable Bridgetown/HTMLEscapedHeredoc + <#{form_tag} #{html_attributes attributes}> + #{add_authenticity_token unless parameters[:method].to_s.casecmp("get").zero?} + #{@method_tag&.() || ""} + #{block ? capture(self, &block) : auto_render_fields} + + HTML } end diff --git a/lib/lifeform/helpers.rb b/lib/lifeform/helpers.rb deleted file mode 100644 index 32cacdf..0000000 --- a/lib/lifeform/helpers.rb +++ /dev/null @@ -1,93 +0,0 @@ -# frozen_string_literal: true - -module Lifeform - module Helpers - # Below is pretty much verbatim copied over from Bridgetown - # TODO: extract both out to a shared gem - - # Create a set of attributes from a hash. - # - # @param options [Hash] key-value pairs of HTML attributes (or use keyword arguments) - # @param prefix_space [Boolean] add a starting space if attributes are present, - # useful in tag builders - # @return [String] - def html_attributes(options = nil, prefix_space: false, **kwargs) - options ||= kwargs - segments = [] - options.each do |attr, option| - attr = dashed(attr) - if option.is_a?(Hash) - option = option.transform_keys { |key| "#{attr}-#{dashed(key)}" } - segments << html_attributes(option) - else - segments << attribute_segment(attr, option) - end - end - segments.join(" ").then do |output| - prefix_space && !output.empty? ? " #{output}" : output - end - end - - # Covert an underscored value into a dashed string. - # - # @example "foo_bar_baz" => "foo-bar-baz" - # - # @param value [String|Symbol] - # @return [String] - def dashed(value) - value.to_s.tr("_", "-") - end - - # Create an attribute segment for a tag. - # - # @param attr [String] the HTML attribute name - # @param value [String] the attribute value - # @return [String] - def attribute_segment(attr, value) - "#{attr}=#{value.to_s.encode(xml: :attr)}" - end - - module PipeableProc - include Serbea::Pipeline::Helper - - attr_accessor :pipe_block, :touched - - def pipe(&block) - return super(self.(), &pipe_block) if pipe_block && !block - - self.touched = true - return self unless block - - tap { _1.pipe_block = block } - end - - def to_s - return self.().to_s if touched - - super - end - - def encode(...) - to_s.encode(...) - end - end - - Proc.prepend(PipeableProc) unless defined?(Bridgetown::HTMLinRuby::PipeableProc) - - def text(callback) - (callback.is_a?(Proc) ? html(callback) : callback).to_s.then do |str| - next str if str.html_safe? - - str.encode(xml: :attr).gsub(%r{\A"|"\Z}, "") - end - end - - def html(callback) - callback.pipe - end - - def html_map(input, &callback) - input.map(&callback).join - end - end -end diff --git a/lib/lifeform/libraries/default/button.rb b/lib/lifeform/libraries/default/button.rb index a0825f0..35026dd 100644 --- a/lib/lifeform/libraries/default/button.rb +++ b/lib/lifeform/libraries/default/button.rb @@ -4,7 +4,7 @@ module Lifeform module Libraries class Default class Button - include Lifeform::Renderable + include Streamlined::Renderable attr_reader :form, :field_definition, :attributes @@ -28,18 +28,16 @@ def template(&block) label_text = block ? capture(self, &block) : @label.is_a?(Proc) ? @label.pipe : @label # rubocop:disable Style/NestedTernaryOperator - field_body = html -> { - <<~HTML # rubocop:disable Bridgetown/HTMLEscapedHeredoc - <#{button_tag}#{html_attributes @attributes, prefix_space: true}>#{text -> { label_text }} - HTML + field_body = html -> { <<~HTML # rubocop:disable Bridgetown/HTMLEscapedHeredoc + <#{button_tag}#{html_attributes @attributes, prefix_space: true}>#{text -> { label_text }} + HTML } return field_body unless wrapper_tag - html -> { - <<~HTML # rubocop:disable Bridgetown/HTMLEscapedHeredoc - <#{wrapper_tag} #{html_attributes name: @attributes[:name]}>#{field_body} - HTML + html -> { <<~HTML # rubocop:disable Bridgetown/HTMLEscapedHeredoc + <#{wrapper_tag} #{html_attributes name: @attributes[:name]}>#{field_body} + HTML } end end diff --git a/lib/lifeform/libraries/default/input.rb b/lib/lifeform/libraries/default/input.rb index 49a8e99..d9b0a0c 100644 --- a/lib/lifeform/libraries/default/input.rb +++ b/lib/lifeform/libraries/default/input.rb @@ -4,7 +4,7 @@ module Lifeform module Libraries class Default class Input - include Lifeform::Renderable + include Streamlined::Renderable attr_reader :form, :field_definition, :attributes @@ -46,10 +46,9 @@ def handle_labels @attributes = attributes.filter_map { |k, v| [k, v] unless k == :label }.to_h - -> { - <<~HTML - - HTML + -> { <<~HTML + + HTML } end @@ -60,22 +59,20 @@ def template(&block) # rubocop:disable Metrics/AbcSize input_tag = dashed self.class.const_get(:INPUT_TAG) closing_tag = input_tag != "input" - field_body = html -> { - <<~HTML # rubocop:disable Bridgetown/HTMLEscapedHeredoc - #{html(@label || -> {}).to_s.strip} - <#{input_tag} #{html_attributes type: @field_type.to_s, **@attributes}>#{ - "" if closing_tag - } - #{html -> { capture(self, &block) } if block} - HTML + field_body = html -> { <<~HTML # rubocop:disable Bridgetown/HTMLEscapedHeredoc + #{html(@label || -> {}).to_s.strip} + <#{input_tag} #{html_attributes type: @field_type.to_s, **@attributes}>#{ + "" if closing_tag + } + #{html -> { capture(self, &block) } if block} + HTML } return field_body unless wrapper_tag - html -> { - <<~HTML # rubocop:disable Bridgetown/HTMLEscapedHeredoc - <#{wrapper_tag} #{html_attributes name: @attributes[:name]}>#{field_body.to_s.strip} - HTML + html -> { <<~HTML # rubocop:disable Bridgetown/HTMLEscapedHeredoc + <#{wrapper_tag} #{html_attributes name: @attributes[:name]}>#{field_body.to_s.strip} + HTML } end end diff --git a/lib/lifeform/libraries/shoelace/button.rb b/lib/lifeform/libraries/shoelace/button.rb index f4452c3..119d72e 100644 --- a/lib/lifeform/libraries/shoelace/button.rb +++ b/lib/lifeform/libraries/shoelace/button.rb @@ -5,8 +5,6 @@ module Libraries class Shoelace class Button < Default::Button BUTTON_TAG = :sl_button - - register_element BUTTON_TAG end end end diff --git a/lib/lifeform/renderable.rb b/lib/lifeform/renderable.rb deleted file mode 100644 index 71b0f65..0000000 --- a/lib/lifeform/renderable.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -module Lifeform - module Renderable - include Lifeform::Helpers - - def render_in(view_context, &block) - @_view_context = view_context - template(&block).to_s.strip - end - - def helpers - @_view_context - end - - def capture(...) - helpers ? helpers.capture(...) : yield(*args) - end - end -end diff --git a/lib/lifeform/version.rb b/lib/lifeform/version.rb index 5b98351..61f6fab 100644 --- a/lib/lifeform/version.rb +++ b/lib/lifeform/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Lifeform - VERSION = "0.11.0" + VERSION = "0.12.0" end diff --git a/lifeform.gemspec b/lifeform.gemspec index 3734124..faad5a0 100644 --- a/lifeform.gemspec +++ b/lifeform.gemspec @@ -25,6 +25,6 @@ Gem::Specification.new do |spec| spec.add_dependency "hash_with_dot_access", ">= 1.2" spec.add_dependency "sequel", ">= 5.72" - spec.add_dependency "serbea", ">= 2.1" + spec.add_dependency "streamlined", ">= 0.2.0" spec.add_dependency "zeitwerk", "~> 2.5" end