feat(compiler): handle compileChildren from @Decorator

This commit is contained in:
Victor Berchet 2015-01-07 18:20:29 +01:00
parent 9cacde92bb
commit 48e50121d4
7 changed files with 51 additions and 7 deletions

View File

@ -80,14 +80,17 @@ export class Decorator extends Directive {
selector, selector,
bind, bind,
lightDomServices, lightDomServices,
implementsTypes implementsTypes,
compileChildren = true
}:{ }:{
selector:string, selector:string,
bind:any, bind:any,
lightDomServices:List, lightDomServices:List,
implementsTypes:List implementsTypes:List,
compileChildren:boolean
}={}) }={})
{ {
this.compileChildren = compileChildren;
super({ super({
selector: selector, selector: selector,
bind: bind, bind: bind,

View File

@ -119,6 +119,9 @@ export class CompileElement {
this.decoratorDirectives = ListWrapper.create(); this.decoratorDirectives = ListWrapper.create();
} }
ListWrapper.push(this.decoratorDirectives, directive); ListWrapper.push(this.decoratorDirectives, directive);
if (!annotation.compileChildren) {
this.compileChildren = false;
}
} else if (annotation instanceof Template) { } else if (annotation instanceof Template) {
this.templateDirective = directive; this.templateDirective = directive;
} else if (annotation instanceof Component) { } else if (annotation instanceof Component) {

View File

@ -23,12 +23,12 @@ export function createDefaultSteps(parser:Parser, compiledComponent: DirectiveMe
return [ return [
new ViewSplitter(parser, compilationUnit), new ViewSplitter(parser, compilationUnit),
new TextInterpolationParser(parser, compilationUnit),
new PropertyBindingParser(parser, compilationUnit), new PropertyBindingParser(parser, compilationUnit),
new DirectiveParser(directives), new DirectiveParser(directives),
new TextInterpolationParser(parser, compilationUnit),
new ElementBindingMarker(), new ElementBindingMarker(),
new ProtoViewBuilder(), new ProtoViewBuilder(),
new ProtoElementInjectorBuilder(), new ProtoElementInjectorBuilder(),
new ElementBinderBuilder() new ElementBinderBuilder()
]; ];
} }

View File

@ -54,6 +54,9 @@ export class TextInterpolationParser extends CompileStep {
} }
process(parent:CompileElement, current:CompileElement, control:CompileControl) { process(parent:CompileElement, current:CompileElement, control:CompileControl) {
if (!current.compileChildren) {
return;
}
var element = current.element; var element = current.element;
var childNodes = DOM.templateAwareRoot(element).childNodes; var childNodes = DOM.templateAwareRoot(element).childNodes;
for (var i=0; i<childNodes.length; i++) { for (var i=0; i<childNodes.length; i++) {

View File

@ -20,7 +20,14 @@ export function main() {
beforeEach( () => { beforeEach( () => {
reader = new DirectiveMetadataReader(); reader = new DirectiveMetadataReader();
directives = [SomeDecorator, SomeTemplate, SomeTemplate2, SomeComponent, SomeComponent2]; directives = [
SomeDecorator,
SomeDecoratorIgnoringChildren,
SomeTemplate,
SomeTemplate2,
SomeComponent,
SomeComponent2
];
}); });
function createPipeline({propertyBindings, variableBindings}={}) { function createPipeline({propertyBindings, variableBindings}={}) {
@ -141,6 +148,16 @@ export function main() {
expect(results[0].decoratorDirectives).toEqual([reader.read(SomeDecorator)]); expect(results[0].decoratorDirectives).toEqual([reader.read(SomeDecorator)]);
}); });
it('should compile children by default', () => {
var results = createPipeline().process(createElement('<div some-decor></div>'));
expect(results[0].compileChildren).toEqual(true);
});
it('should stop compiling children when specified in the decorator config', () => {
var results = createPipeline().process(createElement('<div some-decor-ignoring-children></div>'));
expect(results[0].compileChildren).toEqual(false);
});
it('should detect them in variable bindings', () => { it('should detect them in variable bindings', () => {
var pipeline = createPipeline({variableBindings: { var pipeline = createPipeline({variableBindings: {
'some-decor': 'someExpr' 'some-decor': 'someExpr'
@ -176,6 +193,13 @@ class MockStep extends CompileStep {
}) })
class SomeDecorator {} class SomeDecorator {}
@Decorator({
selector: '[some-decor-ignoring-children]',
compileChildren: false
})
class SomeDecoratorIgnoringChildren {
}
@Template({ @Template({
selector: '[some-templ]' selector: '[some-templ]'
}) })

View File

@ -131,7 +131,7 @@ class MockStep extends CompileStep {
} }
} }
class IgnoreChildrenStep extends CompileStep { export class IgnoreChildrenStep extends CompileStep {
process(parent:CompileElement, current:CompileElement, control:CompileControl) { process(parent:CompileElement, current:CompileElement, control:CompileControl) {
var attributeMap = DOM.attributeMap(current.element); var attributeMap = DOM.attributeMap(current.element);
if (MapWrapper.contains(attributeMap, 'ignore-children')) { if (MapWrapper.contains(attributeMap, 'ignore-children')) {

View File

@ -5,11 +5,15 @@ import {DOM} from 'facade/dom';
import {MapWrapper} from 'facade/collection'; import {MapWrapper} from 'facade/collection';
import {Lexer, Parser} from 'change_detection/change_detection'; import {Lexer, Parser} from 'change_detection/change_detection';
import {IgnoreChildrenStep} from './pipeline_spec';
export function main() { export function main() {
describe('TextInterpolationParser', () => { describe('TextInterpolationParser', () => {
function createPipeline() { function createPipeline() {
return new CompilePipeline([new TextInterpolationParser(new Parser(new Lexer()), null)]); return new CompilePipeline([
new IgnoreChildrenStep(),
new TextInterpolationParser(new Parser(new Lexer()), null)
]);
} }
it('should find text interpolation in normal elements', () => { it('should find text interpolation in normal elements', () => {
@ -32,6 +36,13 @@ export function main() {
expect(MapWrapper.get(bindings, 0).source).toEqual("(expr1)+(expr2)"); expect(MapWrapper.get(bindings, 0).source).toEqual("(expr1)+(expr2)");
}); });
it('should not interpolate when compileChildren is false', () => {
var results = createPipeline().process(createElement('<div>{{included}}<span ignore-children>{{excluded}}</span></div>'));
var bindings = results[0].textNodeBindings;
expect(MapWrapper.get(bindings, 0).source).toEqual("(included)");
expect(results[1].textNodeBindings).toBe(null);
});
it('should allow fixed text before, in between and after expressions', () => { it('should allow fixed text before, in between and after expressions', () => {
var results = createPipeline().process(createElement('<div>a{{expr1}}b{{expr2}}c</div>')); var results = createPipeline().process(createElement('<div>a{{expr1}}b{{expr2}}c</div>'));
var bindings = results[0].textNodeBindings; var bindings = results[0].textNodeBindings;