1
0
Fork 0
mirror of https://github.com/haml/haml.git synced 2022-11-09 12:33:31 -05:00

Create AttributeBuilder

This commit is contained in:
Takashi Kokubun 2015-10-11 15:31:13 +09:00
parent 522ed5699c
commit afb9bcce1f
4 changed files with 106 additions and 1 deletions

View file

@ -1,2 +1,3 @@
require 'hamlit/attribute_builder'
require 'hamlit/engine'
require 'hamlit/version'

View file

@ -0,0 +1,87 @@
require 'temple/utils'
module Hamlit
class AttributeBuilder
def self.build(quote, *args)
builder = self.new(quote)
builder.build(*args)
end
def initialize(quote)
@quote = quote
end
def build(*args)
result = ''
attributes = args.inject({}) do |attrs, arg|
merge_attributes(attrs, arg)
end
attributes.each do |key, value|
if value == true
result += " #{key}"
next
end
value = refine_joinable_value(key, value) if value.is_a?(Array)
escaped = Temple::Utils.escape_html(value)
result += " #{key}=#{@quote}#{escaped}#{@quote}"
end
result
end
private
def refine_joinable_value(key, value)
case key
when :id
value = value.join('_')
when :class
value = value.join(' ')
else
value
end
end
def merge_attributes(base, target)
result = {}
base = flatten_attributes(base)
target = flatten_attributes(target)
(base.keys | target.keys).each do |key|
result[key] = merge_attribute_value(base, target, key)
end
result
end
def merge_attribute_value(base, target, key)
return target[key] unless base[key]
return base[key] unless target[key]
values = [base[key], target[key]].flatten.compact
case key
when :id
values.join('_')
when :class
values.map(&:to_s).sort.uniq.join(' ')
end
end
def flatten_attributes(attributes)
flattened = {}
attributes.each do |key, value|
case value
when Hash
flatten_attributes(value).each do |k, v|
k = k.to_s.gsub(/_/, '-')
flattened["#{key}-#{k}"] = v if v
end
else
flattened[key] = value if value
end
end
flattened
end
end
end

View file

@ -36,6 +36,9 @@ module Hamlit
def compile_tag(node)
attrs = [:html, :attrs]
node.value[:attributes_hashes].each do |attribute_hash|
attrs << [:dynamic, "::Hamlit::AttributeBuilder.build(\"'\", #{attribute_hash})"]
end
node.value[:attributes].each do |name, value|
attrs << [:html, :attr, name, [:static, value]]
end

View file

@ -29,7 +29,21 @@ module Hamlit
end
def render(scope = Object.new, locals = {}, &block)
eval Engine.new.call(@template)
scope = wrap_binding(scope)
set_locals(locals, scope)
eval(Engine.new.call(@template), scope)
end
private
def wrap_binding(scope)
return scope if scope.is_a?(Binding)
scope.instance_eval { binding }
end
def set_locals(locals, scope)
set_locals = locals.map { |k, v| "#{k} = #{v.inspect}" }.join("\n")
eval(set_locals, scope)
end
end
end