require 'hanami/helpers/html_helper'
module Hanami
module Helpers
# LinkTo Helper
#
# Including Hanami::Helpers::LinkTo will include the
# link_to public method.
#
# This helper can be used both in views and templates.
#
# @since 0.2.0
module LinkToHelper
include Hanami::Helpers::HtmlHelper
# Generates an anchor tag for the given arguments.
#
# Contents are automatically escaped.
#
# @overload link_to(content, url, options)
# Use string as content
# @param content [String] content used in the a tag
# @param url [String] url used in href attribute
# @param options [Hash] HTML attributes to pass to the a tag
#
# @overload link_to(url, options, &blk)
# Use block as content
# @param url [String] url used in href attribute
# @param options [Hash] HTML attributes to pass to the a tag
# @param blk [Proc] A block that describes the contents of the a tag
#
# @return [String] HTML markup for the link
#
# @raise [ArgumentError] if the signature isn't respected
#
# @since 0.2.0
#
# @see Hanami::Helpers::HtmlHelper#html
#
# @example Both content and URL are strings
# <%= link_to('Home', '/') %>
# # => Home
#
# @example Content string with route helper
# <%= link_to('Home', routes.path(:home)) %>
# # => Home
#
# @example HTML attributes
# <%= link_to('Home', routes.path(:home), class: 'button') %>
# # => Home
#
# @example Automatic content escape (XSS protection)
# <%= link_to(%(), '/') %>
# # => <script>alert('xss')</script>
#
# @example Automatic content block escape (XSS protection)
# <%=
# link_to('/') do
# %()
# end
# %>
# # => \n<script>alert('xss')</script>\n
#
# @example Content as block with string URL
# <%=
# link_to('/') do
# 'Home'
# end
# %>
# # => Home
#
# @example Content as block
# <%=
# link_to(routes.path(:home)) do
# 'Home'
# end
# %>
# # => Home
#
# @example Content as block with HTML attributes
# <%=
# link_to(routes.path(:home), id: 'home-link') do
# 'Home'
# end
# %>
# # => Home
#
# @example Content as HTML builder block
# <%=
# link_to(routes.path(:home)) do
# strong 'Home'
# end
# %>
# # => Home
#
# @example Provides both content as first argument and block
# <%=
# link_to('Home', routes.path(:home)) do
# strong 'Home'
# end
# %>
# # => ArgumentError
#
# @example Without any argument
# <%= link_to %>
# # => ArgumentError
#
# @example Without any argument and empty block
# <%=
# link_to do
# end
# %>
# # => ArgumentError
#
# @example With only content
# <%= link_to 'Home' %>
# # => ArgumentError
def link_to(content, url = nil, options = {}, &blk)
if block_given?
options = url || {}
url = content
content = nil
end
begin
options[:href] = url or raise ArgumentError
rescue TypeError
raise ArgumentError
end
html.a(blk || content, options).to_s
end
end
end
end