fix: align CSS attribute selector case-sensitivity with the HTML spec

The set of attributes whose values are matched case-insensitively did
not match the spec section its own comment links to. Attributes such as
lang, media and hreflang were missing, so selectors that a browser
applies were pruned as unused and the scoping class was never added.
pull/18779/head
Bao Nguyen 4 days ago
parent 5895c637b0
commit e67f61026c

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: align CSS attribute selector case-sensitivity with the HTML spec

@ -23,47 +23,56 @@ const whitelist_attribute_selector = new Map([
]); ]);
/** /**
* HTML attributes whose enumerated values are case-insensitive per the HTML spec. * Attribute values that CSS attribute selectors match ASCII case-insensitively in HTML documents.
* CSS attribute selectors match these values case-insensitively in HTML documents.
* @see {@link https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors HTML spec} * @see {@link https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors HTML spec}
*/ */
const case_insensitive_attributes = new Set([ const case_insensitive_attributes = new Set([
'accept',
'accept-charset', 'accept-charset',
'autocapitalize', 'align',
'autocomplete', 'alink',
'behavior', 'axis',
'bgcolor',
'charset', 'charset',
'crossorigin', 'checked',
'decoding', 'clear',
'codetype',
'color',
'compact',
'declare',
'defer',
'dir', 'dir',
'direction', 'direction',
'draggable', 'disabled',
'enctype', 'enctype',
'enterkeyhint', 'face',
'fetchpriority', 'frame',
'formenctype', 'hreflang',
'formmethod',
'formtarget',
'hidden',
'http-equiv', 'http-equiv',
'inputmode', 'lang',
'kind', 'language',
'loading', 'link',
'media',
'method', 'method',
'preload', 'multiple',
'referrerpolicy', 'nohref',
'noresize',
'noshade',
'nowrap',
'readonly',
'rel', 'rel',
'rev', 'rev',
'role',
'rules', 'rules',
'scope', 'scope',
'scrolling',
'selected',
'shape', 'shape',
'spellcheck',
'target', 'target',
'translate', 'text',
'type', 'type',
'valign', 'valign',
'wrap' 'valuetype',
'vlink'
]); ]);
/** @type {Compiler.AST.CSS.Combinator} */ /** @type {Compiler.AST.CSS.Combinator} */

@ -0,0 +1,21 @@
import { test } from '../../test';
export default test({
warnings: [
{
filename: 'SvelteComponent.svelte',
code: 'css_unused_selector',
message: 'Unused CSS selector "input[autocomplete="on"]"',
start: {
character: 178,
column: 1,
line: 16
},
end: {
character: 202,
column: 25,
line: 16
}
}
]
});

@ -0,0 +1,11 @@
div[lang="en"].svelte-xyz {
color: red;
}
a[hreflang="en"].svelte-xyz {
color: blue;
}
/* (unused) input[autocomplete="on"] {
color: green;
}*/

@ -0,0 +1 @@
<div class="svelte-xyz" lang="EN">Hello</div> <a class="svelte-xyz" hreflang="EN" href="/">World</a> <input autocomplete="ON" />

@ -0,0 +1,19 @@
<div lang="EN">Hello</div>
<a hreflang="EN" href="/">World</a>
<input autocomplete="ON" />
<style>
div[lang="en"] {
color: red;
}
a[hreflang="en"] {
color: blue;
}
input[autocomplete="on"] {
color: green;
}
</style>
Loading…
Cancel
Save