mirror of
https://github.com/haml/haml.git
synced 2022-11-09 12:33:31 -05:00
Consider about runtime attribute nesting
But accepting all attribute nesting will cause performance regression. So I decided to accept runtime nesting for only 'data'. Fixes #1.
This commit is contained in:
parent
d333f586df
commit
600b03d484
3 changed files with 33 additions and 1 deletions
|
@ -22,6 +22,11 @@ module Hamlit
|
||||||
def build(attributes)
|
def build(attributes)
|
||||||
result = ''
|
result = ''
|
||||||
flatten_attributes(attributes).each do |key, value|
|
flatten_attributes(attributes).each do |key, value|
|
||||||
|
if value == true
|
||||||
|
result += " #{key}"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
escaped = Temple::Utils.escape_html(value)
|
escaped = Temple::Utils.escape_html(value)
|
||||||
result += " #{key}=#{@quote}#{escaped}#{@quote}"
|
result += " #{key}=#{@quote}#{escaped}#{@quote}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,22 +6,32 @@ require 'hamlit/concerns/ripperable'
|
||||||
# This module compiles only old-style attribute, which is
|
# This module compiles only old-style attribute, which is
|
||||||
# surrounded by brackets.
|
# surrounded by brackets.
|
||||||
module Hamlit
|
module Hamlit
|
||||||
|
# This error is raised when hamlit copmiler decide to
|
||||||
|
# copmile the attributes on runtime.
|
||||||
|
class RuntimeBuild < StandardError; end
|
||||||
|
|
||||||
module Compilers
|
module Compilers
|
||||||
module OldAttribute
|
module OldAttribute
|
||||||
include Concerns::AttributeBuilder
|
include Concerns::AttributeBuilder
|
||||||
include Concerns::Balanceable
|
include Concerns::Balanceable
|
||||||
include Concerns::Ripperable
|
include Concerns::Ripperable
|
||||||
|
|
||||||
|
# For performance, only data can be nested.
|
||||||
|
NESTABLE_ATTRIBUTES = %w[data].freeze
|
||||||
IGNORED_EXPRESSIONS = %w[false nil].freeze
|
IGNORED_EXPRESSIONS = %w[false nil].freeze
|
||||||
|
|
||||||
def compile_old_attribute(str)
|
def compile_old_attribute(str)
|
||||||
return runtime_build(str) unless Ripper.sexp(str)
|
raise RuntimeBuild unless Ripper.sexp(str)
|
||||||
|
|
||||||
attrs = parse_old_attributes(str)
|
attrs = parse_old_attributes(str)
|
||||||
format_attributes(attrs).map do |key, value|
|
format_attributes(attrs).map do |key, value|
|
||||||
next true_attribute(key) if value == 'true'
|
next true_attribute(key) if value == 'true'
|
||||||
|
assert_static_value!(value) if NESTABLE_ATTRIBUTES.include?(key)
|
||||||
|
|
||||||
[:html, :attr, key, [:dynamic, value]]
|
[:html, :attr, key, [:dynamic, value]]
|
||||||
end
|
end
|
||||||
|
rescue RuntimeBuild
|
||||||
|
return runtime_build(str)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -38,6 +48,14 @@ module Hamlit
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Give up static copmile when variables are detected.
|
||||||
|
def assert_static_value!(value)
|
||||||
|
tokens = Ripper.lex(value)
|
||||||
|
tokens.each do |(row, col), type, str|
|
||||||
|
raise RuntimeBuild if type == :on_ident
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Parse brace-balanced string and return the result as hash
|
# Parse brace-balanced string and return the result as hash
|
||||||
def parse_old_attributes(str)
|
def parse_old_attributes(str)
|
||||||
attributes = {}
|
attributes = {}
|
||||||
|
|
|
@ -48,6 +48,15 @@ describe Hamlit::Engine do
|
||||||
HTML
|
HTML
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'renders nested hash whose value is variable' do
|
||||||
|
assert_render(<<-'HAML', <<-HTML)
|
||||||
|
- hash = { disable: true }
|
||||||
|
%span{ data: hash } bar
|
||||||
|
HAML
|
||||||
|
<span data-disable>bar</span>
|
||||||
|
HTML
|
||||||
|
end
|
||||||
|
|
||||||
it 'renders false or nil attributes' do
|
it 'renders false or nil attributes' do
|
||||||
assert_render(<<-'HAML', <<-HTML)
|
assert_render(<<-'HAML', <<-HTML)
|
||||||
- hash = { checked: false }
|
- hash = { checked: false }
|
||||||
|
|
Loading…
Add table
Reference in a new issue