Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

Commit

Permalink
fix(material-dialog): Focus mgmt, ARIA attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcy Sutton authored and ThomasBurleson committed Sep 5, 2014
1 parent 4cc7fa3 commit fe054ae
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/base/constants.js
Expand Up @@ -3,6 +3,7 @@ var Constant = {
ROLE : {
BUTTON : 'button',
CHECKBOX : 'checkbox',
DIALOG : 'dialog',
LIST : 'list',
LIST_ITEM : 'listitem',
RADIO : 'radio',
Expand Down
12 changes: 12 additions & 0 deletions src/base/utils.js
Expand Up @@ -46,6 +46,18 @@ var Util = {
return offset ? letter.toUpperCase() : letter;
});
},
/**
* Selects 'n' words from a string
* for use in an HTML attribute
*/
stringFromTextBody: function stringFromTextBody(textBody, numWords) {
var string = textBody.trim();

if(string.split(/\s+/).length > numWords){
string = textBody.split(/\s+/).slice(1, (numWords + 1)).join(" ") + '...';
}
return string;
},

/**
* Spread the arguments as individual parameters to the target function.
Expand Down
32 changes: 29 additions & 3 deletions src/components/dialog/dialog.js
Expand Up @@ -4,7 +4,8 @@
*/
angular.module('material.components.dialog', [
'material.animations',
'material.services.compiler'
'material.services.compiler',
'material.services.aria'
])
.directive('materialDialog', [
'$$rAF',
Expand All @@ -17,6 +18,7 @@ angular.module('material.components.dialog', [
'$rootScope',
'$materialEffects',
'$animate',
'$aria',
MaterialDialogService
]);

Expand Down Expand Up @@ -61,7 +63,7 @@ function MaterialDialogDirective($$rAF) {
* <div ng-controller="MyController">
* <material-button ng-click="openDialog($event)">
* Open a Dialog from this button!
* </material-dialog>
* </material-button>
* </div>
* </hljs>
* <hljs lang="js">
Expand Down Expand Up @@ -102,7 +104,7 @@ function MaterialDialogDirective($$rAF) {
* @param {element=} appendTo The element to append the dialog to. Defaults to appending
* to the root element of the application.
*/
function MaterialDialogService($timeout, $materialCompiler, $rootElement, $rootScope, $materialEffects, $animate) {
function MaterialDialogService($timeout, $materialCompiler, $rootElement, $rootScope, $materialEffects, $animate, $aria) {
var recentDialog;
var dialogParent = $rootElement.find('body');
if ( !dialogParent.length ) {
Expand Down Expand Up @@ -144,6 +146,8 @@ function MaterialDialogService($timeout, $materialCompiler, $rootElement, $rootS
var closeButton = findCloseButton();
var backdrop;

configureAria(element.find('material-dialog'));

if (options.hasBackdrop) {
backdrop = angular.element('<material-backdrop class="opaque ng-enter">');
$animate.enter(backdrop, options.appendTo, null);
Expand Down Expand Up @@ -188,6 +192,10 @@ function MaterialDialogService($timeout, $materialCompiler, $rootElement, $rootS
scope.$destroy();
scope = null;
element = null;

if(popInTarget !== null) {
popInTarget.focus();
}
});
}
function onRootElementKeyup(e) {
Expand All @@ -203,6 +211,24 @@ function MaterialDialogService($timeout, $materialCompiler, $rootElement, $rootS
}
});

/**
* Inject ARIA-specific attributes appropriate for Dialogs
*/
function configureAria(element) {
var ROLE = Constant.ARIA.ROLE;

$aria.update(element, {
'role': ROLE.DIALOG
});

var dialogContent = element.find('.dialog-content');
if(dialogContent.length === 0){
dialogContent = element;
}
var defaultText = Util.stringFromTextBody(dialogContent.text(), 3);
$aria.expect(element, 'aria-label', defaultText);
}

return recentDialog;
}
}
17 changes: 16 additions & 1 deletion src/components/dialog/dialog.spec.js
Expand Up @@ -26,7 +26,22 @@ describe('$materialDialog', function() {

var container = parent.find('.material-dialog-container');
expect(container.length).toBe(1);
expect(container.html().trim()).toEqual(template);
}));

it('should have valid ARIA attributes', inject(function($materialDialog, $rootScope) {
var template = '<material-dialog>Hello</material-dialog>';
var parent = angular.element('<div>');

$materialDialog({
template: template,
appendTo: parent
});

$rootScope.$apply();

var dialog = parent.find('material-dialog');
expect(dialog.attr('role')).toBe('dialog');
expect(dialog.attr('aria-label')).toEqual(dialog.text());
}));

it('should escapeToClose == true', inject(function($materialDialog, $rootScope, $rootElement, $timeout, $materialEffects) {
Expand Down

0 comments on commit fe054ae

Please sign in to comment.