Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
name: "action_cable_meta_tag"
source: "ActionCable::Helpers::ActionCableHelper#action_cable_meta_tag"
gem: "actioncable"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "action_cable_meta_tag"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
name: "auto_discovery_link_tag"
source: "ActionView::Helpers::AssetTagHelper#auto_discovery_link_tag"
gem: "actionview"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
name: "favicon_link_tag"
source: "ActionView::Helpers::AssetTagHelper#favicon_link_tag"
gem: "actionview"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "favicon_link_tag(source = \"favicon.ico\", options = {})"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
name: "javascript_include_tag"
source: "ActionView::Helpers::AssetTagHelper#javascript_include_tag"
gem: "actionview"
output: "html"
visibility: "public"
context: "head"
supported: true
supports_block: false
signature: "javascript_include_tag(*sources)"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
name: "preload_link_tag"
source: "ActionView::Helpers::AssetTagHelper#preload_link_tag"
gem: "actionview"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "preload_link_tag(source, options = {})"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
name: "stylesheet_link_tag"
source: "ActionView::Helpers::AssetTagHelper#stylesheet_link_tag"
gem: "actionview"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "stylesheet_link_tag(*sources)"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
name: "csp_meta_tag"
source: "ActionView::Helpers::CspHelper#csp_meta_tag"
gem: "actionview"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "csp_meta_tag(**options)"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
name: "csrf_meta_tags"
source: "ActionView::Helpers::CsrfHelper#csrf_meta_tags"
gem: "actionview"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "csrf_meta_tags"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
name: "javascript_import_module_tag"
source: "Importmap::ImportmapTagsHelper#javascript_import_module_tag"
gem: "importmap-rails"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "javascript_import_module_tag(*module_names)"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
name: "javascript_importmap_module_preload_tags"
source: "Importmap::ImportmapTagsHelper#javascript_importmap_module_preload_tags"
gem: "importmap-rails"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "javascript_importmap_module_preload_tags(importmap = Rails.application.importmap, entry_point: \"application\")"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ source: "Importmap::ImportmapTagsHelper#javascript_importmap_tags"
gem: "importmap-rails"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "javascript_importmap_tags(entry_point = \"application\", importmap: Rails.application.importmap)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ source: "Importmap::ImportmapTagsHelper#javascript_inline_importmap_tag"
gem: "importmap-rails"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "javascript_inline_importmap_tag(importmap_json = Rails.application.importmap.to_json(resolver: self))"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ source: "Importmap::ImportmapTagsHelper#javascript_module_preload_tag"
gem: "importmap-rails"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "javascript_module_preload_tag(*paths)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ source: "Turbo::DriveHelper#turbo_exempts_page_from_cache_tag"
gem: "turbo-rails"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "turbo_exempts_page_from_cache_tag"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ source: "Turbo::DriveHelper#turbo_exempts_page_from_preview_tag"
gem: "turbo-rails"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "turbo_exempts_page_from_preview_tag"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ source: "Turbo::DriveHelper#turbo_page_requires_reload_tag"
gem: "turbo-rails"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "turbo_page_requires_reload_tag"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ source: "Turbo::DriveHelper#turbo_refresh_method_tag"
gem: "turbo-rails"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "turbo_refresh_method_tag(method = :replace)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ source: "Turbo::DriveHelper#turbo_refresh_scroll_tag"
gem: "turbo-rails"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "turbo_refresh_scroll_tag(scroll = :reset)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ source: "Turbo::DriveHelper#turbo_refreshes_with"
gem: "turbo-rails"
output: "void"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "turbo_refreshes_with(method: :replace, scroll: :reset)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ source: "Turbo::IncludesHelper#turbo_include_tags"
gem: "turbo-rails"
output: "html"
visibility: "public"
context: "head"
supported: false
supports_block: false
signature: "turbo_include_tags"
Expand Down
22 changes: 19 additions & 3 deletions lib/herb/engine/debug_visitor.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# frozen_string_literal: true
# typed: false

require_relative "../action_view/helper_registry"

module Herb
class Engine
class DebugVisitor < Herb::Visitor
HEAD_CONTENT_HELPER_PATTERN = /\b(?:#{Herb::ActionView::HelperRegistry.by_context("head").map { |helper| Regexp.escape(helper.name) }.join("|")})\b/ #: Regexp
private_constant :HEAD_CONTENT_HELPER_PATTERN

def initialize(file_path: nil, project_path: nil)
super()

Expand Down Expand Up @@ -76,7 +81,7 @@ def visit_erb_content_node(node)
if !@in_attribute && !@in_html_comment && !@in_html_doctype && !in_excluded_context? && erb_output?(node.tag_opening.value)
code = node.content.value.strip

@erb_nodes_to_wrap << node unless complex_rails_helper?(code)
@erb_nodes_to_wrap << node unless complex_rails_helper?(code) || head_content_helper?(code)
end

super
Expand Down Expand Up @@ -210,7 +215,7 @@ def create_debug_span_for_erb(erb_node)
code = erb_node.content.value.strip
erb_code = "#{opening} #{code} %>"

return erb_node if complex_rails_helper?(code)
return erb_node if complex_rails_helper?(code) || head_content_helper?(code)

line = erb_node.location&.start&.line
column = erb_node.location&.start&.column
Expand Down Expand Up @@ -329,7 +334,7 @@ def in_script_or_style_context?
end

def in_excluded_context?
excluded_tags = ["script", "style", "head", "title", "textarea", "pre", "svg", "math"]
excluded_tags = ["script", "style", "head", "title", "meta", "link", "base", "textarea", "pre", "svg", "math"]
return true if excluded_tags.any? { |tag| @element_stack.include?(tag) }

if @erb_block_stack.any? { |node| javascript_tag?(node.content.value.strip) || include_debug_disable_comment?(node.content.value.strip) }
Expand Down Expand Up @@ -386,6 +391,17 @@ def javascript_tag?(code)
false
end

# TODO: Rewrite using Prism Nodes once available

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this TODO because related methods have this same TODO

def head_content_helper?(code)
cleaned_code = code.strip.gsub(/\s+/, " ")

return true if cleaned_code.match?(HEAD_CONTENT_HELPER_PATTERN)

return true if cleaned_code.match?(/\btag\.(?:meta|link|title|base)\b/)

false
end

def include_debug_disable_comment?(code)
cleaned_code = code.strip.gsub(/\s+/, " ")

Expand Down
11 changes: 9 additions & 2 deletions sig/herb/action_view/helper_registry.rbs

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

5 changes: 5 additions & 0 deletions sig/herb/engine/debug_visitor.rbs

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

20 changes: 18 additions & 2 deletions templates/lib/herb/action_view/helper_registry.rb.erb
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ module Herb
attr_reader :gem #: String
attr_reader :output #: Symbol
attr_reader :visibility #: String
attr_reader :context #: String?
attr_reader :tag_name #: String?
attr_reader :detect_style #: Symbol
attr_reader :description #: String
Expand All @@ -113,9 +114,9 @@ module Herb
attr_reader :special_behaviors #: Array[Symbol]
attr_reader :aliases #: Array[String]

#: (name: String, type: Symbol, source: String, gem: String, output: Symbol, visibility: String, tag_name: String?, is_void: bool, supports_block: bool, preferred_for_tag: bool, supported: bool, detect_style: Symbol, description: String, signature: String, documentation_url: String, implicit_attribute: HelperImplicitAttribute?, arguments: Array[HelperArgument], options: Array[HelperOption], block_arguments: Array[HelperBlockArgument], special_behaviors: Array[Symbol], aliases: Array[String]) -> void
#: (name: String, type: Symbol, source: String, gem: String, output: Symbol, visibility: String, context: String?, tag_name: String?, is_void: bool, supports_block: bool, preferred_for_tag: bool, supported: bool, detect_style: Symbol, description: String, signature: String, documentation_url: String, implicit_attribute: HelperImplicitAttribute?, arguments: Array[HelperArgument], options: Array[HelperOption], block_arguments: Array[HelperBlockArgument], special_behaviors: Array[Symbol], aliases: Array[String]) -> void
def initialize( # rubocop:disable Metrics/ParameterLists
name:, type:, source:, gem:, output:, visibility:, tag_name:, is_void:, supports_block:,
name:, type:, source:, gem:, output:, visibility:, context:, tag_name:, is_void:, supports_block:,
preferred_for_tag:, supported:, detect_style:, description:, signature:, documentation_url:,
implicit_attribute:, arguments:, options:, block_arguments:, special_behaviors:, aliases:
)
Expand All @@ -125,6 +126,7 @@ module Herb
@gem = gem
@output = output
@visibility = visibility
@context = context
@tag_name = tag_name
@is_void = is_void
@supports_block = supports_block
Expand Down Expand Up @@ -176,6 +178,7 @@ module Herb
gem: "<%= helper.gem %>",
output: :<%= helper.output %>,
visibility: "<%= helper.visibility %>",
context: <%= helper.context ? "\"#{helper.context}\"" : "nil" %>,
tag_name: <%= helper.tag_name ? "\"#{helper.tag_name}\"" : "nil" %>,
is_void: <%= helper.void? %>,
supports_block: <%= helper.supports_block %>,
Expand Down Expand Up @@ -239,6 +242,14 @@ module Herb
<%- end -%>
}.freeze #: Hash[String, Array[HelperEntry]]

<%- helpers_by_context = helpers.select(&:context).group_by(&:context) -%>

BY_CONTEXT = {
<%- helpers_by_context.each do |context, helpers| -%>
"<%= context %>" => [<%= helpers.map(&:constant_name).join(", ") %>].freeze,
<%- end -%>
}.freeze #: Hash[String, Array[HelperEntry]]

class << self
#: (String) -> HelperEntry?
def get(name)
Expand Down Expand Up @@ -294,6 +305,11 @@ module Herb
entries.select(&:supported?)
end

#: (String) -> Array[HelperEntry]
def by_context(context)
BY_CONTEXT[context] || []
end

#: (String) -> Array[HelperEntry]
def by_gem(gem_name)
entries.select { |entry| entry.gem == gem_name }
Expand Down
3 changes: 2 additions & 1 deletion templates/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ def receiver_call_detect?
end

class HelperType
attr_reader :name, :source, :gem, :output, :visibility, :supports_block,
attr_reader :name, :source, :gem, :output, :visibility, :context, :supports_block,
:supported, :description, :signature, :documentation_url, :tag,
:content, :attributes_arg, :attributes_arg_with_block,
:transform_style, :custom_transform,
Expand All @@ -684,6 +684,7 @@ def initialize(config)
@visibility = config.fetch("visibility", "public")
@supports_block = config.fetch("supports_block", false)
@supported = config.fetch("supported", false)
@context = config.fetch("context", nil)
@description = config.fetch("description", "").strip
@signature = config.fetch("signature")
@documentation_url = config.fetch("documentation_url")
Expand Down
Loading
Loading