class Phlex::HTML

def _attributes(**attributes)

def _attributes(**attributes)
	if attributes[:href]&.start_with?(/\s*javascript/)
		attributes[:href] = attributes[:href].sub(/^\s*(javascript:)+/, "")
	end
	buffer = +""
	_build_attributes(attributes, buffer: buffer)
	unless self.class.rendered_at_least_once
		Phlex::ATTRIBUTE_CACHE[attributes.hash] = buffer.freeze
	end
	buffer
end

def _build_attributes(attributes, buffer:)

def _build_attributes(attributes, buffer:)
	attributes.each do |k, v|
		next unless v
		name = case k
			when String then k
			when Symbol then k.name.tr("_", "-")
			else k.to_s
		end
		# Detect unsafe attribute names. Attribute names are considered unsafe if they match an event attribute or include unsafe characters.
		if HTML::EVENT_ATTRIBUTES[name] || name.match?(/[<>&"']/)
			raise ArgumentError, "Unsafe attribute name detected: #{k}."
		end
		case v
		when true
			buffer << " " << name
		when String
			buffer << " " << name << '="' << CGI.escape_html(v) << '"'
		when Symbol
			buffer << " " << name << '="' << CGI.escape_html(v.name) << '"'
		when Hash
			_build_attributes(v.transform_keys { "#{k}-#{_1.name.tr('_', '-')}" }, buffer: buffer)
		else
			buffer << " " << name << '="' << CGI.escape_html(v.to_s) << '"'
		end
	end
	buffer
end

def after_template

def after_template
	nil
end

def around_template

def around_template
	before_template
	yield
	after_template
end

def before_template

def before_template
	nil
end

def call(buffer = +"", view_context: nil, parent: nil, &block)

def call(buffer = +"", view_context: nil, parent: nil, &block)
	return buffer unless render?
	raise "The same view instance shouldn't be rendered twice" if rendered?
	@_rendered = true
	@_target = buffer
	@_view_context = view_context
	@_parent = parent
	around_template { template { yield_content(&block) } }
	self.class.rendered_at_least_once ||= true
	buffer
end

def capture(&block)

def capture(&block)
	return unless block_given?
	original_buffer = @_target
	new_buffer = +""
	@_target = new_buffer
	yield
	@_target = original_buffer
	new_buffer
end

def comment(&block)

def comment(&block)
	@_target << "<!-- "
	yield_content(&block)
	@_target << " -->"
	nil
end

def doctype

def doctype
	@_target << DOCTYPE
	nil
end

def format

def format
	:html
end

def render(renderable, *args, **kwargs, &block)

def render(renderable, *args, **kwargs, &block)
	if renderable.is_a?(Phlex::HTML)
		renderable.call(@_target, view_context: @_view_context, parent: self, &block)
	elsif renderable.is_a?(Class) && renderable < Phlex::HTML
		raise ArgumentError, "You tried to render the Phlex view class: #{renderable.name} but you probably meant to render an instance of that class instead."
	else
		raise ArgumentError, "You can't render a #{renderable}."
	end
	nil
end

def render?

def render?
	true
end

def rendered?

def rendered?
	@_rendered ||= false
end

def text(content)

def text(content)
	case content
	when String
		@_target << CGI.escape_html(content)
	when Symbol
		@_target << CGI.escape_html(content.name)
	when Integer, Float
		@_target << CGI.escape_html(content.to_s)
	end
	nil
end

def unsafe_raw(content = nil, &block)

def unsafe_raw(content = nil, &block)
	@_target << (content || instance_exec(&block))
	nil
end

def whitespace

def whitespace
	@_target << " "
	if block_given?
		yield
		@_target << " "
	end
	nil
end

def yield_content(&block)

def yield_content(&block)
	return unless block_given?
	original_length = @_target.length
	content = yield(self)
	unchanged = (original_length == @_target.length)
	if unchanged
		case content
		when String
			@_target << CGI.escape_html(content)
		when Symbol
			@_target << CGI.escape_html(content.name)
		when Integer, Float
			@_target << CGI.escape_html(content.to_s)
		end
	end
	nil
end