Skip to content

Commit 43a2a7d

Browse files
clydinalan-agius4
authored andcommitted
fix(@angular/build): avoid escaping rebased Sass URL values
Remove escaping of the raw existing values present within a URL when rebasing Sass files. These values are present in input code and should retain their respective errors and behavior as written. The escaping of the prefixed path is retained to prevent parsing errors for the internally injected values. (cherry picked from commit 721d50b)
1 parent 346df49 commit 43a2a7d

File tree

2 files changed

+33
-28
lines changed

2 files changed

+33
-28
lines changed

packages/angular/build/src/builders/application/tests/behavior/stylesheet-url-resolution_spec.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,36 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
295295
harness.expectFile('dist/browser/media/logo.svg').toExist();
296296
});
297297

298+
it('should rebase a URL with interpolation using concatenation referencing a local resource', async () => {
299+
await harness.writeFiles({
300+
'src/styles.scss': `@use 'theme/a';`,
301+
'src/theme/a.scss': `
302+
@import './b';
303+
$extra-var: "2";
304+
$postfix-var: "xyz";
305+
.a {
306+
background-image: url("#{$my-var}logo#{$extra-var+ "-" + $postfix-var}.svg")
307+
}
308+
`,
309+
'src/theme/b.scss': `$my-var: "./images/";`,
310+
'src/theme/images/logo2-xyz.svg': `<svg></svg>`,
311+
});
312+
313+
harness.useTarget('build', {
314+
...BASE_OPTIONS,
315+
outputHashing: OutputHashing.None,
316+
styles: ['src/styles.scss'],
317+
});
318+
319+
const { result } = await harness.executeOnce();
320+
expect(result?.success).toBeTrue();
321+
322+
harness
323+
.expectFile('dist/browser/styles.css')
324+
.content.toContain(`url("./media/logo2-xyz.svg")`);
325+
harness.expectFile('dist/browser/media/logo2-xyz.svg').toExist();
326+
});
327+
298328
it('should rebase a URL with an non-leading interpolation referencing a local resource', async () => {
299329
await harness.writeFiles({
300330
'src/styles.scss': `@use 'theme/a';`,

packages/angular/build/src/tools/sass/rebasing-importer.ts

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,6 @@ export interface DirectoryEntry {
2424
directories: Set<string>;
2525
}
2626

27-
/**
28-
* Ensures that a bare specifier URL path that is intended to be treated as
29-
* a relative path has a leading `./` or `../` prefix.
30-
*
31-
* @param url A bare specifier URL path that should be considered relative.
32-
* @returns
33-
*/
34-
function ensureRelative(url: string): string {
35-
// Empty
36-
if (!url) {
37-
return url;
38-
}
39-
40-
// Already relative
41-
if (url[0] === '.' && (url[1] === '/' || (url[1] === '.' && url[2] === '/'))) {
42-
return url;
43-
}
44-
45-
// Needs prefix
46-
return './' + url;
47-
}
48-
4927
/**
5028
* A Sass Importer base class that provides the load logic to rebase all `url()` functions
5129
* within a stylesheet. The rebasing will ensure that the URLs in the output of the Sass compiler
@@ -100,18 +78,15 @@ abstract class UrlRebasingImporter implements Importer<'sync'> {
10078

10179
// Sass variable usage either starts with a `$` or contains a namespace and a `.$`
10280
const valueNormalized = value[0] === '$' || /^\w+\.\$/.test(value) ? `#{${value}}` : value;
103-
const rebasedPath =
104-
relative(this.entryDirectory, stylesheetDirectory) + '||file:' + valueNormalized;
81+
const rebasedPath = relative(this.entryDirectory, stylesheetDirectory);
10582

10683
// Normalize path separators and escape characters
10784
// https://developer.mozilla.org/en-US/docs/Web/CSS/url#syntax
108-
const rebasedUrl = ensureRelative(
109-
rebasedPath.replace(/\\/g, '/').replace(/[()\s'"]/g, '\\$&'),
110-
);
85+
const rebasedUrl = rebasedPath.replace(/\\/g, '/').replace(/[()\s'"]/g, '\\$&');
11186

11287
updatedContents ??= new MagicString(contents);
11388
// Always quote the URL to avoid potential downstream parsing problems
114-
updatedContents.update(start, end, `"${rebasedUrl}"`);
89+
updatedContents.update(start, end, `"${rebasedUrl}||file:${valueNormalized}"`);
11590
}
11691

11792
if (updatedContents) {

0 commit comments

Comments
 (0)