fix(compiler): always wrap views into an own <template> element

This is needed to allow view instantiation also in browsers that
don’t support the `<template>` element and because of this would
return elements from the content of `<template>` elements when
using `element.querySelectorAll`.

Also stores the `elementBinder.nestedProtoView` correctly
when a template directive was used on a `<template>` element.
This commit is contained in:
Tobias Bosch
2014-12-01 15:18:55 -08:00
parent 95d86d151a
commit 63053438ea
5 changed files with 116 additions and 43 deletions

View File

@ -1,7 +1,7 @@
import {describe, beforeEach, it, expect, iit, ddescribe} from 'test_lib/test_lib';
import {ListWrapper, List} from 'facade/collection';
import {DOM} from 'facade/dom';
import {isPresent, NumberWrapper} from 'facade/lang';
import {isPresent, NumberWrapper, StringWrapper} from 'facade/lang';
import {CompilePipeline} from 'core/compiler/pipeline/compile_pipeline';
import {CompileElement} from 'core/compiler/pipeline/compile_element';
@ -21,16 +21,6 @@ export function main() {
});
describe('control.addParent', () => {
it('should wrap the underlying DOM element', () => {
var element = createElement('<div id="1"><span wrap0="1" id="2"><b id="3"></b></span></div>');
var pipeline = new CompilePipeline([
createWrapperStep('wrap0', [])
]);
pipeline.process(element);
expect(DOM.getOuterHTML(element)).toEqual('<div id="1"><a id="wrap0#0"><span wrap0="1" id="2"><b id="3"></b></span></a></div>');
});
it('should report the new parent to the following processor and the result', () => {
var element = createElement('<div id="1"><span wrap0="1" id="2"><b id="3"></b></span></div>');
var step0Log = [];
@ -95,6 +85,26 @@ export function main() {
});
describe('control.addChild', () => {
it('should report the new child to all processors and the result', () => {
var element = createElement('<div id="1"><div id="2"></div></div>');
var resultLog = [];
var newChild = new CompileElement(createElement('<div id="3"></div>'));
var pipeline = new CompilePipeline([
new MockStep((parent, current, control) => {
if (StringWrapper.equals(current.element.id, '1')) {
control.addChild(newChild);
}
}),
createLoggerStep(resultLog)
]);
var result = pipeline.process(element);
expect(result[2]).toBe(newChild);
expect(resultLog).toEqual(['1', '1<2', '1<3']);
expect(resultIdLog(result)).toEqual(['1', '2', '3']);
});
});
});
}

View File

@ -22,21 +22,35 @@ export function main() {
expect(results[0].isViewRoot).toBe(true);
});
it('should mark <template> elements as viewRoot', () => {
var rootElement = createElement('<div><template></template></div>');
var results = createPipeline().process(rootElement);
expect(results[1].isViewRoot).toBe(true);
describe('<template> elements', () => {
it('should move the content into a new <template> element and mark that as viewRoot', () => {
var rootElement = createElement('<div><template if="true">a</template></div>');
var results = createPipeline().process(rootElement);
expect(DOM.getOuterHTML(results[1].element)).toEqual('<template if="true"></template>');
expect(results[1].isViewRoot).toBe(false);
expect(DOM.getOuterHTML(results[2].element)).toEqual('<template>a</template>');
expect(results[2].isViewRoot).toBe(true);
});
it('should not wrap a root <template> element', () => {
var rootElement = createElement('<div></div>');
var results = createPipeline().process(rootElement);
expect(results.length).toBe(1);
expect(DOM.getOuterHTML(rootElement)).toEqual('<div></div>');
});
});
describe('elements with template attribute', () => {
it('should insert an empty <template> element', () => {
var rootElement = createElement('<div><div template></div></div>');
it('should replace the element with an empty <template> element', () => {
var rootElement = createElement('<div><span template=""></span></div>');
var originalChild = rootElement.childNodes[0];
var results = createPipeline().process(rootElement);
expect(results[0].element).toBe(rootElement);
expect(results[1].element instanceof TemplateElement).toBe(true);
expect(DOM.getInnerHTML(results[1].element)).toEqual('');
expect(DOM.getOuterHTML(results[0].element)).toEqual('<div><template></template></div>');
expect(DOM.getOuterHTML(results[2].element)).toEqual('<span template=""></span>')
expect(results[2].element).toBe(originalChild);
});