Class: HTMLProofer::Element

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/html-proofer/element.rb

Overview

Represents the element currently being processed

Direct Known Subclasses

OpenGraphElement

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#create_nokogiri, #pluralize, #swap

Constructor Details

#initialize(obj, check) ⇒ Element

Returns a new instance of Element.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/html-proofer/element.rb', line 13

def initialize(obj, check)
  # Construct readable ivars for every element
  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

  @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

Instance Attribute Details

#altObject (readonly)

Returns the value of attribute alt.



11
12
13
# File 'lib/html-proofer/element.rb', line 11

def alt
  @alt
end

#data_proofer_ignoreObject (readonly)

Returns the value of attribute data_proofer_ignore.



11
12
13
# File 'lib/html-proofer/element.rb', line 11

def data_proofer_ignore
  @data_proofer_ignore
end

#hrefObject (readonly)

Returns the value of attribute href.



11
12
13
# File 'lib/html-proofer/element.rb', line 11

def href
  @href
end

#idObject (readonly)

Returns the value of attribute id.



11
12
13
# File 'lib/html-proofer/element.rb', line 11

def id
  @id
end

#lineObject (readonly)

Returns the value of attribute line.



11
12
13
# File 'lib/html-proofer/element.rb', line 11

def line
  @line
end

Returns the value of attribute link.



11
12
13
# File 'lib/html-proofer/element.rb', line 11

def link
  @link
end

#nameObject (readonly)

Returns the value of attribute name.



11
12
13
# File 'lib/html-proofer/element.rb', line 11

def name
  @name
end

#srcObject (readonly)

Returns the value of attribute src.



11
12
13
# File 'lib/html-proofer/element.rb', line 11

def src
  @src
end

Instance Method Details

#absolute_pathObject



207
208
209
210
# File 'lib/html-proofer/element.rb', line 207

def absolute_path
  path = file_path || @check.path
  File.expand_path path, Dir.pwd
end

#allow_hash_href?Boolean

Returns:

  • (Boolean)


125
126
127
# File 'lib/html-proofer/element.rb', line 125

def allow_hash_href?
  @check.options[:allow_hash_href]
end

#allow_missing_href?Boolean

Returns:

  • (Boolean)


121
122
123
# File 'lib/html-proofer/element.rb', line 121

def allow_missing_href?
  @check.options[:allow_missing_href]
end

#baseObject



232
233
234
# File 'lib/html-proofer/element.rb', line 232

def base
  @base ||= @html.at_css('base')
end

#check_img_http?Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/html-proofer/element.rb', line 129

def check_img_http?
  @check.options[:check_img_http]
end

#check_sri?Boolean

Returns:

  • (Boolean)


133
134
135
# File 'lib/html-proofer/element.rb', line 133

def check_sri?
  @check.options[:check_sri]
end

#exists?Boolean

checks if a file exists relative to the current pwd

Returns:

  • (Boolean)


201
202
203
204
205
# File 'lib/html-proofer/element.rb', line 201

def exists?
  return @checked_paths[absolute_path] if @checked_paths.key? absolute_path

  @checked_paths[absolute_path] = File.exist? absolute_path
end

#external?Boolean

path is external to the file

Returns:

  • (Boolean)


138
139
140
# File 'lib/html-proofer/element.rb', line 138

def external?
  !internal?
end

#file_pathObject



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/html-proofer/element.rb', line 168

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?Boolean

Returns:

  • (Boolean)


228
229
230
# File 'lib/html-proofer/element.rb', line 228

def follow_location?
  @check.options[:typhoeus] && @check.options[:typhoeus][:followlocation]
end

#hashObject



81
82
83
# File 'lib/html-proofer/element.rb', line 81

def hash
  parts&.fragment
end


160
161
162
# File 'lib/html-proofer/element.rb', line 160

def hash_link
  url.start_with?('#')
end

#htmlObject



236
237
238
239
240
241
242
243
244
245
246
# File 'lib/html-proofer/element.rb', line 236

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?Boolean

Returns:

  • (Boolean)


98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/html-proofer/element.rb', line 98

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?Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/html-proofer/element.rb', line 113

def ignore_alt?
  return true if ignores_pattern_check(@check.options[:alt_ignore]) || @aria_hidden
end

#ignore_empty_alt?Boolean

Returns:

  • (Boolean)


117
118
119
# File 'lib/html-proofer/element.rb', line 117

def ignore_empty_alt?
  @check.options[:empty_alt_ignore]
end

#ignores_pattern_check(links) ⇒ Object



212
213
214
215
216
217
218
219
220
221
222
# File 'lib/html-proofer/element.rb', line 212

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?Boolean

Returns:

  • (Boolean)


142
143
144
# File 'lib/html-proofer/element.rb', line 142

def internal?
  relative_link? || internal_absolute_link?
end

#internal_absolute_link?Boolean

Returns:

  • (Boolean)


146
147
148
# File 'lib/html-proofer/element.rb', line 146

def internal_absolute_link?
  url.start_with?('/')
end

Returns:

  • (Boolean)


156
157
158
# File 'lib/html-proofer/element.rb', line 156

def link_points_to_same_page?
  hash_link || param_link
end

#non_http_remote?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/html-proofer/element.rb', line 94

def non_http_remote?
  !scheme.nil? && !remote?
end


164
165
166
# File 'lib/html-proofer/element.rb', line 164

def param_link
  url.start_with?('?')
end

#partsObject



71
72
73
74
75
# File 'lib/html-proofer/element.rb', line 71

def parts
  @parts ||= Addressable::URI.parse url
rescue URI::Error, Addressable::URI::InvalidURIError
  @parts = nil
end

#pathObject



77
78
79
# File 'lib/html-proofer/element.rb', line 77

def path
  Addressable::URI.unencode parts.path unless parts.nil?
end

#relative_link?Boolean

Returns:

  • (Boolean)


150
151
152
153
154
# File 'lib/html-proofer/element.rb', line 150

def relative_link?
  return false if remote?

  hash_link || param_link || url.start_with?('.') || url =~ /^\S/
end

#remote?Boolean

path is to an external server

Returns:

  • (Boolean)


90
91
92
# File 'lib/html-proofer/element.rb', line 90

def remote?
  %w[http https].include? scheme
end

#schemeObject



85
86
87
# File 'lib/html-proofer/element.rb', line 85

def scheme
  parts&.scheme
end

#unslashed_directory?(file) ⇒ Boolean

Returns:

  • (Boolean)


224
225
226
# File 'lib/html-proofer/element.rb', line 224

def unslashed_directory?(file)
  File.directory?(file) && !file.end_with?(File::SEPARATOR) && !follow_location?
end

#urlObject



57
58
59
60
61
62
63
64
65
# File 'lib/html-proofer/element.rb', line 57

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?Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/html-proofer/element.rb', line 67

def valid?
  !parts.nil?
end