fix: components page copyCode Alpine error and add TPL-012 rule

- Fixed copyCode template literal by using single quotes for outer attribute
- Added TPL-012 architecture rule to detect double quotes inside multi-line
  copyCode template literals that break HTML attribute parsing
- Pattern: @click="copyCode(`...`)" with inner double quotes breaks parsing
- Solution: Use @click='copyCode(`...`)' with single quotes for outer attribute

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-31 23:15:07 +01:00
parent 03209eb691
commit 7adf19c04c
2 changed files with 63 additions and 9 deletions

View File

@@ -1166,6 +1166,57 @@ class ArchitectureValidator:
suggestion=f"Use '{info['replacement']}' macro instead",
)
def _check_escaped_quotes_in_alpine(
self, file_path: Path, content: str, lines: list[str]
):
"""TPL-012: Check for problematic quotes in Alpine copyCode template literals.
When using copyCode() with a multi-line template literal, double quotes
inside the template will prematurely end the outer @click="..." attribute.
Bad: @click="copyCode(`{{ func("arg") }}`)" # inner " ends the attribute
Good: @click='copyCode(`{{ func("arg") }}`)' # single quotes for outer
"""
if "noqa: tpl-012" in content.lower():
return
import re
# Track multi-line copyCode template literals with double-quoted outer attribute
in_copycode_template = False
copycode_start_line = 0
for i, line in enumerate(lines, 1):
if "noqa: tpl-012" in line.lower():
continue
# Check for start of copyCode with double-quoted attribute and template literal
# Pattern: @click="copyCode(` where the backtick doesn't close on same line
if '@click="copyCode(`' in line and '`)' not in line:
in_copycode_template = True
copycode_start_line = i
continue
# Check for end of copyCode template (backtick followed by )" or )')
if in_copycode_template:
if '`)"' in line or "`)'" in line:
in_copycode_template = False
continue
# Check for double quotes that would break the outer attribute
# These appear in Jinja template code like {{ func("arg") }}
if re.search(r'\(\s*"[^"]*"\s*[,)]', line):
self._add_violation(
rule_id="TPL-012",
rule_name="Double quotes in copyCode template literal",
severity=Severity.ERROR,
file_path=file_path,
line_number=i,
message="Double quotes inside multi-line copyCode template literal will break HTML attribute parsing",
context=line.strip()[:80],
suggestion="Change outer attribute to single quotes: @click='copyCode(`...`)'",
)
def _check_alpine_template_vars(
self, file_path: Path, content: str, lines: list[str], js_content: str
):
@@ -3029,6 +3080,9 @@ class ArchitectureValidator:
# TPL-011: Check for deprecated macros
self._check_deprecated_macros(file_path, content, lines)
# TPL-012: Check for escaped quotes in Alpine template literals
self._check_escaped_quotes_in_alpine(file_path, content, lines)
# Skip base/partials for TPL-001 check
if is_base_or_partial:
continue