Skip to content

Commit 6298812

Browse files
authored
Fix root-relative @import URLs as passed to importers (#1371)
Closes #1137
1 parent 5a9dd91 commit 6298812

File tree

4 files changed

+47
-1
lines changed

4 files changed

+47
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
relying on this bug, but if so they can simply add `!global` to the variable
77
declaration to preserve the old behavior.
88

9+
* **Potentially breaking bug fix:** Fix a bug where imports of root-relative
10+
URLs (those that begin with `/`) in `@import` rules would be passed to
11+
both Dart and JS importers as `file:` URLs.
12+
913
## 1.35.1
1014

1115
* Fix a bug where the quiet dependency flag didn't silence warnings in some

lib/src/parse/stylesheet.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,9 @@ abstract class StylesheetParser extends Parser {
11201120
String parseImportUrl(String url) {
11211121
// Backwards-compatibility for implementations that allow absolute Windows
11221122
// paths in imports.
1123-
if (p.windows.isAbsolute(url)) return p.windows.toUri(url).toString();
1123+
if (p.windows.isAbsolute(url) && !p.url.isRootRelative(url)) {
1124+
return p.windows.toUri(url).toString();
1125+
}
11241126

11251127
// Throw a [FormatException] if [url] is invalid.
11261128
Uri.parse(url);

test/dart_api/importer_test.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,27 @@ void main() {
9393
'''));
9494
});
9595

96+
group("the imported URL", () {
97+
// Regression test for #1137.
98+
test("isn't changed if it's root-relative", () {
99+
compileString('@import "/orange";', importers: [
100+
TestImporter(expectAsync1((url) {
101+
expect(url, equals(Uri.parse("/orange")));
102+
return Uri.parse("u:$url");
103+
}), (url) => ImporterResult('', syntax: Syntax.scss))
104+
]);
105+
});
106+
107+
test("is converted to a file: URL if it's an absolute Windows path", () {
108+
compileString('@import "C:/orange";', importers: [
109+
TestImporter(expectAsync1((url) {
110+
expect(url, equals(Uri.parse("file:///C:/orange")));
111+
return Uri.parse("u:$url");
112+
}), (url) => ImporterResult('', syntax: Syntax.scss))
113+
]);
114+
});
115+
});
116+
96117
test("uses an importer's source map URL", () {
97118
late SingleMapping map;
98119
compileString('@import "orange";',

test/node_api/importer_test.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,25 @@ void main() {
364364
}))));
365365
expect(result.stats.includedFiles, equals(['foo']));
366366
});
367+
368+
// Regression test for #1137.
369+
test("isn't changed if it's root-relative", () {
370+
renderSync(RenderOptions(
371+
data: "@import '/foo'",
372+
importer: allowInterop(expectAsync2((url, _) {
373+
expect(url, equals('/foo'));
374+
return NodeImporterResult(contents: '');
375+
}))));
376+
});
377+
378+
test("is converted to a file: URL if it's an absolute Windows path", () {
379+
renderSync(RenderOptions(
380+
data: "@import 'C:/foo'",
381+
importer: allowInterop(expectAsync2((url, _) {
382+
expect(url, equals('file:///C:/foo'));
383+
return NodeImporterResult(contents: '');
384+
}))));
385+
});
367386
});
368387

369388
group("the previous URL", () {

0 commit comments

Comments
 (0)