Class: JsxRosetta::PagesRouting::HrefRewriter

Inherits:
Object
  • Object
show all
Defined in:
lib/jsx_rosetta/pages_routing.rb

Overview

Matches ‘href`/`to` paths against the route table and emits a Rails URL helper invocation. The caller pre-translates any template-literal hole expressions into Ruby; this class itself does no JS-to-Ruby translation.

Defined Under Namespace

Classes: Token

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(routes) ⇒ HrefRewriter

Returns a new instance of HrefRewriter.



120
121
122
# File 'lib/jsx_rosetta/pages_routing.rb', line 120

def initialize(routes)
  @routes = routes
end

Class Method Details

.parse_template_source(js_source) ⇒ Object

Parse a verbatim JS template literal source like “ ‘/foo/$bar` “ into `[[:literal, “/foo/”], [:hole, “bar”], [:literal, “”]]`. Returns nil for malformed input or nested-brace interpolations.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/jsx_rosetta/pages_routing.rb', line 147

def self.parse_template_source(js_source)
  return nil unless js_source.is_a?(String) && js_source.start_with?("`") && js_source.end_with?("`")
  return nil if js_source.length < 2

  body = js_source[1..-2]
  return nil if body.include?("`")

  parts = []
  pos = 0
  hole_count = 0
  body.to_enum(:scan, /\$\{([^{}]+)\}/).each do |_|
    match = ::Regexp.last_match
    parts << [:literal, body[pos...match.begin(0)]]
    parts << [:hole, match[1].strip]
    pos = match.end(0)
    hole_count += 1
  end
  parts << [:literal, body[pos..]]
  # `${...}` left in the trailing literal means an interpolation
  # had nested braces and we can't safely match it.
  return nil if body.scan("${").size != hole_count

  parts
end

Instance Method Details

#rewrite_literal(path) ⇒ Object

Try to rewrite a literal path. Returns Ruby source string or nil.



125
126
127
128
129
130
# File 'lib/jsx_rosetta/pages_routing.rb', line 125

def rewrite_literal(path)
  return nil unless rewritable_path?(path)

  tokens = path.split("/").reject(&:empty?).map { |seg| Token.new(kind: :literal, value: seg) }
  rewrite_tokens(tokens)
end

#rewrite_template(segments) ⇒ Object

Try to rewrite a parsed template literal. ‘segments` is an array of `[:literal, “…”]` / `[:hole, “ruby_expr”]` pairs — the output of `.parse_template_source` after the caller translates each hole. Returns Ruby source or nil.



136
137
138
139
140
141
# File 'lib/jsx_rosetta/pages_routing.rb', line 136

def rewrite_template(segments)
  tokens = template_tokens(segments)
  return nil unless tokens

  rewrite_tokens(tokens)
end