fix(parse5): support comment nodes with getText and setText
In the browser, calling element.textContent causes child comment nodes to be ignored, while getting textContent directly on a comment node will return the comment. This change makes parse5Adapter consistent with this behavior by adding a 2nd argument to getText telling if it's being called recursively. Closes #5805
This commit is contained in:
parent
194dc7da78
commit
693d9dce5d
@ -1,7 +1,5 @@
|
|||||||
import {Inject, Injectable, OpaqueToken} from 'angular2/src/core/di';
|
import {Inject, Injectable, OpaqueToken} from 'angular2/src/core/di';
|
||||||
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
|
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
|
||||||
|
|
||||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
|
||||||
import {
|
import {
|
||||||
isPresent,
|
isPresent,
|
||||||
isBlank,
|
isBlank,
|
||||||
@ -42,9 +40,8 @@ import {
|
|||||||
DefaultProtoViewRef
|
DefaultProtoViewRef
|
||||||
} from 'angular2/src/core/render/view';
|
} from 'angular2/src/core/render/view';
|
||||||
import {ViewEncapsulation} from 'angular2/src/core/metadata';
|
import {ViewEncapsulation} from 'angular2/src/core/metadata';
|
||||||
|
|
||||||
// TODO move it once DdomAdapter is moved
|
|
||||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||||
|
import {camelCaseToDashCase} from './util';
|
||||||
|
|
||||||
const NAMESPACE_URIS =
|
const NAMESPACE_URIS =
|
||||||
CONST_EXPR({'xlink': 'http://www.w3.org/1999/xlink', 'svg': 'http://www.w3.org/2000/svg'});
|
CONST_EXPR({'xlink': 'http://www.w3.org/1999/xlink', 'svg': 'http://www.w3.org/2000/svg'});
|
||||||
@ -162,11 +159,7 @@ export abstract class DomRenderer extends Renderer implements NodeFactory<Node>
|
|||||||
var existingBindings = RegExpWrapper.firstMatch(
|
var existingBindings = RegExpWrapper.firstMatch(
|
||||||
TEMPLATE_BINDINGS_EXP, StringWrapper.replaceAll(DOM.getText(element), /\n/g, ''));
|
TEMPLATE_BINDINGS_EXP, StringWrapper.replaceAll(DOM.getText(element), /\n/g, ''));
|
||||||
var parsedBindings = Json.parse(existingBindings[1]);
|
var parsedBindings = Json.parse(existingBindings[1]);
|
||||||
if (isPresent(propertyValue)) {
|
parsedBindings[dashCasedPropertyName] = propertyValue;
|
||||||
parsedBindings[dashCasedPropertyName] = propertyValue;
|
|
||||||
} else {
|
|
||||||
StringMapWrapper.delete(parsedBindings, dashCasedPropertyName);
|
|
||||||
}
|
|
||||||
DOM.setText(element, StringWrapper.replace(TEMPLATE_COMMENT_TEXT, '{}',
|
DOM.setText(element, StringWrapper.replace(TEMPLATE_COMMENT_TEXT, '{}',
|
||||||
Json.stringify(parsedBindings)));
|
Json.stringify(parsedBindings)));
|
||||||
} else {
|
} else {
|
||||||
|
@ -239,21 +239,25 @@ export class Parse5DomAdapter extends DomAdapter {
|
|||||||
treeAdapter.appendChild(el, content.childNodes[i]);
|
treeAdapter.appendChild(el, content.childNodes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getText(el): string {
|
getText(el, isRecursive?: boolean): string {
|
||||||
if (this.isTextNode(el)) {
|
if (this.isTextNode(el)) {
|
||||||
return el.data;
|
return el.data;
|
||||||
|
} else if (this.isCommentNode(el)) {
|
||||||
|
// In the DOM, comments within an element return an empty string for textContent
|
||||||
|
// However, comment node instances return the comment content for textContent getter
|
||||||
|
return isRecursive ? '' : el.data;
|
||||||
} else if (isBlank(el.childNodes) || el.childNodes.length == 0) {
|
} else if (isBlank(el.childNodes) || el.childNodes.length == 0) {
|
||||||
return "";
|
return "";
|
||||||
} else {
|
} else {
|
||||||
var textContent = "";
|
var textContent = "";
|
||||||
for (var i = 0; i < el.childNodes.length; i++) {
|
for (var i = 0; i < el.childNodes.length; i++) {
|
||||||
textContent += this.getText(el.childNodes[i]);
|
textContent += this.getText(el.childNodes[i], true);
|
||||||
}
|
}
|
||||||
return textContent;
|
return textContent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setText(el, value: string) {
|
setText(el, value: string) {
|
||||||
if (this.isTextNode(el)) {
|
if (this.isTextNode(el) || this.isCommentNode(el)) {
|
||||||
el.data = value;
|
el.data = value;
|
||||||
} else {
|
} else {
|
||||||
this.clearNodes(el);
|
this.clearNodes(el);
|
||||||
|
@ -1613,7 +1613,7 @@ export function main() {
|
|||||||
|
|
||||||
it('should reflect property values on template comments',
|
it('should reflect property values on template comments',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
var tpl = '<template [ng-if]="ctxBoolProp"></template>';
|
var tpl = '<template [ngIf]="ctxBoolProp"></template>';
|
||||||
tcb.overrideView(MyComp, new ViewMetadata({template: tpl, directives: [NgIf]}))
|
tcb.overrideView(MyComp, new ViewMetadata({template: tpl, directives: [NgIf]}))
|
||||||
|
|
||||||
.createAsync(MyComp)
|
.createAsync(MyComp)
|
||||||
|
@ -189,7 +189,7 @@ export function main() {
|
|||||||
it('should update any template comment property/attributes',
|
it('should update any template comment property/attributes',
|
||||||
inject([TestComponentBuilder, Renderer, AsyncTestCompleter],
|
inject([TestComponentBuilder, Renderer, AsyncTestCompleter],
|
||||||
(tcb: TestComponentBuilder, renderer: Renderer, async) => {
|
(tcb: TestComponentBuilder, renderer: Renderer, async) => {
|
||||||
var tpl = '<template [ng-if]="ctxBoolProp"></template>';
|
var tpl = '<template [ngIf]="ctxBoolProp"></template>';
|
||||||
tcb.overrideView(MyComp, new ViewMetadata({template: tpl, directives: [NgIf]}))
|
tcb.overrideView(MyComp, new ViewMetadata({template: tpl, directives: [NgIf]}))
|
||||||
|
|
||||||
.createAsync(MyComp)
|
.createAsync(MyComp)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user