I'm using Ext 2.2.1 and need an ARIA-enabled Ext.form.ComboBox. Where I primarily see the current ComboBox fall short of meeting the ARIA requirements is that it doesn't read the contents of the list items when using screen readers, such as JAWS. I am not an ARIA expert (been looking at it for about a day now), but I took a shot at enabling this. Let me know if you have any comments or better ideas on implementing this.

First, I started with the ARIA class that you can find in the Ext examples:

Code:
Ext.namespace('Ext.a11y');
Ext.a11y.ARIA = Ext.apply(new Ext.util.Observable(), function() {
    return {
        setRole : function(el, role) {
            el = Ext.getDom(el);
            if(el) {
                el.setAttribute('role', role.toString());
            }
        },
        
        setProperty : function(el, key, value) {
            el = Ext.getDom(el);
            if(el) {
                el.setAttribute(key.toString(), value.toString());
            }                
        }
    }
}());

var ARIA = Ext.a11y.ARIA;
Then I augmented ComboBox as follows:

Code:
/*
 * Adds accessibility to the Ext.form.ComboBox by adding ARIA tags.
 * The wrapper around the input field is used as the main 'combobox' widget.
 * The following was copied from the "WAI-ARIA Best Practices" at: 
 *    http://www.w3.org/TR/wai-aria-practices/#combobox
 * The items in the list have been numbered by me and will be used in the code
 * below to reference the item being addressed.
 * 
 *    ---- Copied from "WAI-ARIA Best Practices" -----------------
 *    A combo box is a combination of text field, which may be editable, a drop
 *    button to choose an item to place in the combo box, and a displayable list
 *    of items all wrapped in the form of a single widget. Like text fields a
 *    combobox should be labeled to determine the essence of the widget. Keyboard
 *    focus within the widget must be managed by the widget. Comboboxes are used
 *    extensively in graphical user interfaces and the design pattern for the widget
 *    should be semantically correct.
 *      1. The container element that wraps the combobox must have a role
 *         of "combobox."
 *      2. The first element within the combobox should be an input text field and
 *         is responsible for managing the keyboard focus between the textfield and
 *         the list as well as displaying the list. The textfield should be in the
 *         tab order. If create a textfield without using a standard HTML textfield
 *         form control then you must ensure that it is in the tab order.
 *      3. If the textfield is not editable it must have have aria-readonly="true."
 *      4. The next element should be an html <button> or another html element with
 *         a role of "button".  This button should be in the tab order and be
 *         responsible for opening the list.
 *      5. The next element constitute with a role="list" representing the drop down
 *         list and it should managed the keyboard navigation between each list item
 *         and back to the textfield if necessary.
 *      6. Each item in the list should have a role="listitem". Listitems should not
 *         be in the tab order.
 *      7. You should provide a label which labels the combobox by referencing the
 *         textfield in the combobox. You can use an aria-label to associate this
 *         label with the combobox or you may use the HTML <label> element and its
 *         for attribute to reference the textfield.
 *    ---- End copy ----------------------------------------------
 *    
 *    Note that item #7 is not being addressed at this time.  In my implementation,
 *    the label was attached to the input field via a "for" on the label.
 */
Ext.override(Ext.form.ComboBox, {

	onRender: Ext.form.ComboBox.prototype.onRender.createSequence(function() {

		// marks the input field as the combobox, see item #1 above
		ARIA.setRole(this.wrap, 'combobox');

		// adding 'textfield' is not technically necessary since "this.el" is an input
		// field as described in item #2 above
		ARIA.setRole(this.el, 'textfield');
		
		// mark as readonly if not editable, see item #3 above
		if (!this.editable)
			ARIA.setProperty(this.el, 'aria-readonly', 'true');
		
		// add role of 'button' to the trigger, see item #4 above.
		// NOTE that I did not add the button to the tab order which is a violation of item #4.
		// To do so would require additional coding to allow keyboard selection of the button.
		ARIA.setProperty(this.trigger, 'role', 'button');
		//ARIA.setProperty(this.trigger, 'tabIndex', '0'); // future?

		this.on({
			// when the list is collapsed, clear aria-activedescendant so that the input field
			// becomes the active element again
			collapse:function() { ARIA.setProperty(this.el, 'aria-activedescendant', '');},
			scope:this
		});
	}),

	initList: Ext.form.ComboBox.prototype.initList.createSequence(function() {

		// The drop down list is marked up the first time the list is activated
		if (!this.ariaInit) {
			
			// The 'innerList' is marked as an ARIA 'list' and the input field
			// is marked as the owner of this list.  See item #5 above.
			ARIA.setProperty(this.innerList, 'role', 'list');
			
			// Since the list is not a direct descendant of the combobox, the
			// 'aria-owns' must be set.
			ARIA.setProperty(this.el, 'aria-owns', this.innerList.id);

			// Each element in the list is marked as an ARIA 'listitem'.
			// See item #6 above.
			this.innerList.select('div').each(function(el){
				ARIA.setProperty(el, 'role', 'listitem');
			});
			
			// When the user changes the selection, the selected object is identified
			// as the active descendant for this ComboBox widget.
			this.view.on('selectionchange', function(view,selectionsArray) {
				if (selectionsArray&&selectionsArray.length>0) {
					ARIA.setProperty(this.el, 'aria-activedescendant', Ext.get(selectionsArray[0]).id);
				}
			}, this);
			
			this.ariaInit=true;
		}
	})    
});
I tested this using Firefox and JAWS 10 and pretty much got the behavior I was going for.