Skip to content

Commit

Permalink
Fix additional attributes for js renderers
Browse files Browse the repository at this point in the history
  • Loading branch information
ealmloff committed Jan 22, 2025
1 parent 041c570 commit 77d3b99
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/document/src/elements/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ impl LinkProps {
/// Get all the attributes for the link tag
pub fn attributes(&self) -> Vec<(&'static str, String)> {
let mut attributes = Vec::new();
extend_attributes(&mut attributes, &self.additional_attributes);
if let Some(rel) = &self.rel {
attributes.push(("rel", rel.clone()));
}
Expand Down
1 change: 1 addition & 0 deletions packages/document/src/elements/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl MetaProps {
/// Get all the attributes for the meta tag
pub fn attributes(&self) -> Vec<(&'static str, String)> {
let mut attributes = Vec::new();
extend_attributes(&mut attributes, &self.additional_attributes);
if let Some(property) = &self.property {
attributes.push(("property", property.clone()));
}
Expand Down
23 changes: 23 additions & 0 deletions packages/document/src/elements/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,26 @@ impl DeduplicationContext {
}
}
}

/// Extend a list of string attributes with a list of dioxus attribute
pub(crate) fn extend_attributes(
attributes: &mut Vec<(&'static str, String)>,
additional_attributes: &[Attribute],
) {
for additional_attribute in additional_attributes {
let attribute_value_as_string = match &additional_attribute.value {
dioxus_core::AttributeValue::Text(v) => v.to_string(),
dioxus_core::AttributeValue::Float(v) => v.to_string(),
dioxus_core::AttributeValue::Int(v) => v.to_string(),
dioxus_core::AttributeValue::Bool(v) => v.to_string(),
dioxus_core::AttributeValue::Listener(_) | dioxus_core::AttributeValue::Any(_) => {
tracing::error!("document::* elements do not support event listeners or any value attributes. Expected displayable attribute, found {:?}", additional_attribute.value);
continue;
}
dioxus_core::AttributeValue::None => {
continue;
}
};
attributes.push((additional_attribute.name, attribute_value_as_string));
}
}
1 change: 1 addition & 0 deletions packages/document/src/elements/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ impl ScriptProps {
/// Get all the attributes for the script tag
pub fn attributes(&self) -> Vec<(&'static str, String)> {
let mut attributes = Vec::new();
extend_attributes(&mut attributes, &self.additional_attributes);
if let Some(defer) = &self.defer {
attributes.push(("defer", defer.to_string()));
}
Expand Down
1 change: 1 addition & 0 deletions packages/document/src/elements/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ impl StyleProps {
/// Get all the attributes for the style tag
pub fn attributes(&self) -> Vec<(&'static str, String)> {
let mut attributes = Vec::new();
extend_attributes(&mut attributes, &self.additional_attributes);
if let Some(href) = &self.href {
attributes.push(("href", href.clone()));
}
Expand Down
3 changes: 2 additions & 1 deletion packages/fullstack/src/document/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl Document for ServerDocument {
http_equiv: props.http_equiv,
content: props.content,
property: props.property,
..props.additional_attributes
..props.additional_attributes,
}
});
}
Expand Down Expand Up @@ -142,6 +142,7 @@ impl Document for ServerDocument {
integrity: props.integrity,
r#type: props.r#type,
blocking: props.blocking,
..props.additional_attributes,
}
})
}
Expand Down
31 changes: 31 additions & 0 deletions packages/playwright-tests/fullstack.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,34 @@ test("hydration", async ({ page }) => {
const mountedDiv = page.locator("div.onmounted-div");
await expect(mountedDiv).toHaveText("onmounted was called 1 times");
});

test("document elements", async ({ page }) => {
await page.goto("http://localhost:9999");
// wait until the meta element is mounted
const meta = page.locator("meta#meta-head[name='testing']");
await meta.waitFor({ state: "attached" });
await expect(meta).toHaveAttribute("data", "dioxus-meta-element");

const link = page.locator("link#link-head[rel='stylesheet']");
await link.waitFor({ state: "attached" });
await expect(link).toHaveAttribute(
"href",
"https://fonts.googleapis.com/css?family=Roboto+Mono"
);

const stylesheet = page.locator("link#stylesheet-head[rel='stylesheet']");
await stylesheet.waitFor({ state: "attached" });
await expect(stylesheet).toHaveAttribute(
"href",
"https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic"
);

const script = page.locator("script#script-head");
await script.waitFor({ state: "attached" });
await expect(script).toHaveAttribute("async", "true");

const style = page.locator("style#style-head");
await style.waitFor({ state: "attached" });
const main = page.locator("#main");
await expect(main).toHaveCSS("font-family", "Roboto");
});
17 changes: 17 additions & 0 deletions packages/playwright-tests/fullstack/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ fn app() -> Element {
Errors {}
}
OnMounted {}
DocumentElements {}
}
}

Expand Down Expand Up @@ -117,3 +118,19 @@ pub fn ThrowsError() -> Element {
"success"
}
}

/// This component tests the document::* elements pre-rendered on the server
#[component]
fn DocumentElements() -> Element {
rsx! {
document::Meta { id: "meta-head", name: "testing", data: "dioxus-meta-element" }
document::Link {
id: "link-head",
rel: "stylesheet",
href: "https://fonts.googleapis.com/css?family=Roboto+Mono"
}
document::Stylesheet { id: "stylesheet-head", href: "https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic" }
document::Script { id: "script-head", async: true, "console.log('hello world');" }
document::Style { id: "style-head", "body {{ font-family: 'Roboto'; }}" }
}
}
31 changes: 31 additions & 0 deletions packages/playwright-tests/web.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,34 @@ test("web-sys closure", async ({ page }) => {
await page.keyboard.press("Enter");
await expect(scrollDiv).toHaveText("the keydown event was triggered");
});

test("document elements", async ({ page }) => {
await page.goto("http://localhost:9999");
// wait until the meta element is mounted
const meta = page.locator("meta#meta-head[name='testing']");
await meta.waitFor({ state: "attached" });
await expect(meta).toHaveAttribute("data", "dioxus-meta-element");

const link = page.locator("link#link-head[rel='stylesheet']");
await link.waitFor({ state: "attached" });
await expect(link).toHaveAttribute(
"href",
"https://fonts.googleapis.com/css?family=Roboto+Mono"
);

const stylesheet = page.locator("link#stylesheet-head[rel='stylesheet']");
await stylesheet.waitFor({ state: "attached" });
await expect(stylesheet).toHaveAttribute(
"href",
"https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic"
);

const script = page.locator("script#script-head");
await script.waitFor({ state: "attached" });
await expect(script).toHaveAttribute("async", "true");

const style = page.locator("style#style-head");
await style.waitFor({ state: "attached" });
const main = page.locator("#main");
await expect(main).toHaveCSS("font-family", "Roboto");
});
17 changes: 17 additions & 0 deletions packages/playwright-tests/web/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ fn app() -> Element {
PreventDefault {}
OnMounted {}
WebSysClosure {}
DocumentElements {}
}
}

Expand Down Expand Up @@ -131,6 +132,22 @@ fn WebSysClosure() -> Element {
}
}

/// This component tests the document::* elements
#[component]
fn DocumentElements() -> Element {
rsx! {
document::Meta { id: "meta-head", name: "testing", data: "dioxus-meta-element" }
document::Link {
id: "link-head",
rel: "stylesheet",
href: "https://fonts.googleapis.com/css?family=Roboto+Mono"
}
document::Stylesheet { id: "stylesheet-head", href: "https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic" }
document::Script { id: "script-head", async: true, "console.log('hello world');" }
document::Style { id: "style-head", "body {{ font-family: 'Roboto'; }}" }
}
}

fn main() {
tracing_wasm::set_as_global_default_with_config(
tracing_wasm::WASMLayerConfigBuilder::default()
Expand Down

0 comments on commit 77d3b99

Please sign in to comment.