Skip to content

Commit

Permalink
fix(@angular/build): properly rebase Sass url() values with leading i…
Browse files Browse the repository at this point in the history
…nterpolations

Previously, the Sass url() rebasing logic was skipping values that contained
leading Sass interpolations. This was because an interpolation starts with
the `#` character which in CSS indicates a fragment identifier and not a path.
However, Sass special cases this scenario by checking if the next character is
the `{` character and considers it an interpolation if present. The Angular
rebasing logic will now match this behavior.
  • Loading branch information
clydin committed May 8, 2024
1 parent 5f14787 commit c1b5d20
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,58 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
harness.expectFile('dist/browser/media/logo.svg').toExist();
});

it('should rebase a URL with an leading interpolation referencing a local resource', async () => {
await harness.writeFiles({
'src/styles.scss': `@use 'theme/a';`,
'src/theme/a.scss': `
@import './b';
.a {
background-image: url(#{$my-var}logo.svg)
}
`,
'src/theme/b.scss': `$my-var: "./images/";`,
'src/theme/images/logo.svg': `<svg></svg>`,
});

harness.useTarget('build', {
...BASE_OPTIONS,
outputHashing: OutputHashing.None,
styles: ['src/styles.scss'],
});

const { result } = await harness.executeOnce();
expect(result?.success).toBeTrue();

harness.expectFile('dist/browser/styles.css').content.toContain(`url("./media/logo.svg")`);
harness.expectFile('dist/browser/media/logo.svg').toExist();
});

it('should rebase a URL with an non-leading interpolation referencing a local resource', async () => {
await harness.writeFiles({
'src/styles.scss': `@use 'theme/a';`,
'src/theme/a.scss': `
@import './b';
.a {
background-image: url(./#{$my-var}logo.svg)
}
`,
'src/theme/b.scss': `$my-var: "./images/";`,
'src/theme/images/logo.svg': `<svg></svg>`,
});

harness.useTarget('build', {
...BASE_OPTIONS,
outputHashing: OutputHashing.None,
styles: ['src/styles.scss'],
});

const { result } = await harness.executeOnce();
expect(result?.success).toBeTrue();

harness.expectFile('dist/browser/styles.css').content.toContain(`url("./media/logo.svg")`);
harness.expectFile('dist/browser/media/logo.svg').toExist();
});

it('should not process a URL that has been marked as external', async () => {
await harness.writeFiles({
'src/styles.scss': `@use 'theme/a';`,
Expand Down
7 changes: 6 additions & 1 deletion packages/angular/build/src/tools/sass/rebasing-importer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,12 @@ abstract class UrlRebasingImporter implements Importer<'sync'> {
}

// Skip if root-relative, absolute or protocol relative url
if (/^((?:\w+:)?\/\/|data:|chrome:|#|\/)/.test(value)) {
if (/^((?:\w+:)?\/\/|data:|chrome:|\/)/.test(value)) {
continue;
}

// Skip if a fragment identifier but not a Sass interpolation
if (value[0] === '#' && value[1] !== '{') {
continue;
}

Expand Down

0 comments on commit c1b5d20

Please sign in to comment.