immosquare-cleaner 0.1.91 → 0.1.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 386d987876b864e4d445826193b67f8ea4bfdf30a292fc08f4271b2ab5eb1c06
|
|
4
|
+
data.tar.gz: 410548afe07047e7f7cef616f8d766a299f151ea95ee1f072b6d32ac147d3048
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 219571e479c00ae7575c079b2a504877ea4e3f85176bf0e7d44526684ef43dd68ae12e2b3b78c049a267ffa12dcf03c7925ce1786eba549c835f31cd484d1daf
|
|
7
|
+
data.tar.gz: 6aed55c5b70fa5116a34c4d49cac06f7aa7639b18d01806026ea0bcc2582db0b9f203fb733cd1ec431b58bc40705d3f51a14b13faa44468e7563997cd5279a0e
|
|
@@ -345,23 +345,170 @@ module ERBLint
|
|
|
345
345
|
|
|
346
346
|
##============================================================##
|
|
347
347
|
## Build content_tag call
|
|
348
|
+
## Handles if/unless modifiers by moving them outside content_tag
|
|
348
349
|
##============================================================##
|
|
349
350
|
def build_content_tag(tag_name, content, attributes)
|
|
351
|
+
##============================================================##
|
|
352
|
+
## Extract modifier (if/unless) from content if present
|
|
353
|
+
##============================================================##
|
|
354
|
+
content_part, modifier_part = extract_modifier(content)
|
|
355
|
+
|
|
356
|
+
##============================================================##
|
|
357
|
+
## Wrap content in parentheses if it's an ambiguous method call
|
|
358
|
+
## (method call without parentheses that has arguments)
|
|
359
|
+
##============================================================##
|
|
360
|
+
wrapped_content = needs_parentheses?(content_part) ? "(#{content_part})" : content_part
|
|
361
|
+
|
|
362
|
+
##============================================================##
|
|
363
|
+
## Format tag name as symbol or string depending on characters
|
|
364
|
+
##============================================================##
|
|
365
|
+
formatted_tag = format_tag_name(tag_name)
|
|
366
|
+
|
|
350
367
|
if attributes.empty?
|
|
351
|
-
"
|
|
368
|
+
base = "content_tag(#{formatted_tag}, #{wrapped_content})"
|
|
352
369
|
else
|
|
353
370
|
attrs_str = attributes.map do |name, value|
|
|
354
371
|
key = normalize_attribute_name(name)
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
##============================================================##
|
|
358
|
-
if value&.include?('#{')
|
|
359
|
-
end
|
|
360
|
-
"#{key} => \"#{value}\""
|
|
372
|
+
quoted_value = quote_attribute_value(value)
|
|
373
|
+
"#{key} => #{quoted_value}"
|
|
361
374
|
end.join(", ")
|
|
362
375
|
|
|
363
|
-
"
|
|
376
|
+
base = "content_tag(#{formatted_tag}, #{wrapped_content}, #{attrs_str})"
|
|
364
377
|
end
|
|
378
|
+
|
|
379
|
+
if modifier_part
|
|
380
|
+
"<%= #{base} #{modifier_part} %>"
|
|
381
|
+
else
|
|
382
|
+
"<%= #{base} %>"
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
##============================================================##
|
|
387
|
+
## Format tag name for content_tag
|
|
388
|
+
## - Simple tags (div, span) -> :div, :span
|
|
389
|
+
## - Tags with special chars (x-card) -> "x-card"
|
|
390
|
+
##============================================================##
|
|
391
|
+
def format_tag_name(tag_name)
|
|
392
|
+
if tag_name.match?(/\A[a-z_][a-z0-9_]*\z/i)
|
|
393
|
+
":#{tag_name}"
|
|
394
|
+
else
|
|
395
|
+
"\"#{tag_name}\""
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
##============================================================##
|
|
400
|
+
## Check if Ruby code needs parentheses when used as argument
|
|
401
|
+
## Returns true for method calls without parentheses that have
|
|
402
|
+
## arguments (which would be ambiguous in content_tag context)
|
|
403
|
+
## Example: "tag t('x'), path, :class => 'y'" needs parentheses
|
|
404
|
+
##============================================================##
|
|
405
|
+
def needs_parentheses?(erb_code)
|
|
406
|
+
return false unless erb_code
|
|
407
|
+
|
|
408
|
+
result = Prism.parse(erb_code)
|
|
409
|
+
return false unless result.success?
|
|
410
|
+
|
|
411
|
+
node = result.value.statements.body.first
|
|
412
|
+
return false unless node.is_a?(Prism::CallNode)
|
|
413
|
+
|
|
414
|
+
##============================================================##
|
|
415
|
+
## Check if it's a method call with arguments but no parentheses
|
|
416
|
+
##============================================================##
|
|
417
|
+
has_arguments = node.arguments&.arguments&.any?
|
|
418
|
+
return false unless has_arguments
|
|
419
|
+
|
|
420
|
+
##============================================================##
|
|
421
|
+
## Check if parentheses are missing by looking at the source
|
|
422
|
+
## If the method name is not immediately followed by '(', it
|
|
423
|
+
## needs wrapping
|
|
424
|
+
##============================================================##
|
|
425
|
+
method_name = node.name.to_s
|
|
426
|
+
source = erb_code.strip
|
|
427
|
+
|
|
428
|
+
##============================================================##
|
|
429
|
+
## Find position after method name (accounting for receiver)
|
|
430
|
+
##============================================================##
|
|
431
|
+
if node.receiver
|
|
432
|
+
##============================================================##
|
|
433
|
+
## For calls like "tag.div" or "f.input", find the method call
|
|
434
|
+
##============================================================##
|
|
435
|
+
call_loc = node.call_operator_loc || node.message_loc
|
|
436
|
+
return false unless call_loc
|
|
437
|
+
|
|
438
|
+
after_method = call_loc.end_offset + method_name.length
|
|
439
|
+
else
|
|
440
|
+
after_method = method_name.length
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
##============================================================##
|
|
444
|
+
## Check if character after method name is '('
|
|
445
|
+
##============================================================##
|
|
446
|
+
return false if after_method >= source.length
|
|
447
|
+
|
|
448
|
+
source[after_method] != "("
|
|
449
|
+
rescue StandardError
|
|
450
|
+
false
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
##============================================================##
|
|
454
|
+
## Quote attribute value for Ruby output
|
|
455
|
+
## - Uses double quotes by default
|
|
456
|
+
## - Switches to single quotes if value contains double quotes
|
|
457
|
+
## - Handles interpolation by keeping double quotes and escaping
|
|
458
|
+
##============================================================##
|
|
459
|
+
def quote_attribute_value(value)
|
|
460
|
+
return '""' if value.nil? || value.empty?
|
|
461
|
+
|
|
462
|
+
has_interpolation = value.include?('#{')
|
|
463
|
+
has_double_quotes = value.include?('"')
|
|
464
|
+
|
|
465
|
+
if has_interpolation
|
|
466
|
+
##============================================================##
|
|
467
|
+
## Must use double quotes for interpolation, escape inner quotes
|
|
468
|
+
##============================================================##
|
|
469
|
+
escaped = value.gsub('"', '\\"')
|
|
470
|
+
"\"#{escaped}\""
|
|
471
|
+
elsif has_double_quotes
|
|
472
|
+
##============================================================##
|
|
473
|
+
## Use single quotes to avoid escaping
|
|
474
|
+
##============================================================##
|
|
475
|
+
"'#{value}'"
|
|
476
|
+
else
|
|
477
|
+
"\"#{value}\""
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
##============================================================##
|
|
482
|
+
## Extract if/unless modifier from Ruby code
|
|
483
|
+
## Returns [content, modifier] or [content, nil]
|
|
484
|
+
## Example: "foo if bar" => ["foo", "if bar"]
|
|
485
|
+
##============================================================##
|
|
486
|
+
def extract_modifier(erb_code)
|
|
487
|
+
return [erb_code, nil] unless erb_code
|
|
488
|
+
|
|
489
|
+
result = Prism.parse(erb_code)
|
|
490
|
+
return [erb_code, nil] unless result.success?
|
|
491
|
+
|
|
492
|
+
node = result.value.statements.body.first
|
|
493
|
+
|
|
494
|
+
##============================================================##
|
|
495
|
+
## Check for if/unless modifier
|
|
496
|
+
##============================================================##
|
|
497
|
+
if node.is_a?(Prism::IfNode) || node.is_a?(Prism::UnlessNode)
|
|
498
|
+
##============================================================##
|
|
499
|
+
## Only handle modifier form (no else, single statement body)
|
|
500
|
+
##============================================================##
|
|
501
|
+
if node.consequent.nil? && node.statements&.body&.size == 1
|
|
502
|
+
keyword = node.is_a?(Prism::IfNode) ? "if" : "unless"
|
|
503
|
+
condition = node.predicate.slice
|
|
504
|
+
content = node.statements.body.first.slice
|
|
505
|
+
return [content, "#{keyword} #{condition}"]
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
[erb_code, nil]
|
|
510
|
+
rescue StandardError
|
|
511
|
+
[erb_code, nil]
|
|
365
512
|
end
|
|
366
513
|
|
|
367
514
|
##============================================================##
|