diff --git a/packages/language-server/src/plugins/svelte/features/getCodeActions/getQuickfixes.ts b/packages/language-server/src/plugins/svelte/features/getCodeActions/getQuickfixes.ts index a5b33a987..78c4539cb 100644 --- a/packages/language-server/src/plugins/svelte/features/getCodeActions/getQuickfixes.ts +++ b/packages/language-server/src/plugins/svelte/features/getCodeActions/getQuickfixes.ts @@ -108,7 +108,6 @@ async function createQuickfixActions( return codeActions; } - function createSvelteAnchorMissingAttributeQuickfixAction( textDocument: OptionalVersionedTextDocumentIdentifier, transpiled: ITranspiledSvelteDocument, @@ -118,16 +117,21 @@ function createSvelteAnchorMissingAttributeQuickfixAction( ): CodeAction { // Assert non-null because the node target attribute is required for 'security-anchor-rel-noreferrer' const targetAttribute = node.attributes.find((i: any) => i.name == 'target')!; - const targetAttributePosition = positionAt(targetAttribute.end, content, lineOffsets); + const relAttribute = node.attributes.find((i: any) => i.name == 'rel'); - const relNoReferrerTextEdit = TextEdit.insert(targetAttributePosition, ' rel="noreferrer"'); + const codeActionTextEdit = relAttribute + ? TextEdit.insert(positionAt(relAttribute.end - 1, content, lineOffsets), ' noreferrer') + : TextEdit.insert( + positionAt(targetAttribute.end, content, lineOffsets), + ' rel="noreferrer"' + ); return CodeAction.create( '(svelte) Add missing attribute rel="noreferrer"', { documentChanges: [ TextDocumentEdit.create(textDocument, [ - mapObjWithRangeToOriginal(transpiled, relNoReferrerTextEdit) + mapObjWithRangeToOriginal(transpiled, codeActionTextEdit) ]) ] }, diff --git a/packages/language-server/test/plugins/svelte/features/getCodeAction.test.ts b/packages/language-server/test/plugins/svelte/features/getCodeAction.test.ts index 34848b452..e94dcd2fa 100644 --- a/packages/language-server/test/plugins/svelte/features/getCodeAction.test.ts +++ b/packages/language-server/test/plugins/svelte/features/getCodeAction.test.ts @@ -184,6 +184,88 @@ describe('SveltePlugin#getCodeAction', () => { } ]); }); + + const svelteAnchorMissingAttributeCodeActionRel = + 'svelte-anchor-missing-attribute-code-action-rel.svelte'; + + it('Should not duplicate rel attribute', async () => { + ( + await expectCodeActionFor(svelteAnchorMissingAttributeCodeActionRel, { + diagnostics: [ + { + severity: DiagnosticSeverity.Warning, + code: 'security-anchor-rel-noreferrer', + range: Range.create( + { line: 0, character: 0 }, + { line: 0, character: 70 } + ), + message: + 'Security: Anchor with "target=_blank" should have rel attribute containing the value "noreferrer"', + source: 'svelte' + } + ] + }) + ).toEqual([ + { + edit: { + documentChanges: [ + { + edits: [ + { + newText: ' noreferrer', + range: { + end: { + character: 58, + line: 0 + }, + start: { + character: 58, + line: 0 + } + } + } + ], + textDocument: { + uri: getUri(svelteAnchorMissingAttributeCodeActionRel), + version: null + } + } + ] + }, + title: '(svelte) Add missing attribute rel="noreferrer"', + kind: 'quickfix' + }, + { + edit: { + documentChanges: [ + { + edits: [ + { + newText: `${EOL}`, + range: { + end: { + character: 0, + line: 0 + }, + start: { + character: 0, + line: 0 + } + } + } + ], + textDocument: { + uri: getUri(svelteAnchorMissingAttributeCodeActionRel), + version: null + } + } + ] + }, + title: '(svelte) Disable security-anchor-rel-noreferrer for this line', + kind: 'quickfix' + } + ]); + }); }); describe('It should provide svelte ignore code actions ', () => { diff --git a/packages/language-server/test/plugins/svelte/testfiles/svelte-anchor-missing-attribute-code-action-rel.svelte b/packages/language-server/test/plugins/svelte/testfiles/svelte-anchor-missing-attribute-code-action-rel.svelte new file mode 100644 index 000000000..5c4c0d6c1 --- /dev/null +++ b/packages/language-server/test/plugins/svelte/testfiles/svelte-anchor-missing-attribute-code-action-rel.svelte @@ -0,0 +1 @@ +Svelte