X Tutup
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions modules/angular2/src/core/compiler/style_url_resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ function extractUrls(resolver: UrlResolver, baseUrl: string, cssText: string, fo
string {
return StringWrapper.replaceAllMapped(cssText, _cssImportRe, (m) => {
var url = isPresent(m[1]) ? m[1] : m[2];
var schemeMatch = RegExpWrapper.firstMatch(_urlWithSchemaRe, url);
if (isPresent(schemeMatch) && schemeMatch[1] != 'package') {
// Do not attempt to resolve non-package absolute URLs with URI scheme
return m[0];
}
foundUrls.push(resolver.resolve(baseUrl, url));
return '';
});
Expand All @@ -50,3 +55,6 @@ var _cssUrlRe = /(url\()([^)]*)(\))/g;
var _cssImportRe = /@import\s+(?:url\()?\s*(?:(?:['"]([^'"]*))|([^;\)\s]*))[^;]*;?/g;
var _quoteRe = /['"]/g;
var _dataUrlRe = /^['"]?data:/g;
// TODO: can't use /^[^:/?#.]+:/g due to clang-format bug:
// https://github.com/angular/angular/issues/4596
var _urlWithSchemaRe = /^['"]?([a-zA-Z\-\+\.]+):/g;
11 changes: 11 additions & 0 deletions modules/angular2/src/core/dom/emulated_css.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ List<EmulatedCssRule> emulateRules(Iterable<cssv.TreeNode> rules) {
return new EmulatedCssStyleRule(node);
} else if (node is cssv.MediaDirective) {
return new EmulatedCssMedialRule(node);
} else if (node is cssv.ImportDirective) {
return new EmulatedCssImportRule(node);
}
})
.where((r) => r != null)
Expand Down Expand Up @@ -100,3 +102,12 @@ class EmulatedMediaList {
.map((q) => q.span.text).join(' and ');
}
}

/// Emulates [CSSImportRule](https://developer.mozilla.org/en-US/docs/Web/API/CSSImportRule)
class EmulatedCssImportRule extends EmulatedCssRule {
EmulatedCssImportRule(cssv.ImportDirective directive) {
this
..type = 3
..cssText = '@${directive.span.text};';
}
}
6 changes: 6 additions & 0 deletions modules/angular2/test/core/compiler/shadow_css_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,11 @@ export function main() {
var css = s('x >>> y {}', 'a');
expect(css).toEqual('x[a] y[a] {}');
});

it('should pass through @import directives', () => {
var styleStr = '@import url("https://fonts.googleapis.com/css?family=Roboto");';
var css = s(styleStr, 'a');
expect(css).toEqual(styleStr);
});
});
}
21 changes: 21 additions & 0 deletions modules/angular2/test/core/compiler/style_url_resolver_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,26 @@ export function main() {
.toEqual(['http://ng.io/print1.css', 'http://ng.io/print2.css']);
});

it('should leave absolute non-package @import urls intact', () => {
var css = `@import url('http://server.com/some.css');`;
var styleWithImports = resolveStyleUrls(urlResolver, 'http://ng.io', css);
expect(styleWithImports.style.trim()).toEqual(`@import url('http://server.com/some.css');`);
expect(styleWithImports.styleUrls).toEqual([]);
});

it('should resolve package @import urls', () => {
var css = `@import url('package:a/b/some.css');`;
var styleWithImports = resolveStyleUrls(new FakeUrlResolver(), 'http://ng.io', css);
expect(styleWithImports.style.trim()).toEqual(``);
expect(styleWithImports.styleUrls).toEqual(['fake_resolved_url']);
});

});
}

/// The real thing behaves differently between Dart and JS for package URIs.
class FakeUrlResolver extends UrlResolver {
constructor() { super(); }

resolve(baseUrl: string, url: string): string { return 'fake_resolved_url'; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ Uri toAssetScheme(Uri absoluteUri) {
return absoluteUri;
}
if (absoluteUri.scheme != 'package') {
throw new FormatException(
'Unsupported URI scheme "${absoluteUri.scheme}" encountered.',
absoluteUri);
// Pass through URIs with non-package scheme
return absoluteUri;
}

if (absoluteUri.pathSegments.length < 2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ void allTests() {
.toThrowWith(anInstanceOf: FormatException);
});

it('should throw for unsupported schemes', () {
expect(() => toAssetScheme(Uri.parse('file:///angular2')))
.toThrowWith(anInstanceOf: FormatException);
it('should pass through unsupported schemes', () {
var uri = 'http://server.com/style.css';
expect('${toAssetScheme(Uri.parse(uri))}').toEqual(uri);
});

it('should throw if passed a null uri', () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ const SIMPLE_CSS = '''
}
''';

const HTTP_IMPORT = 'https://fonts.googleapis.com/css?family=Roboto';
const CSS_WITH_IMPORT = '@import url(${HTTP_IMPORT});';

main() {
Html5LibDomAdapter.makeCurrent();
allTests();
Expand Down Expand Up @@ -60,6 +63,20 @@ allTests() {
expect(transform.outputs[1].id.toString())
.toEqual('somepackage|lib/style.css.shim.dart');
});

it('should compile stylesheets with imports', () async {
var cssFile = new Asset.fromString(
new AssetId('somepackage', 'lib/style.css'), CSS_WITH_IMPORT);
var transform = new FakeTransform()..primaryInput = cssFile;
await subject.apply(transform);
expect(transform.outputs.length).toBe(2);
expect(transform.outputs[0].id.toString())
.toEqual('somepackage|lib/style.css.dart');
expect(transform.outputs[1].id.toString())
.toEqual('somepackage|lib/style.css.shim.dart');
expect(await transform.outputs[0].readAsString()).toContain(HTTP_IMPORT);
expect(await transform.outputs[1].readAsString()).toContain(HTTP_IMPORT);
});
}

@proxy
Expand Down
X Tutup