From 48e50121d4e958e043cf9096075f5f748ce438c3 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Wed, 7 Jan 2015 18:20:29 +0100 Subject: [PATCH] feat(compiler): handle compileChildren from @Decorator --- modules/core/src/annotations/annotations.js | 7 +++-- .../src/compiler/pipeline/compile_element.js | 3 +++ .../src/compiler/pipeline/default_steps.js | 4 +-- .../pipeline/text_interpolation_parser.js | 3 +++ .../pipeline/directive_parser_spec.js | 26 ++++++++++++++++++- .../test/compiler/pipeline/pipeline_spec.js | 2 +- .../text_interpolation_parser_spec.js | 13 +++++++++- 7 files changed, 51 insertions(+), 7 deletions(-) diff --git a/modules/core/src/annotations/annotations.js b/modules/core/src/annotations/annotations.js index 6a89cea3e3..96501751d3 100644 --- a/modules/core/src/annotations/annotations.js +++ b/modules/core/src/annotations/annotations.js @@ -80,14 +80,17 @@ export class Decorator extends Directive { selector, bind, lightDomServices, - implementsTypes + implementsTypes, + compileChildren = true }:{ selector:string, bind:any, lightDomServices:List, - implementsTypes:List + implementsTypes:List, + compileChildren:boolean }={}) { + this.compileChildren = compileChildren; super({ selector: selector, bind: bind, diff --git a/modules/core/src/compiler/pipeline/compile_element.js b/modules/core/src/compiler/pipeline/compile_element.js index efe76fd9f9..46a9c70ca3 100644 --- a/modules/core/src/compiler/pipeline/compile_element.js +++ b/modules/core/src/compiler/pipeline/compile_element.js @@ -119,6 +119,9 @@ export class CompileElement { this.decoratorDirectives = ListWrapper.create(); } ListWrapper.push(this.decoratorDirectives, directive); + if (!annotation.compileChildren) { + this.compileChildren = false; + } } else if (annotation instanceof Template) { this.templateDirective = directive; } else if (annotation instanceof Component) { diff --git a/modules/core/src/compiler/pipeline/default_steps.js b/modules/core/src/compiler/pipeline/default_steps.js index cd30e5dafd..012db56ae6 100644 --- a/modules/core/src/compiler/pipeline/default_steps.js +++ b/modules/core/src/compiler/pipeline/default_steps.js @@ -23,12 +23,12 @@ export function createDefaultSteps(parser:Parser, compiledComponent: DirectiveMe return [ new ViewSplitter(parser, compilationUnit), - new TextInterpolationParser(parser, compilationUnit), new PropertyBindingParser(parser, compilationUnit), new DirectiveParser(directives), + new TextInterpolationParser(parser, compilationUnit), new ElementBindingMarker(), new ProtoViewBuilder(), new ProtoElementInjectorBuilder(), new ElementBinderBuilder() ]; -} \ No newline at end of file +} diff --git a/modules/core/src/compiler/pipeline/text_interpolation_parser.js b/modules/core/src/compiler/pipeline/text_interpolation_parser.js index 09c0def1ae..6c89c136cb 100644 --- a/modules/core/src/compiler/pipeline/text_interpolation_parser.js +++ b/modules/core/src/compiler/pipeline/text_interpolation_parser.js @@ -54,6 +54,9 @@ export class TextInterpolationParser extends CompileStep { } process(parent:CompileElement, current:CompileElement, control:CompileControl) { + if (!current.compileChildren) { + return; + } var element = current.element; var childNodes = DOM.templateAwareRoot(element).childNodes; for (var i=0; i { reader = new DirectiveMetadataReader(); - directives = [SomeDecorator, SomeTemplate, SomeTemplate2, SomeComponent, SomeComponent2]; + directives = [ + SomeDecorator, + SomeDecoratorIgnoringChildren, + SomeTemplate, + SomeTemplate2, + SomeComponent, + SomeComponent2 + ]; }); function createPipeline({propertyBindings, variableBindings}={}) { @@ -141,6 +148,16 @@ export function main() { expect(results[0].decoratorDirectives).toEqual([reader.read(SomeDecorator)]); }); + it('should compile children by default', () => { + var results = createPipeline().process(createElement('
')); + expect(results[0].compileChildren).toEqual(true); + }); + + it('should stop compiling children when specified in the decorator config', () => { + var results = createPipeline().process(createElement('
')); + expect(results[0].compileChildren).toEqual(false); + }); + it('should detect them in variable bindings', () => { var pipeline = createPipeline({variableBindings: { 'some-decor': 'someExpr' @@ -176,6 +193,13 @@ class MockStep extends CompileStep { }) class SomeDecorator {} +@Decorator({ + selector: '[some-decor-ignoring-children]', + compileChildren: false +}) +class SomeDecoratorIgnoringChildren { +} + @Template({ selector: '[some-templ]' }) diff --git a/modules/core/test/compiler/pipeline/pipeline_spec.js b/modules/core/test/compiler/pipeline/pipeline_spec.js index 7cf6fa20e7..34b4352a97 100644 --- a/modules/core/test/compiler/pipeline/pipeline_spec.js +++ b/modules/core/test/compiler/pipeline/pipeline_spec.js @@ -131,7 +131,7 @@ class MockStep extends CompileStep { } } -class IgnoreChildrenStep extends CompileStep { +export class IgnoreChildrenStep extends CompileStep { process(parent:CompileElement, current:CompileElement, control:CompileControl) { var attributeMap = DOM.attributeMap(current.element); if (MapWrapper.contains(attributeMap, 'ignore-children')) { diff --git a/modules/core/test/compiler/pipeline/text_interpolation_parser_spec.js b/modules/core/test/compiler/pipeline/text_interpolation_parser_spec.js index 918955c78a..89ebb02dfc 100644 --- a/modules/core/test/compiler/pipeline/text_interpolation_parser_spec.js +++ b/modules/core/test/compiler/pipeline/text_interpolation_parser_spec.js @@ -5,11 +5,15 @@ import {DOM} from 'facade/dom'; import {MapWrapper} from 'facade/collection'; import {Lexer, Parser} from 'change_detection/change_detection'; +import {IgnoreChildrenStep} from './pipeline_spec'; export function main() { describe('TextInterpolationParser', () => { 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', () => { @@ -32,6 +36,13 @@ export function main() { expect(MapWrapper.get(bindings, 0).source).toEqual("(expr1)+(expr2)"); }); + it('should not interpolate when compileChildren is false', () => { + var results = createPipeline().process(createElement('
{{included}}{{excluded}}
')); + 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', () => { var results = createPipeline().process(createElement('
a{{expr1}}b{{expr2}}c
')); var bindings = results[0].textNodeBindings;