-
Notifications
You must be signed in to change notification settings - Fork 19
0.3.1 to 1.0.0 Migration Guide
Work In Progress
The 1.0.0 release of CAM finished adding support for all ARIA roles. It also brought in some bug fixes and improvements, some of which are breaking changes that lead to multiple 1.0 pre-release versions of CAM before the 1.0.0 version was released. The purpose of this page is to document the breaking changes and how to address them in consuming projects. This page organizes the breaking changes by category, but all need to be addressed as part of the upgrade to the 1.0.0 version of CAM.
-
ROLES.OPTIONhas been split intoROLES.SINGLESELECTOPTIONandROLES.MULTISELECTOPTION. This was needed in order to support gettingROLES.SINGLESELECTLISTBOXworking visually consistent across browsers combined with CAM's one-to-one role to HTML tag mapping.- If an option is being added to a
ROLES.SINGLESELECTLISTBOX, then replaceROLES.OPTIONwithROLES.SINGLESELECTOPTION. - For options added to
ROLES.MULTISELECTLISTBOX, then replaceROLES.OPTIONwithROLES.MULTISELECTOPTION.
- If an option is being added to a
- If event listeners are bound after the
registerfunction is called, such as byaddEventListeneroron, then no changes are needed. - In the 0.x versions of CAM, the object passed to
registercould containonFocusandonKeyboardClickcallbacks for handling those particular events. In order to handle any event, those fields have been replaced by aneventsarray of objects that allows for binding an event handler for any event. The objects that make up this array have a field ofeventNamefor the string name of the particular event to bind for, and alistenerfield for specifying the event handler function. A sample of this way of binding event listeners can be seen in the test app at https://github.com/CurriculumAssociates/createjs-accessibility-tester/blob/290d6ab51c49381345b3b831c37c4f5c7ef48c89/src/widgets/ScrollBar.js#L29-L38.- For prior
onFocusandonKeyboardClickfields, for example:onFocus: _focusHandler, onKeyboardClick: _keyboardClickHandler, - Becomes:
events: [ { eventName: 'focus', listener: _focusHandler }, { eventName: 'keyboardClick', listener: _keyboardClickHandler } ],
- For prior
-
ROLES.ROWused to emit akeyboardClickevent when used inside aROLES.TREEGRIDto indicate that a row should expand or collapse. That has been replaced byROLES.TREEGRIDemittingcollapseRoworexpandRowevents. To handle this, thekeyboardClickevent listener on the row DisplayObject should be removed, and event listeners added to the tree grid DisplayObject for the collapse and expand row events.
Due to trying using semantic markup as much as possible, most keyboard behavior is actually the browser's default behavior for that element. But there are cases where CAM needs to add a keydown listener in order to follow WAI-ARIA Practices (https://www.w3.org/TR/wai-aria-practices-1.1/). Since CAM can emit keydown events once .accessible.enableKeyEvents on a registered DisplayObject is set to true, the intent is to allow for calling preventDefault on the event object passed to those listeners to prevent both default browser behavior and CAM's internal keydown listeners from providing their default behavior, in order to allow consuming projects to customize the behavior completely as needed. In 0.x not all keyboard listeners followed this pattern (some would, others would turn off the CAM keydown listener just by setting .accessible.enableKeyEvents to true). So, consuming projects should ensure that they are calling preventDefault in their keydown listeners when they want to disable default keyboard behavior as provided either by the browser or CAM.
CAM tries to help ensure its translation of DisplayObjects to HTML produces valid a HTML structure by performing checks when adding a DisplayObject to the accessibility tree. It does this in the addChild and addChildAt functions of the AccessibilityObject and its subclasses by checking if the role and any other relevant properties of the DisplayObject trying to be added are valid given the this instance's role. However, in 0.x not all roles performed this check leading to it being overly lenient and allowing for invalid DOM structures. An audit and update of all roles was done for 1.0 and the added missing restrictions are:
-
ROLES.BUTTONonly allows for interactive elements (either semantically or with a tabIndex set) to be added as children. This still allows for non-interactive children, such as a button wrapping an image. -
ROLES.CHECKBOX,ROLES.IMG,ROLES.RADIO,ROLES.SINGLELINETEXTBOX,ROLES.SEPARATOR,ROLES.SLIDER, andROLES.SPINBUTTONcannot have children. -
ROLES.ORDEREDLISTandROLES.UNORDEREDLISTcan only haveROLES.LISTITEMas children. -
ROLES.ROWcan only haveROLES.CELL,ROLES.GRIDCELL,ROLES.COLUMNHEADER, andROLES.ROWHEADERas children. -
ROLES.TABLEBODY,ROLES.TABLEFOOT, andROLES.TABLEHEADcan only haveROLES.ROWas children. -
ROLES.TREEcan only haveROLES.TREEITEMas children.
- The
hasPopUpgetter/setter of AccessibilityObject (the base class used to populate a registered DisplayObject's.accessiblefield) has been updated from a boolean to a string in order to allow for all the valid values that https://www.w3.org/TR/wai-aria-1.1/#aria-haspopup specifies- For existing
trueorfalseparameter values, add quotes around the value or use another mechanism to convert it to a string - For existing undefined parameter values, no change needs to be made
- For existing
This module uses camelCase for the various getters/setters available off of a registered DisplayObject's .accessible field. However, in 0.x, not all getters/setters followed this convention which has been corrected as part of the 1.0 release. The table below shows the change in name between 0.x and 1.0, where consuming projects should be updated to the 1.0 names. Since these getters/setters are defined by AccessibilityObject or its subclasses, some roles may already be using the camelCase in 0.x, but for simplicity the table below doesn't break out the 0.x to 1.0 changes by role; the 1.0 name should now work with all roles that support that getter/setter.
| 0.x Name | 1.0 Name |
|---|---|
| autocomplete | autoComplete |
| autofocus | autoFocus |
| colcount | colCount |
| colindex | colIndex |
| colspan | colSpan |
| crossorigin | crossOrigin |
| hreflang | hrefLang |
| ismap | isMap |
| longdesc | lonDesc |
| rowcount | rowCount |
| rowindex | rowIndex |
| rowspan | rowSpan |
| srcset | srcSet |
| usemap | useMap |
| valuetext | valueText |
On AccessibilityObject there used to be a getter named reactProps. While the comment did list its access level as package, due to the lack of a _ some consuming projects thought it was a public property and would directly modify its contents. Since that object and its fields are an internal implementation detail of this module, it should not be accessed or modified by consuming projects. To help make this clear when not looking at the documentation comment, the getter has been removed. Consuming projects should use the public getters/setters of a registered DisplayObject's .accessible field. If there is not one available for the corresponding HTML attribute, then a PR or issue should be opened so adding support for that can be discussed and potentially added.