refactor(Compiler): inline styles before compiling the template
This commit is contained in:
@ -25,6 +25,8 @@ import {
|
||||
} from 'angular2/change_detection';
|
||||
import {ExceptionHandler} from './exception_handler';
|
||||
import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
|
||||
import {StyleUrlResolver} from 'angular2/src/render/dom/compiler/style_url_resolver';
|
||||
import {StyleInliner} from 'angular2/src/render/dom/compiler/style_inliner';
|
||||
import {TemplateResolver} from './compiler/template_resolver';
|
||||
import {DirectiveResolver} from './compiler/directive_resolver';
|
||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||
@ -42,8 +44,6 @@ import {KeyEventsPlugin} from 'angular2/src/render/dom/events/key_events';
|
||||
import {HammerGesturesPlugin} from 'angular2/src/render/dom/events/hammer_gestures';
|
||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
||||
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
||||
import {AppRootUrl} from 'angular2/src/services/app_root_url';
|
||||
import {
|
||||
ComponentRef,
|
||||
@ -105,9 +105,7 @@ function _injectorBindings(appComponentType): List<Type | Binding | List<any>> {
|
||||
},
|
||||
[NgZone]),
|
||||
bind(ShadowDomStrategy)
|
||||
.toFactory((styleInliner, styleUrlResolver, doc) => new EmulatedUnscopedShadowDomStrategy(
|
||||
styleInliner, styleUrlResolver, doc.head),
|
||||
[StyleInliner, StyleUrlResolver, DOCUMENT_TOKEN]),
|
||||
.toFactory((doc) => new EmulatedUnscopedShadowDomStrategy(doc.head), [DOCUMENT_TOKEN]),
|
||||
DomRenderer,
|
||||
DefaultDomCompiler,
|
||||
bind(Renderer).toAlias(DomRenderer),
|
||||
|
@ -22,7 +22,7 @@ export class TemplateResolver {
|
||||
return view;
|
||||
}
|
||||
|
||||
_resolve(component: Type) {
|
||||
_resolve(component: Type): View {
|
||||
var annotations = reflector.annotations(component);
|
||||
for (var i = 0; i < annotations.length; i++) {
|
||||
var annotation = annotations[i];
|
||||
|
@ -67,10 +67,10 @@ class Html5LibDomAdapter implements DomAdapter {
|
||||
throw 'not implemented';
|
||||
}
|
||||
querySelector(el, String selector) {
|
||||
throw 'not implemented';
|
||||
return el.querySelector(selector);
|
||||
}
|
||||
List querySelectorAll(el, String selector) {
|
||||
throw 'not implemented';
|
||||
return el.querySelectorAll(selector);
|
||||
}
|
||||
on(el, evt, listener) {
|
||||
throw 'not implemented';
|
||||
@ -94,7 +94,7 @@ class Html5LibDomAdapter implements DomAdapter {
|
||||
return el.innerHtml;
|
||||
}
|
||||
getOuterHTML(el) {
|
||||
throw 'not implemented';
|
||||
return el.outerHtml;
|
||||
}
|
||||
String nodeName(node) {
|
||||
switch (node.nodeType) {
|
||||
@ -130,12 +130,12 @@ class Html5LibDomAdapter implements DomAdapter {
|
||||
}
|
||||
|
||||
parentElement(el) {
|
||||
throw 'not implemented';
|
||||
return el.parent;
|
||||
}
|
||||
List childNodes(el) => el.nodes;
|
||||
List childNodesAsList(el) => el.nodes;
|
||||
clearNodes(el) {
|
||||
throw 'not implemented';
|
||||
el.nodes.forEach((e) => e.remove());
|
||||
}
|
||||
appendChild(el, node) => el.append(node.remove());
|
||||
removeChild(el, node) {
|
||||
@ -153,7 +153,7 @@ class Html5LibDomAdapter implements DomAdapter {
|
||||
throw 'not implemented';
|
||||
}
|
||||
setInnerHTML(el, value) {
|
||||
throw 'not implemented';
|
||||
el.innerHtml = value;
|
||||
}
|
||||
getText(el) {
|
||||
return el.text;
|
||||
|
@ -303,7 +303,7 @@ export class RenderCompiler {
|
||||
* we don't need to serialize all possible components over the wire,
|
||||
* but only the needed ones based on previous calls.
|
||||
*/
|
||||
compile(template: ViewDefinition): Promise<ProtoViewDto> { return null; }
|
||||
compile(view: ViewDefinition): Promise<ProtoViewDto> { return null; }
|
||||
}
|
||||
|
||||
export interface RenderElementRef {
|
||||
|
@ -1,6 +1,4 @@
|
||||
import {List} from 'angular2/src/facade/collection';
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
|
||||
import {Parser} from 'angular2/change_detection';
|
||||
import {ViewDefinition} from '../../api';
|
||||
import {CompileStep} from './compile_step';
|
||||
@ -12,21 +10,19 @@ import {ShadowDomCompileStep} from '../shadow_dom/shadow_dom_compile_step';
|
||||
import {ShadowDomStrategy} from '../shadow_dom/shadow_dom_strategy';
|
||||
|
||||
export class CompileStepFactory {
|
||||
createSteps(template: ViewDefinition, subTaskPromises: List<Promise<any>>): List<CompileStep> {
|
||||
return null;
|
||||
}
|
||||
createSteps(template: ViewDefinition): List<CompileStep> { return null; }
|
||||
}
|
||||
|
||||
export class DefaultStepFactory extends CompileStepFactory {
|
||||
constructor(public _parser: Parser, public _shadowDomStrategy: ShadowDomStrategy) { super(); }
|
||||
|
||||
createSteps(template: ViewDefinition, subTaskPromises: List<Promise<any>>) {
|
||||
createSteps(template: ViewDefinition): List<CompileStep> {
|
||||
return [
|
||||
new ViewSplitter(this._parser),
|
||||
new PropertyBindingParser(this._parser),
|
||||
new DirectiveParser(this._parser, template.directives),
|
||||
new TextInterpolationParser(this._parser),
|
||||
new ShadowDomCompileStep(this._shadowDomStrategy, template, subTaskPromises)
|
||||
new ShadowDomCompileStep(this._shadowDomStrategy, template)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -28,12 +28,11 @@ export class DomCompiler extends RenderCompiler {
|
||||
super();
|
||||
}
|
||||
|
||||
compile(template: ViewDefinition): Promise<ProtoViewDto> {
|
||||
var tplPromise = this._templateLoader.load(template);
|
||||
compile(view: ViewDefinition): Promise<ProtoViewDto> {
|
||||
var tplPromise = this._templateLoader.load(view);
|
||||
return PromiseWrapper.then(
|
||||
tplPromise, (el) => this._compileTemplate(template, el, ViewType.COMPONENT), (e) => {
|
||||
throw new BaseException(
|
||||
`Failed to load the template for "${template.componentId}" : ${e}`);
|
||||
tplPromise, (el) => this._compileTemplate(view, el, ViewType.COMPONENT), (e) => {
|
||||
throw new BaseException(`Failed to load the template for "${view.componentId}" : ${e}`);
|
||||
});
|
||||
}
|
||||
|
||||
@ -51,17 +50,10 @@ export class DomCompiler extends RenderCompiler {
|
||||
|
||||
_compileTemplate(viewDef: ViewDefinition, tplElement,
|
||||
protoViewType: ViewType): Promise<ProtoViewDto> {
|
||||
var subTaskPromises = [];
|
||||
var pipeline = new CompilePipeline(this._stepFactory.createSteps(viewDef, subTaskPromises));
|
||||
var pipeline = new CompilePipeline(this._stepFactory.createSteps(viewDef));
|
||||
var compileElements = pipeline.process(tplElement, protoViewType, viewDef.componentId);
|
||||
|
||||
var protoView = compileElements[0].inheritedProtoView.build();
|
||||
|
||||
if (subTaskPromises.length > 0) {
|
||||
return PromiseWrapper.all(subTaskPromises).then((_) => protoView);
|
||||
} else {
|
||||
return PromiseWrapper.resolve(protoView);
|
||||
}
|
||||
return PromiseWrapper.resolve(compileElements[0].inheritedProtoView.build());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,15 @@
|
||||
import {Injectable} from 'angular2/di';
|
||||
import {isBlank, isPresent, BaseException, stringify} from 'angular2/src/facade/lang';
|
||||
import {Map, MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {isBlank, isPresent, BaseException, stringify, isPromise} from 'angular2/src/facade/lang';
|
||||
import {Map, MapWrapper, ListWrapper, List} from 'angular2/src/facade/collection';
|
||||
import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
|
||||
import {XHR} from 'angular2/src/render/xhr';
|
||||
|
||||
import {ViewDefinition} from '../../api';
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
|
||||
import {StyleInliner} from './style_inliner';
|
||||
import {StyleUrlResolver} from './style_url_resolver';
|
||||
|
||||
/**
|
||||
* Strategy to load component templates.
|
||||
@ -17,37 +19,36 @@ import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
export class TemplateLoader {
|
||||
_cache: Map<string, Promise<string>> = new Map();
|
||||
|
||||
constructor(private _xhr: XHR, urlResolver: UrlResolver) {}
|
||||
constructor(private _xhr: XHR, private _styleInliner: StyleInliner,
|
||||
private _styleUrlResolver: StyleUrlResolver) {}
|
||||
|
||||
load(view: ViewDefinition): Promise</*element*/ any> {
|
||||
let html;
|
||||
let fetchedStyles;
|
||||
let tplElAndStyles: List<string | Promise<string>> = [this._loadHtml(view)];
|
||||
|
||||
// Load the HTML
|
||||
if (isPresent(view.template)) {
|
||||
html = PromiseWrapper.resolve(view.template);
|
||||
} else if (isPresent(view.templateAbsUrl)) {
|
||||
html = this._loadText(view.templateAbsUrl);
|
||||
} else {
|
||||
throw new BaseException('View should have either the templateUrl or template property set');
|
||||
if (isPresent(view.styles)) {
|
||||
view.styles.forEach((cssText: string) => {
|
||||
let textOrPromise = this._resolveAndInlineCssText(cssText, view.templateAbsUrl);
|
||||
tplElAndStyles.push(textOrPromise);
|
||||
});
|
||||
}
|
||||
|
||||
// Load the styles
|
||||
if (isPresent(view.styleAbsUrls) && view.styleAbsUrls.length > 0) {
|
||||
fetchedStyles = ListWrapper.map(view.styleAbsUrls, url => this._loadText(url));
|
||||
} else {
|
||||
fetchedStyles = [];
|
||||
if (isPresent(view.styleAbsUrls)) {
|
||||
view.styleAbsUrls.forEach(url => {
|
||||
let promise = this._loadText(url).then(
|
||||
cssText => this._resolveAndInlineCssText(cssText, view.templateAbsUrl));
|
||||
tplElAndStyles.push(promise);
|
||||
});
|
||||
}
|
||||
|
||||
// Inline the styles and return a template element
|
||||
return PromiseWrapper.all(ListWrapper.concat([html], fetchedStyles))
|
||||
// Inline the styles from the @View annotation and return a template element
|
||||
return PromiseWrapper.all(tplElAndStyles)
|
||||
.then((res: List<string>) => {
|
||||
let html = res[0];
|
||||
let fetchedStyles = ListWrapper.slice(res, 1);
|
||||
let tplEl = res[0];
|
||||
let cssTexts = ListWrapper.slice(res, 1);
|
||||
|
||||
html = _createStyleTags(view.styles) + _createStyleTags(fetchedStyles) + html;
|
||||
_insertCssTexts(DOM.content(tplEl), cssTexts);
|
||||
|
||||
return DOM.createTemplate(html);
|
||||
return tplEl;
|
||||
});
|
||||
}
|
||||
|
||||
@ -67,10 +68,74 @@ export class TemplateLoader {
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
// Load the html and inline any style tags
|
||||
private _loadHtml(view: ViewDefinition): Promise<any /* element */> {
|
||||
let html;
|
||||
|
||||
// Load the HTML
|
||||
if (isPresent(view.template)) {
|
||||
html = PromiseWrapper.resolve(view.template);
|
||||
} else if (isPresent(view.templateAbsUrl)) {
|
||||
html = this._loadText(view.templateAbsUrl);
|
||||
} else {
|
||||
throw new BaseException('View should have either the templateUrl or template property set');
|
||||
}
|
||||
|
||||
// Inline the style tags from the html
|
||||
return html.then(html => {
|
||||
var tplEl = DOM.createTemplate(html);
|
||||
let styleEls = DOM.querySelectorAll(DOM.content(tplEl), 'STYLE');
|
||||
|
||||
let promises: List<Promise<string>> = [];
|
||||
for (let i = 0; i < styleEls.length; i++) {
|
||||
let promise = this._resolveAndInlineElement(styleEls[i], view.templateAbsUrl);
|
||||
if (isPromise(promise)) {
|
||||
promises.push(promise);
|
||||
}
|
||||
}
|
||||
|
||||
return promises.length > 0 ? PromiseWrapper.all(promises).then(_ => tplEl) : tplEl;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Inlines a style element.
|
||||
*
|
||||
* @param styleEl The style element
|
||||
* @param baseUrl The base url
|
||||
* @returns {Promise<any>} null when no @import rule exist in the css or a Promise
|
||||
* @private
|
||||
*/
|
||||
private _resolveAndInlineElement(styleEl, baseUrl: string): Promise<any> {
|
||||
let textOrPromise = this._resolveAndInlineCssText(DOM.getText(styleEl), baseUrl);
|
||||
|
||||
if (isPromise(textOrPromise)) {
|
||||
return (<Promise<string>>textOrPromise).then(css => { DOM.setText(styleEl, css); });
|
||||
} else {
|
||||
DOM.setText(styleEl, <string>textOrPromise);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private _resolveAndInlineCssText(cssText: string, baseUrl: string): string | Promise<string> {
|
||||
cssText = this._styleUrlResolver.resolveUrls(cssText, baseUrl);
|
||||
return this._styleInliner.inlineImports(cssText, baseUrl);
|
||||
}
|
||||
}
|
||||
|
||||
function _createStyleTags(styles?: List<string>): string {
|
||||
return isBlank(styles) ?
|
||||
'' :
|
||||
ListWrapper.map(styles, css => `<style type='text/css'>${css}</style>`).join('');
|
||||
function _insertCssTexts(element, cssTexts: List<string>): void {
|
||||
if (cssTexts.length == 0) return;
|
||||
|
||||
let insertBefore = DOM.firstChild(element);
|
||||
|
||||
for (let i = cssTexts.length - 1; i >= 0; i--) {
|
||||
let styleEl = DOM.createStyleElement(cssTexts[i]);
|
||||
if (isPresent(insertBefore)) {
|
||||
DOM.insertBefore(insertBefore, styleEl);
|
||||
} else {
|
||||
DOM.appendChild(element, styleEl);
|
||||
}
|
||||
insertBefore = styleEl;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
import {isBlank, isPresent, isPromise} from 'angular2/src/facade/lang';
|
||||
import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
|
||||
import {isBlank, isPresent} from 'angular2/src/facade/lang';
|
||||
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
|
||||
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
||||
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
||||
import {EmulatedUnscopedShadowDomStrategy} from './emulated_unscoped_shadow_dom_strategy';
|
||||
import {
|
||||
getContentAttribute,
|
||||
@ -27,39 +24,21 @@ import {
|
||||
* - see `ShadowCss` for more information and limitations.
|
||||
*/
|
||||
export class EmulatedScopedShadowDomStrategy extends EmulatedUnscopedShadowDomStrategy {
|
||||
constructor(styleInliner: StyleInliner, styleUrlResolver: StyleUrlResolver, styleHost) {
|
||||
super(styleInliner, styleUrlResolver, styleHost);
|
||||
}
|
||||
|
||||
processStyleElement(hostComponentId: string, templateUrl: string, styleEl): Promise<any> {
|
||||
var cssText = DOM.getText(styleEl);
|
||||
|
||||
cssText = this.styleUrlResolver.resolveUrls(cssText, templateUrl);
|
||||
var inlinedCss = this.styleInliner.inlineImports(cssText, templateUrl);
|
||||
|
||||
var ret = null;
|
||||
if (isPromise(inlinedCss)) {
|
||||
DOM.setText(styleEl, '');
|
||||
ret = (<Promise<string>>inlinedCss)
|
||||
.then((css) => {
|
||||
css = shimCssForComponent(css, hostComponentId);
|
||||
DOM.setText(styleEl, css);
|
||||
});
|
||||
} else {
|
||||
var css = shimCssForComponent(<string>inlinedCss, hostComponentId);
|
||||
DOM.setText(styleEl, css);
|
||||
}
|
||||
constructor(styleHost) { super(styleHost); }
|
||||
|
||||
processStyleElement(hostComponentId: string, templateUrl: string, styleEl): void {
|
||||
let cssText = DOM.getText(styleEl);
|
||||
cssText = shimCssForComponent(cssText, hostComponentId);
|
||||
DOM.setText(styleEl, cssText);
|
||||
this._moveToStyleHost(styleEl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_moveToStyleHost(styleEl) {
|
||||
_moveToStyleHost(styleEl): void {
|
||||
DOM.remove(styleEl);
|
||||
insertStyleElement(this.styleHost, styleEl);
|
||||
}
|
||||
|
||||
processElement(hostComponentId: string, elementComponentId: string, element) {
|
||||
processElement(hostComponentId: string, elementComponentId: string, element): void {
|
||||
// Shim the element as a child of the compiled component
|
||||
if (isPresent(hostComponentId)) {
|
||||
var contentAttribute = getContentAttribute(getComponentId(hostComponentId));
|
||||
|
@ -1,14 +1,9 @@
|
||||
import {isPromise} from 'angular2/src/facade/lang';
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
|
||||
import * as viewModule from '../view/view';
|
||||
|
||||
import {LightDom} from './light_dom';
|
||||
import {ShadowDomStrategy} from './shadow_dom_strategy';
|
||||
import {StyleUrlResolver} from './style_url_resolver';
|
||||
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
||||
import {insertSharedStyleText} from './util';
|
||||
|
||||
/**
|
||||
@ -21,10 +16,7 @@ import {insertSharedStyleText} from './util';
|
||||
* - you can **not** use shadow DOM specific selectors in the styles
|
||||
*/
|
||||
export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy {
|
||||
constructor(public styleInliner: StyleInliner, public styleUrlResolver: StyleUrlResolver,
|
||||
public styleHost) {
|
||||
super();
|
||||
}
|
||||
constructor(public styleHost) { super(); }
|
||||
|
||||
hasNativeContentElement(): boolean { return false; }
|
||||
|
||||
@ -34,21 +26,8 @@ export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy {
|
||||
return new LightDom(lightDomView, el);
|
||||
}
|
||||
|
||||
processStyleElement(hostComponentId: string, templateUrl: string, styleEl): Promise<any> {
|
||||
processStyleElement(hostComponentId: string, templateUrl: string, styleEl): void {
|
||||
var cssText = DOM.getText(styleEl);
|
||||
|
||||
cssText = this.styleUrlResolver.resolveUrls(cssText, templateUrl);
|
||||
var inlinedCss = this.styleInliner.inlineImports(cssText, templateUrl);
|
||||
|
||||
var ret = null;
|
||||
if (isPromise(inlinedCss)) {
|
||||
DOM.setText(styleEl, '');
|
||||
ret = (<Promise<string>>inlinedCss).then(css => { DOM.setText(styleEl, css); });
|
||||
} else {
|
||||
DOM.setText(styleEl, <string>inlinedCss);
|
||||
}
|
||||
|
||||
insertSharedStyleText(cssText, this.styleHost, styleEl);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,6 @@
|
||||
import {isPromise} from 'angular2/src/facade/lang';
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
import {Injectable} from 'angular2/di';
|
||||
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
|
||||
import {StyleUrlResolver} from './style_url_resolver';
|
||||
import {ShadowDomStrategy} from './shadow_dom_strategy';
|
||||
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
||||
|
||||
/**
|
||||
* This strategies uses the native Shadow DOM support.
|
||||
@ -16,23 +10,5 @@ import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
||||
*/
|
||||
@Injectable()
|
||||
export class NativeShadowDomStrategy extends ShadowDomStrategy {
|
||||
constructor(public styleInliner: StyleInliner, public styleUrlResolver: StyleUrlResolver) {
|
||||
super();
|
||||
}
|
||||
|
||||
prepareShadowRoot(el) { return DOM.createShadowRoot(el); }
|
||||
|
||||
processStyleElement(hostComponentId: string, templateUrl: string, styleEl): Promise<any> {
|
||||
var cssText = DOM.getText(styleEl);
|
||||
|
||||
cssText = this.styleUrlResolver.resolveUrls(cssText, templateUrl);
|
||||
var inlinedCss = this.styleInliner.inlineImports(cssText, templateUrl);
|
||||
|
||||
if (isPromise(inlinedCss)) {
|
||||
return (<Promise<string>>inlinedCss).then(css => { DOM.setText(styleEl, css); });
|
||||
} else {
|
||||
DOM.setText(styleEl, <string>inlinedCss);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
} from 'angular2/src/facade/lang';
|
||||
|
||||
/**
|
||||
* This file is a port of shadowCSS from webcomponents.js to AtScript.
|
||||
* This file is a port of shadowCSS from webcomponents.js to TypeScript.
|
||||
*
|
||||
* Please make sure to keep to edits in sync with the source file.
|
||||
*
|
||||
|
@ -1,6 +1,4 @@
|
||||
import {isBlank, isPresent, assertionsEnabled, isPromise} from 'angular2/src/facade/lang';
|
||||
import {MapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
||||
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
|
||||
@ -11,8 +9,7 @@ import {ViewDefinition} from '../../api';
|
||||
import {ShadowDomStrategy} from './shadow_dom_strategy';
|
||||
|
||||
export class ShadowDomCompileStep implements CompileStep {
|
||||
constructor(public _shadowDomStrategy: ShadowDomStrategy, public _template: ViewDefinition,
|
||||
public _subTaskPromises: List<Promise<any>>) {}
|
||||
constructor(public _shadowDomStrategy: ShadowDomStrategy, public _view: ViewDefinition) {}
|
||||
|
||||
process(parent: CompileElement, current: CompileElement, control: CompileControl) {
|
||||
var tagName = DOM.tagName(current.element).toUpperCase();
|
||||
@ -22,17 +19,13 @@ export class ShadowDomCompileStep implements CompileStep {
|
||||
this._processContentElement(current);
|
||||
} else {
|
||||
var componentId = current.isBound() ? current.inheritedElementBinder.componentId : null;
|
||||
this._shadowDomStrategy.processElement(this._template.componentId, componentId,
|
||||
current.element);
|
||||
this._shadowDomStrategy.processElement(this._view.componentId, componentId, current.element);
|
||||
}
|
||||
}
|
||||
|
||||
_processStyleElement(current: CompileElement, control: CompileControl) {
|
||||
var stylePromise = this._shadowDomStrategy.processStyleElement(
|
||||
this._template.componentId, this._template.templateAbsUrl, current.element);
|
||||
if (isPresent(stylePromise) && isPromise(stylePromise)) {
|
||||
this._subTaskPromises.push(stylePromise);
|
||||
}
|
||||
this._shadowDomStrategy.processStyleElement(this._view.componentId, this._view.templateAbsUrl,
|
||||
current.element);
|
||||
|
||||
// Style elements should not be further processed by the compiler, as they can not contain
|
||||
// bindings. Skipping further compiler steps allow speeding up the compilation process.
|
||||
|
@ -1,28 +1,20 @@
|
||||
import {isBlank, isPresent} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
import * as viewModule from '../view/view';
|
||||
import {LightDom} from './light_dom';
|
||||
|
||||
export class ShadowDomStrategy {
|
||||
// Whether the strategy understands the native <content> tag
|
||||
hasNativeContentElement(): boolean { return true; }
|
||||
|
||||
/**
|
||||
* Prepares and returns the shadow root for the given element.
|
||||
*/
|
||||
// Prepares and returns the (emulated) shadow root for the given element.
|
||||
prepareShadowRoot(el): any { return null; }
|
||||
|
||||
constructLightDom(lightDomView: viewModule.DomView, el): LightDom { return null; }
|
||||
|
||||
/**
|
||||
* An optional step that can modify the template style elements.
|
||||
*/
|
||||
processStyleElement(hostComponentId: string, templateUrl: string, styleElement): Promise<any> {
|
||||
return null;
|
||||
}
|
||||
// An optional step that can modify the template style elements.
|
||||
processStyleElement(hostComponentId: string, templateUrl: string, styleElement): void {}
|
||||
|
||||
/**
|
||||
* An optional step that can modify the template elements (style elements exlcuded).
|
||||
*/
|
||||
processElement(hostComponentId: string, elementComponentId: string, element) {}
|
||||
// An optional step that can modify the template elements (style elements exlcuded).
|
||||
processElement(hostComponentId: string, elementComponentId: string, element): void {}
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ import {XHR} from 'angular2/src/render/xhr';
|
||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
import {AppRootUrl} from 'angular2/src/services/app_root_url';
|
||||
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
||||
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
||||
import {StyleUrlResolver} from 'angular2/src/render/dom/compiler/style_url_resolver';
|
||||
import {StyleInliner} from 'angular2/src/render/dom/compiler/style_inliner';
|
||||
import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
||||
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
@ -88,9 +88,7 @@ function _getAppBindings() {
|
||||
bind(DOCUMENT_TOKEN)
|
||||
.toValue(appDoc),
|
||||
bind(ShadowDomStrategy)
|
||||
.toFactory((styleInliner, styleUrlResolver, doc) => new EmulatedUnscopedShadowDomStrategy(
|
||||
styleInliner, styleUrlResolver, doc.head),
|
||||
[StyleInliner, StyleUrlResolver, DOCUMENT_TOKEN]),
|
||||
.toFactory((doc) => new EmulatedUnscopedShadowDomStrategy(doc.head), [DOCUMENT_TOKEN]),
|
||||
DomRenderer,
|
||||
DefaultDomCompiler,
|
||||
bind(Renderer).toAlias(DomRenderer),
|
||||
|
@ -1,6 +1,5 @@
|
||||
library angular2.transform.template_compiler.compile_step_factory;
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:angular2/src/change_detection/parser/parser.dart' as ng;
|
||||
import 'package:angular2/src/render/api.dart';
|
||||
import 'package:angular2/src/render/dom/compiler/compile_step.dart';
|
||||
@ -15,8 +14,7 @@ class CompileStepFactory implements base.CompileStepFactory {
|
||||
final ng.Parser _parser;
|
||||
CompileStepFactory(this._parser);
|
||||
|
||||
List<CompileStep> createSteps(
|
||||
ViewDefinition template, List<Future> subTaskPromises) {
|
||||
List<CompileStep> createSteps(ViewDefinition template) {
|
||||
return [
|
||||
new ViewSplitter(_parser),
|
||||
new PropertyBindingParser(_parser),
|
||||
|
@ -7,6 +7,8 @@ import 'package:angular2/src/change_detection/parser/parser.dart' as ng;
|
||||
import 'package:angular2/src/core/compiler/proto_view_factory.dart';
|
||||
import 'package:angular2/src/render/api.dart';
|
||||
import 'package:angular2/src/render/dom/compiler/compile_pipeline.dart';
|
||||
import 'package:angular2/src/render/dom/compiler/style_inliner.dart';
|
||||
import 'package:angular2/src/render/dom/compiler/style_url_resolver.dart';
|
||||
import 'package:angular2/src/render/dom/compiler/template_loader.dart';
|
||||
import 'package:angular2/src/render/xhr.dart' show XHR;
|
||||
import 'package:angular2/src/reflection/reflection.dart';
|
||||
@ -79,11 +81,17 @@ Future<String> processTemplates(AssetReader reader, AssetId entryPoint,
|
||||
/// reflectively accessed from that template.
|
||||
class _TemplateExtractor {
|
||||
final CompileStepFactory _factory;
|
||||
final TemplateLoader _loader;
|
||||
TemplateLoader _loader;
|
||||
|
||||
_TemplateExtractor(XHR xhr)
|
||||
: _factory = new CompileStepFactory(new ng.Parser(new ng.Lexer())),
|
||||
_loader = new TemplateLoader(xhr, new UrlResolver());
|
||||
: _factory = new CompileStepFactory(new ng.Parser(new ng.Lexer())) {
|
||||
|
||||
var urlResolver = new UrlResolver();
|
||||
var styleUrlResolver = new StyleUrlResolver(urlResolver);
|
||||
var styleInliner = new StyleInliner(xhr, styleUrlResolver, urlResolver);
|
||||
|
||||
_loader = new TemplateLoader(xhr, styleInliner, styleUrlResolver);
|
||||
}
|
||||
|
||||
Future<_ExtractResult> extractTemplates(ViewDefinition viewDef) async {
|
||||
// Check for "imperative views".
|
||||
@ -98,9 +106,7 @@ class _TemplateExtractor {
|
||||
var recordingCapabilities = new RecordingReflectionCapabilities();
|
||||
reflector.reflectionCapabilities = recordingCapabilities;
|
||||
|
||||
var subtaskPromises = [];
|
||||
var pipeline =
|
||||
new CompilePipeline(_factory.createSteps(viewDef, subtaskPromises));
|
||||
var pipeline = new CompilePipeline(_factory.createSteps(viewDef));
|
||||
|
||||
var compileElements =
|
||||
pipeline.process(templateEl, ViewType.COMPONENT, viewDef.componentId);
|
||||
@ -109,9 +115,7 @@ class _TemplateExtractor {
|
||||
|
||||
reflector.reflectionCapabilities = savedReflectionCapabilities;
|
||||
|
||||
return Future
|
||||
.wait(subtaskPromises)
|
||||
.then((_) => new _ExtractResult(recordingCapabilities, protoViewDto));
|
||||
return new _ExtractResult(recordingCapabilities, protoViewDto);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user