mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-09 22:25:02 +03:00
fix(session-ui): render the link globe as its own element and drop it once the favicon loads (#61417)
This commit is contained in:
committed by
GitHub
Unverified
parent
6d1c444b8c
commit
ce8ca3084e
@@ -1,4 +1,4 @@
|
||||
import type { Page } from "@playwright/test"
|
||||
import type { Locator, Page } from "@playwright/test"
|
||||
import { expect, sourceURL, story } from "../../stories/playwright/story"
|
||||
|
||||
const png = Buffer.from(
|
||||
@@ -318,8 +318,9 @@ story("shows a stable GitHub mark without changing link text or other sites", as
|
||||
await expect(github).toHaveAttribute("href", "https://github.com/anomalyco/opencode/pull/540")
|
||||
await expect(github).toHaveText("#540")
|
||||
const mark = github.locator(".markdown-link-favicon[data-github]")
|
||||
expect(await mark.evaluate((icon) => getComputedStyle(icon, "::before").width)).toBe("14px")
|
||||
expect(await mark.evaluate((icon) => getComputedStyle(icon, "::before").maskImage)).toContain("data:image/svg+xml")
|
||||
const glyph = mark.locator(".markdown-link-favicon-glyph")
|
||||
expect(await glyph.evaluate((icon) => getComputedStyle(icon).width)).toBe("14px")
|
||||
expect(await glyph.evaluate((icon) => getComputedStyle(icon).maskImage)).toContain("data:image/svg+xml")
|
||||
await expect(mark.locator("img")).toHaveCount(0)
|
||||
await expect(markdown.getByRole("link", { name: "GitHub" }).locator(".markdown-link-favicon[data-github]")).toHaveCount(
|
||||
1,
|
||||
@@ -360,8 +361,10 @@ story("keeps favicon space stable across loading and failure without fetching pr
|
||||
await expect(markdown).toHaveAttribute("data-markdown-ready", "")
|
||||
const docs = markdown.getByRole("link", { name: "docs" })
|
||||
const image = docs.locator(".markdown-link-favicon img")
|
||||
const globe = (link: Locator) => link.locator(".markdown-link-favicon-glyph")
|
||||
await expect.poll(() => requested.some((url) => url.includes("developer.mozilla.org"))).toBe(true)
|
||||
await expect(image).toHaveCSS("opacity", "0")
|
||||
await expect(globe(docs)).toBeVisible()
|
||||
expect((await docs.locator(".markdown-link-favicon").boundingBox())?.width).toBe(14)
|
||||
// A late web font swap also changes the link width; measure after fonts settle.
|
||||
await page.evaluate(() => document.fonts.ready.then(() => undefined))
|
||||
@@ -369,6 +372,7 @@ story("keeps favicon space stable across loading and failure without fetching pr
|
||||
release()
|
||||
await expect(image).toHaveAttribute("data-loaded", "")
|
||||
await expect(image).toHaveCSS("opacity", "1")
|
||||
await expect(globe(docs)).toHaveCount(0)
|
||||
await expect(image).not.toHaveAttribute("role", "button")
|
||||
expect(await image.evaluate((favicon) => favicon.onclick)).toBeNull()
|
||||
expect(await docs.evaluate((link) => link.getBoundingClientRect().width)).toBe(width)
|
||||
@@ -384,6 +388,7 @@ story("keeps favicon space stable across loading and failure without fetching pr
|
||||
await expect(
|
||||
markdown.getByRole("link", { name: "missing" }).locator(".markdown-link-favicon img"),
|
||||
).not.toHaveAttribute("data-loaded", "")
|
||||
await expect(globe(markdown.getByRole("link", { name: "missing" }))).toBeVisible()
|
||||
await expect(markdown.getByRole("link", { name: "private" }).locator(".markdown-link-favicon img")).toHaveCount(0)
|
||||
await expect(markdown.getByRole("link", { name: "GitHub" }).locator(".markdown-link-favicon img")).toHaveCount(0)
|
||||
expect(requested).toHaveLength(2)
|
||||
|
||||
@@ -153,8 +153,7 @@
|
||||
margin-inline-end: 4px;
|
||||
}
|
||||
|
||||
.markdown-link-favicon::before {
|
||||
content: "";
|
||||
.markdown-link-favicon-glyph {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
height: 14px;
|
||||
@@ -163,7 +162,7 @@
|
||||
mask: url("./markdown-globe.svg") center / contain no-repeat;
|
||||
}
|
||||
|
||||
.markdown-link-favicon[data-github]::before {
|
||||
.markdown-link-favicon[data-github] .markdown-link-favicon-glyph {
|
||||
mask-image: url("./markdown-github.svg");
|
||||
}
|
||||
|
||||
|
||||
@@ -361,6 +361,9 @@ function markExternalLinkFavicons(root: HTMLDivElement) {
|
||||
favicon.className = "markdown-link-favicon"
|
||||
favicon.setAttribute("aria-hidden", "true")
|
||||
const host = url.hostname.toLowerCase()
|
||||
const glyph = document.createElement("span")
|
||||
glyph.className = "markdown-link-favicon-glyph"
|
||||
favicon.appendChild(glyph)
|
||||
|
||||
if (host === "github.com") favicon.dataset.github = ""
|
||||
else if (
|
||||
@@ -383,13 +386,19 @@ function markExternalLinkFavicons(root: HTMLDivElement) {
|
||||
})
|
||||
}
|
||||
|
||||
// The globe stands in only until the favicon loads; removing it keeps transparent favicons from showing it through.
|
||||
function showFavicon(image: HTMLImageElement) {
|
||||
image.dataset.loaded = ""
|
||||
image.parentElement?.querySelector(".markdown-link-favicon-glyph")?.remove()
|
||||
}
|
||||
|
||||
function setupExternalLinkFavicons(root: HTMLDivElement) {
|
||||
const loaded = (event: Event) => {
|
||||
const image = event.target
|
||||
|
||||
if (!(image instanceof HTMLImageElement) || !image.hasAttribute("data-markdown-favicon")) return
|
||||
|
||||
if (image.naturalWidth > 0) image.dataset.loaded = ""
|
||||
if (image.naturalWidth > 0) showFavicon(image)
|
||||
}
|
||||
|
||||
root.addEventListener("load", loaded, true)
|
||||
@@ -901,7 +910,7 @@ export function Markdown(
|
||||
images?.update(container)
|
||||
previewImages(container)
|
||||
container.querySelectorAll<HTMLImageElement>("img[data-markdown-favicon]").forEach((image) => {
|
||||
if (image.complete && image.naturalWidth > 0) image.dataset.loaded = ""
|
||||
if (image.complete && image.naturalWidth > 0) showFavicon(image)
|
||||
})
|
||||
|
||||
// A button gets the labels of the run that creates it, so the others only need new ones when the language changes.
|
||||
|
||||
Reference in New Issue
Block a user