Skip to content

Commit

Permalink
A utility function to automatically find strings for PDOm content, see
Browse files Browse the repository at this point in the history
  • Loading branch information
jessegreenberg committed Nov 1, 2024
1 parent 10fe309 commit 8b34da4
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
34 changes: 33 additions & 1 deletion js/accessibility/pdom/PDOMUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import validate from '../../../../axon/js/validate.js';
import Validation from '../../../../axon/js/Validation.js';
import merge from '../../../../phet-core/js/merge.js';
import stripEmbeddingMarks from '../../../../phet-core/js/stripEmbeddingMarks.js';
import { PDOMSiblingStyle, scenery } from '../../imports.js';
import { PDOMSiblingStyle, RichText, scenery, Text } from '../../imports.js';

// constants
const NEXT = 'NEXT';
Expand Down Expand Up @@ -579,6 +579,38 @@ const PDOMUtils = {
element.setAttribute( DATA_FOCUSABLE, focusable );
},

/**
* Given a Node, search for a stringProperty in the Node or its children, recursively. This
* is useful for finding a string to set as ParallelDOM content.
*
* This uses a depth first search to find the first instance of Text or RichText under the Node.
* It won't necessarily be the closest to the root of the Node or most "prominent" Text/RichText
* if there are multiple Text/RichText nodes.
*
* @public
* @returns {TReadOnlyProperty<string>|null}
*/
findStringProperty( node ) {

// Check if the node is an instance of Text or RichText and return the stringProperty
if ( node instanceof Text || node instanceof RichText ) {
return node.stringProperty;
}

// If the node has children, iterate over them recursively
if ( node.children ) {
for ( const child of node.children ) {
const text = PDOMUtils.findStringProperty( child );
if ( text ) {
return text;
}
}
}

// Return null if text is not found
return null;
},

TAGS: {
INPUT: INPUT_TAG,
LABEL: LABEL_TAG,
Expand Down
38 changes: 38 additions & 0 deletions js/accessibility/pdom/PDOMUtilsTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* @author Sam Reid (PhET Interactive Simulations)
*/

import { Node, RichText, Text } from '../../imports.js';
import PDOMUtils from './PDOMUtils.js';

QUnit.module( 'AccessibilityUtils' );
Expand Down Expand Up @@ -147,4 +148,41 @@ QUnit.test( 'setTextContent', assert => {
PDOMUtils.setTextContent( toyElement, invalidHTMLContent );
assert.ok( toyElement.textContent === invalidHTMLContent, 'invalid HTML set as content' );
assert.ok( toyElement.firstElementChild === null, 'fallback to textContent for disallowed tags' );
} );

QUnit.test( 'findStringProperty', assert => {
const testString = 'testing';

const rootNode = new Node();
const a = new Node();
const b = new Node();
const testText = new Text( testString );
const testRichText = new RichText( testString );

rootNode.addChild( a );
a.addChild( b );
b.addChild( testText );

// basic find test
let foundStringProperty = PDOMUtils.findStringProperty( rootNode );
assert.ok( foundStringProperty && foundStringProperty.value === testString, 'found the string content' );

// test with no string to find
b.removeChild( testText );
foundStringProperty = PDOMUtils.findStringProperty( rootNode );
assert.ok( foundStringProperty === null, 'no string content found' );

// test with RichText
b.addChild( testRichText );
foundStringProperty = PDOMUtils.findStringProperty( rootNode );
assert.ok( foundStringProperty && foundStringProperty.value === testString, 'found the RichText content' );

// test with an empty Node
foundStringProperty = PDOMUtils.findStringProperty( new Node() );
assert.ok( foundStringProperty === null, 'no content found in empty Node' );

// test with Text and RichText in the subtree
b.addChild( testText );
foundStringProperty = PDOMUtils.findStringProperty( rootNode );
assert.ok( foundStringProperty && foundStringProperty.value === testString, 'found the string content in subtree' );
} );

0 comments on commit 8b34da4

Please sign in to comment.