From 1b19121189356879ca39a19ba241a04ff4786b62 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 14 May 2012 21:38:30 -0400 Subject: Autocomplete combobox demo: Add combobox-specific classes for styling. Fixes #8322 - Autocomplete: Combobox demo should not override .ui-button styles. --- demos/autocomplete/combobox.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'demos') diff --git a/demos/autocomplete/combobox.html b/demos/autocomplete/combobox.html index e2ef40dd9..051d55e45 100644 --- a/demos/autocomplete/combobox.html +++ b/demos/autocomplete/combobox.html @@ -18,7 +18,7 @@ position: relative; display: inline-block; } - .ui-button { + .ui-combobox-toggle { position: absolute; top: 0; bottom: 0; @@ -28,7 +28,7 @@ *height: 1.7em; *top: 0.1em; } - .ui-autocomplete-input { + .ui-combobox-input { margin: 0; padding: 0.3em; } @@ -75,7 +75,7 @@ .appendTo( wrapper ) .val( value ) .attr( "title", "" ) - .addClass( "ui-state-default" ) + .addClass( "ui-state-default ui-combobox-input" ) .autocomplete({ delay: 0, minLength: 0, @@ -128,7 +128,7 @@ text: false }) .removeClass( "ui-corner-all" ) - .addClass( "ui-corner-right ui-button-icon" ) + .addClass( "ui-corner-right ui-combobox-toggle" ) .click(function() { // close if already visible if ( input.autocomplete( "widget" ).is( ":visible" ) ) { -- cgit v1.2.3 From f4b2d7a4115814b64ff291e3518fe15f2dfbe390 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Tue, 15 May 2012 14:07:35 +0200 Subject: Autocomplete: ARIA live region as extension, adding a messages option. Fixes #7840 - Autocomplete: popup results not read by screen-readers --- demos/autocomplete/multiple-remote.html | 3 +- demos/autocomplete/multiple.html | 5 +-- tests/unit/autocomplete/autocomplete_common.js | 4 +++ tests/unit/menu/menu_common.js | 1 + ui/jquery.ui.autocomplete.js | 48 +++++++++++++++++++++----- ui/jquery.ui.menu.js | 26 +++++++++----- 6 files changed, 68 insertions(+), 19 deletions(-) (limited to 'demos') diff --git a/demos/autocomplete/multiple-remote.html b/demos/autocomplete/multiple-remote.html index 378e449d5..00d739967 100644 --- a/demos/autocomplete/multiple-remote.html +++ b/demos/autocomplete/multiple-remote.html @@ -47,7 +47,8 @@ } }, focus: function() { - // prevent value inserted on focus + // prevent value inserted on focus, update liveRegion instead + $( this ).data( "autocomplete" ).liveRegion.text( ui.item.label ); return false; }, select: function( event, ui ) { diff --git a/demos/autocomplete/multiple.html b/demos/autocomplete/multiple.html index e3f84b65d..3d1326591 100644 --- a/demos/autocomplete/multiple.html +++ b/demos/autocomplete/multiple.html @@ -59,8 +59,9 @@ response( $.ui.autocomplete.filter( availableTags, extractLast( request.term ) ) ); }, - focus: function() { - // prevent value inserted on focus + focus: function( event, ui ) { + // prevent value inserted on focus, update liveRegion instead + $( this ).data( "autocomplete" ).liveRegion.text( ui.item.label ); return false; }, select: function( event, ui ) { diff --git a/tests/unit/autocomplete/autocomplete_common.js b/tests/unit/autocomplete/autocomplete_common.js index c090ce4df..e1d24ef8d 100644 --- a/tests/unit/autocomplete/autocomplete_common.js +++ b/tests/unit/autocomplete/autocomplete_common.js @@ -4,6 +4,10 @@ TestHelpers.commonWidgetTests( "autocomplete", { autoFocus: false, delay: 300, disabled: false, + messages: { + noResults: "No search results.", + results: $.ui.autocomplete.prototype.options.messages.results + }, minLength: 1, position: { my: "left top", diff --git a/tests/unit/menu/menu_common.js b/tests/unit/menu/menu_common.js index ddcdbebf2..07295f1af 100644 --- a/tests/unit/menu/menu_common.js +++ b/tests/unit/menu/menu_common.js @@ -6,6 +6,7 @@ TestHelpers.commonWidgetTests( "menu", { my: "left top", at: "right top" }, + role: "menu", // callbacks blur: null, diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index fab9691a3..fa15bc278 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -60,13 +60,7 @@ $.widget( "ui.autocomplete", { this.element .addClass( "ui-autocomplete-input" ) - .attr( "autocomplete", "off" ) - // TODO verify these actually work as intended - .attr({ - role: "textbox", - "aria-autocomplete": "list", - "aria-haspopup": "true" - }); + .attr( "autocomplete", "off" ); this._bind({ keydown: function( event ) { @@ -188,7 +182,9 @@ $.widget( "ui.autocomplete", { .appendTo( this.document.find( this.options.appendTo || "body" )[0] ) .menu({ // custom key handling for now - input: $() + input: $(), + // disable ARIA support, the live region takes care of that + role: null }) .zIndex( this.element.zIndex() + 1 ) .hide() @@ -532,4 +528,40 @@ $.extend( $.ui.autocomplete, { } }); + +// live region extension, adding a `messages` option +$.widget( "ui.autocomplete", $.ui.autocomplete, { + options: { + messages: { + noResults: "No search results.", + results: function(amount) { + return amount + ( amount > 1 ? " results are" : " result is" ) + " available, use up and down arrow keys to navigate."; + } + } + }, + _create: function() { + this._super(); + this.liveRegion = $( "", { + role: "status", + "aria-live": "polite" + }) + .addClass( "ui-helper-hidden-accessible" ) + .insertAfter( this.element ); + }, + __response: function( content ) { + var message; + this._superApply( arguments ); + if ( this.options.disabled || this.cancelSearch) { + return; + } + if ( content && content.length ) { + message = this.options.messages.results( content.length ); + } else { + message = this.options.messages.noResults; + } + this.liveRegion.text( message ); + } +}); + + }( jQuery )); diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 7704521fb..36f7e1de4 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -26,6 +26,7 @@ $.widget( "ui.menu", { my: "left top", at: "right top" }, + role: "menu", // callbacks blur: null, @@ -42,7 +43,7 @@ $.widget( "ui.menu", { .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) .attr({ id: this.menuId, - role: "menu", + role: this.options.role, tabIndex: 0 }) // need to catch all clicks on disabled menu @@ -267,7 +268,7 @@ $.widget( "ui.menu", { .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) .hide() .attr({ - role: "menu", + role: this.options.role, "aria-hidden": "true", "aria-expanded": "false" }); @@ -281,7 +282,7 @@ $.widget( "ui.menu", { .children( "a" ) .addClass( "ui-corner-all" ) .attr( "tabIndex", -1 ) - .attr( "role", "menuitem" ) + .attr( "role", this._itemRole() ) .attr( "id", function( i ) { return menuId + "-" + i; }); @@ -302,8 +303,15 @@ $.widget( "ui.menu", { }); }, + _itemRole: function() { + return { + menu: "menuitem", + listbox: "option" + }[ this.options.role ]; + }, + focus: function( event, item ) { - var nested, borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; + var nested, borderTop, paddingTop, offset, scroll, elementHeight, itemHeight, focused; this.blur( event, event && event.type === "focus" ); if ( this._hasScroll() ) { @@ -322,10 +330,12 @@ $.widget( "ui.menu", { } this.active = item.first(); - this.element.attr( "aria-activedescendant", - this.active.children( "a" ) - .addClass( "ui-state-focus" ) - .attr( "id" ) ); + focused = this.active.children( "a" ).addClass( "ui-state-focus" ); + // only update aria-activedescendant if there's a role + // otherwise we assume focus is managed elsewhere + if ( this.options.role ) { + this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); + } // highlight active parent menu item, if any this.active.parent().closest( ".ui-menu-item" ).children( "a:first" ).addClass( "ui-state-active" ); -- cgit v1.2.3 From 85639bf0fa39427d8de1dc60131f746045ba4ddc Mon Sep 17 00:00:00 2001 From: Scott González Date: Wed, 16 May 2012 09:43:49 -0400 Subject: Autocomplete: Update live region if focus event is canceled. Remove live region on destroy. --- demos/autocomplete/multiple-remote.html | 3 +-- demos/autocomplete/multiple.html | 5 ++--- ui/jquery.ui.autocomplete.js | 30 ++++++++++++++++++++---------- 3 files changed, 23 insertions(+), 15 deletions(-) (limited to 'demos') diff --git a/demos/autocomplete/multiple-remote.html b/demos/autocomplete/multiple-remote.html index 00d739967..378e449d5 100644 --- a/demos/autocomplete/multiple-remote.html +++ b/demos/autocomplete/multiple-remote.html @@ -47,8 +47,7 @@ } }, focus: function() { - // prevent value inserted on focus, update liveRegion instead - $( this ).data( "autocomplete" ).liveRegion.text( ui.item.label ); + // prevent value inserted on focus return false; }, select: function( event, ui ) { diff --git a/demos/autocomplete/multiple.html b/demos/autocomplete/multiple.html index 3d1326591..e3f84b65d 100644 --- a/demos/autocomplete/multiple.html +++ b/demos/autocomplete/multiple.html @@ -59,9 +59,8 @@ response( $.ui.autocomplete.filter( availableTags, extractLast( request.term ) ) ); }, - focus: function( event, ui ) { - // prevent value inserted on focus, update liveRegion instead - $( this ).data( "autocomplete" ).liveRegion.text( ui.item.label ); + focus: function() { + // prevent value inserted on focus return false; }, select: function( event, ui ) { diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index fa15bc278..1fc01d7a4 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -228,6 +228,13 @@ $.widget( "ui.autocomplete", { if ( /^key/.test(event.originalEvent.type) ) { this._value( item.value ); } + } else { + // Normally the input is populated with the item's value as the + // menu is navigated, causing screen readers to notice a change and + // announce the item. Since the focus event was canceled, this doesn't + // happen, so we update the live region so that screen readers can + // still notice the change and announce it. + this.liveRegion.text( item.value ); } }, menuselect: function( event, ui ) { @@ -261,6 +268,13 @@ $.widget( "ui.autocomplete", { } }); + this.liveRegion = $( "", { + role: "status", + "aria-live": "polite" + }) + .addClass( "ui-helper-hidden-accessible" ) + .insertAfter( this.element ); + if ( $.fn.bgiframe ) { this.menu.element.bgiframe(); } @@ -284,6 +298,7 @@ $.widget( "ui.autocomplete", { .removeAttr( "aria-autocomplete" ) .removeAttr( "aria-haspopup" ); this.menu.element.remove(); + this.liveRegion.remove(); }, _setOption: function( key, value ) { @@ -530,24 +545,19 @@ $.extend( $.ui.autocomplete, { // live region extension, adding a `messages` option +// NOTE: This is an experimental API. We are still investigating +// a full solution for string manipulation and internationalization. $.widget( "ui.autocomplete", $.ui.autocomplete, { options: { messages: { noResults: "No search results.", results: function(amount) { - return amount + ( amount > 1 ? " results are" : " result is" ) + " available, use up and down arrow keys to navigate."; + return amount + ( amount > 1 ? " results are" : " result is" ) + + " available, use up and down arrow keys to navigate."; } } }, - _create: function() { - this._super(); - this.liveRegion = $( "", { - role: "status", - "aria-live": "polite" - }) - .addClass( "ui-helper-hidden-accessible" ) - .insertAfter( this.element ); - }, + __response: function( content ) { var message; this._superApply( arguments ); -- cgit v1.2.3 From 3ccf86cffb61b83a5f9917053b720ecb6e3b51e7 Mon Sep 17 00:00:00 2001 From: Scott González Date: Fri, 18 May 2012 16:18:46 -0400 Subject: Tabs manipulation demo: Update for aria-controls. --- demos/tabs/manipulation.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'demos') diff --git a/demos/tabs/manipulation.html b/demos/tabs/manipulation.html index 205fc2e4d..085d42c43 100644 --- a/demos/tabs/manipulation.html +++ b/demos/tabs/manipulation.html @@ -76,8 +76,8 @@ // close icon: removing the tab on click $( "#tabs span.ui-icon-close" ).live( "click", function() { - $( this ).closest( "li" ).remove(); - $( "#" + $( this ).prev().attr( "aria-controls" ) ).remove(); + var panelId = $( this ).closest( "li" ).remove().attr( "aria-controls" ); + $( "#" + panelId ).remove(); tabs.tabs( "refresh" ); }); }); -- cgit v1.2.3 From 33a91fb19e19e238a4f841908f2a0c8d56fa2162 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 21 May 2012 10:02:57 -0400 Subject: Spinner demo: Don't use .toggle(fn). --- demos/spinner/default.html | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'demos') diff --git a/demos/spinner/default.html b/demos/spinner/default.html index 03ae2ad7d..1827724b9 100644 --- a/demos/spinner/default.html +++ b/demos/spinner/default.html @@ -14,16 +14,20 @@ -- cgit v1.2.3 From 1da4d7e18d9a4393ab49b3e603278247af614a2b Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 21 May 2012 10:06:46 -0400 Subject: Animate demo: Don't use .toggle(fn). --- demos/animate/default.html | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'demos') diff --git a/demos/animate/default.html b/demos/animate/default.html index 4fec428e7..307d030a6 100644 --- a/demos/animate/default.html +++ b/demos/animate/default.html @@ -15,22 +15,23 @@ -- cgit v1.2.3 From fb91d90058175d6b38622393283603737b86e849 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 21 May 2012 10:08:28 -0400 Subject: Effects toggle demo: Coding standards. --- demos/toggle/default.html | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'demos') diff --git a/demos/toggle/default.html b/demos/toggle/default.html index 469674b70..5dcd5eff8 100644 --- a/demos/toggle/default.html +++ b/demos/toggle/default.html @@ -1,4 +1,4 @@ - + @@ -19,18 +19,33 @@ @@ -22,7 +22,7 @@ - + An anchor diff --git a/ui/jquery.ui.button.js b/ui/jquery.ui.button.js index f3abdaf76..0feb1e893 100644 --- a/ui/jquery.ui.button.js +++ b/ui/jquery.ui.button.js @@ -357,7 +357,7 @@ $.widget( "ui.button", { $.widget( "ui.buttonset", { version: "@VERSION", options: { - items: "button, [type=button], :submit, [type=reset], [type=checkbox], [type=radio], a, :data(button)" + items: "button, [type=button], [type=submit], [type=reset], [type=checkbox], [type=radio], a, :data(button)" }, _create: function() { -- cgit v1.2.3 From cb70a5e302aae16fa4b47454c1d7d5aca514bfb7 Mon Sep 17 00:00:00 2001 From: Scott González Date: Tue, 22 May 2012 12:46:00 -0400 Subject: Progressbar demo: Made animated background selector more specific. Fixes #8314 - Theme on animated progressbar remains the same. --- demos/progressbar/animated.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'demos') diff --git a/demos/progressbar/animated.html b/demos/progressbar/animated.html index c8f5ff551..6134a8ca7 100644 --- a/demos/progressbar/animated.html +++ b/demos/progressbar/animated.html @@ -10,7 +10,7 @@