// Copyright 2007. Adobe Systems Incorporated. All Rights Reserved. package fl.accessibility { import flash.accessibility.Accessibility; import flash.events.Event; import fl.controls.ComboBox; import fl.core.UIComponent; /** * The ComboBoxAccImpl class, also called the ComboBox Accessibility Implementation class, * is used to make a ComboBox component accessible. * *

The ComboBoxAccImpl class supports system roles, object-based events, and states.

* *

A ComboBox reports the role ROLE_SYSTEM_COMBOBOX (0x2E) to a screen * reader. Items of a ComboBox report the role ROLE_SYSTEM_LISTITEM (0x22).

* *

A ComboBox reports the following states to a screen reader:

* * *

Additionally, items of a ComboBox report the following states:

* * *

A ComboBox dispatches the following events to a screen reader:

* * * @see fl.controls.ComboBox ComboBox * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public class ComboBoxAccImpl extends AccImpl { //-------------------------------------------------------------------------- // Class initialization //-------------------------------------------------------------------------- /** * @private * Static variable triggering the hookAccessibility() method. * This is used for initializing ComboBoxAccImpl class to hook its * createAccessibilityImplementation() method to ComboBox class * before it gets called from UIComponent. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ private static var accessibilityHooked:Boolean = hookAccessibility(); /** * @private * Static method for swapping the createAccessibilityImplementation() * method of ComboBox with the ComboBoxAccImpl class. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ private static function hookAccessibility():Boolean { ComboBox.createAccessibilityImplementation = createAccessibilityImplementation; return true; } //-------------------------------------------------------------------------- // Class constants //-------------------------------------------------------------------------- /** * @private * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ private static const ROLE_SYSTEM_LISTITEM:uint = 0x22; /** * @private * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ private static const STATE_SYSTEM_FOCUSED:uint = 0x00000004; /** * @private * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ private static const STATE_SYSTEM_SELECTABLE:uint = 0x00200000; /** * @private * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ private static const STATE_SYSTEM_SELECTED:uint = 0x00000002; /** * @private * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ private static const EVENT_OBJECT_VALUECHANGE:uint = 0x800E; /** * @private * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ private static const EVENT_OBJECT_SELECTION:uint = 0x8006; //-------------------------------------------------------------------------- // Class methods //-------------------------------------------------------------------------- /** * @private * * Method for creating the Accessibility class. * This method is called from UIComponent. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public static function createAccessibilityImplementation(component:UIComponent):void { component.accessibilityImplementation = new ComboBoxAccImpl(component); } /** * Enables accessibility for a ComboBox component. * This method is required for the compiler to activate * the accessibility classes for a component. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public static function enableAccessibility():void { ListAccImpl.enableAccessibility(); } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** * @private * @internal Nivesh says: I don't think we should document the constructors * for the accessibility classes. End-users just have to call the * static enableAccessibility method. They don't really create an * instance of the classes. * * Creates a new ComboBox Accessibility Implementation. * * @param master The UIComponent instance that this AccImpl instance * is making accessible. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function ComboBoxAccImpl(master:UIComponent) { super(master); role = 0x2E; } //-------------------------------------------------------------------------- // Overridden properties: AccImpl //-------------------------------------------------------------------------- /** * @private * Array of events that we should listen for from the master component. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override protected function get eventsToHandle():Array { return super.eventsToHandle.concat([ "change", "valueCommit" ]); } //-------------------------------------------------------------------------- // Overridden methods: AccessibilityImplementation //-------------------------------------------------------------------------- /** * @private * Gets the role for the component. * * @param childID uint * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override public function get_accRole(childID:uint):uint { if (childID == 0) { return role; } return ROLE_SYSTEM_LISTITEM; } /** * @private * IAccessible method for returning the value of the ComboBox * (which would be the text of the item selected). * The ComboBox should return the content of the TextField as the value. * * @param childID uint * * @return Value string * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override public function get_accValue(childID:uint):String { if (childID == 0) { return ComboBox(master).text; } return null; } /** * @private * IAccessible method for returning the state of the ListItem * (basically to remove 'not selected'). * States are predefined for all the components in MSAA. * Values are assigned to each state. * Depending upon the listItem being Selected, Selectable, * Invisible, Offscreen, a value is returned. * * @param childID * * @return * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override public function get_accState(childID:uint):uint { var accState:uint = getState(childID); if (childID > 0) { accState |= STATE_SYSTEM_SELECTABLE; if (ComboBox(master).selectedIndex == childID - 1) { accState |= STATE_SYSTEM_SELECTED | STATE_SYSTEM_FOCUSED; } } return accState; } /** * @private * Method to return an array of childIDs. * * @return * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override public function getChildIDArray():Array { var childIDs:Array = []; if (ComboBox(master).dataProvider) { var n:int = ComboBox(master).dataProvider.length; for (var i:int = 0; i < n; i++) { childIDs[i] = i + 1; } } return childIDs; } //-------------------------------------------------------------------------- // Overridden methods: AccImpl //-------------------------------------------------------------------------- /** * @private * Method for returning the name of the ComboBox * For children items, it would add m of n string to the name. * ComboBox should return the name specified in the AccessibilityProperties. * * @param childID * * @return * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override protected function getName(childID:uint):String { var comboBox:ComboBox = ComboBox(master); if (childID == 0 || !comboBox.dataProvider) { return ""; } var mofn:String = " " + childID + " of " + comboBox.dataProvider.length; var item:Object = comboBox.getItemAt(childID - 1); return comboBox.itemToLabel(item) + mofn; } //-------------------------------------------------------------------------- // Overridden event handlers: AccImpl //-------------------------------------------------------------------------- /** * @private * Override the generic event handler. * All AccImpl must implement this to listen for events * from its master component. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override protected function eventHandler(event:Event):void { switch (event.type) { case "change": var index:int = ComboBox(master).selectedIndex; if (index >= 0) { if(Accessibility.active) { var childID:uint = index + 1; Accessibility.sendEvent(master, childID, EVENT_OBJECT_SELECTION); Accessibility.sendEvent(master, 0, EVENT_OBJECT_VALUECHANGE); } } break; case "valueCommit": if(Accessibility.active) { Accessibility.sendEvent(master, 0, EVENT_OBJECT_VALUECHANGE); } break; } } } }