Class: Upkeep::HerbSupport::TemplateManifest::Visitor

Inherits:
Herb::Visitor
  • Object
show all
Defined in:
lib/upkeep/herb/template_manifest.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path:, source:) ⇒ Visitor

Returns a new instance of Visitor.



209
210
211
212
213
214
215
216
217
218
# File 'lib/upkeep/herb/template_manifest.rb', line 209

def initialize(path:, source:)
  super()
  @path = path
  @frontend_tag_plan = []
  @render_nodes = []
  @helper_lowered_elements = []
  @html_stack = []
  @root_shape = nil
  @line_offsets = build_line_offsets(source)
end

Instance Attribute Details

#frontend_tag_planObject (readonly)

Returns the value of attribute frontend_tag_plan.



207
208
209
# File 'lib/upkeep/herb/template_manifest.rb', line 207

def frontend_tag_plan
  @frontend_tag_plan
end

#helper_lowered_elementsObject (readonly)

Returns the value of attribute helper_lowered_elements.



207
208
209
# File 'lib/upkeep/herb/template_manifest.rb', line 207

def helper_lowered_elements
  @helper_lowered_elements
end

#render_nodesObject (readonly)

Returns the value of attribute render_nodes.



207
208
209
# File 'lib/upkeep/herb/template_manifest.rb', line 207

def render_nodes
  @render_nodes
end

Instance Method Details

#root_shapeObject



220
221
222
# File 'lib/upkeep/herb/template_manifest.rb', line 220

def root_shape
  @root_shape || EMPTY_ROOT_SHAPE
end

#visit_document_node(node) ⇒ Object



224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/upkeep/herb/template_manifest.rb', line 224

def visit_document_node(node)
  significant_children = node.children.reject { |child| insignificant_document_child?(child) }
  root_elements = significant_children.select { |child| html_element?(child) }

  @root_shape = {
    significant_children: significant_children.size,
    root_elements: root_elements.size,
    root_types: significant_children.map { |child| child.class.name },
    single_root: significant_children.size == 1 && root_elements.size == 1,
    single_root_element: root_elements.size == 1,
    multi_root: root_elements.size > 1
  }

  if partial_template?
    plan_fragment_root_tag(root_elements.first) if root_shape.fetch(:single_root)
  elsif root_shape.fetch(:single_root_element)
    # A page template's recorded frame target needs a matching DOM marker so it can be
    # resolved during full-page rerender. Page templates routinely carry non-element
    # siblings such as `content_for`/`yield :head` ERB statements that produce no enclosing
    # DOM, so anchor the page-frame marker to the single root element rather than requiring
    # the element to be the only significant child.
    plan_page_root_tag(root_elements.first)
  end

  super
end

#visit_erb_render_node(node) ⇒ Object



251
252
253
254
255
256
257
258
259
# File 'lib/upkeep/herb/template_manifest.rb', line 251

def visit_erb_render_node(node)
  keywords = node.keywords
  render_node = render_node_payload(node, keywords)

  @render_nodes << render_node
  @frontend_tag_plan << render_site_tag(render_node) if render_node.fetch(:render_site_container)

  super
end

#visit_html_element_node(node) ⇒ Object



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/upkeep/herb/template_manifest.rb', line 261

def visit_html_element_node(node)
  if node.respond_to?(:element_source) && node.element_source && node.element_source != "HTML"
    @helper_lowered_elements << {
      location: location_payload(node.location),
      tag_name: token_value(node.tag_name),
      element_source: node.element_source
    }
  end

  @html_stack.push(node)
  begin
    super
  ensure
    @html_stack.pop
  end
end