Class: LiveCable::Rendering::Compiler

Inherits:
Herb::Engine::Compiler
  • Object
show all
Defined in:
lib/live_cable/rendering/compiler.rb

Instance Method Summary collapse

Instance Method Details

#generate_for_token(type, value, _context = nil, _escaped = nil) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/live_cable/rendering/compiler.rb', line 35

def generate_for_token(type, value, _context = nil, _escaped = nil)
  case type
  when :text
    @engine.send(:add_text, value)
  when :code, :expr_block_end
    # Escaping is delegated to Rails' output buffer, so the closing
    # `end` of an output block (:expr_block_end) is emitted as plain
    # code rather than herb's paren-balancing add_expression_block_end.
    @engine.send(:add_code, value)
  when :expr
    indicator = @escape ? '==' : '='
    @engine.send(:add_expression, indicator, value)
  when :expr_escaped
    indicator = @escape ? '=' : '=='
    @engine.send(:add_expression, indicator, value)
  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)
  end
end

#generate_outputObject



21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/live_cable/rendering/compiler.rb', line 21

def generate_output
  tokens = optimize_tokens(@tokens)

  tokens.map do |type, value, context|
    if type == :block
      value.map { |token| generate_for_token(*token) }
    else
      generate_for_token(type, value, context)
    end

    @engine.send(:finish_method, type)
  end
end

#optimize_tokens(unoptimized_tokens) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/live_cable/rendering/compiler.rb', line 59

def optimize_tokens(unoptimized_tokens)
  tokens = super
  optimized_tokens = []
  block_count = 0
  current_block = []

  tokens.each do |token|
    if token[0] == :block_start
      block_count += 1
    elsif token[0] == :block_end
      block_count -= 1

      if block_count.zero?
        optimized_tokens << [:block, current_block]
        current_block = []
      end
    elsif block_count.zero?
      optimized_tokens << token
    else
      current_block << token
    end
  end

  optimized_tokens
end

#visit_erb_block_node(node) ⇒ Object



15
16
17
18
19
# File 'lib/live_cable/rendering/compiler.rb', line 15

def visit_erb_block_node(node)
  @tokens << [:block_start, "\n"]
  super
  @tokens << [:block_end, "\n"]
end

#visit_erb_control_node(node) ⇒ Object

Sentinel tokens carry a "\n" value so herb's whitespace helpers (at_line_start?, preceding_token_ends_with_newline?) treat them like a line boundary instead of crashing on a nil value.



9
10
11
12
13
# File 'lib/live_cable/rendering/compiler.rb', line 9

def visit_erb_control_node(node)
  @tokens << [:block_start, "\n"]
  super
  @tokens << [:block_end, "\n"]
end