class HTMLProofer::Element

Represents the element currently being processed

Attributes

alt[R]
data_proofer_ignore[R]
href[R]
id[R]
line[R]
name[R]
src[R]

Public Class Methods

new(obj, check, logger) click to toggle source
# File lib/html-proofer/element.rb, line 12
def initialize(obj, check, logger)
  @logger = logger
  # Construct readable ivars for every element
  begin
    obj.attributes.each_pair do |attribute, value|
      name = attribute.tr('-:.;', '_').to_s.to_sym
      (class << self; self; end).send(:attr_reader, name)
      instance_variable_set("@#{name}", value.value)
    end
  rescue NameError => e
    @logger.log :error, "Attribute set `#{obj}` contains an error!"
    raise e
  end

  @aria_hidden = defined?(@aria_hidden) && @aria_hidden == 'true' ? true : false

  @data_proofer_ignore = defined?(@data_proofer_ignore)

  @text = obj.content
  @check = check
  @checked_paths = {}
  @type = check.class.name
  @line = obj.line

  @html = check.html

  parent_attributes = obj.ancestors.map { |a| a.respond_to?(:attributes) && a.attributes }
  parent_attributes.pop # remove document at the end
  @parent_ignorable = parent_attributes.any? { |a| !a['data-proofer-ignore'].nil? }

  # fix up missing protocols
  if defined?(@href)
    @href.insert(0, 'http:') if @href =~ %r{^//}
  else
    @href = nil
  end

  if defined?(@src)
    @src.insert(0, 'http:') if @src =~ %r{^//}
  else
    @src = nil
  end

  if defined?(@srcset)
    @srcset.insert(0, 'http:') if @srcset =~ %r{^//}
  else
    @srcset = nil
  end
end

Public Instance Methods

absolute_path() click to toggle source
# File lib/html-proofer/element.rb, line 212
def absolute_path
  path = file_path || @check.path
  File.expand_path path, Dir.pwd
end
allow_hash_href?() click to toggle source
# File lib/html-proofer/element.rb, line 130
def allow_hash_href?
  @check.options[:allow_hash_href]
end
allow_missing_href?() click to toggle source
# File lib/html-proofer/element.rb, line 126
def allow_missing_href?
  @check.options[:allow_missing_href]
end
base() click to toggle source
# File lib/html-proofer/element.rb, line 237
def base
  @base ||= @html.at_css('base')
end
check_img_http?() click to toggle source
# File lib/html-proofer/element.rb, line 134
def check_img_http?
  @check.options[:check_img_http]
end
check_sri?() click to toggle source
# File lib/html-proofer/element.rb, line 138
def check_sri?
  @check.options[:check_sri]
end
exists?() click to toggle source

checks if a file exists relative to the current pwd

# File lib/html-proofer/element.rb, line 206
def exists?
  return @checked_paths[absolute_path] if @checked_paths.key? absolute_path

  @checked_paths[absolute_path] = File.exist? absolute_path
end
external?() click to toggle source

path is external to the file

# File lib/html-proofer/element.rb, line 143
def external?
  !internal?
end
file_path() click to toggle source
# File lib/html-proofer/element.rb, line 173
def file_path
  return if path.nil? || path.empty?

  path_dot_ext = ''

  path_dot_ext = path + @check.options[:extension] if @check.options[:assume_extension]

  if path =~ %r{^/} # path relative to root
    if File.directory?(@check.src)
      base = @check.src
    else
      root_dir = @check.options[:root_dir]
      base = root_dir || File.dirname(@check.src)
    end
  elsif File.exist?(File.expand_path(path, @check.src)) || File.exist?(File.expand_path(path_dot_ext, @check.src)) # relative links, path is a file
    base = File.dirname @check.path
  elsif File.exist?(File.join(File.dirname(@check.path), path)) || File.exist?(File.join(File.dirname(@check.path), path_dot_ext)) # relative links in nested dir, path is a file
    base = File.dirname @check.path
  else # relative link, path is a directory
    base = @check.path
  end

  file = File.join base, path
  if @check.options[:assume_extension] && File.file?("#{file}#{@check.options[:extension]}")
    file = "#{file}#{@check.options[:extension]}"
  elsif File.directory?(file) && !unslashed_directory?(file) # implicit index support
    file = File.join file, @check.options[:directory_index_file]
  end

  file
end
follow_location?() click to toggle source
# File lib/html-proofer/element.rb, line 233
def follow_location?
  @check.options[:typhoeus] && @check.options[:typhoeus][:followlocation]
end
hash() click to toggle source
# File lib/html-proofer/element.rb, line 86
def hash
  parts&.fragment
end
html() click to toggle source
# File lib/html-proofer/element.rb, line 241
def html
  # If link is on the same page, then URL is on the current page. use the same HTML as for current page
  if link_points_to_same_page?
    @html
  elsif internal?
    # link on another page, e.g. /about#Team - need to get HTML from the other page
    create_nokogiri(absolute_path)
  else
    raise NotImplementedError, 'HTMLProofer should not have gotten here. Please report this as a bug.'
  end
end
ignore?() click to toggle source
# File lib/html-proofer/element.rb, line 103
def ignore?
  return true if @data_proofer_ignore
  return true if @parent_ignorable

  return true if url =~ /^javascript:/

  # ignore base64 encoded images
  if %w[ImageCheck FaviconCheck].include? @type
    return true if url =~ /^data:image/
  end

  # ignore user defined URLs
  return true if ignores_pattern_check(@check.options[:url_ignore])
end
ignore_alt?() click to toggle source
# File lib/html-proofer/element.rb, line 118
def ignore_alt?
  return true if ignores_pattern_check(@check.options[:alt_ignore]) || @aria_hidden
end
ignore_empty_alt?() click to toggle source
# File lib/html-proofer/element.rb, line 122
def ignore_empty_alt?
  @check.options[:empty_alt_ignore]
end
ignores_pattern_check(links) click to toggle source
# File lib/html-proofer/element.rb, line 217
def ignores_pattern_check(links)
  links.each do |ignore|
    if ignore.is_a? String
      return true if ignore == url
    elsif ignore.is_a? Regexp
      return true if ignore =~ url
    end
  end

  false
end
internal?() click to toggle source
# File lib/html-proofer/element.rb, line 147
def internal?
  relative_link? || internal_absolute_link?
end
non_http_remote?() click to toggle source
# File lib/html-proofer/element.rb, line 99
def non_http_remote?
  !scheme.nil? && !remote?
end
parts() click to toggle source
# File lib/html-proofer/element.rb, line 76
def parts
  @parts ||= Addressable::URI.parse url
rescue URI::Error, Addressable::URI::InvalidURIError
  @parts = nil
end
path() click to toggle source
# File lib/html-proofer/element.rb, line 82
def path
  Addressable::URI.unencode parts.path unless parts.nil?
end
remote?() click to toggle source

path is to an external server

# File lib/html-proofer/element.rb, line 95
def remote?
  %w[http https].include? scheme
end
scheme() click to toggle source
# File lib/html-proofer/element.rb, line 90
def scheme
  parts&.scheme
end
unslashed_directory?(file) click to toggle source
# File lib/html-proofer/element.rb, line 229
def unslashed_directory?(file)
  File.directory?(file) && !file.end_with?(File::SEPARATOR) && !follow_location?
end
url() click to toggle source
# File lib/html-proofer/element.rb, line 62
def url
  return @url if defined?(@url)

  @url = (@src || @srcset || @href || '').delete("\u200b").strip
  @url = Addressable::URI.join(base.attr('href') || '', url).to_s if base
  return @url if @check.options[:url_swap].empty?

  @url = swap(@url, @check.options[:url_swap])
end
valid?() click to toggle source
# File lib/html-proofer/element.rb, line 72
def valid?
  !parts.nil?
end