57 lines
1.2 KiB
Ruby
57 lines
1.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Repubmark
|
|
module Elems
|
|
class Link < Text
|
|
parents :Joint
|
|
|
|
SCHEMES = %w[http https].freeze
|
|
|
|
def initialize(parent, str, uri, **kwargs)
|
|
super parent, str, **kwargs
|
|
|
|
self.uri = uri
|
|
validate_uri!
|
|
end
|
|
|
|
#################
|
|
# Basic methods #
|
|
#################
|
|
|
|
def to_html
|
|
"<a href=\"#{build_uri('.html')}\">#{str_to_html}</a>".freeze
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :uri
|
|
|
|
def uri=(uri)
|
|
@uri = URI.parse(uri).freeze
|
|
end
|
|
|
|
def validate_uri!
|
|
raise 'Expected normalized URI' unless uri.normalize == uri
|
|
raise 'Expected no userinfo' unless uri.userinfo.nil?
|
|
|
|
validate_uri_http_absolute!
|
|
end
|
|
|
|
def validate_uri_http_absolute!
|
|
return unless uri.is_a?(URI::HTTP) && uri.absolute?
|
|
|
|
raise 'Invalid scheme' unless SCHEMES.include? uri.scheme
|
|
raise 'Expected hostname' unless uri.hostname
|
|
end
|
|
|
|
def build_uri(ext)
|
|
if uri.is_a?(URI::MailTo) || uri.absolute?
|
|
uri
|
|
else
|
|
own_url "#{uri}#{ext}"
|
|
end.to_s.freeze
|
|
end
|
|
end
|
|
end
|
|
end
|