agrobbin/spritely

View on GitHub
lib/spritely/sprockets/preprocessor.rb

Summary

Maintainability
A
0 mins
Test Coverage
require 'sprockets/directive_processor'

module Spritely
  module Sprockets
    # Converts Sprockets directives from this:
    #
    #   //= directory foo/bar
    #   //= sort name desc
    #   //= layout horizontal
    #   //= repeat arrow true
    #   //= spacing_after arrow 10
    #   //= opposite another-image true
    #   //= spacing_before 5
    #   //= spacing_after 5
    #
    # To this:
    #
    #   {
    #     directory: 'foo/bar',
    #     sort: ['name, 'desc'],
    #     layout: 'horizontal',
    #     global: { spacing_before: '5', spacing_after: '5' },
    #     images: {
    #       'arrow' => { repeat: 'true', spacing_before: '10', spacing_after: '5' },
    #       'another-image' => { opposite: 'true', spacing_before: '5', spacing_after: '5' }
    #     }
    #   }
    class Preprocessor < ::Sprockets::DirectiveProcessor
      IMAGE_DIRECTIVES = %w(repeat opposite spacing_before spacing_after).freeze

      def _call(input)
        @sprite_directives = { directory: nil, sort: nil, layout: nil, global: {}, images: {} }

        super.tap do
          merge_global_options!

          input[:metadata][:sprite_directives] = @sprite_directives
        end
      end

      def process_directory_directive(value)
        @sprite_directives[:directory] = value
      end

      def process_sort_directive(*values)
        @sprite_directives[:sort] = values
      end

      def process_layout_directive(value)
        @sprite_directives[:layout] = value
      end

      IMAGE_DIRECTIVES.each do |directive|
        define_method("process_#{directive}_directive") do |image_or_value, value_or_nil = nil|
          if value_or_nil
            process_image_option(directive, image_or_value, value_or_nil)
          else
            process_global_option(directive, image_or_value)
          end
        end
      end

      def process_position_directive(image_or_value, value_or_nil = nil)
        Spritely.logger.warn "The `position` directive is deprecated and has been replaced by `opposite`. It will be removed in Spritely 3.0. (called from #{@filename})"

        if value_or_nil
          process_opposite_directive(image_or_value, 'true')
        else
          process_opposite_directive('true')
        end
      end

      def process_spacing_directive(*args)
        Spritely.logger.warn "The `spacing` directive is deprecated and has been replaced by `spacing_after`. It will be removed in Spritely 3.0. (called from #{@filename})"

        process_spacing_after_directive(*args)
      end

      def process_spacing_above_directive(*args)
        Spritely.logger.warn "The `spacing_above` directive is deprecated and has been replaced by `spacing_before`. It will be removed in Spritely 3.0. (called from #{@filename})"

        process_spacing_before_directive(*args)
      end

      # Use `define_method` here because of the dash in the directive name
      define_method("process_spacing-above_directive") do |*args|
        Spritely.logger.warn "The `spacing-above` directive is deprecated and has been replaced by `spacing_before`. It will be removed in Spritely 3.0. (called from #{@filename})"

        process_spacing_before_directive(*args)
      end

      def process_spacing_below_directive(*args)
        Spritely.logger.warn "The `spacing_below` directive is deprecated and has been replaced by `spacing_after`. It will be removed in Spritely 3.0. (called from #{@filename})"

        process_spacing_after_directive(*args)
      end

      # Use `define_method` here because of the dash in the directive name
      define_method("process_spacing-below_directive") do |*args|
        Spritely.logger.warn "The `spacing-below` directive is deprecated and has been replaced by `spacing_after`. It will be removed in Spritely 3.0. (called from #{@filename})"

        process_spacing_after_directive(*args)
      end

      private

      def process_image_option(directive, image, value)
        @sprite_directives[:images][image] ||= {}
        @sprite_directives[:images][image][directive.to_sym] = value
      end

      def process_global_option(directive, value)
        @sprite_directives[:global][directive.to_sym] = value
      end

      def merge_global_options!
        @sprite_directives[:images].each do |image, options|
          options.merge!(@sprite_directives[:global]) { |key, left, right| left }
        end
      end
    end
  end
end