Fix for checking media type in CSR (#8537)
* bugfix checking media-type * bugfix checking media-type * Update packages/astro/components/ViewTransitions.astro .* is longest possible run, but a dollar won't harm us :) Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com> * make typescript happy --------- Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
This commit is contained in:
parent
eb3c33cff7
commit
f95febf96b
2 changed files with 20 additions and 15 deletions
5
.changeset/sixty-beds-give.md
Normal file
5
.changeset/sixty-beds-give.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
bugfix checking media-type in client-side router
|
|
@ -65,19 +65,19 @@ const { fallback = 'animate' } = Astro.props as Props;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getHTML(href: string) {
|
async function getHTML(href: string) {
|
||||||
let res;
|
|
||||||
try {
|
try {
|
||||||
res = await fetch(href);
|
const res = await fetch(href);
|
||||||
} catch (err) {
|
|
||||||
return { ok: false };
|
|
||||||
}
|
|
||||||
const html = await res.text();
|
const html = await res.text();
|
||||||
return {
|
return {
|
||||||
ok: res.ok,
|
ok: res.ok,
|
||||||
html,
|
html,
|
||||||
redirected: res.redirected ? res.url : undefined,
|
redirected: res.redirected ? res.url : undefined,
|
||||||
contentType: res.headers.get('content-type'),
|
// drop potential charset (+ other name/value pairs) as parser needs the mediaType
|
||||||
|
mediaType: res.headers.get('content-type')?.replace(/;.*$/, ''),
|
||||||
};
|
};
|
||||||
|
} catch (err) {
|
||||||
|
return { ok: false };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFallback(): Fallback {
|
function getFallback(): Fallback {
|
||||||
|
@ -126,13 +126,13 @@ const { fallback = 'animate' } = Astro.props as Props;
|
||||||
|
|
||||||
// A noop element used to prevent styles from being removed
|
// A noop element used to prevent styles from being removed
|
||||||
if (import.meta.env.DEV) {
|
if (import.meta.env.DEV) {
|
||||||
var noopEl: string | undefined = document.createElement('div');
|
var noopEl = document.createElement('div');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateDOM(doc: Document, loc: URL, state?: State, fallback?: Fallback) {
|
async function updateDOM(doc: Document, loc: URL, state?: State, fallback?: Fallback) {
|
||||||
// Check for a head element that should persist, either because it has the data
|
// Check for a head element that should persist, either because it has the data
|
||||||
// attribute or is a link el.
|
// attribute or is a link el.
|
||||||
const persistedHeadElement = (el: Element): Element | null => {
|
const persistedHeadElement = (el: HTMLElement): Element | null => {
|
||||||
const id = el.getAttribute(PERSIST_ATTR);
|
const id = el.getAttribute(PERSIST_ATTR);
|
||||||
const newEl = id && doc.head.querySelector(`[${PERSIST_ATTR}="${id}"]`);
|
const newEl = id && doc.head.querySelector(`[${PERSIST_ATTR}="${id}"]`);
|
||||||
if (newEl) {
|
if (newEl) {
|
||||||
|
@ -189,7 +189,7 @@ const { fallback = 'animate' } = Astro.props as Props;
|
||||||
|
|
||||||
// Swap head
|
// Swap head
|
||||||
for (const el of Array.from(document.head.children)) {
|
for (const el of Array.from(document.head.children)) {
|
||||||
const newEl = persistedHeadElement(el);
|
const newEl = persistedHeadElement(el as HTMLElement);
|
||||||
// If the element exists in the document already, remove it
|
// If the element exists in the document already, remove it
|
||||||
// from the new document and leave the current node alone
|
// from the new document and leave the current node alone
|
||||||
if (newEl) {
|
if (newEl) {
|
||||||
|
@ -290,16 +290,16 @@ const { fallback = 'animate' } = Astro.props as Props;
|
||||||
async function navigate(dir: Direction, loc: URL, state?: State) {
|
async function navigate(dir: Direction, loc: URL, state?: State) {
|
||||||
let finished: Promise<void>;
|
let finished: Promise<void>;
|
||||||
const href = loc.href;
|
const href = loc.href;
|
||||||
const { html, ok, contentType, redirected } = await getHTML(href);
|
const { html, ok, mediaType, redirected } = await getHTML(href);
|
||||||
// if there was a redirection, show the final URL in the browser's address bar
|
// if there was a redirection, show the final URL in the browser's address bar
|
||||||
redirected && (loc = new URL(redirected));
|
redirected && (loc = new URL(redirected));
|
||||||
// If there is a problem fetching the new page, just do an MPA navigation to it.
|
// If there is a problem fetching the new page, just do an MPA navigation to it.
|
||||||
if (!ok || contentType !== 'text/html') {
|
if (!ok || !(mediaType === 'text/html' || mediaType === 'application/xhtml+xml')) {
|
||||||
location.href = href;
|
location.href = href;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const doc = parser.parseFromString(html, contentType);
|
const doc = parser.parseFromString(html, mediaType);
|
||||||
if (!doc.querySelector('[name="astro-view-transitions-enabled"]')) {
|
if (!doc.querySelector('[name="astro-view-transitions-enabled"]')) {
|
||||||
location.href = href;
|
location.href = href;
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue