refactor(Compiler): make shadow DOM stragegy support more flexible
This commit is contained in:
parent
bcf4a96a84
commit
9982520a23
|
@ -24,6 +24,7 @@ import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mappe
|
||||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
var _rootInjector: Injector;
|
var _rootInjector: Injector;
|
||||||
|
|
||||||
|
@ -98,6 +99,7 @@ function _injectorBindings(appComponentType): List<Binding> {
|
||||||
UrlResolver,
|
UrlResolver,
|
||||||
StyleUrlResolver,
|
StyleUrlResolver,
|
||||||
StyleInliner,
|
StyleInliner,
|
||||||
|
CssProcessor,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ import {ShadowDomStrategy} from './shadow_dom_strategy';
|
||||||
import {CompileStep} from './pipeline/compile_step';
|
import {CompileStep} from './pipeline/compile_step';
|
||||||
import {ComponentUrlMapper} from './component_url_mapper';
|
import {ComponentUrlMapper} from './component_url_mapper';
|
||||||
import {UrlResolver} from './url_resolver';
|
import {UrlResolver} from './url_resolver';
|
||||||
|
import {CssProcessor} from './css_processor';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache that stores the ProtoView of the template of a component.
|
* Cache that stores the ProtoView of the template of a component.
|
||||||
|
@ -61,6 +61,7 @@ export class Compiler {
|
||||||
_componentUrlMapper: ComponentUrlMapper;
|
_componentUrlMapper: ComponentUrlMapper;
|
||||||
_urlResolver: UrlResolver;
|
_urlResolver: UrlResolver;
|
||||||
_appUrl: string;
|
_appUrl: string;
|
||||||
|
_cssProcessor: CssProcessor;
|
||||||
|
|
||||||
constructor(changeDetection:ChangeDetection,
|
constructor(changeDetection:ChangeDetection,
|
||||||
templateLoader:TemplateLoader,
|
templateLoader:TemplateLoader,
|
||||||
|
@ -70,7 +71,8 @@ export class Compiler {
|
||||||
shadowDomStrategy: ShadowDomStrategy,
|
shadowDomStrategy: ShadowDomStrategy,
|
||||||
templateResolver: TemplateResolver,
|
templateResolver: TemplateResolver,
|
||||||
componentUrlMapper: ComponentUrlMapper,
|
componentUrlMapper: ComponentUrlMapper,
|
||||||
urlResolver: UrlResolver) {
|
urlResolver: UrlResolver,
|
||||||
|
cssProcessor: CssProcessor) {
|
||||||
this._changeDetection = changeDetection;
|
this._changeDetection = changeDetection;
|
||||||
this._reader = reader;
|
this._reader = reader;
|
||||||
this._parser = parser;
|
this._parser = parser;
|
||||||
|
@ -87,6 +89,7 @@ export class Compiler {
|
||||||
this._componentUrlMapper = componentUrlMapper;
|
this._componentUrlMapper = componentUrlMapper;
|
||||||
this._urlResolver = urlResolver;
|
this._urlResolver = urlResolver;
|
||||||
this._appUrl = urlResolver.resolve(null, './');
|
this._appUrl = urlResolver.resolve(null, './');
|
||||||
|
this._cssProcessor = cssProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
createSteps(component:Type, template: Template):List<CompileStep> {
|
createSteps(component:Type, template: Template):List<CompileStep> {
|
||||||
|
@ -102,7 +105,7 @@ export class Compiler {
|
||||||
var templateUrl = this._templateLoader.getTemplateUrl(template);
|
var templateUrl = this._templateLoader.getTemplateUrl(template);
|
||||||
|
|
||||||
return createDefaultSteps(this._changeDetection, this._parser, cmpMetadata, dirMetadata,
|
return createDefaultSteps(this._changeDetection, this._parser, cmpMetadata, dirMetadata,
|
||||||
this._shadowDomStrategy, templateUrl);
|
this._shadowDomStrategy, templateUrl, this._cssProcessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
compile(component: Type):Promise<ProtoView> {
|
compile(component: Type):Promise<ProtoView> {
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
|
|
||||||
|
import {isPresent} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
|
import {CompileStep} from './pipeline/compile_step';
|
||||||
|
import {CompileElement} from './pipeline/compile_element';
|
||||||
|
import {CompileControl} from './pipeline/compile_control';
|
||||||
|
|
||||||
|
import {ShadowDomStrategy} from './shadow_dom_strategy';
|
||||||
|
import {DirectiveMetadata} from './directive_metadata';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the <style> tags during the compilation.
|
||||||
|
*/
|
||||||
|
export class CssProcessor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a compile step to be added to the compiler pipeline.
|
||||||
|
*
|
||||||
|
* @param {DirectiveMetadata} cmpMetadata
|
||||||
|
* @param {ShadowDomStrategy} shadowDomStrategy
|
||||||
|
* @param {string} templateUrl The base URL of the template
|
||||||
|
*/
|
||||||
|
getCompileStep(cmpMetadata: DirectiveMetadata, shadowDomStrategy: ShadowDomStrategy,
|
||||||
|
templateUrl: string) {
|
||||||
|
var strategyStep = shadowDomStrategy.getStyleCompileStep(cmpMetadata, templateUrl);
|
||||||
|
return new _CssProcessorStep(strategyStep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CssProcessorStep extends CompileStep {
|
||||||
|
_strategyStep: CompileStep;
|
||||||
|
|
||||||
|
constructor(strategyStep: CompileStep) {
|
||||||
|
super();
|
||||||
|
this._strategyStep = strategyStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
||||||
|
if (DOM.tagName(current.element) == 'STYLE') {
|
||||||
|
current.ignoreBindings = true;
|
||||||
|
|
||||||
|
if (isPresent(this._strategyStep)) {
|
||||||
|
this._strategyStep.process(parent, current, control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import {ChangeDetection, Parser} from 'angular2/change_detection';
|
import {ChangeDetection, Parser} from 'angular2/change_detection';
|
||||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
import {isPresent} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {PropertyBindingParser} from './property_binding_parser';
|
import {PropertyBindingParser} from './property_binding_parser';
|
||||||
import {TextInterpolationParser} from './text_interpolation_parser';
|
import {TextInterpolationParser} from './text_interpolation_parser';
|
||||||
|
@ -9,8 +10,8 @@ import {ElementBindingMarker} from './element_binding_marker';
|
||||||
import {ProtoViewBuilder} from './proto_view_builder';
|
import {ProtoViewBuilder} from './proto_view_builder';
|
||||||
import {ProtoElementInjectorBuilder} from './proto_element_injector_builder';
|
import {ProtoElementInjectorBuilder} from './proto_element_injector_builder';
|
||||||
import {ElementBinderBuilder} from './element_binder_builder';
|
import {ElementBinderBuilder} from './element_binder_builder';
|
||||||
import {ResolveCss} from './resolve_css';
|
|
||||||
import {ShimShadowDom} from './shim_shadow_dom';
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
|
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
|
||||||
import {ShadowDomStrategy, EmulatedScopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
import {ShadowDomStrategy, EmulatedScopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||||
|
|
||||||
|
@ -25,11 +26,12 @@ export function createDefaultSteps(
|
||||||
compiledComponent: DirectiveMetadata,
|
compiledComponent: DirectiveMetadata,
|
||||||
directives: List<DirectiveMetadata>,
|
directives: List<DirectiveMetadata>,
|
||||||
shadowDomStrategy: ShadowDomStrategy,
|
shadowDomStrategy: ShadowDomStrategy,
|
||||||
templateUrl: string) {
|
templateUrl: string,
|
||||||
|
cssProcessor: CssProcessor) {
|
||||||
|
|
||||||
var steps = [
|
var steps = [
|
||||||
new ViewSplitter(parser),
|
new ViewSplitter(parser),
|
||||||
new ResolveCss(compiledComponent, shadowDomStrategy, templateUrl),
|
cssProcessor.getCompileStep(compiledComponent, shadowDomStrategy, templateUrl),
|
||||||
new PropertyBindingParser(parser),
|
new PropertyBindingParser(parser),
|
||||||
new DirectiveParser(directives),
|
new DirectiveParser(directives),
|
||||||
new TextInterpolationParser(parser),
|
new TextInterpolationParser(parser),
|
||||||
|
@ -39,9 +41,9 @@ export function createDefaultSteps(
|
||||||
new ElementBinderBuilder(parser),
|
new ElementBinderBuilder(parser),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (shadowDomStrategy instanceof EmulatedScopedShadowDomStrategy) {
|
var shadowDomStep = shadowDomStrategy.getTemplateCompileStep(compiledComponent);
|
||||||
var step = new ShimShadowDom(compiledComponent, shadowDomStrategy);
|
if (isPresent(shadowDomStep)) {
|
||||||
ListWrapper.push(steps, step);
|
ListWrapper.push(steps, shadowDomStep);
|
||||||
}
|
}
|
||||||
|
|
||||||
return steps;
|
return steps;
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
import {CompileStep} from './compile_step';
|
|
||||||
import {CompileElement} from './compile_element';
|
|
||||||
import {CompileControl} from './compile_control';
|
|
||||||
|
|
||||||
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
|
|
||||||
import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
|
||||||
|
|
||||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
|
||||||
import {Type} from 'angular2/src/facade/lang';
|
|
||||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
|
||||||
|
|
||||||
export class ResolveCss extends CompileStep {
|
|
||||||
_strategy: ShadowDomStrategy;
|
|
||||||
_component: Type;
|
|
||||||
_templateUrl: string;
|
|
||||||
|
|
||||||
constructor(cmpMetadata: DirectiveMetadata, strategy: ShadowDomStrategy, templateUrl: string) {
|
|
||||||
super();
|
|
||||||
this._strategy = strategy;
|
|
||||||
this._component = cmpMetadata.type;
|
|
||||||
this._templateUrl = templateUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
|
||||||
// May be remove the styles
|
|
||||||
if (DOM.tagName(current.element) == 'STYLE') {
|
|
||||||
current.ignoreBindings = true;
|
|
||||||
var styleEl = current.element;
|
|
||||||
|
|
||||||
var css = DOM.getText(styleEl);
|
|
||||||
css = this._strategy.transformStyleText(css, this._templateUrl, this._component);
|
|
||||||
if (PromiseWrapper.isPromise(css)) {
|
|
||||||
ListWrapper.push(parent.inheritedProtoView.stylePromises, css);
|
|
||||||
DOM.setText(styleEl, '');
|
|
||||||
css.then((css) => {
|
|
||||||
DOM.setText(styleEl, css);
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
DOM.setText(styleEl, css);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._strategy.handleStyleElement(styleEl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
import {CompileStep} from './compile_step';
|
|
||||||
import {CompileElement} from './compile_element';
|
|
||||||
import {CompileControl} from './compile_control';
|
|
||||||
|
|
||||||
import {isPresent, Type} from 'angular2/src/facade/lang';
|
|
||||||
|
|
||||||
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
|
|
||||||
import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
|
||||||
|
|
||||||
export class ShimShadowDom extends CompileStep {
|
|
||||||
_strategy: ShadowDomStrategy;
|
|
||||||
_component: Type;
|
|
||||||
|
|
||||||
constructor(cmpMetadata: DirectiveMetadata, strategy: ShadowDomStrategy) {
|
|
||||||
super();
|
|
||||||
this._strategy = strategy;
|
|
||||||
this._component = cmpMetadata.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
|
||||||
if (current.ignoreBindings) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shim the element as a child of the compiled component
|
|
||||||
this._strategy.shimContentElement(this._component, current.element);
|
|
||||||
|
|
||||||
// If the current element is also a component, shim it as a host
|
|
||||||
var host = current.componentDirective;
|
|
||||||
if (isPresent(host)) {
|
|
||||||
this._strategy.shimHostElement(host.type, current.element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import {Type, isBlank, isPresent, int} from 'angular2/src/facade/lang';
|
import {Type, isBlank, isPresent, int} from 'angular2/src/facade/lang';
|
||||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
|
||||||
import {List, ListWrapper, MapWrapper, Map} from 'angular2/src/facade/collection';
|
import {List, ListWrapper, MapWrapper, Map} from 'angular2/src/facade/collection';
|
||||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
|
|
||||||
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
|
|
||||||
import {View} from './view';
|
import {View} from './view';
|
||||||
|
|
||||||
import {Content} from './shadow_dom_emulation/content_tag';
|
import {Content} from './shadow_dom_emulation/content_tag';
|
||||||
|
@ -12,15 +13,50 @@ import {ShadowCss} from './shadow_dom_emulation/shadow_css';
|
||||||
import {StyleInliner} from './style_inliner';
|
import {StyleInliner} from './style_inliner';
|
||||||
import {StyleUrlResolver} from './style_url_resolver';
|
import {StyleUrlResolver} from './style_url_resolver';
|
||||||
|
|
||||||
|
import {DirectiveMetadata} from './directive_metadata';
|
||||||
|
|
||||||
|
import {CompileStep} from './pipeline/compile_step';
|
||||||
|
import {CompileElement} from './pipeline/compile_element';
|
||||||
|
import {CompileControl} from './pipeline/compile_control';
|
||||||
|
|
||||||
export class ShadowDomStrategy {
|
export class ShadowDomStrategy {
|
||||||
attachTemplate(el, view:View) {}
|
attachTemplate(el, view:View) {}
|
||||||
constructLightDom(lightDomView:View, shadowDomView:View, el) {}
|
constructLightDom(lightDomView:View, shadowDomView:View, el): LightDom { return null; }
|
||||||
polyfillDirectives():List<Type> { return null; }
|
polyfillDirectives():List<Type> { return []; }
|
||||||
// TODO(vicb): union types: return either a string or a Promise<string>
|
|
||||||
transformStyleText(cssText: string, baseUrl: string, component: Type) {}
|
/**
|
||||||
handleStyleElement(styleEl) {};
|
* An optional step that can modify the template style elements.
|
||||||
shimContentElement(component: Type, element) {}
|
*
|
||||||
shimHostElement(component: Type, element) {}
|
* @param {DirectiveMetadata} cmpMetadata
|
||||||
|
* @param {string} templateUrl the template base URL
|
||||||
|
* @returns {CompileStep} a compile step to append to the compiler pipeline, null if not required.
|
||||||
|
*/
|
||||||
|
getStyleCompileStep(cmpMetadata: DirectiveMetadata, templateUrl: string): CompileStep {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An optional step that can modify the template elements (style elements exlcuded).
|
||||||
|
*
|
||||||
|
* This step could be used to modify the template in order to scope the styles.
|
||||||
|
*
|
||||||
|
* @param {DirectiveMetadata} cmpMetadata
|
||||||
|
* @returns {CompileStep} a compile step to append to the compiler pipeline, null if not required.
|
||||||
|
*/
|
||||||
|
getTemplateCompileStep(cmpMetadata: DirectiveMetadata): CompileStep { return null; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The application element does not go through the compiler pipeline.
|
||||||
|
*
|
||||||
|
* This methods is called when the root ProtoView is created and to optionnaly update the
|
||||||
|
* application root element.
|
||||||
|
*
|
||||||
|
* @see ProtoView.createRootProtoView
|
||||||
|
*
|
||||||
|
* @param {DirectiveMetadata} cmpMetadata
|
||||||
|
* @param element
|
||||||
|
*/
|
||||||
|
shimAppElement(cmpMetadata: DirectiveMetadata, element) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,7 +70,6 @@ export class ShadowDomStrategy {
|
||||||
*/
|
*/
|
||||||
export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy {
|
export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy {
|
||||||
_styleUrlResolver: StyleUrlResolver;
|
_styleUrlResolver: StyleUrlResolver;
|
||||||
_lastInsertedStyle;
|
|
||||||
_styleHost;
|
_styleHost;
|
||||||
|
|
||||||
constructor(styleUrlResolver: StyleUrlResolver, styleHost) {
|
constructor(styleUrlResolver: StyleUrlResolver, styleHost) {
|
||||||
|
@ -48,7 +83,7 @@ export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy {
|
||||||
_moveViewNodesIntoParent(el, view);
|
_moveViewNodesIntoParent(el, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructLightDom(lightDomView:View, shadowDomView:View, el) {
|
constructLightDom(lightDomView:View, shadowDomView:View, el): LightDom {
|
||||||
return new LightDom(lightDomView, shadowDomView, el);
|
return new LightDom(lightDomView, shadowDomView, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,35 +91,9 @@ export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy {
|
||||||
return [Content];
|
return [Content];
|
||||||
}
|
}
|
||||||
|
|
||||||
transformStyleText(cssText: string, baseUrl: string, component: Type) {
|
getStyleCompileStep(cmpMetadata: DirectiveMetadata, templateUrl: string): CompileStep {
|
||||||
return this._styleUrlResolver.resolveUrls(cssText, baseUrl);
|
return new _EmulatedUnscopedCssStep(cmpMetadata, templateUrl, this._styleUrlResolver,
|
||||||
}
|
this._styleHost);
|
||||||
|
|
||||||
handleStyleElement(styleEl) {
|
|
||||||
DOM.remove(styleEl);
|
|
||||||
|
|
||||||
var cssText = DOM.getText(styleEl);
|
|
||||||
|
|
||||||
if (!MapWrapper.contains(_sharedStyleTexts, cssText)) {
|
|
||||||
// Styles are unscoped and shared across components, only append them to the head
|
|
||||||
// when there are not present yet
|
|
||||||
MapWrapper.set(_sharedStyleTexts, cssText, true);
|
|
||||||
this._insertStyleElement(this._styleHost, styleEl);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
_insertStyleElement(host, style) {
|
|
||||||
if (isBlank(this._lastInsertedStyle)) {
|
|
||||||
var firstChild = DOM.firstChild(host);
|
|
||||||
if (isPresent(firstChild)) {
|
|
||||||
DOM.insertBefore(firstChild, style);
|
|
||||||
} else {
|
|
||||||
DOM.appendChild(host, style);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DOM.insertAfter(this._lastInsertedStyle, style);
|
|
||||||
}
|
|
||||||
this._lastInsertedStyle = style;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,31 +117,19 @@ export class EmulatedScopedShadowDomStrategy extends EmulatedUnscopedShadowDomSt
|
||||||
this._styleInliner = styleInliner;
|
this._styleInliner = styleInliner;
|
||||||
}
|
}
|
||||||
|
|
||||||
transformStyleText(cssText: string, baseUrl: string, component: Type) {
|
getStyleCompileStep(cmpMetadata: DirectiveMetadata, templateUrl: string): CompileStep {
|
||||||
cssText = this._styleUrlResolver.resolveUrls(cssText, baseUrl);
|
return new _EmulatedScopedCssStep(cmpMetadata, templateUrl, this._styleInliner,
|
||||||
var css = this._styleInliner.inlineImports(cssText, baseUrl);
|
this._styleUrlResolver, this._styleHost);
|
||||||
if (PromiseWrapper.isPromise(css)) {
|
|
||||||
return css.then((css) => _shimCssForComponent(css, component));
|
|
||||||
} else {
|
|
||||||
return _shimCssForComponent(css, component);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleStyleElement(styleEl) {
|
getTemplateCompileStep(cmpMetadata: DirectiveMetadata): CompileStep {
|
||||||
DOM.remove(styleEl);
|
return new _ShimShadowDomStep(cmpMetadata);
|
||||||
this._insertStyleElement(this._styleHost, styleEl);
|
|
||||||
};
|
|
||||||
|
|
||||||
shimContentElement(component: Type, element) {
|
|
||||||
var id = _getComponentId(component);
|
|
||||||
var attrName = _getContentAttribute(id);
|
|
||||||
DOM.setAttribute(element, attrName, '');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shimHostElement(component: Type, element) {
|
shimAppElement(cmpMetadata: DirectiveMetadata, element) {
|
||||||
var id = _getComponentId(component);
|
var cmpType = cmpMetadata.type;
|
||||||
var attrName = _getHostAttribute(id);
|
var hostAttribute = _getHostAttribute(_getComponentId(cmpType));
|
||||||
DOM.setAttribute(element, attrName, '');
|
DOM.setAttribute(element, hostAttribute, '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,16 +151,125 @@ export class NativeShadowDomStrategy extends ShadowDomStrategy {
|
||||||
_moveViewNodesIntoParent(DOM.createShadowRoot(el), view);
|
_moveViewNodesIntoParent(DOM.createShadowRoot(el), view);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructLightDom(lightDomView:View, shadowDomView:View, el) {
|
getStyleCompileStep(cmpMetadata: DirectiveMetadata, templateUrl: string): CompileStep {
|
||||||
return null;
|
return new _NativeCssStep(templateUrl, this._styleUrlResolver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ShimShadowDomStep extends CompileStep {
|
||||||
|
_contentAttribute: string;
|
||||||
|
|
||||||
|
constructor(cmpMetadata: DirectiveMetadata) {
|
||||||
|
super();
|
||||||
|
var id = _getComponentId(cmpMetadata.type);
|
||||||
|
this._contentAttribute = _getContentAttribute(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
polyfillDirectives():List<Type> {
|
|
||||||
return [];
|
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
||||||
|
if (current.ignoreBindings) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shim the element as a child of the compiled component
|
||||||
|
DOM.setAttribute(current.element, this._contentAttribute, '');
|
||||||
|
|
||||||
|
// If the current element is also a component, shim it as a host
|
||||||
|
var host = current.componentDirective;
|
||||||
|
if (isPresent(host)) {
|
||||||
|
var hostId = _getComponentId(host.type);
|
||||||
|
var hostAttribute = _getHostAttribute(hostId);
|
||||||
|
DOM.setAttribute(current.element, hostAttribute, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EmulatedUnscopedCssStep extends CompileStep {
|
||||||
|
_templateUrl: string;
|
||||||
|
_styleUrlResolver: StyleUrlResolver;
|
||||||
|
_styleHost;
|
||||||
|
|
||||||
|
constructor(cmpMetadata: DirectiveMetadata, templateUrl: string,
|
||||||
|
styleUrlResolver: StyleUrlResolver, styleHost) {
|
||||||
|
super();
|
||||||
|
this._templateUrl = templateUrl;
|
||||||
|
this._styleUrlResolver = styleUrlResolver;
|
||||||
|
this._styleHost = styleHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
transformStyleText(cssText: string, baseUrl: string, component: Type) {
|
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
||||||
return this._styleUrlResolver.resolveUrls(cssText, baseUrl);
|
var styleEl = current.element;
|
||||||
|
var cssText = DOM.getText(styleEl);
|
||||||
|
cssText = this._styleUrlResolver.resolveUrls(cssText, this._templateUrl);
|
||||||
|
DOM.setText(styleEl, cssText);
|
||||||
|
DOM.remove(styleEl);
|
||||||
|
|
||||||
|
if (!MapWrapper.contains(_sharedStyleTexts, cssText)) {
|
||||||
|
// Styles are unscoped and shared across components, only append them to the head
|
||||||
|
// when there are not present yet
|
||||||
|
MapWrapper.set(_sharedStyleTexts, cssText, true);
|
||||||
|
_insertStyleElement(this._styleHost, styleEl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EmulatedScopedCssStep extends CompileStep {
|
||||||
|
_templateUrl: string;
|
||||||
|
_component: Type;
|
||||||
|
_styleInliner: StyleInliner;
|
||||||
|
_styleUrlResolver: StyleUrlResolver;
|
||||||
|
_styleHost;
|
||||||
|
|
||||||
|
constructor(cmpMetadata: DirectiveMetadata, templateUrl: string, styleInliner: StyleInliner,
|
||||||
|
styleUrlResolver: StyleUrlResolver, styleHost) {
|
||||||
|
super();
|
||||||
|
this._templateUrl = templateUrl;
|
||||||
|
this._component = cmpMetadata.type;
|
||||||
|
this._styleInliner = styleInliner;
|
||||||
|
this._styleUrlResolver = styleUrlResolver;
|
||||||
|
this._styleHost = styleHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
||||||
|
var styleEl = current.element;
|
||||||
|
|
||||||
|
var cssText = DOM.getText(styleEl);
|
||||||
|
|
||||||
|
cssText = this._styleUrlResolver.resolveUrls(cssText, this._templateUrl);
|
||||||
|
var css = this._styleInliner.inlineImports(cssText, this._templateUrl);
|
||||||
|
|
||||||
|
if (PromiseWrapper.isPromise(css)) {
|
||||||
|
DOM.setText(styleEl, '');
|
||||||
|
ListWrapper.push(parent.inheritedProtoView.stylePromises, css);
|
||||||
|
return css.then((css) => {
|
||||||
|
css = _shimCssForComponent(css, this._component);
|
||||||
|
DOM.setText(styleEl, css);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
css = _shimCssForComponent(css, this._component);
|
||||||
|
DOM.setText(styleEl, css);
|
||||||
|
}
|
||||||
|
|
||||||
|
DOM.remove(styleEl);
|
||||||
|
_insertStyleElement(this._styleHost, styleEl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NativeCssStep extends CompileStep {
|
||||||
|
_styleUrlResolver: StyleUrlResolver;
|
||||||
|
_templateUrl: string;
|
||||||
|
|
||||||
|
constructor(templateUrl: string, styleUrlResover: StyleUrlResolver) {
|
||||||
|
super();
|
||||||
|
this._styleUrlResolver = styleUrlResover;
|
||||||
|
this._templateUrl = templateUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
||||||
|
var styleEl = current.element;
|
||||||
|
var cssText = DOM.getText(styleEl);
|
||||||
|
cssText = this._styleUrlResolver.resolveUrls(cssText, this._templateUrl);
|
||||||
|
DOM.setText(styleEl, cssText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,6 +282,7 @@ function _moveViewNodesIntoParent(parent, view) {
|
||||||
var _componentUIDs: Map<Type, int> = MapWrapper.create();
|
var _componentUIDs: Map<Type, int> = MapWrapper.create();
|
||||||
var _nextComponentUID: int = 0;
|
var _nextComponentUID: int = 0;
|
||||||
var _sharedStyleTexts: Map<string, boolean> = MapWrapper.create();
|
var _sharedStyleTexts: Map<string, boolean> = MapWrapper.create();
|
||||||
|
var _lastInsertedStyleEl;
|
||||||
|
|
||||||
function _getComponentId(component: Type) {
|
function _getComponentId(component: Type) {
|
||||||
var id = MapWrapper.get(_componentUIDs, component);
|
var id = MapWrapper.get(_componentUIDs, component);
|
||||||
|
@ -186,12 +293,26 @@ function _getComponentId(component: Type) {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _insertStyleElement(host, styleEl) {
|
||||||
|
if (isBlank(_lastInsertedStyleEl)) {
|
||||||
|
var firstChild = DOM.firstChild(host);
|
||||||
|
if (isPresent(firstChild)) {
|
||||||
|
DOM.insertBefore(firstChild, styleEl);
|
||||||
|
} else {
|
||||||
|
DOM.appendChild(host, styleEl);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DOM.insertAfter(_lastInsertedStyleEl, styleEl);
|
||||||
|
}
|
||||||
|
_lastInsertedStyleEl = styleEl;
|
||||||
|
}
|
||||||
|
|
||||||
// Return the attribute to be added to the component
|
// Return the attribute to be added to the component
|
||||||
function _getHostAttribute(id: int) {
|
function _getHostAttribute(id: int) {
|
||||||
return `_nghost-${id}`;
|
return `_nghost-${id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the attribute to be added on every single nodes in the component
|
// Returns the attribute to be added on every single element nodes in the component
|
||||||
function _getContentAttribute(id: int) {
|
function _getContentAttribute(id: int) {
|
||||||
return `_ngcontent-${id}`;
|
return `_ngcontent-${id}`;
|
||||||
}
|
}
|
||||||
|
@ -207,4 +328,5 @@ export function resetShadowDomCache() {
|
||||||
MapWrapper.clear(_componentUIDs);
|
MapWrapper.clear(_componentUIDs);
|
||||||
_nextComponentUID = 0;
|
_nextComponentUID = 0;
|
||||||
MapWrapper.clear(_sharedStyleTexts);
|
MapWrapper.clear(_sharedStyleTexts);
|
||||||
|
_lastInsertedStyleEl = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -544,7 +544,7 @@ export class ProtoView {
|
||||||
new ProtoElementInjector(null, 0, [cmpType], true));
|
new ProtoElementInjector(null, 0, [cmpType], true));
|
||||||
binder.componentDirective = rootComponentAnnotatedType;
|
binder.componentDirective = rootComponentAnnotatedType;
|
||||||
binder.nestedProtoView = protoView;
|
binder.nestedProtoView = protoView;
|
||||||
shadowDomStrategy.shimHostElement(cmpType, insertionElement);
|
shadowDomStrategy.shimAppElement(rootComponentAnnotatedType, insertionElement);
|
||||||
return rootProtoView;
|
return rootProtoView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||||
import {ComponentUrlMapper, RuntimeComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper, RuntimeComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
import {Lexer, Parser, dynamicChangeDetection} from 'angular2/change_detection';
|
import {Lexer, Parser, dynamicChangeDetection} from 'angular2/change_detection';
|
||||||
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||||
|
@ -300,7 +301,8 @@ class TestableCompiler extends Compiler {
|
||||||
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
||||||
templateResolver,
|
templateResolver,
|
||||||
cmpUrlMapper,
|
cmpUrlMapper,
|
||||||
urlResolver);
|
urlResolver,
|
||||||
|
new CssProcessor());
|
||||||
|
|
||||||
this.steps = steps;
|
this.steps = steps;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
import {describe, it, expect, beforeEach, ddescribe, iit, xit, el} from 'angular2/test_lib';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
|
import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||||
|
|
||||||
|
import {CompilePipeline} from 'angular2/src/core/compiler/pipeline/compile_pipeline';
|
||||||
|
import {CompileElement} from 'angular2/src/core/compiler/pipeline/compile_element';
|
||||||
|
import {CompileStep} from 'angular2/src/core/compiler/pipeline/compile_step';
|
||||||
|
import {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
|
||||||
|
|
||||||
|
import {Component} from 'angular2/src/core/annotations/annotations';
|
||||||
|
|
||||||
|
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
|
||||||
|
|
||||||
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
describe('CssProcessor', () => {
|
||||||
|
describe('compile step', () => {
|
||||||
|
function createPipeline(cssProcessor: CssProcessor, strategy: ShadowDomStrategy,
|
||||||
|
templateUrl: string) {
|
||||||
|
var annotation = new Component();
|
||||||
|
var meta = new DirectiveMetadata(SomeComponent, annotation);
|
||||||
|
return new CompilePipeline([
|
||||||
|
cssProcessor.getCompileStep(meta, strategy, templateUrl)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
it('it should set ignoreBindings to true for style elements', () => {
|
||||||
|
var strategy = new FakeShadowDomStrategy(null);
|
||||||
|
var cssProcessor = new CssProcessor();
|
||||||
|
|
||||||
|
var pipeline = createPipeline(cssProcessor, strategy, 'http://base');
|
||||||
|
var results = pipeline.process(el('<div><style></style></div>'));
|
||||||
|
|
||||||
|
expect(results[0].ignoreBindings).toBe(false);
|
||||||
|
expect(results[1].ignoreBindings).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should execute the strategy step for style elements', () => {
|
||||||
|
var processedEls = [];
|
||||||
|
var compileStep = new MockStep((parent, current, control) => {
|
||||||
|
ListWrapper.push(processedEls, current.element);
|
||||||
|
});
|
||||||
|
var strategy = new FakeShadowDomStrategy(compileStep);
|
||||||
|
|
||||||
|
var cssProcessor = new CssProcessor();
|
||||||
|
var pipeline = createPipeline(cssProcessor, strategy, 'http://base');
|
||||||
|
var results = pipeline.process(el('<div><style></style></div>'));
|
||||||
|
|
||||||
|
expect(processedEls.length).toEqual(1);
|
||||||
|
expect(processedEls[0]).toBe(results[1].element);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeShadowDomStrategy extends ShadowDomStrategy {
|
||||||
|
_compileStep: CompileStep;
|
||||||
|
|
||||||
|
constructor(compileStep: CompileStep) {
|
||||||
|
super();
|
||||||
|
this._compileStep = compileStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStyleCompileStep(cmpMetadata: DirectiveMetadata, templateUrl: string): CompileStep {
|
||||||
|
return this._compileStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MockStep extends CompileStep {
|
||||||
|
processClosure:Function;
|
||||||
|
constructor(process) {
|
||||||
|
super();
|
||||||
|
this.processClosure = process;
|
||||||
|
}
|
||||||
|
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
||||||
|
this.processClosure(parent, current, control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SomeComponent {}
|
|
@ -17,6 +17,7 @@ import {BindingPropagationConfig} from 'angular2/src/core/compiler/binding_propa
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
|
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
|
||||||
import {Template} from 'angular2/src/core/annotations/template';
|
import {Template} from 'angular2/src/core/annotations/template';
|
||||||
|
@ -40,7 +41,8 @@ export function main() {
|
||||||
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
||||||
tplResolver,
|
tplResolver,
|
||||||
new ComponentUrlMapper(),
|
new ComponentUrlMapper(),
|
||||||
urlResolver
|
urlResolver,
|
||||||
|
new CssProcessor()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,137 +0,0 @@
|
||||||
import {
|
|
||||||
describe,
|
|
||||||
beforeEach,
|
|
||||||
expect,
|
|
||||||
it,
|
|
||||||
iit,
|
|
||||||
ddescribe,
|
|
||||||
el,
|
|
||||||
SpyObject,
|
|
||||||
proxy,
|
|
||||||
} from 'angular2/test_lib';
|
|
||||||
|
|
||||||
import {CompilePipeline} from 'angular2/src/core/compiler/pipeline/compile_pipeline';
|
|
||||||
import {ResolveCss} from 'angular2/src/core/compiler/pipeline/resolve_css';
|
|
||||||
import {CompileElement} from 'angular2/src/core/compiler/pipeline/compile_element';
|
|
||||||
import {CompileStep} from 'angular2/src/core/compiler/pipeline/compile_step';
|
|
||||||
import {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
|
|
||||||
|
|
||||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
|
||||||
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
|
|
||||||
import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
|
||||||
import {ProtoView} from 'angular2/src/core/compiler/view';
|
|
||||||
|
|
||||||
import {IMPLEMENTS, Type, stringify} from 'angular2/src/facade/lang';
|
|
||||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
|
||||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
|
||||||
|
|
||||||
export function main() {
|
|
||||||
describe('ResolveCss', () => {
|
|
||||||
function createPipeline(strategy:ShadowDomStrategy) {
|
|
||||||
var annotation = new Component({selector: 'selector'});
|
|
||||||
var meta = new DirectiveMetadata(SomeComponent, annotation);
|
|
||||||
var resolveCss = new ResolveCss(meta, strategy, 'http://base');
|
|
||||||
return new CompilePipeline([
|
|
||||||
new MockStep((parent, current, control) => {
|
|
||||||
current.inheritedProtoView = new ProtoView(null, null, null);
|
|
||||||
}),
|
|
||||||
resolveCss
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
it('it should set ignoreBindings to true for style elements', () => {
|
|
||||||
var strategy = new DummyStrategy();
|
|
||||||
strategy.spy('transformStyleText').andCallFake((a, b, c) => '.css {}');
|
|
||||||
strategy.spy('handleStyleElement');
|
|
||||||
|
|
||||||
var pipeline = createPipeline(strategy);
|
|
||||||
var results = pipeline.process(el('<div><style></style></div>'));
|
|
||||||
expect(results[0].ignoreBindings).toBe(false);
|
|
||||||
expect(results[1].ignoreBindings).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should delegate the handling of style elements to the strategy', () => {
|
|
||||||
var strategy = new DummyStrategy();
|
|
||||||
strategy.spy('transformStyleText').andCallFake((a, b, c) => '.css {}');
|
|
||||||
strategy.spy('handleStyleElement');
|
|
||||||
|
|
||||||
var pipeline = createPipeline(strategy);
|
|
||||||
var template = el('<div></div>');
|
|
||||||
var styleEl = el('<style></style>');
|
|
||||||
DOM.appendChild(template, styleEl);
|
|
||||||
|
|
||||||
pipeline.process(template);
|
|
||||||
|
|
||||||
expect(strategy.spy('handleStyleElement')).toHaveBeenCalledWith(styleEl);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle css transformed synchronously', () => {
|
|
||||||
var strategy = new DummyStrategy();
|
|
||||||
strategy.spy('transformStyleText').andCallFake((css, url, cmp) => {
|
|
||||||
return `${css}, ${url}, ${stringify(cmp)}`;
|
|
||||||
});
|
|
||||||
strategy.spy('handleStyleElement');
|
|
||||||
|
|
||||||
var pipeline = createPipeline(strategy);
|
|
||||||
var template = el('<div></div>');
|
|
||||||
var styleEl = el('<style>/*css*/</style>');
|
|
||||||
DOM.appendChild(template, styleEl);
|
|
||||||
|
|
||||||
var results = pipeline.process(template);
|
|
||||||
expect(styleEl).toHaveText('/*css*/, http://base, SomeComponent');
|
|
||||||
expect(results[0].inheritedProtoView.stylePromises.length).toBe(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle css transformed asynchronously', (done) => {
|
|
||||||
var completer = PromiseWrapper.completer();
|
|
||||||
var strategy = new DummyStrategy();
|
|
||||||
var futureCss;
|
|
||||||
strategy.spy('transformStyleText').andCallFake((css, url, cmp) => {
|
|
||||||
futureCss = `${css}, ${url}, ${stringify(cmp)}`;
|
|
||||||
return completer.promise;
|
|
||||||
});
|
|
||||||
strategy.spy('handleStyleElement');
|
|
||||||
|
|
||||||
var pipeline = createPipeline(strategy);
|
|
||||||
var template = el('<div></div>');
|
|
||||||
var styleEl = el('<style>/*css*/</style>');
|
|
||||||
DOM.appendChild(template, styleEl);
|
|
||||||
|
|
||||||
var results = pipeline.process(template);
|
|
||||||
|
|
||||||
// The css should be empty before the style promise is resolved
|
|
||||||
expect(styleEl).toHaveText('');
|
|
||||||
expect(results[0].inheritedProtoView.stylePromises[0]).toBe(completer.promise);
|
|
||||||
|
|
||||||
completer.resolve(futureCss);
|
|
||||||
|
|
||||||
// TODO(vicb): refactor once we have better support for async tests
|
|
||||||
completer.promise.then((_) => {
|
|
||||||
expect(styleEl).toHaveText('/*css*/, http://base, SomeComponent');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@proxy
|
|
||||||
@IMPLEMENTS(ShadowDomStrategy)
|
|
||||||
class DummyStrategy extends SpyObject {
|
|
||||||
noSuchMethod(m) {
|
|
||||||
return super.noSuchMethod(m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SomeComponent {}
|
|
||||||
|
|
||||||
class MockStep extends CompileStep {
|
|
||||||
processClosure:Function;
|
|
||||||
constructor(process) {
|
|
||||||
super();
|
|
||||||
this.processClosure = process;
|
|
||||||
}
|
|
||||||
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
|
||||||
this.processClosure(parent, current, control);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
import {describe, beforeEach, expect, it, iit, ddescribe, el} from 'angular2/test_lib';
|
|
||||||
|
|
||||||
import {CompilePipeline} from 'angular2/src/core/compiler/pipeline/compile_pipeline';
|
|
||||||
import {ShimShadowDom} from 'angular2/src/core/compiler/pipeline/shim_shadow_dom';
|
|
||||||
import {CompileElement} from 'angular2/src/core/compiler/pipeline/compile_element';
|
|
||||||
import {CompileStep} from 'angular2/src/core/compiler/pipeline/compile_step';
|
|
||||||
import {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
|
|
||||||
|
|
||||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
|
||||||
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
|
|
||||||
import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
|
||||||
|
|
||||||
import {Type, isBlank, stringify} from 'angular2/src/facade/lang';
|
|
||||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
|
||||||
|
|
||||||
export function main() {
|
|
||||||
describe('ShimShadowDom', () => {
|
|
||||||
function createPipeline(ignoreBindings: boolean) {
|
|
||||||
var annotation = new Component({selector: 'selector'});
|
|
||||||
var meta = new DirectiveMetadata(SomeComponent, annotation);
|
|
||||||
var shimShadowDom = new ShimShadowDom(meta, new FakeStrategy());
|
|
||||||
|
|
||||||
return new CompilePipeline([
|
|
||||||
new MockStep((parent, current, control) => {
|
|
||||||
current.ignoreBindings = ignoreBindings;
|
|
||||||
}),
|
|
||||||
new MockStep((parent, current, control) => {
|
|
||||||
var el = current.element;
|
|
||||||
if (DOM.hasClass(el, 'host')) {
|
|
||||||
current.componentDirective = new DirectiveMetadata(SomeComponent, null);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
shimShadowDom
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should add the content attribute to content element', () => {
|
|
||||||
var pipeline = createPipeline(false);
|
|
||||||
var results = pipeline.process(el('<div></div>'));
|
|
||||||
expect(DOM.getAttribute(results[0].element, 'SomeComponent-content')).toEqual('');
|
|
||||||
expect(isBlank(DOM.getAttribute(results[0].element, 'SomeComponent-host'))).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add both the content and host attributes to host element', () => {
|
|
||||||
var pipeline = createPipeline(false);
|
|
||||||
var results = pipeline.process(el('<div class="host"></div>'));
|
|
||||||
expect(DOM.getAttribute(results[0].element, 'SomeComponent-content')).toEqual('');
|
|
||||||
expect(DOM.getAttribute(results[0].element, 'SomeComponent-host')).toEqual('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should do nothing when ignoreBindings is true', () => {
|
|
||||||
var pipeline = createPipeline(true);
|
|
||||||
var results = pipeline.process(el('<div class="host"></div>'));
|
|
||||||
expect(isBlank(DOM.getAttribute(results[0].element, 'SomeComponent-content'))).toBeTruthy();
|
|
||||||
expect(isBlank(DOM.getAttribute(results[0].element, 'SomeComponent-host'))).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakeStrategy extends ShadowDomStrategy {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
shimContentElement(component: Type, element) {
|
|
||||||
var attrName = stringify(component) + '-content';
|
|
||||||
DOM.setAttribute(element, attrName, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
shimHostElement(component: Type, element) {
|
|
||||||
var attrName = stringify(component) + '-host';
|
|
||||||
DOM.setAttribute(element, attrName, '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MockStep extends CompileStep {
|
|
||||||
processClosure:Function;
|
|
||||||
constructor(process) {
|
|
||||||
super();
|
|
||||||
this.processClosure = process;
|
|
||||||
}
|
|
||||||
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
|
||||||
this.processClosure(parent, current, control);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SomeComponent {}
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mappe
|
||||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
import {MockTemplateResolver} from 'angular2/src/mock/template_resolver_mock';
|
import {MockTemplateResolver} from 'angular2/src/mock/template_resolver_mock';
|
||||||
|
|
||||||
|
@ -58,7 +59,8 @@ export function main() {
|
||||||
strategy,
|
strategy,
|
||||||
tplResolver,
|
tplResolver,
|
||||||
new ComponentUrlMapper(),
|
new ComponentUrlMapper(),
|
||||||
urlResolver
|
urlResolver,
|
||||||
|
new CssProcessor()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,10 @@ import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
||||||
import {ProtoView} from 'angular2/src/core/compiler/view';
|
import {ProtoView} from 'angular2/src/core/compiler/view';
|
||||||
|
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
|
||||||
|
|
||||||
|
import {CompileElement} from 'angular2/src/core/compiler/pipeline/compile_element';
|
||||||
|
|
||||||
import {XHR} from 'angular2/src/core/compiler/xhr/xhr';
|
import {XHR} from 'angular2/src/core/compiler/xhr/xhr';
|
||||||
|
|
||||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||||
|
@ -41,16 +45,24 @@ export function main() {
|
||||||
expect(shadowRoot).toHaveText('view');
|
expect(shadowRoot).toHaveText('view');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should should not transform template elements', () => {
|
||||||
|
expect(strategy.getTemplateCompileStep(null)).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
it('should rewrite style urls', () => {
|
it('should rewrite style urls', () => {
|
||||||
var css = '.foo {background-image: url("img.jpg");}';
|
var step = strategy.getStyleCompileStep(null, 'http://base');
|
||||||
expect(strategy.transformStyleText(css, 'http://base', null))
|
var styleElement = DOM.createStyleElement('.one {background-image: url("img.jpg");}');
|
||||||
.toEqual(".foo {background-image: url('http://base/img.jpg');}");
|
var compileElement = new CompileElement(styleElement);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
expect(styleElement).toHaveText(".one {background-image: url('http://base/img.jpg');}");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not inline import rules', () => {
|
it('should not inline import rules', () => {
|
||||||
var css = '@import "other.css";';
|
var step = strategy.getStyleCompileStep(null, 'http://base');
|
||||||
expect(strategy.transformStyleText(css, 'http://base', null))
|
var styleElement = DOM.createStyleElement('@import "other.css";');
|
||||||
.toEqual("@import 'http://base/other.css';");
|
var compileElement = new CompileElement(styleElement);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
expect(styleElement).toHaveText("@import 'http://base/other.css';");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -81,65 +93,113 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should rewrite style urls', () => {
|
it('should rewrite style urls', () => {
|
||||||
var css = '.foo {background-image: url("img.jpg");}';
|
var template = el('<div><style>.foo {background-image: url("img.jpg");}</style></div>');
|
||||||
expect(strategy.transformStyleText(css, 'http://base', SomeComponent))
|
var cmpMetadata = new DirectiveMetadata(SomeComponent, null);
|
||||||
.toEqual(".foo[_ngcontent-0] {\nbackground-image: url(http://base/img.jpg);\n}");
|
var step = strategy.getStyleCompileStep(cmpMetadata, 'http://base');
|
||||||
|
var styleElement = DOM.firstChild(template);
|
||||||
|
var compileElement = new CompileElement(styleElement);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
expect(styleElement).toHaveText(".foo[_ngcontent-0] {\n" +
|
||||||
|
"background-image: url(http://base/img.jpg);\n" +
|
||||||
|
"}");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should scope style', () => {
|
it('should scope styles', () => {
|
||||||
var css = '.foo {} :host {}';
|
var template = el('<div><style>.foo {} :host {}</style></div>');
|
||||||
expect(strategy.transformStyleText(css, 'http://base', SomeComponent))
|
var cmpMetadata = new DirectiveMetadata(SomeComponent, null);
|
||||||
.toEqual(".foo[_ngcontent-0] {\n\n}\n\n[_nghost-0] {\n\n}");
|
var step = strategy.getStyleCompileStep(cmpMetadata, 'http://base');
|
||||||
|
var styleElement = DOM.firstChild(template);
|
||||||
|
var compileElement = new CompileElement(styleElement);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
expect(styleElement).toHaveText(".foo[_ngcontent-0] {\n\n}\n\n[_nghost-0] {\n\n}");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should inline @import rules', (done) => {
|
it('should inline @import rules', (done) => {
|
||||||
xhr.reply('http://base/one.css', '.one {}');
|
xhr.reply('http://base/one.css', '.one {}');
|
||||||
var css = '@import "one.css";';
|
|
||||||
var promise = strategy.transformStyleText(css, 'http://base', SomeComponent);
|
var template = el('<div><style>@import "one.css";</style></div>');
|
||||||
expect(promise).toBePromise();
|
var cmpMetadata = new DirectiveMetadata(SomeComponent, null);
|
||||||
promise.then((css) => {
|
var step = strategy.getStyleCompileStep(cmpMetadata, 'http://base');
|
||||||
expect(css).toEqual('.one[_ngcontent-0] {\n\n}');
|
var styleElement = DOM.firstChild(template);
|
||||||
|
var parentElement = new CompileElement(template);
|
||||||
|
var compileElement = new CompileElement(styleElement);
|
||||||
|
var parentpv = new ProtoView(null, null, null);
|
||||||
|
parentElement.inheritedProtoView = parentpv;
|
||||||
|
step.process(parentElement, compileElement, null);
|
||||||
|
|
||||||
|
expect(parentpv.stylePromises.length).toEqual(1);
|
||||||
|
expect(parentpv.stylePromises[0]).toBePromise();
|
||||||
|
|
||||||
|
expect(styleElement).toHaveText('');
|
||||||
|
parentpv.stylePromises[0].then((_) => {
|
||||||
|
expect(styleElement).toHaveText('.one[_ngcontent-0] {\n\n}');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the same style given the same component', () => {
|
it('should return the same style given the same component', () => {
|
||||||
var css = '.foo {} :host {}';
|
var template = el('<div><style>.foo {} :host {}</style></div>');
|
||||||
expect(strategy.transformStyleText(css, 'http://base', SomeComponent))
|
var cmpMetadata = new DirectiveMetadata(SomeComponent, null);
|
||||||
.toEqual(".foo[_ngcontent-0] {\n\n}\n\n[_nghost-0] {\n\n}");
|
var step = strategy.getStyleCompileStep(cmpMetadata, 'http://base');
|
||||||
expect(strategy.transformStyleText(css, 'http://base', SomeComponent))
|
var styleElement = DOM.firstChild(template);
|
||||||
.toEqual(".foo[_ngcontent-0] {\n\n}\n\n[_nghost-0] {\n\n}");
|
var compileElement = new CompileElement(styleElement);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
|
||||||
|
var template2 = el('<div><style>.foo {} :host {}</style></div>');
|
||||||
|
var step2 = strategy.getStyleCompileStep(cmpMetadata, 'http://base');
|
||||||
|
var styleElement2 = DOM.firstChild(template2);
|
||||||
|
var compileElement2 = new CompileElement(styleElement2);
|
||||||
|
step2.process(null, compileElement2, null);
|
||||||
|
|
||||||
|
expect(DOM.getText(styleElement)).toEqual(DOM.getText(styleElement2));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return different styles given different components', () => {
|
it('should return different styles given different components', () => {
|
||||||
var css = '.foo {} :host {}';
|
var template = el('<div><style>.foo {} :host {}</style></div>');
|
||||||
expect(strategy.transformStyleText(css, 'http://base', SomeComponent))
|
var cmpMetadata = new DirectiveMetadata(SomeComponent, null);
|
||||||
.toEqual(".foo[_ngcontent-0] {\n\n}\n\n[_nghost-0] {\n\n}");
|
var step = strategy.getStyleCompileStep(cmpMetadata, 'http://base');
|
||||||
expect(strategy.transformStyleText(css, 'http://base', SomeOtherComponent))
|
var styleElement = DOM.firstChild(template);
|
||||||
.toEqual(".foo[_ngcontent-1] {\n\n}\n\n[_nghost-1] {\n\n}");
|
var compileElement = new CompileElement(styleElement);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
|
||||||
|
var template2 = el('<div><style>.foo {} :host {}</style></div>');
|
||||||
|
var cmpMetadata2 = new DirectiveMetadata(SomeOtherComponent, null);
|
||||||
|
var step2 = strategy.getStyleCompileStep(cmpMetadata2, 'http://base');
|
||||||
|
var styleElement2 = DOM.firstChild(template2);
|
||||||
|
var compileElement2 = new CompileElement(styleElement2);
|
||||||
|
step2.process(null, compileElement2, null);
|
||||||
|
|
||||||
|
expect(DOM.getText(styleElement)).not.toEqual(DOM.getText(styleElement2));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should move the style element to the style host', () => {
|
it('should move the style element to the style host', () => {
|
||||||
var originalHost = el('<div></div>');
|
var template = el('<div><style>.one {}</style></div>');
|
||||||
var styleEl = el('<style>/*css*/</style>');
|
var cmpMetadata = new DirectiveMetadata(SomeComponent, null);
|
||||||
DOM.appendChild(originalHost, styleEl);
|
var step = strategy.getStyleCompileStep(cmpMetadata, 'http://base');
|
||||||
expect(originalHost).toHaveText('/*css*/');
|
var styleElement = DOM.firstChild(template);
|
||||||
|
var compileElement = new CompileElement(styleElement);
|
||||||
strategy.handleStyleElement(styleEl);
|
step.process(null, compileElement, null);
|
||||||
expect(originalHost).toHaveText('');
|
expect(template).toHaveText('');
|
||||||
expect(styleHost).toHaveText('/*css*/');
|
expect(styleHost).toHaveText('.one[_ngcontent-0] {\n\n}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add an attribute to the content elements', () => {
|
it('should add an attribute to the content elements', () => {
|
||||||
var elt = el('<div></div>');
|
var template = el('<div></div>');
|
||||||
strategy.shimContentElement(SomeComponent, elt);
|
var cmpMetadata = new DirectiveMetadata(SomeComponent, null);
|
||||||
expect(DOM.getAttribute(elt, '_ngcontent-0')).toEqual('');
|
var step = strategy.getTemplateCompileStep(cmpMetadata);
|
||||||
|
var compileElement = new CompileElement(template);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
expect(DOM.getAttribute(template, '_ngcontent-0')).toEqual('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add an attribute to the host elements', () => {
|
it('should add an attribute to the host elements', () => {
|
||||||
var elt = el('<div></div>');
|
var template = el('<div></div>');
|
||||||
strategy.shimHostElement(SomeComponent, elt);
|
var cmpMetadata = new DirectiveMetadata(SomeComponent, null);
|
||||||
expect(DOM.getAttribute(elt, '_nghost-0')).toEqual('');
|
var step = strategy.getTemplateCompileStep(cmpMetadata);
|
||||||
|
var compileElement = new CompileElement(template);
|
||||||
|
compileElement.componentDirective = new DirectiveMetadata(SomeOtherComponent, null);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
expect(DOM.getAttribute(template, '_nghost-1')).toEqual('');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -168,43 +228,45 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should rewrite style urls', () => {
|
it('should rewrite style urls', () => {
|
||||||
var css = '.foo {background-image: url("img.jpg");}';
|
var template = el('<div><style>.one {background-image: url("img.jpg");}</style></div>')
|
||||||
expect(strategy.transformStyleText(css, 'http://base', null))
|
var step = strategy.getStyleCompileStep(null, 'http://base');
|
||||||
.toEqual(".foo {background-image: url('http://base/img.jpg');}");
|
var styleElement = DOM.firstChild(template);
|
||||||
|
var compileElement = new CompileElement(styleElement);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
expect(styleElement).toHaveText(".one {background-image: url('http://base/img.jpg');}");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not inline import rules', () => {
|
it('should not inline import rules', () => {
|
||||||
var css = '@import "other.css";';
|
var template = el('<div><style>@import "other.css";</style></div>')
|
||||||
expect(strategy.transformStyleText(css, 'http://base', null))
|
var step = strategy.getStyleCompileStep(null, 'http://base');
|
||||||
.toEqual("@import 'http://base/other.css';");
|
var styleElement = DOM.firstChild(template);
|
||||||
|
var compileElement = new CompileElement(styleElement);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
expect(styleElement).toHaveText("@import 'http://base/other.css';");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should move the style element to the style host', () => {
|
it('should move the style element to the style host', () => {
|
||||||
var originalHost = el('<div></div>');
|
var template = el('<div><style>/*css*/</style></div>')
|
||||||
var styleEl = el('<style>/*css*/</style>');
|
var step = strategy.getStyleCompileStep(null, 'http://base');
|
||||||
DOM.appendChild(originalHost, styleEl);
|
var styleElement = DOM.firstChild(template);
|
||||||
expect(originalHost).toHaveText('/*css*/');
|
var compileElement = new CompileElement(styleElement);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
strategy.handleStyleElement(styleEl);
|
expect(styleHost).toHaveText("/*css*/");
|
||||||
expect(originalHost).toHaveText('');
|
|
||||||
expect(styleHost).toHaveText('/*css*/');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should insert the same style only once in the style host', () => {
|
it('should insert the same style only once in the style host', () => {
|
||||||
var originalHost = el('<div></div>');
|
var template = el('<div><style>/*css1*/</style><style>/*css2*/</style>' +
|
||||||
var styleEl1 = el('<style>/*css 1*/</style>');
|
'<style>/*css1*/</style></div>')
|
||||||
var styleEl2 = el('<style>/*css 2*/</style>');
|
var step = strategy.getStyleCompileStep(null, 'http://base');
|
||||||
var styleEl1bis = el('<style>/*css 1*/</style>');
|
var styleElements = DOM.childNodes(template);
|
||||||
|
var compileElement = new CompileElement(styleElements[0]);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
compileElement = new CompileElement(styleElements[0]);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
compileElement = new CompileElement(styleElements[0]);
|
||||||
|
step.process(null, compileElement, null);
|
||||||
|
|
||||||
DOM.appendChild(originalHost, styleEl1);
|
expect(styleHost).toHaveText("/*css1*//*css2*/");
|
||||||
DOM.appendChild(originalHost, styleEl2);
|
|
||||||
DOM.appendChild(originalHost, styleEl1bis);
|
|
||||||
|
|
||||||
strategy.handleStyleElement(styleEl1);
|
|
||||||
strategy.handleStyleElement(styleEl2);
|
|
||||||
strategy.handleStyleElement(styleEl1bis);
|
|
||||||
expect(originalHost).toHaveText('');
|
|
||||||
expect(styleHost).toHaveText('/*css 1*//*css 2*/');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
import {Template} from 'angular2/src/core/annotations/template';
|
import {Template} from 'angular2/src/core/annotations/template';
|
||||||
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
|
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
|
||||||
|
@ -36,7 +37,9 @@ export function main() {
|
||||||
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
||||||
tplResolver,
|
tplResolver,
|
||||||
new ComponentUrlMapper(),
|
new ComponentUrlMapper(),
|
||||||
urlResolver);
|
urlResolver,
|
||||||
|
new CssProcessor()
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
function createView(pv) {
|
function createView(pv) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
import {Component} from 'angular2/src/core/annotations/annotations';
|
||||||
import {Template} from 'angular2/src/core/annotations/template';
|
import {Template} from 'angular2/src/core/annotations/template';
|
||||||
|
@ -36,7 +37,9 @@ export function main() {
|
||||||
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
||||||
tplResolver,
|
tplResolver,
|
||||||
new ComponentUrlMapper(),
|
new ComponentUrlMapper(),
|
||||||
urlResolver);
|
urlResolver,
|
||||||
|
new CssProcessor()
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
function createView(pv) {
|
function createView(pv) {
|
||||||
|
|
|
@ -9,6 +9,8 @@ import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_str
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
|
|
||||||
import {Decorator, Component} from 'angular2/src/core/annotations/annotations';
|
import {Decorator, Component} from 'angular2/src/core/annotations/annotations';
|
||||||
import {Template} from 'angular2/src/core/annotations/template';
|
import {Template} from 'angular2/src/core/annotations/template';
|
||||||
|
@ -33,7 +35,9 @@ export function main() {
|
||||||
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
||||||
tplResolver,
|
tplResolver,
|
||||||
new ComponentUrlMapper(),
|
new ComponentUrlMapper(),
|
||||||
urlResolver);
|
urlResolver,
|
||||||
|
new CssProcessor()
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
function createView(pv) {
|
function createView(pv) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_str
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
import {Component} from 'angular2/src/core/annotations/annotations';
|
||||||
import {Template} from 'angular2/src/core/annotations/template';
|
import {Template} from 'angular2/src/core/annotations/template';
|
||||||
|
@ -31,7 +32,9 @@ export function main() {
|
||||||
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
||||||
tplResolver,
|
tplResolver,
|
||||||
new ComponentUrlMapper(),
|
new ComponentUrlMapper(),
|
||||||
urlResolver);
|
urlResolver,
|
||||||
|
new CssProcessor()
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
function createView(pv) {
|
function createView(pv) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
import {MockTemplateResolver} from 'angular2/src/mock/template_resolver_mock';
|
import {MockTemplateResolver} from 'angular2/src/mock/template_resolver_mock';
|
||||||
|
|
||||||
|
@ -37,7 +38,8 @@ export function main() {
|
||||||
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
new NativeShadowDomStrategy(new StyleUrlResolver(urlResolver)),
|
||||||
tplResolver,
|
tplResolver,
|
||||||
new ComponentUrlMapper(),
|
new ComponentUrlMapper(),
|
||||||
urlResolver
|
urlResolver,
|
||||||
|
new CssProcessor()
|
||||||
);
|
);
|
||||||
|
|
||||||
tplResolver.setTemplate(componentType, new Template({
|
tplResolver.setTemplate(componentType, new Template({
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
||||||
|
@ -100,7 +101,9 @@ export function main() {
|
||||||
new NativeShadowDomStrategy(styleUrlResolver),
|
new NativeShadowDomStrategy(styleUrlResolver),
|
||||||
templateResolver,
|
templateResolver,
|
||||||
new ComponentUrlMapper(),
|
new ComponentUrlMapper(),
|
||||||
urlResolver);
|
urlResolver,
|
||||||
|
new CssProcessor()
|
||||||
|
);
|
||||||
var templateNoBindings = createTemplateHtml('templateNoBindings', count);
|
var templateNoBindings = createTemplateHtml('templateNoBindings', count);
|
||||||
var templateWithBindings = createTemplateHtml('templateWithBindings', count);
|
var templateWithBindings = createTemplateHtml('templateWithBindings', count);
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
import {If, Foreach} from 'angular2/directives';
|
import {If, Foreach} from 'angular2/directives';
|
||||||
import {App, setupReflectorForApp} from './app';
|
import {App, setupReflectorForApp} from './app';
|
||||||
|
@ -180,12 +181,12 @@ export function setupReflectorForAngular() {
|
||||||
|
|
||||||
reflector.registerType(Compiler, {
|
reflector.registerType(Compiler, {
|
||||||
"factory": (changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
|
"factory": (changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
|
||||||
tplResolver, cmpUrlMapper, urlResolver) =>
|
tplResolver, cmpUrlMapper, urlResolver, cssProcessor) =>
|
||||||
new Compiler(changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
|
new Compiler(changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
|
||||||
tplResolver, cmpUrlMapper, urlResolver),
|
tplResolver, cmpUrlMapper, urlResolver, cssProcessor),
|
||||||
"parameters": [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader], [Parser],
|
"parameters": [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader], [Parser],
|
||||||
[CompilerCache], [ShadowDomStrategy], [TemplateResolver], [ComponentUrlMapper],
|
[CompilerCache], [ShadowDomStrategy], [TemplateResolver], [ComponentUrlMapper],
|
||||||
[UrlResolver]],
|
[UrlResolver], [CssProcessor]],
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -279,4 +280,10 @@ export function setupReflectorForAngular() {
|
||||||
"parameters": [[XHR], [StyleUrlResolver], [UrlResolver]],
|
"parameters": [[XHR], [StyleUrlResolver], [UrlResolver]],
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reflector.registerType(CssProcessor, {
|
||||||
|
"factory": () => new CssProcessor(),
|
||||||
|
"parameters": [],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
|
@ -69,12 +70,12 @@ function setupReflector() {
|
||||||
|
|
||||||
reflector.registerType(Compiler, {
|
reflector.registerType(Compiler, {
|
||||||
'factory': (cd, templateLoader, reader, parser, compilerCache, strategy, tplResolver,
|
'factory': (cd, templateLoader, reader, parser, compilerCache, strategy, tplResolver,
|
||||||
cmpUrlMapper, urlResolver) =>
|
cmpUrlMapper, urlResolver, cssProcessor) =>
|
||||||
new Compiler(cd, templateLoader, reader, parser, compilerCache, strategy, tplResolver,
|
new Compiler(cd, templateLoader, reader, parser, compilerCache, strategy, tplResolver,
|
||||||
cmpUrlMapper, urlResolver),
|
cmpUrlMapper, urlResolver, cssProcessor),
|
||||||
'parameters': [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader],
|
'parameters': [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader],
|
||||||
[Parser], [CompilerCache], [ShadowDomStrategy], [TemplateResolver],
|
[Parser], [CompilerCache], [ShadowDomStrategy], [TemplateResolver],
|
||||||
[ComponentUrlMapper], [UrlResolver]],
|
[ComponentUrlMapper], [UrlResolver], [CssProcessor]],
|
||||||
'annotations': []
|
'annotations': []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -170,6 +171,12 @@ function setupReflector() {
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reflector.registerType(CssProcessor, {
|
||||||
|
"factory": () => new CssProcessor(),
|
||||||
|
"parameters": [],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
|
|
||||||
reflector.registerGetters({
|
reflector.registerGetters({
|
||||||
'value': (a) => a.value,
|
'value': (a) => a.value,
|
||||||
'left': (a) => a.left,
|
'left': (a) => a.left,
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
||||||
|
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||||
|
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
|
|
||||||
|
@ -49,12 +50,12 @@ function setup() {
|
||||||
|
|
||||||
reflector.registerType(Compiler, {
|
reflector.registerType(Compiler, {
|
||||||
"factory": (changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
|
"factory": (changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
|
||||||
tplResolver, cmpUrlMapper, urlResolver) =>
|
tplResolver, cmpUrlMapper, urlResolver, cssProcessor) =>
|
||||||
new Compiler(changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
|
new Compiler(changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
|
||||||
tplResolver, cmpUrlMapper, urlResolver),
|
tplResolver, cmpUrlMapper, urlResolver, cssProcessor),
|
||||||
"parameters": [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader], [Parser],
|
"parameters": [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader], [Parser],
|
||||||
[CompilerCache], [ShadowDomStrategy], [TemplateResolver], [ComponentUrlMapper],
|
[CompilerCache], [ShadowDomStrategy], [TemplateResolver], [ComponentUrlMapper],
|
||||||
[UrlResolver]],
|
[UrlResolver], [CssProcessor]],
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -149,6 +150,12 @@ function setup() {
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reflector.registerType(CssProcessor, {
|
||||||
|
"factory": () => new CssProcessor(),
|
||||||
|
"parameters": [],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
|
|
||||||
reflector.registerGetters({
|
reflector.registerGetters({
|
||||||
"greeting": (a) => a.greeting
|
"greeting": (a) => a.greeting
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue