Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {int, isPresent, isBlank, Type, BaseException, StringWrapper, RegExpWrapper, stringify} from 'angular2/src/facade/lang';
import {int, isPresent, isBlank, Type, BaseException, StringWrapper, RegExpWrapper, isString, stringify} from 'angular2/src/facade/lang';
import {Element, DOM} from 'angular2/src/facade/dom';
import {ListWrapper, List, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';

Expand Down Expand Up @@ -81,6 +81,18 @@ function styleSetterFactory(styleName:string, stylesuffix:string) {
return setterFn;
}

const ROLE_ATTR = 'role';
function roleSetter(element:Element, value) {
if (isString(value)) {
DOM.setAttribute(element, ROLE_ATTR, value);
} else {
DOM.removeAttribute(element, ROLE_ATTR);
if (isPresent(value)) {
throw new BaseException("Invalid role attribute, only string values are allowed, got '" + stringify(value) + "'");
}
}
}

/**
* Creates the ElementBinders and adds watches to the
* ProtoChangeDetector.
Expand Down Expand Up @@ -155,6 +167,8 @@ export class ElementBinderBuilder extends CompileStep {

if (StringWrapper.startsWith(property, ARIA_PREFIX)) {
setterFn = ariaSetterFactory(property);
} else if (StringWrapper.equals(property, ROLE_ATTR)) {
setterFn = roleSetter;
} else if (StringWrapper.startsWith(property, CLASS_PREFIX)) {
setterFn = classSetterFactory(StringWrapper.substring(property, CLASS_PREFIX.length));
} else if (StringWrapper.startsWith(property, STYLE_PREFIX)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,47 @@ export function main() {
expect(DOM.getAttribute(view.nodes[0], 'aria-busy')).toEqual('false');
});

it('should bind to ARIA role attribute', () => {
var propertyBindings = MapWrapper.createFromStringMap({
'role': '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 = 'alert';
changeDetector.detectChanges();
expect(DOM.getAttribute(view.nodes[0], 'role')).toEqual('alert');

evalContext.prop1 = 'alertdialog';
changeDetector.detectChanges();
expect(DOM.getAttribute(view.nodes[0], 'role')).toEqual('alertdialog');

evalContext.prop1 = null;
changeDetector.detectChanges();
expect(DOM.getAttribute(view.nodes[0], 'role')).toBeNull();
});

it('should throw for a non-string ARIA role', () => {
var propertyBindings = MapWrapper.createFromStringMap({
'role': 'prop1'
});
var pipeline = createPipeline({propertyBindings: propertyBindings});
var results = pipeline.process(el('<div viewroot prop-binding></div>'));
var pv = results[0].inheritedProtoView;

instantiateView(pv);

expect( () => {
evalContext.prop1 = 1; //invalid, non-string role
changeDetector.detectChanges();
}).toThrowError("Invalid role attribute, only string values are allowed, got '1'");
});

it('should bind class with a dot', () => {
var propertyBindings = MapWrapper.createFromStringMap({
'class.bar': 'prop1',
Expand Down