Skip to content

Commit 0c98674

Browse files
Preserve camelCase for known svg elements (yewstack#3875)
* Fix SVG element casing to preserve camelCase names SVG elements like feDropShadow were incorrectly converted to lowercase, breaking their functionality. Now properly preserves casing for known SVG elements while normalizing regular HTML elements. Fixes svg filter rendering issue where filters would not display. * Preserve camelCase for all elements per worldsender's suggestion * Remove accidentally committed test files * add pixel color test * remove extra comments and screenshot tests for now * adjust lint warning message --------- Co-authored-by: Martin Molzer <WorldSEnder@users.noreply.github.com>
1 parent bb031eb commit 0c98674

File tree

3 files changed

+12
-7
lines changed

3 files changed

+12
-7
lines changed

packages/yew-macro/src/html_tree/html_element.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,17 +370,20 @@ impl ToTokens for HtmlElement {
370370
tokens.extend(match &name {
371371
TagName::Lit(dashedname) => {
372372
let name_span = dashedname.span();
373-
let name = dashedname.to_ascii_lowercase_string();
373+
let name = dashedname.to_string();
374+
let lowercase_name = dashedname.to_ascii_lowercase_string();
374375
if !is_normalised_element_name(&dashedname.to_string()) {
375376
emit_warning!(
376377
name_span.clone(),
377378
format!(
378-
"The tag '{dashedname}' is not matching its normalized form '{name}'. If you want \
379-
to keep this form, change this to a dynamic tag `@{{\"{dashedname}\"}}`."
379+
"The tag '{dashedname}' is not matching its normalized form '{lowercase_name}' \
380+
and is not a recognized SVG or MathML element. If you want to keep this name, \
381+
you can use the dynamic tag `@{{\"{dashedname}\"}}` to silence this warning."
380382
)
381383
)
382384
}
383-
let node = match &*name {
385+
// Use lowercase for compile-time checks but preserve original casing in output
386+
let node = match &*lowercase_name {
384387
"input" => {
385388
let value = value();
386389
let checked = checked();

packages/yew-macro/tests/html_lints/fail.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
warning: The tag 'tExTAreA' is not matching its normalized form 'textarea'. If you want to keep this form, change this to a dynamic tag `@{"tExTAreA"}`.
1+
warning: The tag 'tExTAreA' is not matching its normalized form 'textarea' and is not a recognized SVG or MathML element. If you want to keep this name, you can use the dynamic tag `@{"tExTAreA"}` to silence this warning.
22
--> tests/html_lints/fail.rs:17:10
33
|
44
17 | <tExTAreA />

packages/yew/src/virtual_dom/vtag.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,9 @@ impl VTag {
152152
/// Creates a new [VTag] instance with `tag` name (cannot be changed later in DOM).
153153
pub fn new(tag: impl Into<AttrValue>) -> Self {
154154
let tag = tag.into();
155+
let lowercase_tag = tag.to_ascii_lowercase();
155156
Self::new_base(
156-
match &*tag.to_ascii_lowercase() {
157+
match &*lowercase_tag {
157158
"input" => VTagInner::Input(Default::default()),
158159
"textarea" => VTagInner::Textarea(Default::default()),
159160
_ => VTagInner::Other {
@@ -531,7 +532,8 @@ mod feat_ssr {
531532
let _ = w.write_str("</textarea>");
532533
}
533534
VTagInner::Other { tag, children } => {
534-
if !VOID_ELEMENTS.contains(&tag.as_ref()) {
535+
let lowercase_tag = tag.to_ascii_lowercase();
536+
if !VOID_ELEMENTS.contains(&lowercase_tag.as_ref()) {
535537
children
536538
.render_into_stream(w, parent_scope, hydratable, tag.into())
537539
.await;

0 commit comments

Comments
 (0)