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)
|
||||
result = ''
|
||||
flatten_attributes(attributes).each do |key, value|
|
||||
if value == true
|
||||
result += " #{key}"
|
||||
next
|
||||
end
|
||||
|
||||
escaped = Temple::Utils.escape_html(value)
|
||||
result += " #{key}=#{@quote}#{escaped}#{@quote}"
|
||||
end
|
||||
|
|
|
@ -6,22 +6,32 @@ require 'hamlit/concerns/ripperable'
|
|||
# This module compiles only old-style attribute, which is
|
||||
# surrounded by brackets.
|
||||
module Hamlit
|
||||
# This error is raised when hamlit copmiler decide to
|
||||
# copmile the attributes on runtime.
|
||||
class RuntimeBuild < StandardError; end
|
||||
|
||||
module Compilers
|
||||
module OldAttribute
|
||||
include Concerns::AttributeBuilder
|
||||
include Concerns::Balanceable
|
||||
include Concerns::Ripperable
|
||||
|
||||
# For performance, only data can be nested.
|
||||
NESTABLE_ATTRIBUTES = %w[data].freeze
|
||||
IGNORED_EXPRESSIONS = %w[false nil].freeze
|
||||
|
||||
def compile_old_attribute(str)
|
||||
return runtime_build(str) unless Ripper.sexp(str)
|
||||
raise RuntimeBuild unless Ripper.sexp(str)
|
||||
|
||||
attrs = parse_old_attributes(str)
|
||||
format_attributes(attrs).map do |key, value|
|
||||
next true_attribute(key) if value == 'true'
|
||||
assert_static_value!(value) if NESTABLE_ATTRIBUTES.include?(key)
|
||||
|
||||
[:html, :attr, key, [:dynamic, value]]
|
||||
end
|
||||
rescue RuntimeBuild
|
||||
return runtime_build(str)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -38,6 +48,14 @@ module Hamlit
|
|||
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
|
||||
def parse_old_attributes(str)
|
||||
attributes = {}
|
||||
|
|
|
@ -48,6 +48,15 @@ describe Hamlit::Engine do
|
|||
HTML
|
||||
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
|
||||
assert_render(<<-'HAML', <<-HTML)
|
||||
- hash = { checked: false }
|
||||
|
|
Loading…
Add table
Reference in a new issue