fix(compiler): make text interpolation more robust
Allows to add or remove previous siblings of text interpolations (e.g. by added `<script>` tags for content reproduction, or by removed `<style>` tags). Also calculates correctly whether an element is empty. Fixes #2591
This commit is contained in:
@@ -5,6 +5,7 @@ import {MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {Lexer, Parser} from 'angular2/change_detection';
|
||||
import {IgnoreChildrenStep} from './pipeline_spec';
|
||||
import {ElementBinderBuilder} from 'angular2/src/render/dom/view/proto_view_builder';
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
|
||||
export function main() {
|
||||
describe('TextInterpolationParser', () => {
|
||||
@@ -20,7 +21,8 @@ export function main() {
|
||||
|
||||
function assertTextBinding(elementBinder, bindingIndex, nodeIndex, expression) {
|
||||
expect(elementBinder.textBindings[bindingIndex].source).toEqual(expression);
|
||||
expect(elementBinder.textBindingIndices[bindingIndex]).toEqual(nodeIndex);
|
||||
expect(elementBinder.textBindingNodes[bindingIndex])
|
||||
.toEqual(DOM.childNodes(DOM.templateAwareRoot(elementBinder.element))[nodeIndex]);
|
||||
}
|
||||
|
||||
it('should find text interpolation in normal elements', () => {
|
||||
|
||||
@@ -36,15 +36,16 @@ import {DomTestbed} from './dom_testbed';
|
||||
|
||||
export function main() {
|
||||
describe('ShadowDom integration tests', function() {
|
||||
var styleHost;
|
||||
var strategies = {
|
||||
"scoped":
|
||||
bind(ShadowDomStrategy)
|
||||
.toFactory((styleInliner, styleUrlResolver) => new EmulatedScopedShadowDomStrategy(
|
||||
styleInliner, styleUrlResolver, null),
|
||||
styleInliner, styleUrlResolver, styleHost),
|
||||
[StyleInliner, StyleUrlResolver]),
|
||||
"unscoped": bind(ShadowDomStrategy)
|
||||
.toFactory((styleUrlResolver) =>
|
||||
new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, null),
|
||||
.toFactory((styleUrlResolver) => new EmulatedUnscopedShadowDomStrategy(
|
||||
styleUrlResolver, styleHost),
|
||||
[StyleUrlResolver])
|
||||
};
|
||||
if (DOM.supportsNativeShadowDOM()) {
|
||||
@@ -54,12 +55,15 @@ export function main() {
|
||||
.toFactory((styleUrlResolver) => new NativeShadowDomStrategy(styleUrlResolver),
|
||||
[StyleUrlResolver]));
|
||||
}
|
||||
beforeEach(() => { styleHost = el('<div></div>'); });
|
||||
|
||||
StringMapWrapper.forEach(strategies, (strategyBinding, name) => {
|
||||
describe(`${name} shadow dom strategy`, () => {
|
||||
beforeEachBindings(() => { return [strategyBinding, DomTestbed]; });
|
||||
|
||||
// GH-2095 - https://github.com/angular/angular/issues/2095
|
||||
// important as we are adding a content end element during compilation,
|
||||
// which could skrew up text node indices.
|
||||
it('should support text nodes after content tags',
|
||||
inject([DomTestbed, AsyncTestCompleter], (tb, async) => {
|
||||
tb.compileAll([
|
||||
@@ -80,6 +84,28 @@ export function main() {
|
||||
});
|
||||
}));
|
||||
|
||||
// important as we are moving style tags around during compilation,
|
||||
// which could skrew up text node indices.
|
||||
it('should support text nodes after style tags',
|
||||
inject([DomTestbed, AsyncTestCompleter], (tb, async) => {
|
||||
tb.compileAll([
|
||||
simple,
|
||||
new ViewDefinition({
|
||||
componentId: 'simple',
|
||||
template: '<style></style><p>P,</p>{{a}}',
|
||||
directives: []
|
||||
})
|
||||
])
|
||||
.then((protoViewDtos) => {
|
||||
var rootView = tb.createRootView(protoViewDtos[0]);
|
||||
var cmpView = tb.createComponentView(rootView.viewRef, 0, protoViewDtos[1]);
|
||||
|
||||
tb.renderer.setText(cmpView.viewRef, 0, 'text');
|
||||
expect(tb.rootEl).toHaveText('P,text');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should support simple components',
|
||||
inject([AsyncTestCompleter, DomTestbed], (async, tb) => {
|
||||
tb.compileAll([
|
||||
@@ -102,6 +128,29 @@ export function main() {
|
||||
});
|
||||
}));
|
||||
|
||||
it('should support simple components with text interpolation as direct children',
|
||||
inject([AsyncTestCompleter, DomTestbed], (async, tb) => {
|
||||
tb.compileAll([
|
||||
mainDir,
|
||||
new ViewDefinition({
|
||||
componentId: 'main',
|
||||
template: '<simple>' +
|
||||
'{{text}}' +
|
||||
'</simple>',
|
||||
directives: [simple]
|
||||
}),
|
||||
simpleTemplate
|
||||
])
|
||||
.then((protoViews) => {
|
||||
var cmpView = tb.createRootViews(protoViews)[1];
|
||||
tb.renderer.setText(cmpView.viewRef, 0, 'A');
|
||||
|
||||
expect(tb.rootEl).toHaveText('SIMPLE(A)');
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should not show the light dom even if there is not content tag',
|
||||
inject([AsyncTestCompleter, DomTestbed], (async, tb) => {
|
||||
tb.compileAll([
|
||||
|
||||
@@ -30,8 +30,12 @@ export function main() {
|
||||
binders = [];
|
||||
}
|
||||
var rootEl = el('<div></div>');
|
||||
return new DomProtoView(
|
||||
{element: rootEl, elementBinders: binders, transitiveContentTagCount: 0});
|
||||
return new DomProtoView({
|
||||
element: rootEl,
|
||||
elementBinders: binders,
|
||||
transitiveContentTagCount: 0,
|
||||
boundTextNodeCount: 0
|
||||
});
|
||||
}
|
||||
|
||||
function createView(pv = null, boundElementCount = 0) {
|
||||
|
||||
Reference in New Issue
Block a user