parent
d35fdfcd40
commit
5926d2e2f7
|
@ -52,27 +52,16 @@ export class DirectiveParser extends CompileStep {
|
||||||
for (var i=0; i < classList.length; i++) {
|
for (var i=0; i < classList.length; i++) {
|
||||||
cssSelector.addClassName(classList[i]);
|
cssSelector.addClassName(classList[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
MapWrapper.forEach(attrs, (attrValue, attrName) => {
|
MapWrapper.forEach(attrs, (attrValue, attrName) => {
|
||||||
if (isBlank(current.propertyBindings) ||
|
cssSelector.addAttribute(attrName, attrValue);
|
||||||
isPresent(current.propertyBindings) && !MapWrapper.contains(current.propertyBindings, attrName)) {
|
|
||||||
cssSelector.addAttribute(attrName, attrValue);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if (isPresent(current.propertyBindings)) {
|
|
||||||
MapWrapper.forEach(current.propertyBindings, (expression, prop) => {
|
|
||||||
cssSelector.addAttribute(prop, expression.source);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (isPresent(current.variableBindings)) {
|
|
||||||
MapWrapper.forEach(current.variableBindings, (value, name) => {
|
|
||||||
cssSelector.addAttribute(name, value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Note: We assume that the ViewSplitter already did its work, i.e. template directive should
|
// Note: We assume that the ViewSplitter already did its work, i.e. template directive should
|
||||||
// only be present on <template> elements any more!
|
// only be present on <template> elements any more!
|
||||||
var isTemplateElement = DOM.isTemplateElement(current.element);
|
var isTemplateElement = DOM.isTemplateElement(current.element);
|
||||||
var matchedProperties; // StringMap - used in dev mode to store all properties that have been matched
|
var matchedProperties; // StringMap - used in dev mode to store all properties that have been matched
|
||||||
|
|
||||||
this._selectorMatcher.match(cssSelector, (selector, directive) => {
|
this._selectorMatcher.match(cssSelector, (selector, directive) => {
|
||||||
matchedProperties = updateMatchedProperties(matchedProperties, selector, directive);
|
matchedProperties = updateMatchedProperties(matchedProperties, selector, directive);
|
||||||
checkDirectiveValidity(directive, current, isTemplateElement);
|
checkDirectiveValidity(directive, current, isTemplateElement);
|
||||||
|
@ -102,7 +91,7 @@ function updateMatchedProperties(matchedProperties, selector, directive) {
|
||||||
if (isPresent(directive.annotation) && isPresent(directive.annotation.bind)) {
|
if (isPresent(directive.annotation) && isPresent(directive.annotation.bind)) {
|
||||||
var bindMap = directive.annotation.bind;
|
var bindMap = directive.annotation.bind;
|
||||||
StringMapWrapper.forEach(bindMap, (value, key) => {
|
StringMapWrapper.forEach(bindMap, (value, key) => {
|
||||||
// value is the name of the property that is intepreted
|
// value is the name of the property that is interpreted
|
||||||
// e.g. 'myprop' or 'myprop | double' when a pipe is used to transform the property
|
// e.g. 'myprop' or 'myprop | double' when a pipe is used to transform the property
|
||||||
|
|
||||||
// keep the property name and remove the pipe
|
// keep the property name and remove the pipe
|
||||||
|
@ -142,7 +131,7 @@ function checkMissingDirectives(current, matchedProperties, isTemplateElement) {
|
||||||
if (!DOM.hasProperty(current.element, prop) && !isSpecialProperty(prop)) {
|
if (!DOM.hasProperty(current.element, prop) && !isSpecialProperty(prop)) {
|
||||||
if (!isPresent(matchedProperties) || !isPresent(StringMapWrapper.get(matchedProperties, prop))) {
|
if (!isPresent(matchedProperties) || !isPresent(StringMapWrapper.get(matchedProperties, prop))) {
|
||||||
throw new BaseException(`Missing directive to handle '${prop}' in ${current.elementDescription}`);
|
throw new BaseException(`Missing directive to handle '${prop}' in ${current.elementDescription}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,27 +40,32 @@ export class PropertyBindingParser extends CompileStep {
|
||||||
}
|
}
|
||||||
|
|
||||||
var attrs = current.attrs();
|
var attrs = current.attrs();
|
||||||
|
var newAttrs = MapWrapper.create();
|
||||||
var desc = current.elementDescription;
|
var desc = current.elementDescription;
|
||||||
|
|
||||||
MapWrapper.forEach(attrs, (attrValue, attrName) => {
|
MapWrapper.forEach(attrs, (attrValue, attrName) => {
|
||||||
var bindParts = RegExpWrapper.firstMatch(BIND_NAME_REGEXP, attrName);
|
var bindParts = RegExpWrapper.firstMatch(BIND_NAME_REGEXP, attrName);
|
||||||
if (isPresent(bindParts)) {
|
if (isPresent(bindParts)) {
|
||||||
if (isPresent(bindParts[1])) {
|
if (isPresent(bindParts[1])) {
|
||||||
// match: bind-prop
|
// match: bind-prop
|
||||||
current.addPropertyBinding(bindParts[4], this._parseBinding(attrValue, desc));
|
current.addPropertyBinding(bindParts[4], this._parseBinding(attrValue, desc));
|
||||||
|
MapWrapper.set(newAttrs, bindParts[4], attrValue);
|
||||||
} else if (isPresent(bindParts[2]) || isPresent(bindParts[7])) {
|
} else if (isPresent(bindParts[2]) || isPresent(bindParts[7])) {
|
||||||
// match: var-name / var-name="iden" / #name / #name="iden"
|
// match: var-name / var-name="iden" / #name / #name="iden"
|
||||||
var identifier = (isPresent(bindParts[4]) && bindParts[4] !== '') ?
|
var identifier = (isPresent(bindParts[4]) && bindParts[4] !== '') ?
|
||||||
bindParts[4] : bindParts[8];
|
bindParts[4] : bindParts[8];
|
||||||
var value = attrValue == '' ? '\$implicit' : attrValue;
|
var value = attrValue == '' ? '\$implicit' : attrValue;
|
||||||
current.addVariableBinding(identifier, value);
|
current.addVariableBinding(identifier, value);
|
||||||
|
MapWrapper.set(newAttrs, identifier, value);
|
||||||
} else if (isPresent(bindParts[3])) {
|
} else if (isPresent(bindParts[3])) {
|
||||||
// match: on-prop
|
// match: on-event
|
||||||
current.addEventBinding(bindParts[4], this._parseAction(attrValue, desc));
|
current.addEventBinding(bindParts[4], this._parseAction(attrValue, desc));
|
||||||
} else if (isPresent(bindParts[5])) {
|
} else if (isPresent(bindParts[5])) {
|
||||||
// match: [prop]
|
// match: [prop]
|
||||||
current.addPropertyBinding(bindParts[5], this._parseBinding(attrValue, desc));
|
current.addPropertyBinding(bindParts[5], this._parseBinding(attrValue, desc));
|
||||||
|
MapWrapper.set(newAttrs, bindParts[5], attrValue);
|
||||||
} else if (isPresent(bindParts[6])) {
|
} else if (isPresent(bindParts[6])) {
|
||||||
// match: (prop)
|
// match: (event)
|
||||||
current.addEventBinding(bindParts[6], this._parseBinding(attrValue, desc));
|
current.addEventBinding(bindParts[6], this._parseBinding(attrValue, desc));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -70,6 +75,10 @@ export class PropertyBindingParser extends CompileStep {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
MapWrapper.forEach(newAttrs, (attrValue, attrName) => {
|
||||||
|
MapWrapper.set(attrs, attrName, attrValue);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_parseInterpolation(input:string, location:string):AST {
|
_parseInterpolation(input:string, location:string):AST {
|
||||||
|
|
|
@ -109,8 +109,10 @@ export class ViewSplitter extends CompileStep {
|
||||||
var binding = bindings[i];
|
var binding = bindings[i];
|
||||||
if (binding.keyIsVar) {
|
if (binding.keyIsVar) {
|
||||||
compileElement.addVariableBinding(binding.key, binding.name);
|
compileElement.addVariableBinding(binding.key, binding.name);
|
||||||
|
MapWrapper.set(compileElement.attrs(), binding.key, binding.name);
|
||||||
} else if (isPresent(binding.expression)) {
|
} else if (isPresent(binding.expression)) {
|
||||||
compileElement.addPropertyBinding(binding.key, binding.expression);
|
compileElement.addPropertyBinding(binding.key, binding.expression);
|
||||||
|
MapWrapper.set(compileElement.attrs(), binding.key, binding.expression.source);
|
||||||
} else {
|
} else {
|
||||||
DOM.setAttribute(compileElement.element, binding.key, '');
|
DOM.setAttribute(compileElement.element, binding.key, '');
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,6 +243,30 @@ export function main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support directives where a selector matches property binding', function(done) {
|
||||||
|
tplResolver.setTemplate(MyComp,
|
||||||
|
new Template({
|
||||||
|
inline: '<p [id]="ctxProp"></p>',
|
||||||
|
directives: [IdComponent]
|
||||||
|
}));
|
||||||
|
|
||||||
|
compiler.compile(MyComp).then((pv) => {
|
||||||
|
createView(pv);
|
||||||
|
|
||||||
|
ctx.ctxProp = 'some_id';
|
||||||
|
cd.detectChanges();
|
||||||
|
expect(view.nodes[0].id).toEqual('some_id');
|
||||||
|
expect(DOM.getInnerHTML(view.nodes[0].shadowRoot.childNodes[0])).toEqual('Matched on id with some_id');
|
||||||
|
|
||||||
|
ctx.ctxProp = 'other_id';
|
||||||
|
cd.detectChanges();
|
||||||
|
expect(view.nodes[0].id).toEqual('other_id');
|
||||||
|
expect(DOM.getInnerHTML(view.nodes[0].shadowRoot.childNodes[0])).toEqual('Matched on id with other_id');
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should support template directives via `<template>` elements.', (done) => {
|
it('should support template directives via `<template>` elements.', (done) => {
|
||||||
tplResolver.setTemplate(MyComp,
|
tplResolver.setTemplate(MyComp,
|
||||||
new Template({
|
new Template({
|
||||||
|
@ -714,3 +738,14 @@ class DecoratorListeningEvent {
|
||||||
this.msg = msg;
|
this.msg = msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: '[id]',
|
||||||
|
bind: {'id': 'id'}
|
||||||
|
})
|
||||||
|
@Template({
|
||||||
|
inline: '<div>Matched on id with {{id}}</div>'
|
||||||
|
})
|
||||||
|
class IdComponent {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
|
@ -39,10 +39,14 @@ export function main() {
|
||||||
if (isPresent(propertyBindings)) {
|
if (isPresent(propertyBindings)) {
|
||||||
StringMapWrapper.forEach(propertyBindings, (v, k) => {
|
StringMapWrapper.forEach(propertyBindings, (v, k) => {
|
||||||
current.addPropertyBinding(k, parser.parseBinding(v, null));
|
current.addPropertyBinding(k, parser.parseBinding(v, null));
|
||||||
|
MapWrapper.set(current.attrs(), k, v);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (isPresent(variableBindings)) {
|
if (isPresent(variableBindings)) {
|
||||||
current.variableBindings = MapWrapper.createFromStringMap(variableBindings);
|
StringMapWrapper.forEach(variableBindings, (v, k) => {
|
||||||
|
current.addVariableBinding(k, v);
|
||||||
|
MapWrapper.set(current.attrs(), k, v);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}), new DirectiveParser(annotatedDirectives)]);
|
}), new DirectiveParser(annotatedDirectives)]);
|
||||||
}
|
}
|
||||||
|
@ -89,7 +93,7 @@ export function main() {
|
||||||
createPipeline().process(
|
createPipeline().process(
|
||||||
el('<div some-comp some-comp2></div>')
|
el('<div some-comp some-comp2></div>')
|
||||||
);
|
);
|
||||||
}).toThrowError('Multiple component directives not allowed on the same element - check <div some-comp some-comp2>');
|
}).toThrowError('Multiple component directives not allowed on the same element - check <div some-comp some-comp2>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow component directives on <template> elements', () => {
|
it('should not allow component directives on <template> elements', () => {
|
||||||
|
|
Loading…
Reference in New Issue