From 7adf19c04c90ccf24f8512cb3757f47d5ecde0fa Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Wed, 31 Dec 2025 23:15:07 +0100 Subject: [PATCH] fix: components page copyCode Alpine error and add TPL-012 rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- app/templates/admin/components.html | 18 +++++----- scripts/validate_architecture.py | 54 +++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/app/templates/admin/components.html b/app/templates/admin/components.html index fc889e87..b98bc6a3 100644 --- a/app/templates/admin/components.html +++ b/app/templates/admin/components.html @@ -2199,17 +2199,17 @@ goToPage(n) { if (n !== '...' && n >= 1 && n <= this.totalPages) { this.paginati (Click Option 1 to see loading state) - diff --git a/scripts/validate_architecture.py b/scripts/validate_architecture.py index 951c83bf..45d0cccd 100755 --- a/scripts/validate_architecture.py +++ b/scripts/validate_architecture.py @@ -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