class Hatemile::Implementation::AccessibleFormImplementation

The AccessibleFormImplementation class is official implementation of AccessibleForm interface.

Constants

DATETIME_FIELDS_LIST

The client-site datetime fields list.

DATE_FIELDS_LIST

The client-site date fields list.

EMAIL_FIELDS_LIST

The client-site email fields list.

ID_SCRIPT_EXECUTE_VALIDATION

The ID of script element that execute validations on fields.

ID_SCRIPT_LIST_VALIDATION_FIELDS

The ID of script element that contains the list of IDs of fields with validation.

LIMITED_FIELDS_LIST

The client-site fields with length list.

MONTH_FIELDS_LIST

The client-site month fields list.

PATTERN_FIELDS_LIST

The client-site pattern fields list.

RANGE_FIELDS_LIST

The client-site range fields list.

REQUIRED_FIELDS_LIST

The client-site required fields list.

TIME_FIELDS_LIST

The client-site time fields list.

URL_FIELDS_LIST

The client-site URL fields list.

WEEK_FIELDS_LIST

The client-site week fields list.

Public Class Methods

new(parser) click to toggle source

Initializes a new object that manipulate the accessibility of the forms of parser.

@param parser [Hatemile::Util::Html::HTMLDOMParser] The HTML parser.

# File lib/hatemile/implementation/accessible_form_implementation.rb, line 239
def initialize(parser)
  Hatemile::Helper.require_not_nil(parser)
  Hatemile::Helper.require_valid_type(
    parser,
    Hatemile::Util::Html::HTMLDOMParser
  )

  @parser = parser
  @id_generator = Hatemile::Util::IDGenerator.new('form')
  @scripts_added = false
  @script_list_fields_with_validation = nil
end

Public Instance Methods

mark_all_autocomplete_fields() click to toggle source

@see Hatemile::AccessibleForm#mark_all_autocomplete_fields

# File lib/hatemile/implementation/accessible_form_implementation.rb, line 312
def mark_all_autocomplete_fields
  elements = @parser.find(
    'input[autocomplete],textarea[autocomplete],form[autocomplete] ' \
    'input,form[autocomplete] textarea,[list],[form]'
  ).list_results
  elements.each do |element|
    if Hatemile::Util::CommonFunctions.is_valid_element?(element)
      mark_autocomplete_field(element)
    end
  end
end
mark_all_invalid_fields() click to toggle source

@see Hatemile::AccessibleForm#mark_all_invalid_fields

# File lib/hatemile/implementation/accessible_form_implementation.rb, line 368
def mark_all_invalid_fields
  fields = @parser.find(
    '[required],input[pattern],input[minlength],input[maxlength],' \
    'textarea[minlength],textarea[maxlength],input[type=week],' \
    'input[type=month],input[type=datetime-local],' \
    'input[type=datetime],input[type=time],input[type=date],' \
    'input[type=number],input[type=range],input[type=email],' \
    'input[type=url],[aria-required=true],input[aria-valuemin],' \
    'input[aria-valuemax]'
  ).list_results
  fields.each do |field|
    if Hatemile::Util::CommonFunctions.is_valid_element?(field)
      mark_invalid_field(field)
    end
  end
end
mark_all_range_fields() click to toggle source

@see Hatemile::AccessibleForm#mark_all_range_fields

# File lib/hatemile/implementation/accessible_form_implementation.rb, line 291
def mark_all_range_fields
  range_fields = @parser.find('[min],[max]').list_results
  range_fields.each do |range_field|
    if Hatemile::Util::CommonFunctions.is_valid_element?(range_field)
      mark_range_field(range_field)
    end
  end
end
mark_all_required_fields() click to toggle source

@see Hatemile::AccessibleForm#mark_all_required_fields

# File lib/hatemile/implementation/accessible_form_implementation.rb, line 262
def mark_all_required_fields
  required_fields = @parser.find('[required]').list_results
  required_fields.each do |required_field|
    if Hatemile::Util::CommonFunctions.is_valid_element?(required_field)
      mark_required_field(required_field)
    end
  end
end
mark_autocomplete_field(autocomplete_field) click to toggle source

@see Hatemile::AccessibleForm#mark_autocomplete_field

# File lib/hatemile/implementation/accessible_form_implementation.rb, line 302
def mark_autocomplete_field(autocomplete_field)
  aria_autocomplete = get_aria_autocomplete(autocomplete_field)

  return if aria_autocomplete.nil?

  autocomplete_field.set_attribute('aria-autocomplete', aria_autocomplete)
end
mark_invalid_field(field) click to toggle source

@see Hatemile::AccessibleForm#mark_invalid_field

# File lib/hatemile/implementation/accessible_form_implementation.rb, line 326
def mark_invalid_field(field)
  if field.has_attribute?('required') ||
     (
       field.has_attribute?('aria-required') &&
       field.get_attribute('aria-required').casecmp('true').zero?
     )
    validate(field, REQUIRED_FIELDS_LIST)
  end
  validate(field, PATTERN_FIELDS_LIST) if field.has_attribute?('pattern')
  if field.has_attribute?('minlength') ||
     field.has_attribute?('maxlength')
    validate(field, LIMITED_FIELDS_LIST)
  end
  if field.has_attribute?('aria-valuemin') ||
     field.has_attribute?('aria-valuemax')
    validate(field, RANGE_FIELDS_LIST)
  end

  return unless field.has_attribute?('type')

  type_field = field.get_attribute('type').downcase
  if type_field == 'week'
    validate(field, WEEK_FIELDS_LIST)
  elsif type_field == 'month'
    validate(field, MONTH_FIELDS_LIST)
  elsif %w[datetime-local datetime].include?(type_field)
    validate(field, DATETIME_FIELDS_LIST)
  elsif type_field == 'time'
    validate(field, TIME_FIELDS_LIST)
  elsif type_field == 'date'
    validate(field, DATE_FIELDS_LIST)
  elsif %w[number range].include?(type_field)
    validate(field, RANGE_FIELDS_LIST)
  elsif type_field == 'email'
    validate(field, EMAIL_FIELDS_LIST)
  elsif type_field == 'url'
    validate(field, AccessibleFormImplementation.URL_FIELDS_LIST)
  end
end
mark_range_field(range_field) click to toggle source

@see Hatemile::AccessibleForm#mark_range_field

# File lib/hatemile/implementation/accessible_form_implementation.rb, line 273
def mark_range_field(range_field)
  if range_field.has_attribute?('min')
    range_field.set_attribute(
      'aria-valuemin',
      range_field.get_attribute('min')
    )
  end

  return unless range_field.has_attribute?('max')

  range_field.set_attribute(
    'aria-valuemax',
    range_field.get_attribute('max')
  )
end
mark_required_field(required_field) click to toggle source

@see Hatemile::AccessibleForm#mark_required_field

# File lib/hatemile/implementation/accessible_form_implementation.rb, line 254
def mark_required_field(required_field)
  return unless required_field.has_attribute?('required')

  required_field.set_attribute('aria-required', 'true')
end

Protected Instance Methods

generate_validation_scripts() click to toggle source

Include the scripts used by solutions.

# File lib/hatemile/implementation/accessible_form_implementation.rb, line 151
def generate_validation_scripts
  local = @parser.find('head,body').first_result
  unless local.nil?
    if @parser.find(
      "##{AccessibleEventImplementation::ID_SCRIPT_COMMON_FUNCTIONS}"
    ).first_result.nil?
      common_functions_script = @parser.create_element('script')
      common_functions_script.set_attribute(
        'id',
        AccessibleEventImplementation::ID_SCRIPT_COMMON_FUNCTIONS
      )
      common_functions_script.set_attribute('type', 'text/javascript')
      common_functions_script.append_text(
        File.read(
          File.join(
            File.dirname(File.dirname(File.dirname(__FILE__))),
            'js',
            'common.js'
          )
        )
      )
      local.prepend_element(common_functions_script)
    end
  end
  @script_list_fields_with_validation = @parser.find(
    "##{ID_SCRIPT_LIST_VALIDATION_FIELDS}"
  ).first_result
  if @script_list_fields_with_validation.nil?
    @script_list_fields_with_validation = @parser.create_element('script')
    @script_list_fields_with_validation.set_attribute(
      'id',
      ID_SCRIPT_LIST_VALIDATION_FIELDS
    )
    @script_list_fields_with_validation.set_attribute(
      'type',
      'text/javascript'
    )
    @script_list_fields_with_validation.append_text(
      File.read(
        File.join(
          File.dirname(File.dirname(File.dirname(__FILE__))),
          'js',
          'scriptlist_validation_fields.js'
        )
      )
    )
    local.append_element(@script_list_fields_with_validation)
  end
  if @parser.find("##{ID_SCRIPT_EXECUTE_VALIDATION}").first_result.nil?
    script_function = @parser.create_element('script')
    script_function.set_attribute('id', ID_SCRIPT_EXECUTE_VALIDATION)
    script_function.set_attribute('type', 'text/javascript')
    script_function.append_text(
      File.read(
        File.join(
          File.dirname(File.dirname(File.dirname(__FILE__))),
          'js',
          'validation.js'
        )
      )
    )
    @parser.find('body').first_result.append_element(script_function)
  end
  @scripts_added = true
end
get_aria_autocomplete(field) click to toggle source

Returns the appropriate value for attribute aria-autocomplete of field.

@param field [Hatemile::Util::Html::HTMLDOMElement] The field. @return [String] The ARIA value of field.

# File lib/hatemile/implementation/accessible_form_implementation.rb, line 103
def get_aria_autocomplete(field)
  tag_name = field.get_tag_name
  type = nil
  if field.has_attribute?('type')
    type = field.get_attribute('type').downcase
  end
  if (tag_name == 'TEXTAREA') ||
     (
       (tag_name == 'INPUT') &&
       !(
         (type == 'button') ||
         (type == 'submit') ||
         (type == 'reset') ||
         (type == 'image') ||
         (type == 'file') ||
         (type == 'checkbox') ||
         (type == 'radio') ||
         (type == 'hidden')
       )
     )
    value = nil
    if field.has_attribute?('list')
      list_id = field.get_attribute('list')
      unless @parser.find("datalist[id=\"#{list_id}\"]").first_result.nil?
        return 'list'
      end
    end
    if field.has_attribute?('autocomplete')
      value = field.get_attribute('autocomplete').downcase
    else
      form = @parser.find(field).find_ancestors('form').first_result
      if form.nil? && field.has_attribute?('form')
        form = @parser.find(
          "##{field.get_attribute('form')}"
        ).first_result
      end
      if !form.nil? && form.has_attribute?('autocomplete')
        value = form.get_attribute('autocomplete').downcase
      end
    end
    return 'both' if value == 'on'
    return 'none' if value == 'off'
  end
  nil
end
validate(field, list_attribute) click to toggle source

Validate the field when its value change.

@param field [Hatemile::Util::Html::HTMLDOMElement] The field. @param list_attribute [String] The list attribute of field with

validation.
# File lib/hatemile/implementation/accessible_form_implementation.rb, line 223
def validate(field, list_attribute)
  generate_validation_scripts unless @scripts_added
  @id_generator.generate_id(field)
  @script_list_fields_with_validation.append_text(
    "hatemileValidationList.#{list_attribute}.push(" \
    "'#{field.get_attribute('id')}');"
  )
end