refactor(Compiler): introduce ShimComponent to shim CSS & DOM in emulated mode

Closes #715
This commit is contained in:
Victor Berchet
2015-02-19 11:55:43 +01:00
committed by Misko Hevery
parent 5111f9ae37
commit d0ca07afaa
12 changed files with 486 additions and 705 deletions

View File

@ -9,9 +9,10 @@ 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 {ShadowDomTransformer} from './shadow_dom_transformer';
import {ShimShadowCss} from './shim_shadow_css';
import {ShimShadowDom} from './shim_shadow_dom';
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
import {ShadowDomStrategy, EmulatedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
import {stringify} from 'angular2/src/facade/lang';
import {DOM} from 'angular2/src/facade/dom';
@ -31,8 +32,8 @@ export function createDefaultSteps(
var steps = [new ViewSplitter(parser, compilationUnit)];
if (!(shadowDomStrategy instanceof NativeShadowDomStrategy)) {
var step = new ShadowDomTransformer(compiledComponent, shadowDomStrategy, DOM.defaultDoc().head);
if (shadowDomStrategy instanceof EmulatedShadowDomStrategy) {
var step = new ShimShadowCss(compiledComponent, shadowDomStrategy, DOM.defaultDoc().head);
ListWrapper.push(steps, step);
}
@ -46,5 +47,10 @@ export function createDefaultSteps(
new ElementBinderBuilder(parser, compilationUnit)
]);
if (shadowDomStrategy instanceof EmulatedShadowDomStrategy) {
var step = new ShimShadowDom(compiledComponent, shadowDomStrategy);
ListWrapper.push(steps, step);
}
return steps;
}

View File

@ -4,24 +4,20 @@ 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 {shimCssText} from 'angular2/src/core/compiler/shadow_dom_emulation/shim_css';
import {DOM, Element} from 'angular2/src/facade/dom';
import {isPresent, isBlank} from 'angular2/src/facade/lang';
import {StringMapWrapper} from 'angular2/src/facade/collection';
import {isPresent, isBlank, Type} from 'angular2/src/facade/lang';
var _cssCache = StringMapWrapper.create();
export class ShadowDomTransformer extends CompileStep {
_selector: string;
export class ShimShadowCss extends CompileStep {
_strategy: ShadowDomStrategy;
_styleHost: Element;
_lastInsertedStyle: Element;
_component: Type;
constructor(cmpMetadata: DirectiveMetadata, strategy: ShadowDomStrategy, styleHost: Element) {
super();
this._strategy = strategy;
this._selector = cmpMetadata.annotation.selector;
this._component = cmpMetadata.type;
this._styleHost = styleHost;
this._lastInsertedStyle = null;
}
@ -33,34 +29,13 @@ export class ShadowDomTransformer extends CompileStep {
if (this._strategy.extractStyles()) {
DOM.remove(current.element);
var css = DOM.getText(current.element);
if (this._strategy.shim()) {
// The css generated here is unique for the component (because of the shim).
// Then we do not need to cache it.
css = shimCssText(css, this._selector);
this._insertStyle(this._styleHost, css);
} else {
var seen = isPresent(StringMapWrapper.get(_cssCache, css));
if (!seen) {
StringMapWrapper.set(_cssCache, css, true);
this._insertStyle(this._styleHost, css);
}
}
}
} else {
if (this._strategy.shim()) {
try {
DOM.setAttribute(current.element, this._selector, '');
} catch(e) {
// TODO(vicb): for now only simple selector (tag name) are supported
}
var shimComponent = this._strategy.getShimComponent(this._component);
css = shimComponent.shimCssText(css);
this._insertStyle(this._styleHost, css);
}
}
}
clearCache() {
_cssCache = StringMapWrapper.create();
}
_insertStyle(el: Element, css: string) {
var style = DOM.createStyleElement(css);
if (isBlank(this._lastInsertedStyle)) {

View File

@ -0,0 +1,38 @@
import {CompileStep} from './compile_step';
import {CompileElement} from './compile_element';
import {CompileControl} from './compile_control';
import {isPresent} from 'angular2/src/facade/lang';
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
import {ShimComponent} from 'angular2/src/core/compiler/shadow_dom_emulation/shim_component';
export class ShimShadowDom extends CompileStep {
_strategy: ShadowDomStrategy;
_shimComponent: ShimComponent;
constructor(cmpMetadata: DirectiveMetadata, strategy: ShadowDomStrategy) {
super();
this._strategy = strategy;
this._shimComponent = strategy.getShimComponent(cmpMetadata.type);
}
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
if (current.ignoreBindings) {
return;
}
// Shim the element as a child of the compiled component
this._shimComponent.shimContentElement(current.element);
// If the current element is also a component, shim it as a host
var host = current.componentDirective;
if (isPresent(host)) {
var shimComponent = this._strategy.getShimComponent(host.type);
shimComponent.shimHostElement(current.element);
}
}
}