PDOMPeer¶
Overview¶
An accessible peer controls the appearance of an accessible Node's instance in the parallel DOM. A PDOMPeer can have up to four self.Elements displayed in the PDOM, see ftructor for details.
@author Jonathan Olson <jonathan.olson@colorado.edu> @author Jesse Greenberg
Class PDOMPeer¶
Constructor¶
new PDOMPeer( pdomInstance, options )¶
Instance Methods¶
initializePDOMPeer( pdomInstance, options )¶
Initializes the object (either from a freshly-created state, or from a "disposed" state brought back from a pool).
NOTE: the PDOMPeer is not fully constructed until calling PDOMPeer.update() after creating from pool. @private
@param {PDOMInstance} pdomInstance @param {Object} [options] @returns {PDOMPeer} - Returns 'this' reference, for chaining
orderElements( config )¶
Handle the internal ordering of the elements in the peer, this involves setting the proper value of this.topLevelElements @param {Object} config - the computed mixin options to be applied to the peer. (select ParallelDOM mutator keys) @private
getPrimarySibling()¶
Get the primary sibling element for the peer @public @returns {HTMLElement|null}
getLabelSibling()¶
Get the primary sibling element for the peer @public @returns {HTMLElement|null}
getDescriptionSibling()¶
Get the primary sibling element for the peer @public @returns {HTMLElement|null}
getContainerParent()¶
Get the primary sibling element for the peer @public @returns {HTMLElement|null}
getTopLevelElementContainingPrimarySibling()¶
Returns the top-level element that contains the primary sibling. If there is no container parent, then the primary sibling is returned. @public
@returns {HTMLElement|null}
onAriaLabelledbyAssociationChange()¶
Recompute the aria-labelledby attributes for all of the peer's elements @public
onAriaDescribedbyAssociationChange()¶
Recompute the aria-describedby attributes for all of the peer's elements @public
onActiveDescendantAssociationChange()¶
Recompute the aria-activedescendant attributes for all of the peer's elements @public
handleAttributeWithPDOMOption( key, value )¶
Set the new attribute to the element if the value is a string. It will otherwise be null or undefined and should then be removed from the element. This allows empty strings to be set as values.
@param {string} key @param {string|null|undefined} value @private
onAttributeChange( pdomOptions )¶
Set all pdom attributes onto the peer elements from the model's stored data objects @private
@param {Object} [pdomOptions] - these can override the values of the node, see this.update()
onClassChange()¶
Set all classes onto the peer elements from the model's stored data objects @private
setClassToElement( className, options )¶
Add the provided className to the element's classList.
@public @param {string} className @param {Object} [options]
removeClassFromElement( className, options )¶
Remove the specified className from the element. @public
@param {string} className @param {Object} [options]
arrangeContentElement( contentElement, appendElement )¶
The contentElement will either be a label or description element. The contentElement will be sorted relative to the primarySibling. Its placement will also depend on whether or not this node wants to append this element, see setAppendLabel() and setAppendDescription(). By default, the "content" element will be placed before the primarySibling.
NOTE: This function assumes it is called on label sibling before description sibling for inserting elements into the correct order.
@param {HTMLElement} contentElement @param {boolean} appendElement
isVisible()¶
Is this peer hidden in the PDOM @public
@returns {boolean}
setVisible( visible )¶
Set whether or not the peer is visible in the PDOM @public
@param {boolean} visible
setFocusable( focusable )¶
Make the peer focusable. Only the primary sibling is ever considered focusable. @public @param {boolean} focusable
setPDOMTransformSourceNode( node )¶
Sets the pdomTransformSourceNode so that the primary sibling will be transformed with changes to along the unique trail to the source node. If null, repositioning happens with transform changes along this pdomInstance's trail. @public
@param {../nodes/Node|null} node
getElementId( siblingName, stringId )¶
updateIndicesStringAndElementIds()¶
invalidateCSSPositioning( forceReflowWorkaround )¶
Mark that the siblings of this PDOMPeer need to be updated in the next Display update. Possibly from a change of accessible content or node transformation. Does nothing if already marked dirty.
@param [forceReflowWorkaround] - In addition to repositioning, force a reflow next animation frame? See this.forceReflowWorkaround for more information. @private
positionElements( positionInPDOM )¶
Update the CSS positioning of the primary and label siblings. Required to support accessibility on mobile devices. On activation of focusable elements, certain AT will send fake pointer events to the browser at the center of the client bounding rectangle of the HTML element. By positioning elements over graphical display objects we can capture those events. A transformation matrix is calculated that will transform the position and dimension of the HTML element in pixels to the global coordinate frame. The matrix is used to transform the bounds of the element prior to any other transformation so we can set the element's left, top, width, and height with CSS attributes.
For now we are only transforming the primary and label siblings if the primary sibling is focusable. If focusable, the primary sibling needs to be transformed to receive user input. VoiceOver includes the label bounds in its calculation for where to send the events, so it needs to be transformed as well. Descriptions are not considered and do not need to be positioned.
Initially, we tried to set the CSS transformations on elements directly through the transform attribute. While this worked for basic input, it did not support other AT features like tapping the screen to focus elements. With this strategy, the VoiceOver "touch area" was a small box around the top left corner of the element. It was never clear why this was this case, but forced us to change our strategy to set the left, top, width, and height attributes instead.
This function assumes that elements have other style attributes so they can be positioned correctly and don't interfere with scenery input, see SceneryStyle in PDOMUtils.
Additional notes were taken in https://github.com/phetsims/scenery/issues/852, see that issue for more information.
Review: This function could be simplified by setting the element width/height a small arbitrary shape at the center of the node's global bounds. There is a drawback in that the VO default highlight won't surround the Node anymore. But it could be a performance enhancement and simplify this function. Or maybe a big rectangle larger than the Display div still centered on the node so we never see the VO highlight?
recursiveDisable( disabled )¶
Recursively set this PDOMPeer and children to be disabled. This will overwrite any previous value of disabled that may have been set, but will keep track of the old value, and restore its state upon re-enabling. @param {boolean} disabled @public
Source Code¶
See the source for PDOMPeer.js in the scenery repository.