Skip to content

Commit 929fc65

Browse files
committed
refactor(template loading): add support for base URLs, css rewriting
fixes angular#654
1 parent 26872f6 commit 929fc65

42 files changed

Lines changed: 1151 additions & 638 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

modules/angular2/src/core/application.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import {XHRImpl} from 'angular2/src/core/compiler/xhr/xhr_impl';
1919
import {EventManager, DomEventsPlugin} from 'angular2/src/core/events/event_manager';
2020
import {HammerGesturesPlugin} from 'angular2/src/core/events/hammer_gestures';
2121
import {Binding} from 'angular2/src/di/binding';
22+
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
23+
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
24+
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
25+
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
2226

2327
var _rootInjector: Injector;
2428

@@ -78,7 +82,7 @@ function _injectorBindings(appComponentType): List<Binding> {
7882
var plugins = [new HammerGesturesPlugin(), new DomEventsPlugin()];
7983
return new EventManager(plugins, zone);
8084
}, [VmTurnZone]),
81-
bind(ShadowDomStrategy).toValue(new NativeShadowDomStrategy()),
85+
bind(ShadowDomStrategy).toClass(NativeShadowDomStrategy),
8286
Compiler,
8387
CompilerCache,
8488
TemplateResolver,
@@ -89,6 +93,10 @@ function _injectorBindings(appComponentType): List<Binding> {
8993
Lexer,
9094
ExceptionHandler,
9195
bind(XHR).toValue(new XHRImpl()),
96+
ComponentUrlMapper,
97+
UrlResolver,
98+
StyleUrlResolver,
99+
StyleInliner,
92100
];
93101
}
94102

modules/angular2/src/core/compiler/compiler.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import {DirectiveMetadata} from './directive_metadata';
1616
import {Template} from '../annotations/template';
1717
import {ShadowDomStrategy} from './shadow_dom_strategy';
1818
import {CompileStep} from './pipeline/compile_step';
19+
import {ComponentUrlMapper} from './component_url_mapper';
20+
import {UrlResolver} from './url_resolver';
1921

2022

2123
/**
@@ -57,14 +59,19 @@ export class Compiler {
5759
_shadowDomStrategy: ShadowDomStrategy;
5860
_shadowDomDirectives: List<DirectiveMetadata>;
5961
_templateResolver: TemplateResolver;
62+
_componentUrlMapper: ComponentUrlMapper;
63+
_urlResolver: UrlResolver;
64+
_appUrl: string;
6065

6166
constructor(changeDetection:ChangeDetection,
6267
templateLoader:TemplateLoader,
6368
reader: DirectiveMetadataReader,
6469
parser:Parser,
6570
cache:CompilerCache,
6671
shadowDomStrategy: ShadowDomStrategy,
67-
templateResolver: TemplateResolver) {
72+
templateResolver: TemplateResolver,
73+
componentUrlMapper: ComponentUrlMapper,
74+
urlResolver: UrlResolver) {
6875
this._changeDetection = changeDetection;
6976
this._reader = reader;
7077
this._parser = parser;
@@ -78,6 +85,9 @@ export class Compiler {
7885
ListWrapper.push(this._shadowDomDirectives, reader.read(types[i]));
7986
}
8087
this._templateResolver = templateResolver;
88+
this._componentUrlMapper = componentUrlMapper;
89+
this._urlResolver = urlResolver;
90+
this._appUrl = urlResolver.resolve(null, './');
8191
}
8292

8393
createSteps(component:Type, template: Template):List<CompileStep> {
@@ -90,8 +100,10 @@ export class Compiler {
90100

91101
var cmpMetadata = this._reader.read(component);
92102

103+
var templateUrl = this._templateLoader.getTemplateUrl(template);
104+
93105
return createDefaultSteps(this._changeDetection, this._parser, cmpMetadata, dirMetadata,
94-
this._shadowDomStrategy);
106+
this._shadowDomStrategy, templateUrl);
95107
}
96108

97109
compile(component: Type):Promise<ProtoView> {
@@ -118,6 +130,10 @@ export class Compiler {
118130

119131
var template = this._templateResolver.resolve(component);
120132

133+
var componentUrl = this._componentUrlMapper.getUrl(component);
134+
var baseUrl = this._urlResolver.resolve(this._appUrl, componentUrl);
135+
this._templateLoader.setBaseUrl(template, baseUrl);
136+
121137
var tplElement = this._templateLoader.load(template);
122138

123139
if (PromiseWrapper.isPromise(tplElement)) {
@@ -160,6 +176,12 @@ export class Compiler {
160176
}
161177
}
162178

179+
if (protoView.stylePromises.length > 0) {
180+
// The protoView is ready after all asynchronous styles are ready
181+
var syncProtoView = protoView;
182+
protoView = PromiseWrapper.all(syncProtoView.stylePromises).then((_) => syncProtoView);
183+
}
184+
163185
if (nestedPVPromises.length > 0) {
164186
// Returns ProtoView Promise when there are any asynchronous nested ProtoViews.
165187
// The promise will resolved after nested ProtoViews are compiled.
@@ -169,7 +191,6 @@ export class Compiler {
169191
);
170192
}
171193

172-
// When there is no asynchronous nested ProtoViews, return the ProtoView
173194
return protoView;
174195
}
175196

modules/angular2/src/core/compiler/component_url_mapper.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import {Type, isPresent} from 'angular2/src/facade/lang';
2-
import {Map, MapWrapper} from 'angular2/src/facade/lang';
2+
import {Map, MapWrapper} from 'angular2/src/facade/collection';
33

44
export class ComponentUrlMapper {
5-
// Returns the url to the component source file.
6-
// The returned url could be:
5+
// Returns the base URL to the component source file.
6+
// The returned URL could be:
77
// - an absolute URL,
8-
// - a URL relative to the application
8+
// - a path relative to the application
99
getUrl(component: Type): string {
1010
return './';
1111
}

modules/angular2/src/core/compiler/pipeline/default_steps.js

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ import {ElementBindingMarker} from './element_binding_marker';
99
import {ProtoViewBuilder} from './proto_view_builder';
1010
import {ProtoElementInjectorBuilder} from './proto_element_injector_builder';
1111
import {ElementBinderBuilder} from './element_binder_builder';
12-
import {ShimShadowCss} from './shim_shadow_css';
12+
import {ResolveCss} from './resolve_css';
1313
import {ShimShadowDom} from './shim_shadow_dom';
1414
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
1515
import {ShadowDomStrategy, EmulatedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
16-
import {DOM} from 'angular2/src/facade/dom';
1716

1817
/**
1918
* Default steps used for compiling a template.
@@ -25,24 +24,20 @@ export function createDefaultSteps(
2524
parser:Parser,
2625
compiledComponent: DirectiveMetadata,
2726
directives: List<DirectiveMetadata>,
28-
shadowDomStrategy: ShadowDomStrategy) {
27+
shadowDomStrategy: ShadowDomStrategy,
28+
templateUrl: string) {
2929

30-
var steps = [new ViewSplitter(parser)];
31-
32-
if (shadowDomStrategy instanceof EmulatedShadowDomStrategy) {
33-
var step = new ShimShadowCss(compiledComponent, shadowDomStrategy, DOM.defaultDoc().head);
34-
ListWrapper.push(steps, step);
35-
}
36-
37-
steps = ListWrapper.concat(steps,[
30+
var steps = [
31+
new ViewSplitter(parser),
32+
new ResolveCss(compiledComponent, shadowDomStrategy, templateUrl),
3833
new PropertyBindingParser(parser),
3934
new DirectiveParser(directives),
4035
new TextInterpolationParser(parser),
4136
new ElementBindingMarker(),
4237
new ProtoViewBuilder(changeDetection, shadowDomStrategy),
4338
new ProtoElementInjectorBuilder(),
44-
new ElementBinderBuilder(parser)
45-
]);
39+
new ElementBinderBuilder(parser),
40+
]
4641

4742
if (shadowDomStrategy instanceof EmulatedShadowDomStrategy) {
4843
var step = new ShimShadowDom(compiledComponent, shadowDomStrategy);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import {CompileStep} from './compile_step';
2+
import {CompileElement} from './compile_element';
3+
import {CompileControl} from './compile_control';
4+
5+
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
6+
import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
7+
8+
import {DOM} from 'angular2/src/facade/dom';
9+
import {Type} from 'angular2/src/facade/lang';
10+
import {PromiseWrapper} from 'angular2/src/facade/async';
11+
import {ListWrapper} from 'angular2/src/facade/collection';
12+
13+
export class ResolveCss extends CompileStep {
14+
_strategy: ShadowDomStrategy;
15+
_component: Type;
16+
_templateUrl: string;
17+
18+
constructor(cmpMetadata: DirectiveMetadata, strategy: ShadowDomStrategy, templateUrl: string) {
19+
super();
20+
this._strategy = strategy;
21+
this._component = cmpMetadata.type;
22+
this._templateUrl = templateUrl;
23+
}
24+
25+
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
26+
// May be remove the styles
27+
if (DOM.tagName(current.element) == 'STYLE') {
28+
current.ignoreBindings = true;
29+
var styleEl = current.element;
30+
31+
var css = DOM.getText(styleEl);
32+
css = this._strategy.transformStyleText(css, this._templateUrl, this._component);
33+
if (PromiseWrapper.isPromise(css)) {
34+
ListWrapper.push(parent.inheritedProtoView.stylePromises, css);
35+
DOM.setText(styleEl, '');
36+
css.then((css) => {
37+
DOM.setText(styleEl, css);
38+
})
39+
} else {
40+
DOM.setText(styleEl, css);
41+
}
42+
43+
this._strategy.handleStyleElement(styleEl);
44+
}
45+
}
46+
}
47+

modules/angular2/src/core/compiler/pipeline/shim_shadow_css.js

Lines changed: 0 additions & 55 deletions
This file was deleted.

modules/angular2/src/core/compiler/pipeline/shim_shadow_dom.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,19 @@ import {CompileStep} from './compile_step';
22
import {CompileElement} from './compile_element';
33
import {CompileControl} from './compile_control';
44

5-
import {isPresent} from 'angular2/src/facade/lang';
5+
import {isPresent, Type} from 'angular2/src/facade/lang';
66

77
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
88
import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
99

10-
import {ShimComponent} from 'angular2/src/core/compiler/shadow_dom_emulation/shim_component';
11-
1210
export class ShimShadowDom extends CompileStep {
1311
_strategy: ShadowDomStrategy;
14-
_shimComponent: ShimComponent;
12+
_component: Type;
1513

1614
constructor(cmpMetadata: DirectiveMetadata, strategy: ShadowDomStrategy) {
1715
super();
1816
this._strategy = strategy;
19-
this._shimComponent = strategy.getShimComponent(cmpMetadata.type);
17+
this._component = cmpMetadata.type;
2018
}
2119

2220
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
@@ -25,13 +23,12 @@ export class ShimShadowDom extends CompileStep {
2523
}
2624

2725
// Shim the element as a child of the compiled component
28-
this._shimComponent.shimContentElement(current.element);
26+
this._strategy.shimContentElement(this._component, current.element);
2927

3028
// If the current element is also a component, shim it as a host
3129
var host = current.componentDirective;
3230
if (isPresent(host)) {
33-
var shimComponent = this._strategy.getShimComponent(host.type);
34-
shimComponent.shimHostElement(current.element);
31+
this._strategy.shimHostElement(host.type, current.element);
3532
}
3633
}
3734
}

0 commit comments

Comments
 (0)