Skip to content

Dialog: Improve accessibilty #794

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 43 commits into from
Nov 26, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
2a887e4
Dialog: Improve accessibilty - add an aria-describedby attribute on t…
jzaefferer Oct 26, 2012
8ee8046
Dialog: Keep focus inside modal dialog, by handling focus events on e…
jzaefferer Oct 26, 2012
0a25b2c
Dialog: move to top when opening again, and focus as if opened from s…
jzaefferer Oct 26, 2012
2062a18
Dialog: Inline code review
jzaefferer Oct 27, 2012
4632780
Dialog: Fix yoda-if, remove unnecessary TODOs; add missing callbacks …
jzaefferer Nov 9, 2012
b6cefc7
Dialog: Remove deprecated disableSelection() usage.
jzaefferer Nov 9, 2012
4e03321
Dialog: Trigger focus event when dialog is moved to top.
jzaefferer Nov 9, 2012
324d54d
Dialog: Use $.isEmptyObject() to check if there a button-option prope…
jzaefferer Nov 9, 2012
f7d3a51
Dialog: Only add the new dialogClass, not the base classes when chang…
jzaefferer Nov 9, 2012
6edce86
Dialog: Remove attroperty workaround for title attribute. Make the de…
jzaefferer Nov 9, 2012
0848040
Dialog: Focus tabbable only when dialog lost focus before.
jzaefferer Nov 9, 2012
83a9f21
Dialog: Use button widget for close button (was already listed as dep…
jzaefferer Nov 15, 2012
fed2972
Dialog: Refactor _setOption to call _super early. Move dialogClass up…
jzaefferer Nov 15, 2012
7e964be
Dialog: Have _createButtons access the buttons option directly. Start…
jzaefferer Nov 15, 2012
16a79c1
Dialog: Finish refactoring _setOption, getting rid of unnecessary swi…
jzaefferer Nov 15, 2012
c8aef20
Dialog: Have _makeResizable look at options instead of passing handles.
jzaefferer Nov 15, 2012
1001504
Dialog: Remove outdated TODO
jzaefferer Nov 15, 2012
7a03535
Dialog: Refactor the mousedown-bind call to use _on, removing the nee…
jzaefferer Nov 15, 2012
f0acaac
Dialog: Refactor uiDialogTitlebar variable, use this.uiDialogTitlebar…
jzaefferer Nov 15, 2012
1d6ce64
Dialog: Refactor _create, extracting title bar creation in _createTit…
jzaefferer Nov 15, 2012
4c9caa8
Dialog: Extract button pane creation into _createButtonPane
jzaefferer Nov 15, 2012
625a111
Dialog: Extracting wrapper creation into _createWrapper. Merging the …
jzaefferer Nov 15, 2012
0ae6fc1
Dialog: Remove useless tmp vars.
jzaefferer Nov 15, 2012
972f5c1
Dialog: Button is now a fixed dependency, so remove the check
jzaefferer Nov 15, 2012
0bc73b7
Dialog: Remove busted ui-dialog-disabled class, shouldn't be there. R…
jzaefferer Nov 15, 2012
e3dcaf2
Dialog: Remove uuid and getTitleId. Leftovers from 240b22b1439df22408…
jzaefferer Nov 15, 2012
d8b98ec
Dialog: Tiny code improvements
jzaefferer Nov 16, 2012
9996173
Dialog: Pass through icons and showText (as 'text') options to button…
jzaefferer Nov 16, 2012
b694409
Dialog: Extend visual test to verify DOM position restore on destroy;…
jzaefferer Nov 16, 2012
299681e
Dialog: Cleanup in ticket tests: TODO to merge one test, fix whitespace
jzaefferer Nov 16, 2012
b27db7e
Dialog: Extend autofocus, starting with [autofocus], then :tabbable c…
jzaefferer Nov 16, 2012
0be97bf
Dialog: Removed broken disabled option from dialog, defuse disable/en…
jzaefferer Nov 17, 2012
a0310eb
Dialog: Move array notation support for position option to backCompat…
jzaefferer Nov 17, 2012
41c2afd
Dialog: Refactor overlay handling into two instance methods. Remove u…
jzaefferer Nov 17, 2012
32a8931
Dialog: Improve _destroy method, detaching dialog content from wrappe…
jzaefferer Nov 17, 2012
5aac8f5
Dialog: Add missing unit test for aria-describedby attribute
jzaefferer Nov 17, 2012
73533d9
Dialog: Exclude deprecated units from phantomjs
jzaefferer Nov 17, 2012
f3525af
Dialog: Update focus-tabbable test with a timer workaround to get IE8…
jzaefferer Nov 17, 2012
a09f5c0
Dialog: Follow-up to 9fe3a62d8 - also deprecate string notation for p…
jzaefferer Nov 21, 2012
ec1f1bd
Dialog: Follow-up to c77ca67 - exclude button options from properties…
jzaefferer Nov 22, 2012
d179cba
Dialog: Update position when size is changed. Fixes #8789 - Dialog do…
kborchers Nov 25, 2012
60486ac
Dialog: Don't focus dialog when mousedown is on close button. Fixes #…
jzaefferer Nov 26, 2012
7e9060c
Dialog: Extract setting the title into a _title method, use .text() t…
jzaefferer Nov 26, 2012
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
1 change: 1 addition & 0 deletions build/tasks/testswarm.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var versions = {
"Core": "core/core.html",
"Datepicker": "datepicker/datepicker.html",
"Dialog": "dialog/dialog.html",
"Dialog_deprecated": "dialog/dialog_deprecated.html",
"Draggable": "draggable/draggable.html",
"Droppable": "droppable/droppable.html",
"Effects": "effects/effects.html",
Expand Down
1 change: 1 addition & 0 deletions demos/dialog/animated.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<script src="../../ui/jquery.ui.draggable.js"></script>
<script src="../../ui/jquery.ui.position.js"></script>
<script src="../../ui/jquery.ui.resizable.js"></script>
<script src="../../ui/jquery.ui.button.js"></script>
<script src="../../ui/jquery.ui.dialog.js"></script>
<script src="../../ui/jquery.ui.effect.js"></script>
<script src="../../ui/jquery.ui.effect-blind.js"></script>
Expand Down
1 change: 1 addition & 0 deletions demos/dialog/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<script src="../../ui/jquery.ui.draggable.js"></script>
<script src="../../ui/jquery.ui.position.js"></script>
<script src="../../ui/jquery.ui.resizable.js"></script>
<script src="../../ui/jquery.ui.button.js"></script>
<script src="../../ui/jquery.ui.dialog.js"></script>
<link rel="stylesheet" href="../demos.css">
<script>
Expand Down
1 change: 1 addition & 0 deletions demos/dialog/modal-confirmation.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<script src="../../ui/jquery.ui.button.js"></script>
<script src="../../ui/jquery.ui.draggable.js"></script>
<script src="../../ui/jquery.ui.position.js"></script>
<script src="../../ui/jquery.ui.button.js"></script>
<script src="../../ui/jquery.ui.dialog.js"></script>
<link rel="stylesheet" href="../demos.css">
<script>
Expand Down
7 changes: 4 additions & 3 deletions demos/dialog/modal-form.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<script src="../../ui/jquery.ui.draggable.js"></script>
<script src="../../ui/jquery.ui.position.js"></script>
<script src="../../ui/jquery.ui.resizable.js"></script>
<script src="../../ui/jquery.ui.button.js"></script>
<script src="../../ui/jquery.ui.dialog.js"></script>
<script src="../../ui/jquery.ui.effect.js"></script>
<link rel="stylesheet" href="../demos.css">
Expand Down Expand Up @@ -86,10 +87,10 @@

if ( bValid ) {
$( "#users tbody" ).append( "<tr>" +
"<td>" + name.val() + "</td>" +
"<td>" + email.val() + "</td>" +
"<td>" + name.val() + "</td>" +
"<td>" + email.val() + "</td>" +
"<td>" + password.val() + "</td>" +
"</tr>" );
"</tr>" );
$( this ).dialog( "close" );
}
},
Expand Down
1 change: 1 addition & 0 deletions demos/dialog/modal-message.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<script src="../../ui/jquery.ui.draggable.js"></script>
<script src="../../ui/jquery.ui.position.js"></script>
<script src="../../ui/jquery.ui.resizable.js"></script>
<script src="../../ui/jquery.ui.button.js"></script>
<script src="../../ui/jquery.ui.dialog.js"></script>
<link rel="stylesheet" href="../demos.css">
<script>
Expand Down
1 change: 1 addition & 0 deletions demos/dialog/modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<script src="../../ui/jquery.ui.draggable.js"></script>
<script src="../../ui/jquery.ui.position.js"></script>
<script src="../../ui/jquery.ui.resizable.js"></script>
<script src="../../ui/jquery.ui.button.js"></script>
<script src="../../ui/jquery.ui.dialog.js"></script>
<link rel="stylesheet" href="../demos.css">
<script>
Expand Down
2 changes: 1 addition & 1 deletion grunt.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ grunt.initConfig({
files: grunt.file.expandFiles( "tests/unit/**/*.html" ).filter(function( file ) {
// disabling everything that doesn't (quite) work with PhantomJS for now
// TODO except for all|index|test, try to include more as we go
return !( /(all|index|test|dialog|tabs|tooltip)\.html$/ ).test( file );
return !( /(all|index|test|dialog|dialog_deprecated|tabs|tooltip)\.html$/ ).test( file );
})
},
lint: {
Expand Down
1 change: 1 addition & 0 deletions tests/unit/all.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"core/core.html",
"datepicker/datepicker.html",
"dialog/dialog.html",
"dialog/dialog_deprecated.html",
"draggable/draggable.html",
"droppable/droppable.html",
"effects/effects.html",
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/dialog/dialog.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<title>jQuery UI Dialog Test Suite</title>

<script src="../../jquery.js"></script>
<script>
$.uiBackCompat = false;
</script>
<link rel="stylesheet" href="../../../external/qunit.css">
<script src="../../../external/qunit.js"></script>
<script src="../../jquery.simulate.js"></script>
Expand All @@ -19,6 +22,7 @@
"ui/jquery.ui.mouse.js",
"ui/jquery.ui.draggable.js",
"ui/jquery.ui.resizable.js",
"ui/jquery.ui.button.js",
"ui/jquery.ui.dialog.js"
]
});
Expand All @@ -44,6 +48,17 @@ <h2 id="qunit-userAgent"></h2>
<div id="qunit-fixture">
<div id="dialog1"></div>
<div id="dialog2"></div>
<div id="form-dialog" title="Profile Information">
<fieldset>
<legend>Please share some personal information</legend>
<label for="favorite-animal">Your favorite animal</label><input id="favorite-animal">
<label for="favorite-color">Your favorite color</label><input id="favorite-color">
</fieldset>
<div role="group" aria-describedby="section2">
<p id="section2">Some more (optional) information</p>
<label for="favorite-food">Favorite food</label><input id="favorite-food">
</div>
</div>
</div>
</body>
</html>
14 changes: 12 additions & 2 deletions tests/unit/dialog/dialog_common.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,20 @@ TestHelpers.commonWidgetTests( "dialog", {
},
resizable: true,
show: null,
title: '',
title: null,
width: 300,

// callbacks
create: null
beforeClose: null,
close: null,
create: null,
drag: null,
dragStart: null,
dragStop: null,
focus: null,
open: null,
resize: null,
resizeStart: null,
resizeStop: null
}
});
66 changes: 52 additions & 14 deletions tests/unit/dialog/dialog_core.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,18 @@ test("title id", function() {
el.remove();
});

test("ARIA", function() {
expect(4);
test( "ARIA", function() {
expect( 4 );

var labelledBy,
el = $('<div></div>').dialog();

equal(el.dialog('widget').attr('role'), 'dialog', 'dialog role');

labelledBy = el.dialog('widget').attr('aria-labelledby');
ok(labelledBy.length > 0, 'has aria-labelledby attribute');
equal(el.dialog('widget').find('.ui-dialog-title').attr('id'), labelledBy,
'proper aria-labelledby attribute');

equal(el.dialog('widget').find('.ui-dialog-titlebar-close').attr('role'), 'button',
'close link role');
var el = $( "<div></div>" ).dialog(),
wrapper = el.dialog( "widget" );
equal( wrapper.attr( "role" ), "dialog", "dialog role" );
equal( wrapper.attr( "aria-labelledby" ), wrapper.find( ".ui-dialog-title" ).attr( "id" ) );
equal( wrapper.attr( "aria-describedby" ), el.attr( "id" ), "aria-describedby added" );
el.remove();

el = $( '<div><div aria-describedby="section2"><p id="section2">descriotion</p></div></div>' ).dialog();
strictEqual( el.dialog( "widget" ).attr( "aria-describedby" ), undefined, "no aria-describedby added, as already present in markup" );
el.remove();
});

Expand All @@ -42,4 +38,46 @@ test("widget method", function() {
deepEqual(dialog.parent()[0], dialog.dialog("widget")[0]);
});

test( "focus tabbable", function() {
expect( 5 );
var el,
options = {
buttons: [{
text: "Ok",
click: $.noop
}]
};

el = $( "<div><input><input autofocus></div>" ).dialog( options );
equal( document.activeElement, el.find( "input" )[ 1 ], "1. first element inside the dialog matching [autofocus]" );
el.remove();

// IE8 fails to focus the input, <body> ends up being the activeElement
// so wait for that stupid browser
stop();
setTimeout(function() {
el = $( "<div><input><input></div>" ).dialog( options );
equal( document.activeElement, el.find( "input" )[ 0 ], "2. tabbable element inside the content element" );
el.remove();

el = $( "<div>text</div>" ).dialog( options );
equal( document.activeElement, el.dialog( "widget" ).find( ".ui-dialog-buttonpane button" )[ 0 ], "3. tabbable element inside the buttonpane" );
el.remove();

el = $( "<div>text</div>" ).dialog();
equal( document.activeElement, el.dialog( "widget" ).find( ".ui-dialog-titlebar .ui-dialog-titlebar-close" )[ 0 ], "4. the close button" );
el.remove();

el = $( "<div>text</div>" ).dialog({
autoOpen: false
});
el.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).hide();
el.dialog( "open" );
equal( document.activeElement, el.parent()[ 0 ], "5. the dialog itself" );
el.remove();

start();
}, 13);
});

})(jQuery);
62 changes: 62 additions & 0 deletions tests/unit/dialog/dialog_deprecated.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Dialog Test Suite</title>

<script src="../../jquery.js"></script>
<link rel="stylesheet" href="../../../external/qunit.css">
<script src="../../../external/qunit.js"></script>
<script src="../../jquery.simulate.js"></script>
<script src="../testsuite.js"></script>
<script>
TestHelpers.loadResources({
css: [ "ui.core", "ui.dialog" ],
js: [
"ui/jquery.ui.core.js",
"ui/jquery.ui.widget.js",
"ui/jquery.ui.position.js",
"ui/jquery.ui.mouse.js",
"ui/jquery.ui.draggable.js",
"ui/jquery.ui.resizable.js",
"ui/jquery.ui.button.js",
"ui/jquery.ui.dialog.js"
]
});
</script>

<script src="dialog_common.js"></script>
<script src="dialog_core.js"></script>
<script src="dialog_events.js"></script>
<script src="dialog_methods.js"></script>
<script src="dialog_options.js"></script>
<script src="dialog_test_helpers.js"></script>
<script src="dialog_tickets.js"></script>
<script src="dialog_deprecated.js"></script>

<script src="../swarminject.js"></script>
</head>
<body>

<h1 id="qunit-header">jQuery UI Dialog Test Suite</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">
<div id="dialog1"></div>
<div id="dialog2"></div>
<div id="form-dialog" title="Profile Information">
<fieldset>
<legend>Please share some personal information</legend>
<label for="favorite-animal">Your favorite animal</label><input id="favorite-animal">
<label for="favorite-color">Your favorite color</label><input id="favorite-color">
</fieldset>
<div role="group" aria-describedby="section2">
<p id="section2">Some more (optional) information</p>
<label for="favorite-food">Favorite food</label><input id="favorite-food">
</div>
</div>
</div>
</body>
</html>
53 changes: 53 additions & 0 deletions tests/unit/dialog/dialog_deprecated.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
module("dialog (deprecated): position option with string and array");

if ( !$.ui.ie ) {
test("position, right bottom on window w/array", function() {
expect( 2 );
var el = $('<div></div>').dialog({ position: ["right", "bottom"] }),
dialog = el.dialog('widget'),
offset = dialog.offset();
closeEnough(offset.left, $(window).width() - dialog.outerWidth() + $(window).scrollLeft(), 1);
closeEnough(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop(), 1);
el.remove();
});

test("position, right bottom on window", function() {
expect( 2 );
var el = $('<div></div>').dialog({ position: "right bottom" }),
dialog = el.dialog('widget'),
offset = dialog.offset();
closeEnough(offset.left, $(window).width() - dialog.outerWidth() + $(window).scrollLeft(), 1);
closeEnough(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop(), 1);
el.remove();
});
}

test("position, offset from top left w/array", function() {
expect( 2 );
var el = $('<div></div>').dialog({ position: [10, 10] }),
dialog = el.dialog('widget'),
offset = dialog.offset();
closeEnough(offset.left, 10 + $(window).scrollLeft(), 1);
closeEnough(offset.top, 10 + $(window).scrollTop(), 1);
el.remove();
});

test("position, top on window", function() {
expect( 2 );
var el = $('<div></div>').dialog({ position: "top" }),
dialog = el.dialog('widget'),
offset = dialog.offset();
closeEnough(offset.left, Math.round($(window).width() / 2 - dialog.outerWidth() / 2) + $(window).scrollLeft(), 1);
closeEnough(offset.top, $(window).scrollTop(), 1);
el.remove();
});

test("position, left on window", function() {
expect( 2 );
var el = $('<div></div>').dialog({ position: "left" }),
dialog = el.dialog('widget'),
offset = dialog.offset();
closeEnough(offset.left, 0, 1);
closeEnough(offset.top, Math.round($(window).height() / 2 - dialog.outerHeight() / 2) + $(window).scrollTop(), 1);
el.remove();
});
45 changes: 45 additions & 0 deletions tests/unit/dialog/dialog_events.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,51 @@ test("open", function() {
el.remove();
});


test( "focus", function() {
expect( 5 );
var el, other;
el = $("#dialog1").dialog({
autoOpen: false
});
other = $("#dialog2").dialog({
autoOpen: false
});

el.one( "dialogopen", function() {
ok( true, "open, just once" );
});
el.one( "dialogfocus", function() {
ok( true, "focus on open" );
});
other.dialog( "open" );

el.one( "dialogfocus", function() {
ok( true, "when opening and already open and wasn't on top" );
});
other.dialog( "open" );
el.dialog( "open" );

el.one( "dialogfocus", function() {
ok( true, "when calling moveToTop and wasn't on top" );
});
other.dialog( "moveToTop" );
el.dialog( "moveToTop" );

el.bind( "dialogfocus", function() {
ok( true, "when mousedown anywhere on the dialog and it wasn't on top" );
});
other.dialog( "moveToTop" );
el.trigger( "mousedown" );

// triggers just once when already on top
el.dialog( "open" );
el.dialog( "moveToTop" );
el.trigger( "mousedown" );

el.add( other ).remove();
});

test("dragStart", function() {
expect(9);

Expand Down
Loading