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

Resurrect Ruby implementation of AttributeBuilder

This commit is contained in:
Takashi Kokubun 2018-11-01 15:30:12 +09:00
parent df6493b3f7
commit 0ec2d61c04

View file

@ -1,8 +1,4 @@
# frozen_string_literal: true
unless /java/ === RUBY_PLATFORM # exclude JRuby
require 'hamlit/hamlit'
end
require 'hamlit/utils'
require 'hamlit/object_ref'
module Hamlit::AttributeBuilder
@ -12,4 +8,161 @@ module Hamlit::AttributeBuilder
autofocus novalidate formnovalidate open pubdate
itemscope allowfullscreen default inert sortable
truespeed typemustmatch download].freeze
if /java/ === RUBY_PLATFORM # JRuby
class << self
def build(escape_attrs, quote, format, object_ref, *hashes)
hashes << Hamlit::ObjectRef.parse(object_ref) if object_ref
buf = []
hash = merge_all_attrs(hashes)
keys = hash.keys.sort!
keys.each do |key|
case key
when 'id'.freeze
buf << " id=#{quote}#{build_id(escape_attrs, *hash[key])}#{quote}"
when 'class'.freeze
buf << " class=#{quote}#{build_class(escape_attrs, *hash[key])}#{quote}"
when 'data'.freeze
buf << build_data(escape_attrs, quote, *hash[key])
when *BOOLEAN_ATTRIBUTES, /\Adata-/
build_boolean!(escape_attrs, quote, format, buf, key, hash[key])
else
buf << " #{key}=#{quote}#{escape_html(escape_attrs, hash[key].to_s)}#{quote}"
end
end
buf.join
end
def build_id(escape_attrs, *values)
escape_html(escape_attrs, values.flatten.select { |v| v }.join('_'))
end
def build_class(escape_attrs, *values)
if values.size == 1
value = values.first
case
when value.is_a?(String)
# noop
when value.is_a?(Array)
value = value.flatten.select { |v| v }.map(&:to_s).sort.uniq.join(' ')
when value
value = value.to_s
else
return ''
end
return escape_html(escape_attrs, value)
end
classes = []
values.each do |value|
case
when value.is_a?(String)
classes += value.split(' ')
when value.is_a?(Array)
classes += value.select { |v| v }
when value
classes << value.to_s
end
end
escape_html(escape_attrs, classes.map(&:to_s).sort.uniq.join(' '))
end
def build_data(escape_attrs, quote, *hashes)
build_data_attribute(:data, escape_attrs, quote, *hashes)
end
def build_aria(escape_attrs, quote, *hashes)
build_data_attribute(:aria, escape_attrs, quote, *hashes)
end
private
def build_data_attribute(key, escape_attrs, quote, *hashes)
attrs = []
hash = flatten_attributes(key => hashes.first)
hash.sort_by(&:first).each do |key, value|
case value
when true
attrs << " #{key}"
when nil, false
# noop
else
attrs << " #{key}=#{quote}#{escape_html(escape_attrs, value.to_s)}#{quote}"
end
end
attrs.join
end
def flatten_attributes(attributes)
flattened = {}
attributes.each do |key, value|
case value
when attributes
when Hash
flatten_attributes(value).each do |k, v|
if k
flattened["#{key}-#{k.to_s.gsub(/_/, '-')}"] = v
else
flattened[key] = v
end
end
else
flattened[key] = value if value
end
end
flattened
end
def merge_all_attrs(hashes)
merged = {}
hashes.each do |hash|
hash.each do |key, value|
key = key.to_s
case key
when 'id'.freeze, 'class'.freeze, 'data'.freeze
merged[key] ||= []
merged[key] << value
else
merged[key] = value
end
end
end
merged
end
def build_boolean!(escape_attrs, quote, format, buf, key, value)
case value
when true
case format
when :xhtml
buf << " #{key}=#{quote}#{key}#{quote}"
else
buf << " #{key}"
end
when false, nil
# omitted
else
buf << " #{key}=#{quote}#{escape_html(escape_attrs, value)}#{quote}"
end
end
def escape_html(escape_attrs, str)
if escape_attrs
Hamlit::Utils.escape_html(str)
else
str
end
end
end
else
# Hamlit::AttributeBuilder.build
# Hamlit::AttributeBuilder.build_id
# Hamlit::AttributeBuilder.build_class
# Hamlit::AttributeBuilder.build_data
# Hamlit::AttributeBuilder.build_aria
require 'hamlit/hamlit'
end
end