parent
6d45153b67
commit
1846ce8c68
|
@ -18,6 +18,26 @@ import {CompileControl} from './compile_control';
|
||||||
|
|
||||||
var DOT_REGEXP = RegExpWrapper.create('\\.');
|
var DOT_REGEXP = RegExpWrapper.create('\\.');
|
||||||
|
|
||||||
|
const ARIA_PREFIX = 'aria-';
|
||||||
|
var ariaSettersCache = StringMapWrapper.create();
|
||||||
|
|
||||||
|
function ariaSetterFactory(attrName:string) {
|
||||||
|
var setterFn = StringMapWrapper.get(ariaSettersCache, attrName);
|
||||||
|
|
||||||
|
if (isBlank(setterFn)) {
|
||||||
|
setterFn = function(element:Element, value) {
|
||||||
|
if (isPresent(value)) {
|
||||||
|
DOM.setAttribute(element, attrName, stringify(value));
|
||||||
|
} else {
|
||||||
|
DOM.removeAttribute(element, attrName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
StringMapWrapper.set(ariaSettersCache, attrName, setterFn);
|
||||||
|
}
|
||||||
|
|
||||||
|
return setterFn;
|
||||||
|
}
|
||||||
|
|
||||||
const CLASS_PREFIX = 'class.';
|
const CLASS_PREFIX = 'class.';
|
||||||
var classSettersCache = StringMapWrapper.create();
|
var classSettersCache = StringMapWrapper.create();
|
||||||
|
|
||||||
|
@ -133,7 +153,9 @@ export class ElementBinderBuilder extends CompileStep {
|
||||||
MapWrapper.forEach(compileElement.propertyBindings, (expression, property) => {
|
MapWrapper.forEach(compileElement.propertyBindings, (expression, property) => {
|
||||||
var setterFn, styleParts, styleSuffix;
|
var setterFn, styleParts, styleSuffix;
|
||||||
|
|
||||||
if (StringWrapper.startsWith(property, CLASS_PREFIX)) {
|
if (StringWrapper.startsWith(property, ARIA_PREFIX)) {
|
||||||
|
setterFn = ariaSetterFactory(property);
|
||||||
|
} else if (StringWrapper.startsWith(property, CLASS_PREFIX)) {
|
||||||
setterFn = classSetterFactory(StringWrapper.substring(property, CLASS_PREFIX.length));
|
setterFn = classSetterFactory(StringWrapper.substring(property, CLASS_PREFIX.length));
|
||||||
} else if (StringWrapper.startsWith(property, STYLE_PREFIX)) {
|
} else if (StringWrapper.startsWith(property, STYLE_PREFIX)) {
|
||||||
styleParts = StringWrapper.split(property, DOT_REGEXP);
|
styleParts = StringWrapper.split(property, DOT_REGEXP);
|
||||||
|
|
|
@ -148,6 +148,12 @@ class DOM {
|
||||||
element.setAttribute(name, value);
|
element.setAttribute(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void removeAttribute(Element element, String name) {
|
||||||
|
//there is no removeAttribute method as of now in Dart:
|
||||||
|
//https://code.google.com/p/dart/issues/detail?id=19934
|
||||||
|
element.attributes.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
static Node templateAwareRoot(Element el) =>
|
static Node templateAwareRoot(Element el) =>
|
||||||
el is TemplateElement ? el.content : el;
|
el is TemplateElement ? el.content : el;
|
||||||
|
|
||||||
|
|
|
@ -166,6 +166,9 @@ export class DOM {
|
||||||
static setAttribute(element:Element, name:string, value:string) {
|
static setAttribute(element:Element, name:string, value:string) {
|
||||||
element.setAttribute(name, value);
|
element.setAttribute(name, value);
|
||||||
}
|
}
|
||||||
|
static removeAttribute(element:Element, attribute:string) {
|
||||||
|
return element.removeAttribute(attribute);
|
||||||
|
}
|
||||||
static templateAwareRoot(el:Element):Node {
|
static templateAwareRoot(el:Element):Node {
|
||||||
return el instanceof TemplateElement ? el.content : el;
|
return el instanceof TemplateElement ? el.content : el;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,24 @@ export function main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should consume binding to aria-* attributes', (done) => {
|
||||||
|
tplResolver.setTemplate(MyComp, new Template({inline: '<div [aria-label]="ctxProp"></div>'}));
|
||||||
|
|
||||||
|
compiler.compile(MyComp).then((pv) => {
|
||||||
|
createView(pv);
|
||||||
|
|
||||||
|
ctx.ctxProp = 'Initial aria label';
|
||||||
|
cd.detectChanges();
|
||||||
|
expect(DOM.getAttribute(view.nodes[0], 'aria-label')).toEqual('Initial aria label');
|
||||||
|
|
||||||
|
ctx.ctxProp = 'Changed aria label';
|
||||||
|
cd.detectChanges();
|
||||||
|
expect(DOM.getAttribute(view.nodes[0], 'aria-label')).toEqual('Changed aria label');
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should consume directive watch expression change.', (done) => {
|
it('should consume directive watch expression change.', (done) => {
|
||||||
var tpl =
|
var tpl =
|
||||||
'<div>' +
|
'<div>' +
|
||||||
|
|
|
@ -195,6 +195,52 @@ export function main() {
|
||||||
expect(view.nodes[0].hidden).toEqual(false);
|
expect(view.nodes[0].hidden).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should bind to aria-* attributes when exp evaluates to strings', () => {
|
||||||
|
var propertyBindings = MapWrapper.createFromStringMap({
|
||||||
|
'aria-label': 'prop1'
|
||||||
|
});
|
||||||
|
var pipeline = createPipeline({propertyBindings: propertyBindings});
|
||||||
|
var results = pipeline.process(el('<div viewroot prop-binding></div>'));
|
||||||
|
var pv = results[0].inheritedProtoView;
|
||||||
|
|
||||||
|
expect(pv.elementBinders[0].hasElementPropertyBindings).toBe(true);
|
||||||
|
|
||||||
|
instantiateView(pv);
|
||||||
|
|
||||||
|
evalContext.prop1 = 'some label';
|
||||||
|
changeDetector.detectChanges();
|
||||||
|
expect(DOM.getAttribute(view.nodes[0], 'aria-label')).toEqual('some label');
|
||||||
|
|
||||||
|
evalContext.prop1 = 'some other label';
|
||||||
|
changeDetector.detectChanges();
|
||||||
|
expect(DOM.getAttribute(view.nodes[0], 'aria-label')).toEqual('some other label');
|
||||||
|
|
||||||
|
evalContext.prop1 = null;
|
||||||
|
changeDetector.detectChanges();
|
||||||
|
expect(DOM.getAttribute(view.nodes[0], 'aria-label')).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should bind to aria-* attributes when exp evaluates to booleans', () => {
|
||||||
|
var propertyBindings = MapWrapper.createFromStringMap({
|
||||||
|
'aria-busy': 'prop1'
|
||||||
|
});
|
||||||
|
var pipeline = createPipeline({propertyBindings: propertyBindings});
|
||||||
|
var results = pipeline.process(el('<div viewroot prop-binding></div>'));
|
||||||
|
var pv = results[0].inheritedProtoView;
|
||||||
|
|
||||||
|
expect(pv.elementBinders[0].hasElementPropertyBindings).toBe(true);
|
||||||
|
|
||||||
|
instantiateView(pv);
|
||||||
|
|
||||||
|
evalContext.prop1 = true;
|
||||||
|
changeDetector.detectChanges();
|
||||||
|
expect(DOM.getAttribute(view.nodes[0], 'aria-busy')).toEqual('true');
|
||||||
|
|
||||||
|
evalContext.prop1 = false;
|
||||||
|
changeDetector.detectChanges();
|
||||||
|
expect(DOM.getAttribute(view.nodes[0], 'aria-busy')).toEqual('false');
|
||||||
|
});
|
||||||
|
|
||||||
it('should bind class with a dot', () => {
|
it('should bind class with a dot', () => {
|
||||||
var propertyBindings = MapWrapper.createFromStringMap({
|
var propertyBindings = MapWrapper.createFromStringMap({
|
||||||
'class.bar': 'prop1',
|
'class.bar': 'prop1',
|
||||||
|
|
Loading…
Reference in New Issue