module Exclaim::UiConfiguration

Constants

EXPLICIT_ELEMENT_NAMES

Public Instance Methods

parse!(implementation_map, ui_config) click to toggle source
# File lib/exclaim/ui_configuration.rb, line 9
def parse!(implementation_map, ui_config)
  raise UiConfigurationError.new("ui_config must be a Hash, given: #{ui_config.class}") unless ui_config.is_a?(Hash)

  parsed_ui = parse_config_value(implementation_map, ui_config)

  unless parsed_ui.is_a?(Exclaim::Component)
    error_message = 'ui_config must declare a component at the top-level that is present in implementation_map'
    raise UiConfigurationError.new(error_message)
  end

  parsed_ui
end

Private Instance Methods

component?(element) click to toggle source
# File lib/exclaim/ui_configuration.rb, line 123
def component?(element)
  element_type(element) == 'component'
end
element_type(element) click to toggle source
# File lib/exclaim/ui_configuration.rb, line 131
def element_type(element)
  if element.respond_to?(:component?)
    element.component? ? 'component' : 'helper'
  elsif element.respond_to?(:helper?)
    element.helper? ? 'helper' : 'component'
  end
end
helper?(element) click to toggle source
# File lib/exclaim/ui_configuration.rb, line 127
def helper?(element)
  element_type(element) == 'helper'
end
parse_config_hash(implementation_map, config_hash) click to toggle source
# File lib/exclaim/ui_configuration.rb, line 35
def parse_config_hash(implementation_map, config_hash)
  # config_hash will be either an Exclaim element declaration or just plain configuration values
  element_name = parse_element_name(implementation_map, config_hash)
  if element_name.nil?
    config_hash.transform_values { |val| parse_config_value(implementation_map, val) }
  else
    parse_element(implementation_map, element_name, config_hash)
  end
end
parse_config_value(implementation_map, config_value) click to toggle source
# File lib/exclaim/ui_configuration.rb, line 24
def parse_config_value(implementation_map, config_value)
  case config_value
  in Hash => hash
    parse_config_hash(implementation_map, hash)
  in Array => array
    array.map { |value| parse_config_value(implementation_map, value) }
  else
    config_value
  end
end
parse_element(implementation_map, element_name, element_declaration_hash) click to toggle source
# File lib/exclaim/ui_configuration.rb, line 45
def parse_element(implementation_map, element_name, element_declaration_hash)
  implementation = implementation_map[element_name]

  if helper?(implementation)
    config = parse_element_config(implementation_map, element_declaration_hash)
    Exclaim::Helper.new(json_declaration: element_declaration_hash,
                        name: element_name,
                        implementation: implementation,
                        config: config)
  elsif component?(implementation)
    config = parse_element_config(implementation_map, element_declaration_hash)
    Exclaim::Component.new(json_declaration: element_declaration_hash,
                           name: element_name,
                           implementation: implementation,
                           config: config)
  else
    Exclaim::Bind.new(json_declaration: element_declaration_hash, path: element_declaration_hash['$bind'])
  end
end
parse_element_config(implementation_map, element_declaration_hash) click to toggle source
# File lib/exclaim/ui_configuration.rb, line 65
def parse_element_config(implementation_map, element_declaration_hash)
  element_declaration_hash.each_with_object({}) do |(key, val), parsed_element_config|
    parsed_element_config[key] = if ['$component', '$helper'].include?(key)
                                   val
                                 else
                                   parse_config_value(implementation_map, val)
                                 end
  end
end
parse_element_name(implementation_map, config_hash) click to toggle source
# File lib/exclaim/ui_configuration.rb, line 75
def parse_element_name(implementation_map, config_hash)
  candidate_names = config_hash.keys.filter_map do |key|
    key[1..] if key.start_with?('$') && !EXPLICIT_ELEMENT_NAMES.include?(key)
  end
  candidate_names.reject! do |name|
    unrecognized = implementation_map[name].nil?
    Exclaim.logger.warn("ui_config includes key \"$#{name}\" which has no matching implementation") if unrecognized
    unrecognized
  end

  explicit_component_name = parse_explicit_declaration(implementation_map, config_hash, '$component')
  explicit_helper_name = parse_explicit_declaration(implementation_map, config_hash, '$helper')

  candidate_names.push(explicit_component_name, explicit_helper_name)
  candidate_names.compact!

  # binds do not have implementations, but they are still special Exclaim elements
  candidate_names.push('bind') if config_hash.include?('$bind')

  if candidate_names.count > 1
    error_message = "Multiple Exclaim elements defined at one configuration level: #{candidate_names}. " \
                    'Only one allowed.'
    raise UiConfigurationError.new(error_message)
  end

  # returns nil when config_hash is not an Exclaim element declaration
  candidate_names.first
end
parse_explicit_declaration(implementation_map, config_hash, explicit_key) click to toggle source
# File lib/exclaim/ui_configuration.rb, line 104
def parse_explicit_declaration(implementation_map, config_hash, explicit_key)
  explicit_name = config_hash[explicit_key]
  return nil if explicit_name.nil?

  if explicit_name.start_with?('$')
    error_message = "Invalid: \"#{explicit_key}\": \"#{explicit_name}\", " \
                    "when declaring explicit \"#{explicit_key}\" do not prefix the name with \"$\""
    raise UiConfigurationError.new(error_message)
  end

  if implementation_map[explicit_name].nil?
    error_message = "ui_config declares \"#{explicit_key}\": \"#{explicit_name}\" " \
                    'which has no matching implementation'
    raise UiConfigurationError.new(error_message)
  end

  explicit_name
end