Class: Phlex::SGML::State
- Inherits:
-
Object
- Object
- Phlex::SGML::State
- Defined in:
- lib/phlex/sgml/state.rb
Instance Attribute Summary collapse
-
#buffer ⇒ Object
readonly
Returns the value of attribute buffer.
-
#capturing ⇒ Object
Returns the value of attribute capturing.
-
#fragment_depth ⇒ Object
readonly
Returns the value of attribute fragment_depth.
-
#fragments ⇒ Object
readonly
Returns the value of attribute fragments.
-
#output_buffer ⇒ Object
readonly
Returns the value of attribute output_buffer.
-
#user_context ⇒ Object
Returns the value of attribute user_context.
Instance Method Summary collapse
- #around_render(component) ⇒ Object
- #begin_fragment(id) ⇒ Object
- #caching ⇒ Object
- #caching? ⇒ Boolean
- #capture ⇒ Object
- #end_fragment(id) ⇒ Object
- #flush ⇒ Object
-
#initialize(user_context: {}, output_buffer:, fragments:) ⇒ State
constructor
A new instance of State.
- #record_fragment(id, offset, length, nested_fragments) ⇒ Object
- #should_render? ⇒ Boolean
Constructor Details
#initialize(user_context: {}, output_buffer:, fragments:) ⇒ State
Returns a new instance of State.
4 5 6 7 8 9 10 11 12 13 |
# File 'lib/phlex/sgml/state.rb', line 4 def initialize(user_context: {}, output_buffer:, fragments:) @buffer = +"" @capturing = false @user_context = user_context @fragments = fragments @fragment_depth = 0 @cache_stack = [] @halt_signal = nil @output_buffer = output_buffer end |
Instance Attribute Details
#buffer ⇒ Object (readonly)
Returns the value of attribute buffer.
17 18 19 |
# File 'lib/phlex/sgml/state.rb', line 17 def buffer @buffer end |
#capturing ⇒ Object
Returns the value of attribute capturing.
15 16 17 |
# File 'lib/phlex/sgml/state.rb', line 15 def capturing @capturing end |
#fragment_depth ⇒ Object (readonly)
Returns the value of attribute fragment_depth.
17 18 19 |
# File 'lib/phlex/sgml/state.rb', line 17 def fragment_depth @fragment_depth end |
#fragments ⇒ Object (readonly)
Returns the value of attribute fragments.
17 18 19 |
# File 'lib/phlex/sgml/state.rb', line 17 def fragments @fragments end |
#output_buffer ⇒ Object (readonly)
Returns the value of attribute output_buffer.
17 18 19 |
# File 'lib/phlex/sgml/state.rb', line 17 def output_buffer @output_buffer end |
#user_context ⇒ Object
Returns the value of attribute user_context.
15 16 17 |
# File 'lib/phlex/sgml/state.rb', line 15 def user_context @user_context end |
Instance Method Details
#around_render(component) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/phlex/sgml/state.rb', line 19 def around_render(component) stack = @stack if !@fragments || @halt_signal yield else catch do |signal| @halt_signal = signal yield end end end |
#begin_fragment(id) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/phlex/sgml/state.rb', line 36 def begin_fragment(id) @fragment_depth += 1 if @fragments&.include?(id) if caching? current_byte_offset = 0 # Start tracking the byte offset of this fragment from the start of the cache buffer @cache_stack.reverse_each do |(cache_buffer, fragment_map)| # We'll iterate deepest to shallowest current_byte_offset += cache_buffer.bytesize # Add the length of the cache buffer to the current byte offset fragment_map[id] = [current_byte_offset, nil, []] # Record the byte offset, length, and store a list of the nested fragments fragment_map.each do |name, (_offset, length, nested_fragments)| # Iterate over the other fragments next if name == id || length # Skip if it's the current fragment, or if the fragment has already ended nested_fragments << id # Add the current fragment to the list of nested fragments end end end end |
#caching ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/phlex/sgml/state.rb', line 78 def caching(&) result = nil capture do @cache_stack.push([buffer, {}].freeze) yield result = @cache_stack.pop end result end |
#caching? ⇒ Boolean
90 91 92 |
# File 'lib/phlex/sgml/state.rb', line 90 def caching? @cache_stack.length > 0 end |
#capture ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/phlex/sgml/state.rb', line 94 def capture new_buffer = +"" original_buffer = @buffer original_capturing = @capturing original_fragments = @fragments begin @buffer = new_buffer @capturing = true @fragments = nil yield ensure @buffer = original_buffer @capturing = original_capturing @fragments = original_fragments end new_buffer end |
#end_fragment(id) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/phlex/sgml/state.rb', line 53 def end_fragment(id) if caching? byte_length = nil @cache_stack.reverse_each do |(cache_buffer, fragment_map)| # We'll iterate deepest to shallowest byte_length ||= cache_buffer.bytesize - fragment_map[id][0] # The byte length is the difference between the current byte offset and the byte offset of the fragment fragment_map[id][1] = byte_length # All cache contexts will use the same by end end return unless @fragments&.include?(id) @fragments.delete(id) @fragment_depth -= 1 throw @halt_signal if @fragments.length == 0 end |
#flush ⇒ Object
114 115 116 117 118 119 120 121 122 |
# File 'lib/phlex/sgml/state.rb', line 114 def flush return if capturing buffer = @buffer @output_buffer << buffer.dup buffer.clear nil end |
#record_fragment(id, offset, length, nested_fragments) ⇒ Object
69 70 71 72 73 74 75 76 |
# File 'lib/phlex/sgml/state.rb', line 69 def record_fragment(id, offset, length, nested_fragments) return unless caching? @cache_stack.reverse_each do |(cache_buffer, fragment_map)| offset += cache_buffer.bytesize fragment_map[id] = [offset, length, nested_fragments] end end |
#should_render? ⇒ Boolean
32 33 34 |
# File 'lib/phlex/sgml/state.rb', line 32 def should_render? !@fragments || @fragment_depth > 0 end |