Skip to content

Commit 0d51474

Browse files
fix: error on duplicate style and class directive (#13097)
Closes #13095
1 parent 35bd12b commit 0d51474

File tree

8 files changed

+42
-3
lines changed

8 files changed

+42
-3
lines changed

.changeset/dirty-jars-tap.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: error on duplicate style and class directive

packages/svelte/src/compiler/phases/1-parse/state/element.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,24 @@ export default function element(parser) {
189189

190190
let attribute;
191191
while ((attribute = read(parser))) {
192-
if (attribute.type === 'Attribute' || attribute.type === 'BindDirective') {
193-
if (unique_names.includes(attribute.name)) {
192+
// animate and transition can only be specified once per element so no need
193+
// to check here, use can be used multiple times, same for the on directive
194+
// finally let already has error handling in case of duplicate variable names
195+
if (
196+
attribute.type === 'Attribute' ||
197+
attribute.type === 'BindDirective' ||
198+
attribute.type === 'StyleDirective' ||
199+
attribute.type === 'ClassDirective'
200+
) {
201+
// `bind:attribute` and `attribute` are just the same but `class:attribute`,
202+
// `style:attribute` and `attribute` are different and should be allowed together
203+
// so we concatenate the type while normalizing the type for BindDirective
204+
const type = attribute.type === 'BindDirective' ? 'Attribute' : attribute.type;
205+
if (unique_names.includes(type + attribute.name)) {
194206
e.attribute_duplicate(attribute);
195207
// <svelte:element bind:this this=..> is allowed
196208
} else if (attribute.name !== 'this') {
197-
unique_names.push(attribute.name);
209+
unique_names.push(type + attribute.name);
198210
}
199211
}
200212

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
error: {
5+
code: 'attribute_duplicate',
6+
message: 'Attributes need to be unique',
7+
position: [23, 40]
8+
}
9+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div class:cool={true} class:cool={true}></div>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
error: {
5+
code: 'attribute_duplicate',
6+
message: 'Attributes need to be unique',
7+
position: [23, 42]
8+
}
9+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div style:color="red" style:color="green"></div>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div color="red" style:color="red" class:color={true} ></div>

0 commit comments

Comments
 (0)