class RuboCop::Cop::Rails::LinkToBlank

link_to ‘Click here’, url, target: ‘_blank’, rel: ‘noopener’
# good
link_to ‘Click here’, url, target: ‘_blank’
# bad
@example
and could change its location for phishing purposes.
risk as the loaded page will have control over the previous page
`target: ‘_blank’‘ but no `rel: ’noopener’‘. This can be a security
This cop checks for calls to `link_to` that contain a

def add_rel(send_node, offence_node, corrector)

def add_rel(send_node, offence_node, corrector)
  opening_quote = offence_node.children.last.source[0]
  closing_quote = opening_quote == ':' ? '' : opening_quote
  new_rel_exp = ", rel: #{opening_quote}noopener#{closing_quote}"
  range = send_node.arguments.last.source_range
  corrector.insert_after(range, new_rel_exp)
end

def append_to_rel(rel_node, corrector)

def append_to_rel(rel_node, corrector)
  existing_rel = rel_node.children.last.value
  str_range = rel_node.children.last.loc.expression.adjust(
    begin_pos: 1,
    end_pos: -1
  )
  corrector.replace(str_range, "#{existing_rel} noopener")
end

def autocorrect(node)

def autocorrect(node)
  lambda do |corrector|
    send_node = node.parent.parent
    option_nodes = send_node.each_child_node(:hash)
    rel_node = nil
    option_nodes.map(&:children).each do |options|
      rel_node ||= options.find { |o| rel_node?(o) }
    end
    if rel_node
      append_to_rel(rel_node, corrector)
    else
      add_rel(send_node, node, corrector)
    end
  end
end

def contains_noopener?(value)

def contains_noopener?(value)
  return false unless value
  value.to_s.split(' ').include?('noopener')
end

def on_send(node)

def on_send(node)
  return unless node.method?(:link_to)
  option_nodes = node.each_child_node(:hash)
  option_nodes.map(&:children).each do |options|
    blank = options.find { |o| blank_target?(o) }
    if blank && options.none? { |o| includes_noopener?(o) }
      add_offense(blank)
    end
  end
end