refactor(Compiler): make shadow DOM stragegy support more flexible
This commit is contained in:

committed by
Misko Hevery

parent
bcf4a96a84
commit
9982520a23
2
modules/angular2/src/core/application.js
vendored
2
modules/angular2/src/core/application.js
vendored
@ -24,6 +24,7 @@ import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mappe
|
||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
|
||||
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
|
||||
|
||||
var _rootInjector: Injector;
|
||||
|
||||
@ -98,6 +99,7 @@ function _injectorBindings(appComponentType): List<Binding> {
|
||||
UrlResolver,
|
||||
StyleUrlResolver,
|
||||
StyleInliner,
|
||||
CssProcessor,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ import {ShadowDomStrategy} from './shadow_dom_strategy';
|
||||
import {CompileStep} from './pipeline/compile_step';
|
||||
import {ComponentUrlMapper} from './component_url_mapper';
|
||||
import {UrlResolver} from './url_resolver';
|
||||
|
||||
import {CssProcessor} from './css_processor';
|
||||
|
||||
/**
|
||||
* Cache that stores the ProtoView of the template of a component.
|
||||
@ -61,6 +61,7 @@ export class Compiler {
|
||||
_componentUrlMapper: ComponentUrlMapper;
|
||||
_urlResolver: UrlResolver;
|
||||
_appUrl: string;
|
||||
_cssProcessor: CssProcessor;
|
||||
|
||||
constructor(changeDetection:ChangeDetection,
|
||||
templateLoader:TemplateLoader,
|
||||
@ -70,7 +71,8 @@ export class Compiler {
|
||||
shadowDomStrategy: ShadowDomStrategy,
|
||||
templateResolver: TemplateResolver,
|
||||
componentUrlMapper: ComponentUrlMapper,
|
||||
urlResolver: UrlResolver) {
|
||||
urlResolver: UrlResolver,
|
||||
cssProcessor: CssProcessor) {
|
||||
this._changeDetection = changeDetection;
|
||||
this._reader = reader;
|
||||
this._parser = parser;
|
||||
@ -87,6 +89,7 @@ export class Compiler {
|
||||
this._componentUrlMapper = componentUrlMapper;
|
||||
this._urlResolver = urlResolver;
|
||||
this._appUrl = urlResolver.resolve(null, './');
|
||||
this._cssProcessor = cssProcessor;
|
||||
}
|
||||
|
||||
createSteps(component:Type, template: Template):List<CompileStep> {
|
||||
@ -102,7 +105,7 @@ export class Compiler {
|
||||
var templateUrl = this._templateLoader.getTemplateUrl(template);
|
||||
|
||||
return createDefaultSteps(this._changeDetection, this._parser, cmpMetadata, dirMetadata,
|
||||
this._shadowDomStrategy, templateUrl);
|
||||
this._shadowDomStrategy, templateUrl, this._cssProcessor);
|
||||
}
|
||||
|
||||
compile(component: Type):Promise<ProtoView> {
|
||||
|
48
modules/angular2/src/core/compiler/css_processor.js
vendored
Normal file
48
modules/angular2/src/core/compiler/css_processor.js
vendored
Normal file
@ -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 {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {isPresent} from 'angular2/src/facade/lang';
|
||||
|
||||
import {PropertyBindingParser} from './property_binding_parser';
|
||||
import {TextInterpolationParser} from './text_interpolation_parser';
|
||||
@ -9,8 +10,8 @@ import {ElementBindingMarker} from './element_binding_marker';
|
||||
import {ProtoViewBuilder} from './proto_view_builder';
|
||||
import {ProtoElementInjectorBuilder} from './proto_element_injector_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 {ShadowDomStrategy, EmulatedScopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
|
||||
@ -25,11 +26,12 @@ export function createDefaultSteps(
|
||||
compiledComponent: DirectiveMetadata,
|
||||
directives: List<DirectiveMetadata>,
|
||||
shadowDomStrategy: ShadowDomStrategy,
|
||||
templateUrl: string) {
|
||||
templateUrl: string,
|
||||
cssProcessor: CssProcessor) {
|
||||
|
||||
var steps = [
|
||||
new ViewSplitter(parser),
|
||||
new ResolveCss(compiledComponent, shadowDomStrategy, templateUrl),
|
||||
cssProcessor.getCompileStep(compiledComponent, shadowDomStrategy, templateUrl),
|
||||
new PropertyBindingParser(parser),
|
||||
new DirectiveParser(directives),
|
||||
new TextInterpolationParser(parser),
|
||||
@ -39,9 +41,9 @@ export function createDefaultSteps(
|
||||
new ElementBinderBuilder(parser),
|
||||
];
|
||||
|
||||
if (shadowDomStrategy instanceof EmulatedScopedShadowDomStrategy) {
|
||||
var step = new ShimShadowDom(compiledComponent, shadowDomStrategy);
|
||||
ListWrapper.push(steps, step);
|
||||
var shadowDomStep = shadowDomStrategy.getTemplateCompileStep(compiledComponent);
|
||||
if (isPresent(shadowDomStep)) {
|
||||
ListWrapper.push(steps, shadowDomStep);
|
||||
}
|
||||
|
||||
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 {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
import {List, ListWrapper, MapWrapper, Map} from 'angular2/src/facade/collection';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
|
||||
import {View} from './view';
|
||||
|
||||
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 {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 {
|
||||
attachTemplate(el, view:View) {}
|
||||
constructLightDom(lightDomView:View, shadowDomView:View, el) {}
|
||||
polyfillDirectives():List<Type> { return null; }
|
||||
// TODO(vicb): union types: return either a string or a Promise<string>
|
||||
transformStyleText(cssText: string, baseUrl: string, component: Type) {}
|
||||
handleStyleElement(styleEl) {};
|
||||
shimContentElement(component: Type, element) {}
|
||||
shimHostElement(component: Type, element) {}
|
||||
constructLightDom(lightDomView:View, shadowDomView:View, el): LightDom { return null; }
|
||||
polyfillDirectives():List<Type> { return []; }
|
||||
|
||||
/**
|
||||
* An optional step that can modify the template style elements.
|
||||
*
|
||||
* @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 {
|
||||
_styleUrlResolver: StyleUrlResolver;
|
||||
_lastInsertedStyle;
|
||||
_styleHost;
|
||||
|
||||
constructor(styleUrlResolver: StyleUrlResolver, styleHost) {
|
||||
@ -48,7 +83,7 @@ export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy {
|
||||
_moveViewNodesIntoParent(el, view);
|
||||
}
|
||||
|
||||
constructLightDom(lightDomView:View, shadowDomView:View, el) {
|
||||
constructLightDom(lightDomView:View, shadowDomView:View, el): LightDom {
|
||||
return new LightDom(lightDomView, shadowDomView, el);
|
||||
}
|
||||
|
||||
@ -56,35 +91,9 @@ export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy {
|
||||
return [Content];
|
||||
}
|
||||
|
||||
transformStyleText(cssText: string, baseUrl: string, component: Type) {
|
||||
return this._styleUrlResolver.resolveUrls(cssText, baseUrl);
|
||||
}
|
||||
|
||||
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;
|
||||
getStyleCompileStep(cmpMetadata: DirectiveMetadata, templateUrl: string): CompileStep {
|
||||
return new _EmulatedUnscopedCssStep(cmpMetadata, templateUrl, this._styleUrlResolver,
|
||||
this._styleHost);
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,31 +117,19 @@ export class EmulatedScopedShadowDomStrategy extends EmulatedUnscopedShadowDomSt
|
||||
this._styleInliner = styleInliner;
|
||||
}
|
||||
|
||||
transformStyleText(cssText: string, baseUrl: string, component: Type) {
|
||||
cssText = this._styleUrlResolver.resolveUrls(cssText, baseUrl);
|
||||
var css = this._styleInliner.inlineImports(cssText, baseUrl);
|
||||
if (PromiseWrapper.isPromise(css)) {
|
||||
return css.then((css) => _shimCssForComponent(css, component));
|
||||
} else {
|
||||
return _shimCssForComponent(css, component);
|
||||
}
|
||||
getStyleCompileStep(cmpMetadata: DirectiveMetadata, templateUrl: string): CompileStep {
|
||||
return new _EmulatedScopedCssStep(cmpMetadata, templateUrl, this._styleInliner,
|
||||
this._styleUrlResolver, this._styleHost);
|
||||
}
|
||||
|
||||
handleStyleElement(styleEl) {
|
||||
DOM.remove(styleEl);
|
||||
this._insertStyleElement(this._styleHost, styleEl);
|
||||
};
|
||||
|
||||
shimContentElement(component: Type, element) {
|
||||
var id = _getComponentId(component);
|
||||
var attrName = _getContentAttribute(id);
|
||||
DOM.setAttribute(element, attrName, '');
|
||||
getTemplateCompileStep(cmpMetadata: DirectiveMetadata): CompileStep {
|
||||
return new _ShimShadowDomStep(cmpMetadata);
|
||||
}
|
||||
|
||||
shimHostElement(component: Type, element) {
|
||||
var id = _getComponentId(component);
|
||||
var attrName = _getHostAttribute(id);
|
||||
DOM.setAttribute(element, attrName, '');
|
||||
shimAppElement(cmpMetadata: DirectiveMetadata, element) {
|
||||
var cmpType = cmpMetadata.type;
|
||||
var hostAttribute = _getHostAttribute(_getComponentId(cmpType));
|
||||
DOM.setAttribute(element, hostAttribute, '');
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,16 +151,125 @@ export class NativeShadowDomStrategy extends ShadowDomStrategy {
|
||||
_moveViewNodesIntoParent(DOM.createShadowRoot(el), view);
|
||||
}
|
||||
|
||||
constructLightDom(lightDomView:View, shadowDomView:View, el) {
|
||||
return null;
|
||||
getStyleCompileStep(cmpMetadata: DirectiveMetadata, templateUrl: string): CompileStep {
|
||||
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) {
|
||||
return this._styleUrlResolver.resolveUrls(cssText, baseUrl);
|
||||
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);
|
||||
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 _nextComponentUID: int = 0;
|
||||
var _sharedStyleTexts: Map<string, boolean> = MapWrapper.create();
|
||||
var _lastInsertedStyleEl;
|
||||
|
||||
function _getComponentId(component: Type) {
|
||||
var id = MapWrapper.get(_componentUIDs, component);
|
||||
@ -186,12 +293,26 @@ function _getComponentId(component: Type) {
|
||||
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
|
||||
function _getHostAttribute(id: int) {
|
||||
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) {
|
||||
return `_ngcontent-${id}`;
|
||||
}
|
||||
@ -207,4 +328,5 @@ export function resetShadowDomCache() {
|
||||
MapWrapper.clear(_componentUIDs);
|
||||
_nextComponentUID = 0;
|
||||
MapWrapper.clear(_sharedStyleTexts);
|
||||
_lastInsertedStyleEl = null;
|
||||
}
|
||||
|
2
modules/angular2/src/core/compiler/view.js
vendored
2
modules/angular2/src/core/compiler/view.js
vendored
@ -544,7 +544,7 @@ export class ProtoView {
|
||||
new ProtoElementInjector(null, 0, [cmpType], true));
|
||||
binder.componentDirective = rootComponentAnnotatedType;
|
||||
binder.nestedProtoView = protoView;
|
||||
shadowDomStrategy.shimHostElement(cmpType, insertionElement);
|
||||
shadowDomStrategy.shimAppElement(rootComponentAnnotatedType, insertionElement);
|
||||
return rootProtoView;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user