UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

71 lines (70 loc) • 2.38 kB
import { makePageDataKey } from "./plugins/util.js"; /** * From its route and component, get the page data from the build internals. * @param internals Build Internals with all the pages * @param route The route of the page, used to identify the page * @param component The component of the page, used to identify the page */ export function getPageData(internals, route, component) { let pageData = internals.pagesByKeys.get(makePageDataKey(route, component)); if (pageData) { return pageData; } return undefined; } /** * Sort a page's CSS by depth. A higher depth means that the CSS comes from shared subcomponents. * A lower depth means it comes directly from the top-level page. * Can be used to sort stylesheets so that shared rules come first * and page-specific rules come after. */ export function cssOrder(a, b) { let depthA = a.depth, depthB = b.depth, orderA = a.order, orderB = b.order; if (orderA === -1 && orderB >= 0) { return 1; } else if (orderB === -1 && orderA >= 0) { return -1; } else if (orderA > orderB) { return 1; } else if (orderA < orderB) { return -1; } else { if (depthA === -1) { return -1; } else if (depthB === -1) { return 1; } else { return depthA > depthB ? -1 : 1; } } } /** * Merges inline CSS into as few stylesheets as possible, * preserving ordering when there are non-inlined in between. * * CSS chunks containing `@import` are never merged with other chunks. * Per CSS spec, `@import` rules must appear at the top of a stylesheet * or browsers silently ignore them. Keeping these chunks as separate * `<style>` tags ensures the `@import` stays at the top of its own stylesheet. */ export function mergeInlineCss(acc, current) { const lastAdded = acc.at(acc.length - 1); const lastWasInline = lastAdded?.type === "inline"; const currentIsInline = current?.type === "inline"; if (lastWasInline && currentIsInline) { // Don't merge chunks that contain @import rules — they must be at the // top of their stylesheet to be valid CSS. const currentHasImport = current.content.includes("@import"); const lastHasImport = lastAdded.content.includes("@import"); if (!currentHasImport && !lastHasImport) { const merged = { type: "inline", content: lastAdded.content + current.content }; acc[acc.length - 1] = merged; return acc; } } acc.push(current); return acc; }