From 4f2f083b1601af1d4a62fb61a0c04f0b93f5e69f Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Wed, 7 Jan 2015 17:32:46 +0100 Subject: [PATCH] feat(compiler): allow ignoring element children --- modules/core/src/annotations/annotations.js | 1 + .../src/compiler/pipeline/compile_element.js | 2 ++ .../src/compiler/pipeline/compile_pipeline.js | 19 +++++----- .../test/compiler/pipeline/pipeline_spec.js | 36 +++++++++++++++---- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/modules/core/src/annotations/annotations.js b/modules/core/src/annotations/annotations.js index 40f292329e..6a89cea3e3 100644 --- a/modules/core/src/annotations/annotations.js +++ b/modules/core/src/annotations/annotations.js @@ -74,6 +74,7 @@ export class Component extends Directive { } export class Decorator extends Directive { + compileChildren: boolean; @CONST() constructor({ selector, diff --git a/modules/core/src/compiler/pipeline/compile_element.js b/modules/core/src/compiler/pipeline/compile_element.js index 962a2a58c1..efe76fd9f9 100644 --- a/modules/core/src/compiler/pipeline/compile_element.js +++ b/modules/core/src/compiler/pipeline/compile_element.js @@ -32,6 +32,7 @@ export class CompileElement { inheritedProtoView:ProtoView; inheritedProtoElementInjector:ProtoElementInjector; inheritedElementBinder:ElementBinder; + compileChildren: boolean; constructor(element:Element) { this.element = element; this._attrs = null; @@ -54,6 +55,7 @@ export class CompileElement { // inherited down to children if they don't have // an own elementBinder this.inheritedElementBinder = null; + this.compileChildren = true; } refreshAttrs() { diff --git a/modules/core/src/compiler/pipeline/compile_pipeline.js b/modules/core/src/compiler/pipeline/compile_pipeline.js index c2c1255ee1..3d74a2b28a 100644 --- a/modules/core/src/compiler/pipeline/compile_pipeline.js +++ b/modules/core/src/compiler/pipeline/compile_pipeline.js @@ -24,15 +24,18 @@ export class CompilePipeline { _process(results, parent:CompileElement, current:CompileElement) { var additionalChildren = this._control.internalProcess(results, 0, parent, current); - var node = DOM.templateAwareRoot(current.element).firstChild; - while (isPresent(node)) { - // compiliation can potentially move the node, so we need to store the - // next sibling before recursing. - var nextNode = DOM.nextSibling(node); - if (node.nodeType === Node.ELEMENT_NODE) { - this._process(results, current, new CompileElement(node)); + + if (current.compileChildren) { + var node = DOM.templateAwareRoot(current.element).firstChild; + while (isPresent(node)) { + // compiliation can potentially move the node, so we need to store the + // next sibling before recursing. + var nextNode = DOM.nextSibling(node); + if (node.nodeType === Node.ELEMENT_NODE) { + this._process(results, current, new CompileElement(node)); + } + node = nextNode; } - node = nextNode; } if (isPresent(additionalChildren)) { diff --git a/modules/core/test/compiler/pipeline/pipeline_spec.js b/modules/core/test/compiler/pipeline/pipeline_spec.js index 9d3f7670eb..7cf6fa20e7 100644 --- a/modules/core/test/compiler/pipeline/pipeline_spec.js +++ b/modules/core/test/compiler/pipeline/pipeline_spec.js @@ -1,5 +1,5 @@ import {describe, beforeEach, it, expect, iit, ddescribe} from 'test_lib/test_lib'; -import {ListWrapper, List} from 'facade/collection'; +import {ListWrapper, List, MapWrapper} from 'facade/collection'; import {DOM} from 'facade/dom'; import {isPresent, NumberWrapper, StringWrapper} from 'facade/lang'; @@ -10,14 +10,27 @@ import {CompileControl} from 'core/compiler/pipeline/compile_control'; export function main() { describe('compile_pipeline', () => { - it('should walk the tree in depth first order including template contents', () => { - var element = createElement('
'); + describe('children compilation', () => { + it('should walk the tree in depth first order including template contents', () => { + var element = createElement('
'); - var step0Log = []; - var results = new CompilePipeline([createLoggerStep(step0Log)]).process(element); + var step0Log = []; + var results = new CompilePipeline([createLoggerStep(step0Log)]).process(element); - expect(step0Log).toEqual(['1', '1<2', '2<3']); - expect(resultIdLog(results)).toEqual(['1', '2', '3']); + expect(step0Log).toEqual(['1', '1<2', '2<3']); + expect(resultIdLog(results)).toEqual(['1', '2', '3']); + }); + + it('should stop walking the tree when compileChildren is false', () => { + var element = createElement('
'); + + var step0Log = []; + var pipeline = new CompilePipeline([new IgnoreChildrenStep(), createLoggerStep(step0Log)]); + var results = pipeline.process(element); + + expect(step0Log).toEqual(['1', '1<2']); + expect(resultIdLog(results)).toEqual(['1', '2']); + }); }); describe('control.addParent', () => { @@ -118,6 +131,15 @@ class MockStep extends CompileStep { } } +class IgnoreChildrenStep extends CompileStep { + process(parent:CompileElement, current:CompileElement, control:CompileControl) { + var attributeMap = DOM.attributeMap(current.element); + if (MapWrapper.contains(attributeMap, 'ignore-children')) { + current.compileChildren = false; + } + } +} + function logEntry(log, parent, current) { var parentId = ''; if (isPresent(parent)) {