@@ -132,9 +132,12 @@ const special_elements = {
132
132
'invalid-customElement-shadow-attribute' : ( ) => '"shadow" must be either "open" or "none"' ,
133
133
'unknown-svelte-option-attribute' : /** @param {string } name */ ( name ) =>
134
134
`<svelte:options> unknown attribute '${ name } '` ,
135
+ 'illegal-svelte-head-attribute' : ( ) => '<svelte:head> cannot have attributes nor directives' ,
135
136
'invalid-svelte-fragment-attribute' : ( ) =>
136
137
`<svelte:fragment> can only have a slot attribute and (optionally) a let: directive` ,
137
138
'invalid-svelte-fragment-slot' : ( ) => `<svelte:fragment> slot attribute must have a static value` ,
139
+ 'invalid-svelte-fragment-placement' : ( ) =>
140
+ `<svelte:fragment> must be the direct child of a component` ,
138
141
/** @param {string } name */
139
142
'invalid-svelte-element-placement' : ( name ) =>
140
143
`<${ name } > tags cannot be inside elements or blocks` ,
@@ -211,31 +214,75 @@ const elements = {
211
214
* @param {string } node
212
215
* @param {string } parent
213
216
*/
214
- 'invalid-node-placement' : ( node , parent ) => `${ node } is invalid inside <${ parent } >`
217
+ 'invalid-node-placement' : ( node , parent ) => `${ node } is invalid inside <${ parent } >` ,
218
+ 'illegal-title-attribute' : ( ) => '<title> cannot have attributes nor directives' ,
219
+ 'invalid-title-content' : ( ) => '<title> can only contain text and {tags}'
215
220
} ;
216
221
217
222
/** @satisfies {Errors } */
218
223
const components = {
219
- 'invalid-component-directive' : ( ) => `Directive is not valid on components`
224
+ 'invalid-component-directive' : ( ) => `This type of directive is not valid on components`
220
225
} ;
221
226
222
227
/** @satisfies {Errors } */
223
228
const attributes = {
224
229
'empty-attribute-shorthand' : ( ) => `Attribute shorthand cannot be empty` ,
225
230
'duplicate-attribute' : ( ) => `Attributes need to be unique` ,
226
231
'invalid-event-attribute-value' : ( ) =>
227
- `Event attribute must be a JavaScript expression, not a string`
232
+ `Event attribute must be a JavaScript expression, not a string` ,
233
+ /** @param {string } name */
234
+ 'invalid-attribute-name' : ( name ) => `'${ name } ' is not a valid attribute name` ,
235
+ /** @param {'no-each' | 'each-key' | 'child' } type */
236
+ 'invalid-animation' : ( type ) =>
237
+ type === 'no-each'
238
+ ? `An element that uses the animate directive must be the immediate child of a keyed each block`
239
+ : type === 'each-key'
240
+ ? `An element that uses the animate directive must be used inside a keyed each block. Did you forget to add a key to your each block?`
241
+ : `An element that uses the animate directive must be the sole child of a keyed each block` ,
242
+ 'duplicate-animation' : ( ) => `An element can only have one 'animate' directive` ,
243
+ /** @param {string[] | undefined } [modifiers] */
244
+ 'invalid-event-modifier' : ( modifiers ) =>
245
+ modifiers
246
+ ? `Valid event modifiers are ${ modifiers . slice ( 0 , - 1 ) . join ( ', ' ) } or ${ modifiers . slice ( - 1 ) } `
247
+ : `Event modifiers other than 'once' can only be used on DOM elements` ,
248
+ /**
249
+ * @param {string } modifier1
250
+ * @param {string } modifier2
251
+ */
252
+ 'invalid-event-modifier-combination' : ( modifier1 , modifier2 ) =>
253
+ `The '${ modifier1 } ' and '${ modifier2 } ' modifiers cannot be used together` ,
254
+ /**
255
+ * @param {string } directive1
256
+ * @param {string } directive2
257
+ */
258
+ 'duplicate-transition' : ( directive1 , directive2 ) => {
259
+ /** @param {string } _directive */
260
+ function describe ( _directive ) {
261
+ return _directive === 'transition' ? "a 'transition'" : `an '${ _directive } '` ;
262
+ }
263
+
264
+ return directive1 === directive2
265
+ ? `An element can only have one '${ directive1 } ' directive`
266
+ : `An element cannot have both ${ describe ( directive1 ) } directive and ${ describe (
267
+ directive2
268
+ ) } directive`;
269
+ } ,
270
+ 'invalid-let-directive-placement' : ( ) => 'let directive at invalid position'
228
271
} ;
229
272
230
273
/** @satisfies {Errors } */
231
274
const slots = {
232
275
'invalid-slot-element-attribute' : ( ) => `<slot> can only receive attributes, not directives` ,
233
276
'invalid-slot-attribute' : ( ) => `slot attribute must be a static value` ,
234
- 'invalid-slot-name' : ( ) => `slot attribute must be a static value` ,
277
+ /** @param {boolean } is_default */
278
+ 'invalid-slot-name' : ( is_default ) =>
279
+ is_default
280
+ ? `default is a reserved word — it cannot be used as a slot name`
281
+ : `slot attribute must be a static value` ,
235
282
'invalid-slot-placement' : ( ) =>
236
283
`Element with a slot='...' attribute must be a child of a component or a descendant of a custom element` ,
237
- 'duplicate-slot-name' : /** @param {string } name @param {string } component */ ( name , component ) =>
238
- `Duplicate slot name '${ name } ' in <${ component } >` ,
284
+ /** @param {string } name @param {string } component */
285
+ 'duplicate-slot-name' : ( name , component ) => `Duplicate slot name '${ name } ' in <${ component } >` ,
239
286
'invalid-default-slot-content' : ( ) =>
240
287
`Found default slot content alongside an explicit slot="default"`
241
288
} ;
@@ -256,13 +303,20 @@ const bindings = {
256
303
'invalid-type-attribute' : ( ) =>
257
304
`'type' attribute must be a static text value if input uses two-way binding` ,
258
305
'invalid-multiple-attribute' : ( ) =>
259
- `'multiple' attribute must be static if select uses two-way binding`
306
+ `'multiple' attribute must be static if select uses two-way binding` ,
307
+ 'missing-contenteditable-attribute' : ( ) =>
308
+ `'contenteditable' attribute is required for textContent, innerHTML and innerText two-way bindings` ,
309
+ 'dynamic-contenteditable-attribute' : ( ) =>
310
+ `'contenteditable' attribute cannot be dynamic if element uses two-way binding`
260
311
} ;
261
312
262
313
/** @satisfies {Errors } */
263
314
const variables = {
264
315
'illegal-global' : /** @param {string } name */ ( name ) =>
265
- `${ name } is an illegal variable name. To reference a global variable called ${ name } , use globalThis.${ name } `
316
+ `${ name } is an illegal variable name. To reference a global variable called ${ name } , use globalThis.${ name } ` ,
317
+ /** @param {string } name */
318
+ 'duplicate-declaration' : ( name ) => `'${ name } ' has already been declared` ,
319
+ 'default-export' : ( ) => `A component cannot have a default export`
266
320
} ;
267
321
268
322
/** @satisfies {Errors } */
@@ -279,6 +333,12 @@ const compiler_options = {
279
333
'removed-compiler-option' : ( msg ) => `Invalid compiler option: ${ msg } `
280
334
} ;
281
335
336
+ /** @satisfies {Errors } */
337
+ const const_tag = {
338
+ 'invalid-const-placement' : ( ) =>
339
+ `{@const} must be the immediate child of {#if}, {:else if}, {:else}, {#each}, {:then}, {:catch}, <svelte:fragment> or <Component>`
340
+ } ;
341
+
282
342
/** @satisfies {Errors } */
283
343
const errors = {
284
344
...internal ,
@@ -293,7 +353,8 @@ const errors = {
293
353
...bindings ,
294
354
...variables ,
295
355
...compiler_options ,
296
- ...legacy_reactivity
356
+ ...legacy_reactivity ,
357
+ ...const_tag
297
358
298
359
// missing_contenteditable_attribute: {
299
360
// code: 'missing-contenteditable-attribute',
@@ -304,34 +365,11 @@ const errors = {
304
365
// code: 'dynamic-contenteditable-attribute',
305
366
// message: "'contenteditable' attribute cannot be dynamic if element uses two-way binding"
306
367
// },
307
- // invalid_event_modifier_combination: /**
308
- // * @param {string } modifier1
309
- // * @param {string } modifier2
310
- // */ (modifier1, modifier2) => ({
311
- // code: 'invalid-event-modifier',
312
- // message: `The '${modifier1}' and '${modifier2}' modifiers cannot be used together`
313
- // }),
314
- // invalid_event_modifier_legacy: /** @param {string } modifier */ (modifier) => ({
315
- // code: 'invalid-event-modifier',
316
- // message: `The '${modifier}' modifier cannot be used in legacy mode`
317
- // }),
318
- // invalid_event_modifier: /** @param {string } valid */ (valid) => ({
319
- // code: 'invalid-event-modifier',
320
- // message: `Valid event modifiers are ${valid}`
321
- // }),
322
- // invalid_event_modifier_component: {
323
- // code: 'invalid-event-modifier',
324
- // message: "Event modifiers other than 'once' can only be used on DOM elements"
325
- // },
326
368
// textarea_duplicate_value: {
327
369
// code: 'textarea-duplicate-value',
328
370
// message:
329
371
// 'A <textarea> can have either a value attribute or (equivalently) child content, but not both'
330
372
// },
331
- // illegal_attribute: /** @param {string } name */ (name) => ({
332
- // code: 'illegal-attribute',
333
- // message: `'${name}' is not a valid attribute name`
334
- // }),
335
373
// invalid_attribute_head: {
336
374
// code: 'invalid-attribute',
337
375
// message: '<svelte:head> should not have any attributes or directives'
@@ -340,10 +378,6 @@ const errors = {
340
378
// code: 'invalid-action',
341
379
// message: 'Actions can only be applied to DOM elements, not components'
342
380
// },
343
- // invalid_animation: {
344
- // code: 'invalid-animation',
345
- // message: 'Animations can only be applied to DOM elements, not components'
346
- // },
347
381
// invalid_class: {
348
382
// code: 'invalid-class',
349
383
// message: 'Classes can only be applied to DOM elements, not components'
@@ -364,22 +398,10 @@ const errors = {
364
398
// code: 'dynamic-slot-name',
365
399
// message: '<slot> name cannot be dynamic'
366
400
// },
367
- // invalid_slot_name: {
368
- // code: 'invalid-slot-name',
369
- // message: 'default is a reserved word — it cannot be used as a slot name'
370
- // },
371
401
// invalid_slot_attribute_value_missing: {
372
402
// code: 'invalid-slot-attribute',
373
403
// message: 'slot attribute value is missing'
374
404
// },
375
- // invalid_slotted_content_fragment: {
376
- // code: 'invalid-slotted-content',
377
- // message: '<svelte:fragment> must be a child of a component'
378
- // },
379
- // illegal_attribute_title: {
380
- // code: 'illegal-attribute',
381
- // message: '<title> cannot have attributes'
382
- // },
383
405
// illegal_structure_title: {
384
406
// code: 'illegal-structure',
385
407
// message: '<title> can only contain text and {tags}'
@@ -428,10 +450,6 @@ const errors = {
428
450
// code: 'illegal-variable-declaration',
429
451
// message: 'Cannot declare same variable name which is imported inside <script context="module">'
430
452
// },
431
- // css_invalid_global: {
432
- // code: 'css-invalid-global',
433
- // message: ':global(...) can be at the start or end of a selector sequence, but not in the middle'
434
- // },
435
453
// css_invalid_global_selector: {
436
454
// code: 'css-invalid-global-selector',
437
455
// message: ':global(...) must contain a single selector'
@@ -445,55 +463,15 @@ const errors = {
445
463
// code: 'css-invalid-selector',
446
464
// message: `Invalid selector "${selector}"`
447
465
// }),
448
- // duplicate_animation: {
449
- // code: 'duplicate-animation',
450
- // message: "An element can only have one 'animate' directive"
451
- // },
452
- // invalid_animation_immediate: {
453
- // code: 'invalid-animation',
454
- // message:
455
- // 'An element that uses the animate directive must be the immediate child of a keyed each block'
456
- // },
457
- // invalid_animation_key: {
458
- // code: 'invalid-animation',
459
- // message:
460
- // 'An element that uses the animate directive must be used inside a keyed each block. Did you forget to add a key to your each block?'
461
- // },
462
- // invalid_animation_sole: {
463
- // code: 'invalid-animation',
464
- // message:
465
- // 'An element that uses the animate directive must be the sole child of a keyed each block'
466
- // },
467
- // invalid_animation_dynamic_element: {
468
- // code: 'invalid-animation',
469
- // message: '<svelte:element> cannot have a animate directive'
470
- // },
471
466
// invalid_directive_value: {
472
467
// code: 'invalid-directive-value',
473
468
// message:
474
469
// 'Can only bind to an identifier (e.g. `foo`) or a member expression (e.g. `foo.bar` or `foo[baz]`)'
475
470
// },
476
- // invalid_const_placement: {
477
- // code: 'invalid-const-placement',
478
- // message:
479
- // '{@const } must be the immediate child of {#if}, {:else if}, {:else}, {#each}, {:then}, {:catch}, <svelte:fragment> or <Component>'
480
- // },
481
- // invalid_const_declaration: /** @param {string } name */ (name) => ({
482
- // code: 'invalid-const-declaration',
483
- // message: `'${name}' has already been declared`
484
- // }),
485
- // invalid_const_update: /** @param {string } name */ (name) => ({
486
- // code: 'invalid-const-update',
487
- // message: `'${name}' is declared using {@const ...} and is read-only`
488
- // }),
489
471
// cyclical_const_tags: /** @param {string[] } cycle */ (cycle) => ({
490
472
// code: 'cyclical-const-tags',
491
473
// message: `Cyclical dependency detected: ${cycle.join(' → ')}`
492
474
// }),
493
- // invalid_component_style_directive: {
494
- // code: 'invalid-component-style-directive',
495
- // message: 'Style directives cannot be used on components'
496
- // },
497
475
// invalid_var_declaration: {
498
476
// code: 'invalid_var_declaration',
499
477
// message: '"var" scope should not extend outside the reactive block'
0 commit comments