From acb3d65a54c399d7daebd4846f4b475b47af3018 Mon Sep 17 00:00:00 2001 From: Christian Oliff Date: Wed, 26 Nov 2025 13:22:46 +0900 Subject: [PATCH 1/3] Add autofix support for the form-method-require rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit implemented autofix support for the `form-method-require` rule. - ✅ Added createFormMethodRequireFix() function in htmlhint-server/src/server.ts - ✅ Added the new rule to the autofix switch statement - ✅ Updated README.md to document the new autofix support - ✅ Compiled successfully with no errors The autofix will add an empty method="" attribute, leaving the cursor positioned so users can easily fill in get, post, or dialog as needed. --- htmlhint-server/src/server.ts | 106 ++++++++++++++++++++++++++++++++++ htmlhint/CHANGELOG.md | 1 + htmlhint/README.md | 1 + 3 files changed, 108 insertions(+) diff --git a/htmlhint-server/src/server.ts b/htmlhint-server/src/server.ts index d755515..4bd2981 100644 --- a/htmlhint-server/src/server.ts +++ b/htmlhint-server/src/server.ts @@ -1966,6 +1966,108 @@ function createAttrNoDuplicationFix( }; } +/** + * Create auto-fix action for form-method-require rule + */ +function createFormMethodRequireFix( + document: TextDocument, + diagnostic: Diagnostic, +): CodeAction | null { + trace( + `[DEBUG] createFormMethodRequireFix called with diagnostic: ${JSON.stringify(diagnostic)}`, + ); + + if (!diagnostic.data || diagnostic.data.ruleId !== "form-method-require") { + trace( + `[DEBUG] createFormMethodRequireFix: Invalid diagnostic data or ruleId`, + ); + return null; + } + + const text = document.getText(); + const diagnosticOffset = document.offsetAt(diagnostic.range.start); + + // Use robust tag boundary detection to find the form tag + const tagBoundaries = findTagBoundaries(text, diagnosticOffset); + if (!tagBoundaries) { + trace(`[DEBUG] createFormMethodRequireFix: Could not find tag boundaries`); + return null; + } + + const { tagStart, tagEnd } = tagBoundaries; + const tagContent = text.substring(tagStart, tagEnd + 1); + trace(`[DEBUG] createFormMethodRequireFix: Found tag: ${tagContent}`); + + // Verify this is a form tag + const formTagMatch = tagContent.match(/^<\s*form\b/i); + if (!formTagMatch) { + trace(`[DEBUG] createFormMethodRequireFix: Not a form tag`); + return null; + } + + // Check if method attribute already exists + const methodAttrMatch = tagContent.match(/\bmethod\s*=/i); + if (methodAttrMatch) { + trace( + `[DEBUG] createFormMethodRequireFix: Method attribute already exists`, + ); + return null; + } + + // Find the best position to insert the method attribute + // We'll add it after the opening form tag name but before the closing > + const formMatch = tagContent.match(/^(<\s*form)(\s+[^>]*?)?(\/?\s*>)$/i); + if (!formMatch) { + trace( + `[DEBUG] createFormMethodRequireFix: Could not parse form tag structure`, + ); + return null; + } + + const beforeAttrs = formMatch[1]; // "" or "/>" + + // Calculate insertion position + let insertPosition: number; + let newText: string; + + if (existingAttrs.trim()) { + // There are existing attributes, add method after them + insertPosition = tagStart + beforeAttrs.length + existingAttrs.length; + newText = ' method=""'; + } else { + // No existing attributes, add method right after "form" + insertPosition = tagStart + beforeAttrs.length; + newText = ' method=""'; + } + + const edit: TextEdit = { + range: { + start: document.positionAt(insertPosition), + end: document.positionAt(insertPosition), + }, + newText: newText, + }; + + trace( + `[DEBUG] createFormMethodRequireFix: Will insert "${newText}" at position ${insertPosition}`, + ); + + const workspaceEdit: WorkspaceEdit = { + changes: { + [document.uri]: [edit], + }, + }; + + return { + title: 'Add method="" attribute to form', + kind: CodeActionKind.QuickFix, + edit: workspaceEdit, + isPreferred: true, + }; +} + /** * Create auto-fix actions for supported rules */ @@ -2064,6 +2166,10 @@ async function createAutoFixes( trace(`[DEBUG] Calling createAttrNoDuplicationFix`); fix = createAttrNoDuplicationFix(document, diagnostic); break; + case "form-method-require": + trace(`[DEBUG] Calling createFormMethodRequireFix`); + fix = createFormMethodRequireFix(document, diagnostic); + break; default: trace(`[DEBUG] No autofix function found for rule: ${ruleId}`); break; diff --git a/htmlhint/CHANGELOG.md b/htmlhint/CHANGELOG.md index c5e6b73..1268611 100644 --- a/htmlhint/CHANGELOG.md +++ b/htmlhint/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to the "vscode-htmlhint" extension will be documented in thi ### v1.14.0 (2025-11-26) - Add autofix for the `attr-no-duplication` rule +- Add autofix for the `form-method-require` rule ### v1.13.0 (2025-11-25) diff --git a/htmlhint/README.md b/htmlhint/README.md index d9e02d3..d9b5c03 100644 --- a/htmlhint/README.md +++ b/htmlhint/README.md @@ -35,6 +35,7 @@ The extension provides automatic fixes for many common HTML issues. Currently su - **`button-type-require`** - Adds type attribute to buttons - **`doctype-first`** - Adds DOCTYPE declaration at the beginning - **`doctype-html5`** - Updates DOCTYPE to HTML5 +- **`form-method-require`** - Adds empty method attribute to forms - **`html-lang-require`** - Adds `lang` attribute to `` tag - **`meta-charset-require`** - Adds charset meta tag - **`meta-description-require`** - Adds description meta tag From c1abb7330b47185cd36b4097e4b7ecd706193646 Mon Sep 17 00:00:00 2001 From: Christian Oliff Date: Wed, 26 Nov 2025 13:26:02 +0900 Subject: [PATCH 2/3] Potential fix for pull request finding 'Unused variable, import, function or class' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> --- htmlhint-server/src/server.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/htmlhint-server/src/server.ts b/htmlhint-server/src/server.ts index 4bd2981..6d5b5cd 100644 --- a/htmlhint-server/src/server.ts +++ b/htmlhint-server/src/server.ts @@ -2026,7 +2026,6 @@ function createFormMethodRequireFix( const beforeAttrs = formMatch[1]; // "" or "/>" // Calculate insertion position let insertPosition: number; From 349df24fac9e820309fdb837844c03d85cac6494 Mon Sep 17 00:00:00 2001 From: Christian Oliff Date: Wed, 26 Nov 2025 13:29:40 +0900 Subject: [PATCH 3/3] Refactor form method attribute insertion logic Simplifies the logic for inserting the 'method' attribute into form tags by moving the assignment of newText outside the conditional branches. --- htmlhint-server/src/server.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/htmlhint-server/src/server.ts b/htmlhint-server/src/server.ts index 6d5b5cd..abf21d4 100644 --- a/htmlhint-server/src/server.ts +++ b/htmlhint-server/src/server.ts @@ -2028,17 +2028,15 @@ function createFormMethodRequireFix( const existingAttrs = formMatch[2] || ""; // existing attributes // Calculate insertion position + const newText = ' method=""'; let insertPosition: number; - let newText: string; if (existingAttrs.trim()) { // There are existing attributes, add method after them insertPosition = tagStart + beforeAttrs.length + existingAttrs.length; - newText = ' method=""'; } else { // No existing attributes, add method right after "form" insertPosition = tagStart + beforeAttrs.length; - newText = ' method=""'; } const edit: TextEdit = {