Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions lib/herb/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ def initialize(input, properties = {})
@bufvar = properties[:bufvar] || properties[:outvar] || "_buf"
@escape = properties.fetch(:escape) { properties.fetch(:escape_html, false) }
@escapefunc = properties.fetch(:escapefunc, @escape ? "__herb.h" : "::Herb::Engine.h")
@attrfunc = properties.fetch(:attrfunc, @escape ? "__herb.attr" : "::Herb::Engine.attr")
@jsfunc = properties.fetch(:jsfunc, @escape ? "__herb.js" : "::Herb::Engine.js")
@cssfunc = properties.fetch(:cssfunc, @escape ? "__herb.css" : "::Herb::Engine.css")
@src = properties[:src] || String.new
@chain_appends = properties[:chain_appends]
@buffer_on_stack = false
Expand Down Expand Up @@ -244,6 +247,24 @@ def add_expression(indicator, code)
end
end

def add_context_aware_expression(indicator, code, context)
escapefunc = context_escape_function(context)

if escapefunc.nil?
add_expression(indicator, code)
else
with_buffer { @src << " << #{escapefunc}((" << code << trailing_newline(code) << "))" }
end
end

def context_escape_function(context)
case context
when :attribute_value then @attrfunc
when :script_content then @jsfunc
when :style_content then @cssfunc
end
end

def add_expression_result(code)
with_buffer {
@src << " << (" << code << trailing_newline(code) << ").to_s"
Expand Down
58 changes: 17 additions & 41 deletions lib/herb/engine/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ def initialize(engine, options = {})

@engine = engine
@escape = options.fetch(:escape) { options.fetch(:escape_html, false) }
@attrfunc = options.fetch(:attrfunc, @escape ? "__herb.attr" : "::Herb::Engine.attr")
@jsfunc = options.fetch(:jsfunc, @escape ? "__herb.js" : "::Herb::Engine.js")
@cssfunc = options.fetch(:cssfunc, @escape ? "__herb.css" : "::Herb::Engine.css")
@tokens = [] #: Array[untyped]
@element_stack = [] #: Array[String]
@context_stack = [:html_content]
Expand All @@ -28,26 +25,16 @@ def generate_output
@engine.send(:add_text, value)
when :code
@engine.send(:add_code, value)
when :expr
if [:attribute_value, :script_content, :style_content].include?(context)
add_context_aware_expression(value, context)
else
indicator = @escape ? "==" : "="
@engine.send(:add_expression, indicator, value)
end
when :expr_escaped
if [:attribute_value, :script_content, :style_content].include?(context)
add_context_aware_expression(value, context)
when :expr, :expr_escaped
indicator = indicator_for(type)

if context_aware_context?(context)
@engine.send(:add_context_aware_expression, indicator, value, context)
else
indicator = @escape ? "=" : "=="
@engine.send(:add_expression, indicator, value)
end
when :expr_block
indicator = @escape ? "==" : "="
@engine.send(:add_expression_block, indicator, value)
when :expr_block_escaped
indicator = @escape ? "=" : "=="
@engine.send(:add_expression_block, indicator, value)
when :expr_block, :expr_block_escaped
@engine.send(:add_expression_block, indicator_for(type), value)
when :expr_block_end
@engine.send(:add_expression_block_end, value, escaped: escaped)
end
Expand Down Expand Up @@ -342,27 +329,6 @@ def pop_context
@context_stack.pop
end

def add_context_aware_expression(code, context)
closing = code.include?("#") ? "\n))" : "))"

case context
when :attribute_value
@engine.send(:with_buffer) {
@engine.src << " << #{@attrfunc}((" << code << closing
}
when :script_content
@engine.send(:with_buffer) {
@engine.src << " << #{@jsfunc}((" << code << closing
}
when :style_content
@engine.send(:with_buffer) {
@engine.src << " << #{@cssfunc}((" << code << closing
}
else
@engine.send(:add_expression_result_escaped, code)
end
end

def process_erb_tag(node, skip_comment_check: false)
opening = node.tag_opening.value

Expand Down Expand Up @@ -503,6 +469,16 @@ def process_erb_output(node, opening, code)
@trim_next_whitespace = true if has_right_trim
end

def indicator_for(type)
escaped = [:expr_escaped, :expr_block_escaped].include?(type)

escaped ^ @escape ? "==" : "="
end

def context_aware_context?(context)
[:attribute_value, :script_content, :style_content].include?(context)
end

def should_escape_output?(opening)
is_double_equals = opening == "<%=="
is_double_equals ? !@escape : @escape
Expand Down
4 changes: 4 additions & 0 deletions sig/herb/engine.rbs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions sig/herb/engine/compiler.rbs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading