Repository navigation
fix(core): a sub-composition's stylesheet from the project root loads in the preview - #5143
Draft
miguel-heygen wants to merge 2 commits into
Draft
miguel-heygen wants to merge 2 commits into
miguel-heygen wants to merge 2 commits into
Conversation
Contributor
Edit accuracy: accurate 2059 (base branch 2059), smooth 1601 of thoseThe gate passes. Quarantined, measured but not gated (0) |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A
<link rel="stylesheet" href="assets/theme.css">inside a sub-composition now loads in the preview from the same place the render loads it, instead of 404ing atcompositions/assets/theme.cssand leaving the sub-composition unstyled.Why
The compiler and the runtime loader resolve a sub-composition's relative paths by one rule (
rewriteAssetPathinparsers/src/rewriteSubCompPaths.ts): a../path is relative to the composition's file; a plain path is the file beside the composition when one exists, otherwise the project root's. The runtime loader follows that rule for[src]/[href]attributes and<script src>, but the<link>it hoists into the document head resolved every href against the composition's URL. So a stylesheet authored the way the render accepts it (assets/theme.cssfromcompositions/scene.html) rendered styled and previewed unstyled.To reproduce on main: a project with
assets/theme.cssandcompositions/scene.htmlwhose<template>holds<link rel="stylesheet" href="assets/theme.css">, mounted fromindex.htmlwithdata-composition-src="compositions/scene.html". The preview requestscompositions/assets/theme.css(404); the render inlinesassets/theme.css.Related work
None.
How
hoistedLinkHrefinruntime/compositionLoader.tsgives the hoisted link the compiler's rule. The runtime cannot read the disk, so for a plain href whose sibling and project-root URLs differ it sends oneHEADfor the sibling (the preview server answers a missing file with 404) and uses the sibling only when it is there; otherwise the project-root URL.../hrefs are already absolute by then (rewriteSubCompositionAssetPaths), and absolute, root anddata:hrefs resolve as before. A sibling stylesheet beside its composition (_shared.css) still resolves beside it.Test plan
compositionLoader.test.ts, "a plain stylesheet path resolves as the render does", with no sibling file (the project root) and with a sibling (beside the composition). On main the no-sibling case fails (it getscompositions/assets/theme.css) and the sibling case passes; with the fix both pass. The file's 68 tests pass 3 runs in a row; the existing sibling-link tests are unchanged and pass.studio-server/src/routes/preview.ts(a missing file answers 404; Hono answersHEADfrom theGETroute), not by a request.packages/coretypecheck and oxlint/oxfmt on the changed files are clean. The full core suite was not compared against main locally (the run reported failures in files that do not import the loader and fail without built sibling packages; the baseline comparison could not complete), so CI is the full-suite check.