Fix additional attributes for js renderers (#3625)
This commit is contained in:
1 parent
67515ce812
commit
2d188452ae
10 files changed
+125
-1
No files matched your search
@@ -28,6 +28,7 @@ impl LinkProps {
|
|||||||
/// Get all the attributes for the link tag
|
/// Get all the attributes for the link tag
|
||||||
pub fn attributes(&self) -> Vec<(&'static str, String)> {
|
pub fn attributes(&self) -> Vec<(&'static str, String)> {
|
||||||
let mut attributes = Vec::new();
|
let mut attributes = Vec::new();
|
||||||
|
extend_attributes(&mut attributes, &self.additional_attributes);
|
||||||
if let Some(rel) = &self.rel {
|
if let Some(rel) = &self.rel {
|
||||||
attributes.push(("rel", rel.clone()));
|
attributes.push(("rel", rel.clone()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ impl MetaProps {
|
|||||||
/// Get all the attributes for the meta tag
|
/// Get all the attributes for the meta tag
|
||||||
pub fn attributes(&self) -> Vec<(&'static str, String)> {
|
pub fn attributes(&self) -> Vec<(&'static str, String)> {
|
||||||
let mut attributes = Vec::new();
|
let mut attributes = Vec::new();
|
||||||
|
extend_attributes(&mut attributes, &self.additional_attributes);
|
||||||
if let Some(property) = &self.property {
|
if let Some(property) = &self.property {
|
||||||
attributes.push(("property", property.clone()));
|
attributes.push(("property", property.clone()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ impl ScriptProps {
|
|||||||
/// Get all the attributes for the script tag
|
/// Get all the attributes for the script tag
|
||||||
pub fn attributes(&self) -> Vec<(&'static str, String)> {
|
pub fn attributes(&self) -> Vec<(&'static str, String)> {
|
||||||
let mut attributes = Vec::new();
|
let mut attributes = Vec::new();
|
||||||
|
extend_attributes(&mut attributes, &self.additional_attributes);
|
||||||
if let Some(defer) = &self.defer {
|
if let Some(defer) = &self.defer {
|
||||||
attributes.push(("defer", defer.to_string()));
|
attributes.push(("defer", defer.to_string()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ impl StyleProps {
|
|||||||
/// Get all the attributes for the style tag
|
/// Get all the attributes for the style tag
|
||||||
pub fn attributes(&self) -> Vec<(&'static str, String)> {
|
pub fn attributes(&self) -> Vec<(&'static str, String)> {
|
||||||
let mut attributes = Vec::new();
|
let mut attributes = Vec::new();
|
||||||
|
extend_attributes(&mut attributes, &self.additional_attributes);
|
||||||
if let Some(href) = &self.href {
|
if let Some(href) = &self.href {
|
||||||
attributes.push(("href", href.clone()));
|
attributes.push(("href", href.clone()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ impl Document for ServerDocument {
|
|||||||
http_equiv: props.http_equiv,
|
http_equiv: props.http_equiv,
|
||||||
content: props.content,
|
content: props.content,
|
||||||
property: props.property,
|
property: props.property,
|
||||||
..props.additional_attributes
|
..props.additional_attributes,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -142,6 +142,7 @@ impl Document for ServerDocument {
|
|||||||
integrity: props.integrity,
|
integrity: props.integrity,
|
||||||
r#type: props.r#type,
|
r#type: props.r#type,
|
||||||
blocking: props.blocking,
|
blocking: props.blocking,
|
||||||
|
..props.additional_attributes,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,3 +37,34 @@ test("hydration", async ({ page }) => {
|
|||||||
const mountedDiv = page.locator("div.onmounted-div");
|
const mountedDiv = page.locator("div.onmounted-div");
|
||||||
await expect(mountedDiv).toHaveText("onmounted was called 1 times");
|
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");
|
||||||
|
});
|
||||||
@@ -41,6 +41,7 @@ fn app() -> Element {
|
|||||||
Errors {}
|
Errors {}
|
||||||
}
|
}
|
||||||
OnMounted {}
|
OnMounted {}
|
||||||
|
DocumentElements {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,3 +118,19 @@ pub fn ThrowsError() -> Element {
|
|||||||
"success"
|
"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'; }}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -124,3 +124,34 @@ test("web-sys closure", async ({ page }) => {
|
|||||||
await page.keyboard.press("Enter");
|
await page.keyboard.press("Enter");
|
||||||
await expect(scrollDiv).toHaveText("the keydown event was triggered");
|
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");
|
||||||
|
});
|
||||||
@@ -62,6 +62,7 @@ fn app() -> Element {
|
|||||||
PreventDefault {}
|
PreventDefault {}
|
||||||
OnMounted {}
|
OnMounted {}
|
||||||
WebSysClosure {}
|
WebSysClosure {}
|
||||||
|
DocumentElements {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +139,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() {
|
fn main() {
|
||||||
tracing_wasm::set_as_global_default_with_config(
|
tracing_wasm::set_as_global_default_with_config(
|
||||||
tracing_wasm::WASMLayerConfigBuilder::default()
|
tracing_wasm::WASMLayerConfigBuilder::default()
|
||||||
|
|||||||
Reference in new issue
Block a user