fix: Allow links with duplicate href if rel is different (#5071)
Fixes #5070
This commit is contained in:
1 parent
c01770fcfb
commit
8a38e7ca76
3 files changed
+52
-4
No files matched your search
@@ -20,7 +20,7 @@ pub struct LinkProps {
|
|||||||
pub disabled: Option<bool>,
|
pub disabled: Option<bool>,
|
||||||
pub r#as: Option<String>,
|
pub r#as: Option<String>,
|
||||||
pub sizes: Option<String>,
|
pub sizes: Option<String>,
|
||||||
/// Links are deduplicated by their href attribute
|
/// Links are deduplicated by their href and rel attributes
|
||||||
pub href: Option<String>,
|
pub href: Option<String>,
|
||||||
pub crossorigin: Option<String>,
|
pub crossorigin: Option<String>,
|
||||||
pub referrerpolicy: Option<String>,
|
pub referrerpolicy: Option<String>,
|
||||||
@@ -122,7 +122,7 @@ pub fn Link(props: LinkProps) -> Element {
|
|||||||
let document = document();
|
let document = document();
|
||||||
let mut insert_link = document.create_head_component();
|
let mut insert_link = document.create_head_component();
|
||||||
if let Some(href) = &props.href {
|
if let Some(href) = &props.href {
|
||||||
if !should_insert_link(href) {
|
if !should_insert_link(href, props.rel.as_deref()) {
|
||||||
insert_link = false;
|
insert_link = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,8 +140,14 @@ pub fn Link(props: LinkProps) -> Element {
|
|||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
struct LinkContext(DeduplicationContext);
|
struct LinkContext(DeduplicationContext);
|
||||||
|
|
||||||
fn should_insert_link(href: &str) -> bool {
|
fn should_insert_link(href: &str, rel: Option<&str>) -> bool {
|
||||||
|
// Include rel in the deduplication key so that the same href can be used
|
||||||
|
// with different rel values (e.g., rel="preload" and rel="stylesheet")
|
||||||
|
let key = match rel {
|
||||||
|
Some(rel) => format!("{href}|{rel}"),
|
||||||
|
None => href.to_string(),
|
||||||
|
};
|
||||||
get_or_insert_root_context::<LinkContext>()
|
get_or_insert_root_context::<LinkContext>()
|
||||||
.0
|
.0
|
||||||
.should_insert(href)
|
.should_insert(&key)
|
||||||
}
|
}
|
||||||
@@ -156,6 +156,22 @@ test("document elements", async ({ page }) => {
|
|||||||
await expect(main).toHaveCSS("font-family", "Roboto");
|
await expect(main).toHaveCSS("font-family", "Roboto");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("link preload and stylesheet with same href are not deduplicated", async ({ page }) => {
|
||||||
|
await page.goto("http://localhost:9990");
|
||||||
|
|
||||||
|
// Both links should exist (different rel = not deduplicated)
|
||||||
|
await expect(page.locator("link#dedup-preload[rel='preload']")).toHaveCount(1);
|
||||||
|
await expect(page.locator("link#dedup-stylesheet[rel='stylesheet']")).toHaveCount(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("links with same href and rel are deduplicated", async ({ page }) => {
|
||||||
|
await page.goto("http://localhost:9990");
|
||||||
|
|
||||||
|
// Only first link should exist (same rel = deduplicated)
|
||||||
|
await expect(page.locator("link#dedup-first")).toHaveCount(1);
|
||||||
|
await expect(page.locator("link#dedup-second")).toHaveCount(0);
|
||||||
|
});
|
||||||
|
|
||||||
test("merge styles", async ({ page }) => {
|
test("merge styles", async ({ page }) => {
|
||||||
await page.goto("http://localhost:9990");
|
await page.goto("http://localhost:9990");
|
||||||
// wait until the div is mounted
|
// wait until the div is mounted
|
||||||
|
|||||||
@@ -154,6 +154,32 @@ fn DocumentElements() -> Element {
|
|||||||
document::Stylesheet { id: "stylesheet-head", href: "https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic" }
|
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::Script { id: "script-head", async: true, "console.log('hello world');" }
|
||||||
document::Style { id: "style-head", "body {{ font-family: 'Roboto'; }}" }
|
document::Style { id: "style-head", "body {{ font-family: 'Roboto'; }}" }
|
||||||
|
|
||||||
|
// Test that links with same href but different rel are NOT deduplicated
|
||||||
|
// See https://github.com/DioxusLabs/dioxus/issues/5070
|
||||||
|
document::Link {
|
||||||
|
id: "dedup-preload",
|
||||||
|
rel: "preload",
|
||||||
|
href: "dedup-test.css",
|
||||||
|
r#as: "style",
|
||||||
|
}
|
||||||
|
document::Link {
|
||||||
|
id: "dedup-stylesheet",
|
||||||
|
rel: "stylesheet",
|
||||||
|
href: "dedup-test.css",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that links with same href AND same rel ARE deduplicated
|
||||||
|
document::Link {
|
||||||
|
id: "dedup-first",
|
||||||
|
rel: "stylesheet",
|
||||||
|
href: "dedup-same.css",
|
||||||
|
}
|
||||||
|
document::Link {
|
||||||
|
id: "dedup-second",
|
||||||
|
rel: "stylesheet",
|
||||||
|
href: "dedup-same.css",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user