mirror of
https://github.com/haml/haml.git
synced 2022-11-09 12:33:31 -05:00
172 lines
4.3 KiB
Ruby
172 lines
4.3 KiB
Ruby
require 'temple/utils'
|
|
|
|
module Hamlit
|
|
class AttributeBuilder
|
|
BOOLEAN_ATTRIBUTES = %w[disabled readonly multiple checked autobuffer
|
|
autoplay controls loop selected hidden scoped async
|
|
defer reversed ismap seamless muted required
|
|
autofocus novalidate formnovalidate open pubdate
|
|
itemscope allowfullscreen default inert sortable
|
|
truespeed typemustmatch data].freeze
|
|
DATA_BOOLEAN_ATTRIBUTES = BOOLEAN_ATTRIBUTES.map { |a| "data-#{a}" }.freeze
|
|
|
|
class << self
|
|
def build(options, *hashes)
|
|
builder = self.new(options)
|
|
builder.build(*hashes)
|
|
end
|
|
|
|
def build_id(*values)
|
|
values.flatten.select { |v| v }.join('_')
|
|
end
|
|
|
|
def build_class(*values)
|
|
classes = []
|
|
values.each do |value|
|
|
case
|
|
when value.is_a?(String)
|
|
classes += value.split(' ')
|
|
when value.is_a?(Array)
|
|
classes += value.select { |a| a }
|
|
when value
|
|
classes << value.to_s
|
|
end
|
|
end
|
|
classes.sort.uniq.join(' ')
|
|
end
|
|
|
|
def build_data(*hashes)
|
|
attrs = []
|
|
hash = flat_hyphenate(*hashes)
|
|
|
|
hash.sort_by(&:first).each do |key, value|
|
|
case key
|
|
when nil
|
|
attrs << " data='".freeze
|
|
attrs << Temple::Utils.escape_html(value.to_s)
|
|
attrs << "'".freeze
|
|
when *BOOLEAN_ATTRIBUTES
|
|
if value
|
|
attrs << ' data-'.freeze
|
|
attrs << key
|
|
end
|
|
else
|
|
attrs << ' data-'.freeze
|
|
attrs << key
|
|
attrs << "='".freeze
|
|
attrs << Temple::Utils.escape_html(value.to_s)
|
|
attrs << "'".freeze
|
|
end
|
|
end
|
|
attrs.join
|
|
end
|
|
|
|
private
|
|
|
|
def escape_html(value)
|
|
Temple::Utils.escape_html(value)
|
|
end
|
|
|
|
def flat_hyphenate(*hashes)
|
|
result = {}
|
|
hashes.each do |hash|
|
|
unless hash.is_a?(Hash)
|
|
result[nil] = hash
|
|
next
|
|
end
|
|
|
|
hash.each do |key, value|
|
|
key = key.to_s.tr('_'.freeze, '-'.freeze) unless key.nil?
|
|
case value
|
|
when hash
|
|
when Hash
|
|
key = '' if key.nil?
|
|
flat_hyphenate(value).each do |k, v|
|
|
result[key << '-'.freeze << k] = v
|
|
end
|
|
else
|
|
result[key] = value
|
|
end
|
|
end
|
|
end
|
|
result
|
|
end
|
|
end
|
|
|
|
def initialize(options)
|
|
@quote = options[:quote]
|
|
@format = options[:format]
|
|
@escape_attrs = options[:escape_attrs]
|
|
end
|
|
|
|
def build(*hashes)
|
|
buf = []
|
|
hashes = hashes.map { |h| stringify_keys(h) }
|
|
|
|
keys = hashes.map(&:keys).flatten.sort.uniq
|
|
keys.each do |key|
|
|
values = hashes.map { |h| h[key] }.compact
|
|
case key
|
|
when 'id'.freeze
|
|
build_id!(buf, values)
|
|
when 'class'.freeze
|
|
build_class!(buf, values)
|
|
when 'data'.freeze
|
|
build_data!(buf, values)
|
|
when *BOOLEAN_ATTRIBUTES, *DATA_BOOLEAN_ATTRIBUTES
|
|
build_boolean!(buf, key, values)
|
|
else
|
|
build_common!(buf, key, values)
|
|
end
|
|
end
|
|
buf.join
|
|
end
|
|
|
|
private
|
|
|
|
def stringify_keys(hash)
|
|
result = {}
|
|
hash.each do |key, value|
|
|
result[key.to_s] = value
|
|
end
|
|
result
|
|
end
|
|
|
|
def build_id!(buf, values)
|
|
buf << ' id='.freeze
|
|
buf << @quote
|
|
buf << AttributeBuilder.build_id(*values)
|
|
buf << @quote
|
|
end
|
|
|
|
def build_class!(buf, values)
|
|
buf << ' class='.freeze
|
|
buf << @quote
|
|
buf << AttributeBuilder.build_class(*values)
|
|
buf << @quote
|
|
end
|
|
|
|
def build_data!(buf, values)
|
|
buf << AttributeBuilder.build_data(*values)
|
|
end
|
|
|
|
def build_boolean!(buf, key, values)
|
|
value = values.last
|
|
if value
|
|
buf << ' '.freeze
|
|
buf << key
|
|
end
|
|
end
|
|
|
|
def build_common!(buf, key, values)
|
|
buf << ' '.freeze
|
|
buf << key
|
|
buf << '='.freeze
|
|
buf << @quote
|
|
value = values.first.to_s
|
|
value = Temple::Utils.escape_html(value) if @escape_attrs
|
|
buf << value
|
|
buf << @quote
|
|
end
|
|
end
|
|
end
|