fix(compiler, view): centralize TemplateElement checks and fix inconsistencies
Fixes #189 Closes #194
This commit is contained in:
parent
5e0ff2cbb7
commit
1b79c91320
@ -1,5 +1,5 @@
|
|||||||
import {List, ListWrapper} from 'facade/collection';
|
import {List, ListWrapper} from 'facade/collection';
|
||||||
import {Element, TemplateElement, Node} from 'facade/dom';
|
import {Element, Node, DOM} from 'facade/dom';
|
||||||
import {CompileElement} from './compile_element';
|
import {CompileElement} from './compile_element';
|
||||||
import {CompileControl} from './compile_control';
|
import {CompileControl} from './compile_control';
|
||||||
import {CompileStep} from './compile_step';
|
import {CompileStep} from './compile_step';
|
||||||
@ -23,12 +23,7 @@ export class CompilePipeline {
|
|||||||
_process(results, parent:CompileElement, element:Element) {
|
_process(results, parent:CompileElement, element:Element) {
|
||||||
var current = new CompileElement(element);
|
var current = new CompileElement(element);
|
||||||
this._control.internalProcess(results, 0, parent, current);
|
this._control.internalProcess(results, 0, parent, current);
|
||||||
var childNodes;
|
var childNodes = DOM.templateAwareRoot(element).childNodes;
|
||||||
if (element instanceof TemplateElement) {
|
|
||||||
childNodes = element.content.childNodes;
|
|
||||||
} else {
|
|
||||||
childNodes = element.childNodes;
|
|
||||||
}
|
|
||||||
for (var i=0; i<childNodes.length; i++) {
|
for (var i=0; i<childNodes.length; i++) {
|
||||||
var node = childNodes[i];
|
var node = childNodes[i];
|
||||||
if (node.nodeType === Node.ELEMENT_NODE) {
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {RegExpWrapper, StringWrapper} from 'facade/lang';
|
import {RegExpWrapper, StringWrapper} from 'facade/lang';
|
||||||
import {TemplateElement, Node, DOM} from 'facade/dom';
|
import {Node, DOM} from 'facade/dom';
|
||||||
|
|
||||||
import {CompileStep} from './compile_step';
|
import {CompileStep} from './compile_step';
|
||||||
import {CompileElement} from './compile_element';
|
import {CompileElement} from './compile_element';
|
||||||
@ -17,12 +17,7 @@ var INTERPOLATION_REGEXP = RegExpWrapper.create('\\{\\{(.*?)\\}\\}');
|
|||||||
export class TextInterpolationParser extends CompileStep {
|
export class TextInterpolationParser extends CompileStep {
|
||||||
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
||||||
var element = current.element;
|
var element = current.element;
|
||||||
var childNodes;
|
var childNodes = DOM.templateAwareRoot(element).childNodes;
|
||||||
if (element instanceof TemplateElement) {
|
|
||||||
childNodes = element.content.childNodes;
|
|
||||||
} else {
|
|
||||||
childNodes = element.childNodes;
|
|
||||||
}
|
|
||||||
for (var i=0; i<childNodes.length; i++) {
|
for (var i=0; i<childNodes.length; i++) {
|
||||||
var node = childNodes[i];
|
var node = childNodes[i];
|
||||||
if (node.nodeType === Node.TEXT_NODE) {
|
if (node.nodeType === Node.TEXT_NODE) {
|
||||||
|
@ -75,7 +75,12 @@ export class ProtoView {
|
|||||||
|
|
||||||
instantiate(context, appInjector:Injector):View {
|
instantiate(context, appInjector:Injector):View {
|
||||||
var clone = DOM.clone(this.element);
|
var clone = DOM.clone(this.element);
|
||||||
var elements = ListWrapper.clone(DOM.getElementsByClassName(clone, NG_BINDING_CLASS));
|
var elements;
|
||||||
|
if (clone instanceof TemplateElement) {
|
||||||
|
elements = ListWrapper.clone(DOM.querySelectorAll(clone.content, `.${NG_BINDING_CLASS}`));
|
||||||
|
} else {
|
||||||
|
elements = ListWrapper.clone(DOM.getElementsByClassName(clone, NG_BINDING_CLASS));
|
||||||
|
}
|
||||||
if (DOM.hasClass(clone, NG_BINDING_CLASS)) {
|
if (DOM.hasClass(clone, NG_BINDING_CLASS)) {
|
||||||
ListWrapper.insert(elements, 0, clone);
|
ListWrapper.insert(elements, 0, clone);
|
||||||
}
|
}
|
||||||
@ -202,7 +207,7 @@ export class ProtoView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static _collectTextNodes(allTextNodes, element, indices) {
|
static _collectTextNodes(allTextNodes, element, indices) {
|
||||||
var childNodes = DOM.childNodes(element);
|
var childNodes = DOM.templateAwareRoot(element).childNodes;
|
||||||
for (var i = 0; i < indices.length; ++i) {
|
for (var i = 0; i < indices.length; ++i) {
|
||||||
ListWrapper.push(allTextNodes, childNodes[indices[i]]);
|
ListWrapper.push(allTextNodes, childNodes[indices[i]]);
|
||||||
}
|
}
|
||||||
|
@ -20,29 +20,23 @@ export function main() {
|
|||||||
|
|
||||||
describe('ProtoView.instantiate', function() {
|
describe('ProtoView.instantiate', function() {
|
||||||
|
|
||||||
describe('collect root nodes', () => {
|
function createCollectDomNodesTestCases(useTemplateElement:boolean) {
|
||||||
|
|
||||||
it('should use the ProtoView element if it is no TemplateElement', () => {
|
function templateAwareCreateElement(html) {
|
||||||
var pv = new ProtoView(createElement('<div id="1"></div>'), new ProtoWatchGroup());
|
return createElement(useTemplateElement ? `<template>${html}</template>` : html);
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should collect the root node in the ProtoView element', () => {
|
||||||
|
var pv = new ProtoView(templateAwareCreateElement('<div id="1"></div>'), new ProtoWatchGroup());
|
||||||
var view = pv.instantiate(null, null);
|
var view = pv.instantiate(null, null);
|
||||||
expect(view.nodes.length).toBe(1);
|
expect(view.nodes.length).toBe(1);
|
||||||
expect(view.nodes[0].getAttribute('id')).toEqual('1');
|
expect(view.nodes[0].getAttribute('id')).toEqual('1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use the ProtoView elements children if it is a TemplateElement', () => {
|
|
||||||
var pv = new ProtoView(createElement('<template><div id="1"></div></template>'),
|
|
||||||
new ProtoWatchGroup());
|
|
||||||
var view = pv.instantiate(null, null);
|
|
||||||
expect(view.nodes.length).toBe(1);
|
|
||||||
expect(view.nodes[0].getAttribute('id')).toEqual('1');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('collect elements with property bindings', () => {
|
describe('collect elements with property bindings', () => {
|
||||||
|
|
||||||
it('should collect property bindings on the root element if it has the ng-binding class', () => {
|
it('should collect property bindings on the root element if it has the ng-binding class', () => {
|
||||||
var pv = new ProtoView(createElement('<div [prop]="a" class="ng-binding"></div>'), new ProtoWatchGroup());
|
var pv = new ProtoView(templateAwareCreateElement('<div [prop]="a" class="ng-binding"></div>'), new ProtoWatchGroup());
|
||||||
pv.bindElement(null);
|
pv.bindElement(null);
|
||||||
pv.bindElementProperty('prop', parser.parseBinding('a'));
|
pv.bindElementProperty('prop', parser.parseBinding('a'));
|
||||||
|
|
||||||
@ -52,7 +46,7 @@ export function main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should collect property bindings on child elements with ng-binding class', () => {
|
it('should collect property bindings on child elements with ng-binding class', () => {
|
||||||
var pv = new ProtoView(createElement('<div><span></span><span class="ng-binding"></span></div>'),
|
var pv = new ProtoView(templateAwareCreateElement('<div><span></span><span class="ng-binding"></span></div>'),
|
||||||
new ProtoWatchGroup());
|
new ProtoWatchGroup());
|
||||||
pv.bindElement(null);
|
pv.bindElement(null);
|
||||||
pv.bindElementProperty('a', parser.parseBinding('b'));
|
pv.bindElementProperty('a', parser.parseBinding('b'));
|
||||||
@ -67,7 +61,7 @@ export function main() {
|
|||||||
describe('collect text nodes with bindings', () => {
|
describe('collect text nodes with bindings', () => {
|
||||||
|
|
||||||
it('should collect text nodes under the root element', () => {
|
it('should collect text nodes under the root element', () => {
|
||||||
var pv = new ProtoView(createElement('<div class="ng-binding">{{}}<span></span>{{}}</div>'), new ProtoWatchGroup());
|
var pv = new ProtoView(templateAwareCreateElement('<div class="ng-binding">{{}}<span></span>{{}}</div>'), new ProtoWatchGroup());
|
||||||
pv.bindElement(null);
|
pv.bindElement(null);
|
||||||
pv.bindTextNode(0, parser.parseBinding('a'));
|
pv.bindTextNode(0, parser.parseBinding('a'));
|
||||||
pv.bindTextNode(2, parser.parseBinding('b'));
|
pv.bindTextNode(2, parser.parseBinding('b'));
|
||||||
@ -79,7 +73,7 @@ export function main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should collect text nodes with bindings on child elements with ng-binding class', () => {
|
it('should collect text nodes with bindings on child elements with ng-binding class', () => {
|
||||||
var pv = new ProtoView(createElement('<div><span> </span><span class="ng-binding">{{}}</span></div>'),
|
var pv = new ProtoView(templateAwareCreateElement('<div><span> </span><span class="ng-binding">{{}}</span></div>'),
|
||||||
new ProtoWatchGroup());
|
new ProtoWatchGroup());
|
||||||
pv.bindElement(null);
|
pv.bindElement(null);
|
||||||
pv.bindTextNode(0, parser.parseBinding('b'));
|
pv.bindTextNode(0, parser.parseBinding('b'));
|
||||||
@ -90,6 +84,15 @@ export function main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('collect dom nodes with a regular element as root', () => {
|
||||||
|
createCollectDomNodesTestCases(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('collect dom nodes with a template element as root', () => {
|
||||||
|
createCollectDomNodesTestCases(true);
|
||||||
|
});
|
||||||
|
|
||||||
describe('create ElementInjectors', () => {
|
describe('create ElementInjectors', () => {
|
||||||
it('should use the directives of the ProtoElementInjector', () => {
|
it('should use the directives of the ProtoElementInjector', () => {
|
||||||
|
@ -79,4 +79,7 @@ class DOM {
|
|||||||
static attributeMap(Element element) {
|
static attributeMap(Element element) {
|
||||||
return element.attributes;
|
return element.attributes;
|
||||||
}
|
}
|
||||||
|
static Node templateAwareRoot(Element el) {
|
||||||
|
return el is TemplateElement ? el.content : el;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,5 +78,7 @@ export class DOM {
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
static templateAwareRoot(el:Element):Node {
|
||||||
|
return el instanceof TemplateElement ? el.content : el;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user