astro 3.0.9 → 3.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ViewTransitions.astro +46 -46
- package/dist/assets/vite-plugin-assets.js +3 -2
- package/dist/cli/telemetry/index.js +1 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/messages.js +2 -2
- package/dist/runtime/server/render/any.js +2 -0
- package/package.json +2 -2
|
@@ -19,7 +19,9 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
19
19
|
};
|
|
20
20
|
type Events = 'astro:page-load' | 'astro:after-swap';
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
// only update history entries that are managed by us
|
|
23
|
+
// leave other entries alone and do not accidently add state.
|
|
24
|
+
const persistState = (state: State) => history.state && history.replaceState(state, '');
|
|
23
25
|
const supportsViewTransitions = !!document.startViewTransition;
|
|
24
26
|
const transitionEnabledOnThisPage = () =>
|
|
25
27
|
!!document.querySelector('[name="astro-view-transitions-enabled"]');
|
|
@@ -32,11 +34,13 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
32
34
|
// can use that to determine popstate if going forward or back.
|
|
33
35
|
let currentHistoryIndex = 0;
|
|
34
36
|
if (history.state) {
|
|
35
|
-
// we reloaded a page with history state
|
|
37
|
+
// we reloaded a page with history state
|
|
38
|
+
// (e.g. history navigation from non-transition page or browser reload)
|
|
36
39
|
currentHistoryIndex = history.state.index;
|
|
37
40
|
scrollTo({ left: 0, top: history.state.scrollY });
|
|
41
|
+
} else if (transitionEnabledOnThisPage()) {
|
|
42
|
+
history.replaceState({ index: currentHistoryIndex, scrollY }, '');
|
|
38
43
|
}
|
|
39
|
-
|
|
40
44
|
const throttle = (cb: (...args: any[]) => any, delay: number) => {
|
|
41
45
|
let wait = false;
|
|
42
46
|
// During the waiting time additional events are lost.
|
|
@@ -102,20 +106,14 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
102
106
|
|
|
103
107
|
function isInfinite(animation: Animation) {
|
|
104
108
|
const effect = animation.effect;
|
|
105
|
-
if(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
) return false;
|
|
110
|
-
const style = window.getComputedStyle(effect.target, effect.pseudoElement);
|
|
111
|
-
return style.animationIterationCount === "infinite";
|
|
112
|
-
}
|
|
109
|
+
if (!effect || !(effect instanceof KeyframeEffect) || !effect.target) return false;
|
|
110
|
+
const style = window.getComputedStyle(effect.target, effect.pseudoElement);
|
|
111
|
+
return style.animationIterationCount === 'infinite';
|
|
112
|
+
}
|
|
113
113
|
|
|
114
114
|
const parser = new DOMParser();
|
|
115
115
|
|
|
116
|
-
async function updateDOM(
|
|
117
|
-
const doc = parser.parseFromString(html, 'text/html');
|
|
118
|
-
|
|
116
|
+
async function updateDOM(doc: Document, loc: URL, state?: State, fallback?: Fallback) {
|
|
119
117
|
// Check for a head element that should persist, either because it has the data
|
|
120
118
|
// attribute or is a link el.
|
|
121
119
|
const persistedHeadElement = (el: Element): Element | null => {
|
|
@@ -193,19 +191,17 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
193
191
|
// Chromium based browsers (Chrome, Edge, Opera, ...)
|
|
194
192
|
scrollTo({ left: 0, top: 0, behavior: 'instant' });
|
|
195
193
|
|
|
196
|
-
|
|
197
|
-
|
|
194
|
+
let initialScrollY = 0;
|
|
195
|
+
if (!state && loc.hash) {
|
|
196
|
+
const id = decodeURIComponent(loc.hash.slice(1));
|
|
198
197
|
const elem = document.getElementById(id);
|
|
199
198
|
// prefer scrollIntoView() over scrollTo() because it takes scroll-padding into account
|
|
200
|
-
|
|
201
|
-
state.scrollY = elem.offsetTop;
|
|
202
|
-
persistState(state); // first guess, later updated by scroll handler
|
|
203
|
-
elem.scrollIntoView(); // for Firefox, this should better be {behavior: 'instant'}
|
|
204
|
-
}
|
|
199
|
+
elem && (initialScrollY = elem.offsetTop) && elem.scrollIntoView();
|
|
205
200
|
} else if (state && state.scrollY !== 0) {
|
|
206
201
|
scrollTo(0, state.scrollY); // usings default scrollBehavior
|
|
207
202
|
}
|
|
208
|
-
|
|
203
|
+
!state &&
|
|
204
|
+
history.pushState({ index: ++currentHistoryIndex, scrollY: initialScrollY }, '', loc.href);
|
|
209
205
|
triggerEvent('astro:after-swap');
|
|
210
206
|
};
|
|
211
207
|
|
|
@@ -236,8 +232,10 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
236
232
|
// Trigger the animations
|
|
237
233
|
const currentAnimations = document.getAnimations();
|
|
238
234
|
document.documentElement.dataset.astroTransitionFallback = 'old';
|
|
239
|
-
const newAnimations = document
|
|
240
|
-
|
|
235
|
+
const newAnimations = document
|
|
236
|
+
.getAnimations()
|
|
237
|
+
.filter((a) => !currentAnimations.includes(a) && !isInfinite(a));
|
|
238
|
+
const finished = Promise.all(newAnimations.map((a) => a.finished));
|
|
241
239
|
const fallbackSwap = () => {
|
|
242
240
|
swap();
|
|
243
241
|
document.documentElement.dataset.astroTransitionFallback = 'new';
|
|
@@ -249,19 +247,26 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
249
247
|
}
|
|
250
248
|
}
|
|
251
249
|
|
|
252
|
-
async function navigate(dir: Direction,
|
|
250
|
+
async function navigate(dir: Direction, loc: URL, state?: State) {
|
|
253
251
|
let finished: Promise<void>;
|
|
252
|
+
const href = loc.href;
|
|
254
253
|
const { html, ok } = await getHTML(href);
|
|
255
254
|
// If there is a problem fetching the new page, just do an MPA navigation to it.
|
|
256
255
|
if (!ok) {
|
|
257
256
|
location.href = href;
|
|
258
257
|
return;
|
|
259
258
|
}
|
|
259
|
+
const doc = parser.parseFromString(html, 'text/html');
|
|
260
|
+
if (!doc.querySelector('[name="astro-view-transitions-enabled"]')) {
|
|
261
|
+
location.href = href;
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
260
265
|
document.documentElement.dataset.astroTransition = dir;
|
|
261
266
|
if (supportsViewTransitions) {
|
|
262
|
-
finished = document.startViewTransition(() => updateDOM(
|
|
267
|
+
finished = document.startViewTransition(() => updateDOM(doc, loc, state)).finished;
|
|
263
268
|
} else {
|
|
264
|
-
finished = updateDOM(
|
|
269
|
+
finished = updateDOM(doc, loc, state, getFallback());
|
|
265
270
|
}
|
|
266
271
|
try {
|
|
267
272
|
await finished;
|
|
@@ -313,11 +318,11 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
313
318
|
ev.shiftKey || // new window
|
|
314
319
|
ev.defaultPrevented ||
|
|
315
320
|
!transitionEnabledOnThisPage()
|
|
316
|
-
)
|
|
321
|
+
) {
|
|
317
322
|
// No page transitions in these cases,
|
|
318
323
|
// Let the browser standard action handle this
|
|
319
324
|
return;
|
|
320
|
-
|
|
325
|
+
}
|
|
321
326
|
// We do not need to handle same page links because there are no page transitions
|
|
322
327
|
// Same page means same path and same query params (but different hash)
|
|
323
328
|
if (location.pathname === link.pathname && location.search === link.search) {
|
|
@@ -343,10 +348,8 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
343
348
|
|
|
344
349
|
// these are the cases we will handle: same origin, different page
|
|
345
350
|
ev.preventDefault();
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
persistState({ index: currentHistoryIndex - 1, scrollY });
|
|
349
|
-
history.pushState(newState, '', link.href);
|
|
351
|
+
persistState({ index: currentHistoryIndex, scrollY });
|
|
352
|
+
navigate('forward', new URL(link.href));
|
|
350
353
|
});
|
|
351
354
|
|
|
352
355
|
addEventListener('popstate', (ev) => {
|
|
@@ -354,7 +357,7 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
354
357
|
// The current page doesn't haven't View Transitions,
|
|
355
358
|
// respect that with a full page reload
|
|
356
359
|
// -- but only for transition managed by us (ev.state is set)
|
|
357
|
-
history.scrollRestoration && (history.scrollRestoration =
|
|
360
|
+
history.scrollRestoration && (history.scrollRestoration = 'manual');
|
|
358
361
|
location.reload();
|
|
359
362
|
return;
|
|
360
363
|
}
|
|
@@ -365,7 +368,7 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
365
368
|
// The browser will handle navigation fine without our help
|
|
366
369
|
if (ev.state === null) {
|
|
367
370
|
if (history.scrollRestoration) {
|
|
368
|
-
history.scrollRestoration =
|
|
371
|
+
history.scrollRestoration = 'auto';
|
|
369
372
|
}
|
|
370
373
|
return;
|
|
371
374
|
}
|
|
@@ -373,14 +376,14 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
373
376
|
// With the default "auto", the browser will jump to the old scroll position
|
|
374
377
|
// before the ViewTransition is complete.
|
|
375
378
|
if (history.scrollRestoration) {
|
|
376
|
-
history.scrollRestoration =
|
|
379
|
+
history.scrollRestoration = 'manual';
|
|
377
380
|
}
|
|
378
381
|
|
|
379
|
-
const state: State
|
|
380
|
-
const nextIndex = state
|
|
382
|
+
const state: State = history.state;
|
|
383
|
+
const nextIndex = state.index;
|
|
381
384
|
const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back';
|
|
382
|
-
navigate(direction, location.href, state);
|
|
383
385
|
currentHistoryIndex = nextIndex;
|
|
386
|
+
navigate(direction, new URL(location.href), state);
|
|
384
387
|
});
|
|
385
388
|
|
|
386
389
|
['mouseenter', 'touchstart', 'focus'].forEach((evName) => {
|
|
@@ -404,13 +407,10 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
404
407
|
addEventListener('load', onPageLoad);
|
|
405
408
|
// There's not a good way to record scroll position before a back button.
|
|
406
409
|
// So the way we do it is by listening to scrollend if supported, and if not continuously record the scroll position.
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
persistState({ ...history.state, scrollY });
|
|
412
|
-
}
|
|
413
|
-
}
|
|
410
|
+
const updateState = () => {
|
|
411
|
+
persistState({ ...history.state, scrollY });
|
|
412
|
+
};
|
|
413
|
+
|
|
414
414
|
if ('onscrollend' in window) addEventListener('scrollend', updateState);
|
|
415
415
|
else addEventListener('scroll', throttle(updateState, 300));
|
|
416
416
|
}
|
|
@@ -6,10 +6,11 @@ import {
|
|
|
6
6
|
prependForwardSlash,
|
|
7
7
|
removeQueryString
|
|
8
8
|
} from "../core/path.js";
|
|
9
|
-
import { VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from "./consts.js";
|
|
9
|
+
import { VALID_INPUT_FORMATS, VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from "./consts.js";
|
|
10
10
|
import { emitESMImage } from "./utils/emitAsset.js";
|
|
11
11
|
import { hashTransform, propsToFilename } from "./utils/transformToPath.js";
|
|
12
12
|
const resolvedVirtualModuleId = "\0" + VIRTUAL_MODULE_ID;
|
|
13
|
+
const assetRegex = new RegExp(`.(${VALID_INPUT_FORMATS.join("|")})$`, "i");
|
|
13
14
|
function assets({
|
|
14
15
|
settings,
|
|
15
16
|
mode
|
|
@@ -99,7 +100,7 @@ function assets({
|
|
|
99
100
|
if (id !== removeQueryString(id)) {
|
|
100
101
|
return;
|
|
101
102
|
}
|
|
102
|
-
if (
|
|
103
|
+
if (assetRegex.test(id)) {
|
|
103
104
|
const meta = await emitESMImage(id, this.meta.watchMode, this.emitFile);
|
|
104
105
|
return `export default ${JSON.stringify(meta)}`;
|
|
105
106
|
}
|
|
@@ -2,7 +2,7 @@ import whichPm from "which-pm";
|
|
|
2
2
|
import * as msg from "../../core/messages.js";
|
|
3
3
|
import { telemetry } from "../../events/index.js";
|
|
4
4
|
async function notify() {
|
|
5
|
-
const packageManager = (await whichPm(process.cwd()))
|
|
5
|
+
const packageManager = (await whichPm(process.cwd()))?.name ?? "npm";
|
|
6
6
|
await telemetry.notify(() => {
|
|
7
7
|
console.log(msg.telemetryNotice(packageManager) + "\n");
|
|
8
8
|
return true;
|
package/dist/core/constants.js
CHANGED
package/dist/core/dev/dev.js
CHANGED
|
@@ -20,7 +20,7 @@ async function dev(inlineConfig) {
|
|
|
20
20
|
base: restart.container.settings.config.base
|
|
21
21
|
})
|
|
22
22
|
);
|
|
23
|
-
const currentVersion = "3.0.
|
|
23
|
+
const currentVersion = "3.0.11";
|
|
24
24
|
if (currentVersion.includes("-")) {
|
|
25
25
|
logger.warn(null, msg.prerelease({ currentVersion }));
|
|
26
26
|
}
|
package/dist/core/messages.js
CHANGED
|
@@ -50,7 +50,7 @@ function serverStart({
|
|
|
50
50
|
base,
|
|
51
51
|
isRestart = false
|
|
52
52
|
}) {
|
|
53
|
-
const version = "3.0.
|
|
53
|
+
const version = "3.0.11";
|
|
54
54
|
const localPrefix = `${dim("\u2503")} Local `;
|
|
55
55
|
const networkPrefix = `${dim("\u2503")} Network `;
|
|
56
56
|
const emptyPrefix = " ".repeat(11);
|
|
@@ -235,7 +235,7 @@ function printHelp({
|
|
|
235
235
|
message.push(
|
|
236
236
|
linebreak(),
|
|
237
237
|
` ${bgGreen(black(` ${commandName} `))} ${green(
|
|
238
|
-
`v${"3.0.
|
|
238
|
+
`v${"3.0.11"}`
|
|
239
239
|
)} ${headline}`
|
|
240
240
|
);
|
|
241
241
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.11",
|
|
4
4
|
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "withastro",
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
"yargs-parser": "^21.1.1",
|
|
160
160
|
"zod": "3.21.1",
|
|
161
161
|
"@astrojs/internal-helpers": "0.2.0",
|
|
162
|
-
"@astrojs/markdown-remark": "3.
|
|
162
|
+
"@astrojs/markdown-remark": "3.1.0",
|
|
163
163
|
"@astrojs/telemetry": "3.0.1"
|
|
164
164
|
},
|
|
165
165
|
"optionalDependencies": {
|