-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tapping paragraph instead of button disables Mobile VO #1631
Comments
Here is an error from @terracoda 's phone, tethered to her Mac: And in the debug version: |
Code in question is here: const target = domEvent.target;
if ( target && target instanceof window.Element && this.display.isElementUnderPDOM( target ) ) {
const trailIndices = target.getAttribute( PDOMUtils.DATA_PDOM_UNIQUE_ID );
assert && assert( trailIndices, 'should not be null' );
return PDOMInstance.uniqueIdToTrail( this.display, trailIndices! );
} This shows that every element in the PDOM has the attribute. So I believe, that that the only way we can hit this is if the target is the root of the PDOM. |
Subject: [PATCH] Update usages of KeyboardListener and KeyboardDragListener after changes from https://github.com/phetsims/scenery/issues/1570
---
Index: js/display/Display.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/display/Display.ts b/js/display/Display.ts
--- a/js/display/Display.ts (revision a0c37f52fc88810fb6bcdce1f31df03ab09b6ad8)
+++ b/js/display/Display.ts (date 1715199696664)
@@ -938,9 +938,20 @@
/**
* Returns true if the element is in the PDOM. That is only possible if the display is accessible.
+ * @param element
+ * @param allowRoot - If true, the root of the PDOM is also considered to be "under" the PDOM.
*/
- public isElementUnderPDOM( element: Element ): boolean {
- return this._accessible && this.pdomRootElement!.contains( element );
+ public isElementUnderPDOM( element: Element, allowRoot: boolean ): boolean {
+ if ( !this._accessible ) {
+ return false;
+ }
+
+ const isElementContained = this.pdomRootElement!.contains( element );
+ const isNotRootElement = element !== this.pdomRootElement;
+
+ // If allowRoot is true, just return if the element is contained.
+ // Otherwise, also ensure it's not the root element itself.
+ return allowRoot ? isElementContained : ( isElementContained && isNotRootElement );
}
/**
Index: js/accessibility/FocusManager.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/accessibility/FocusManager.ts b/js/accessibility/FocusManager.ts
--- a/js/accessibility/FocusManager.ts (revision a0c37f52fc88810fb6bcdce1f31df03ab09b6ad8)
+++ b/js/accessibility/FocusManager.ts (date 1715199538536)
@@ -201,7 +201,7 @@
const display = displays[ i ];
const activeElement = document.activeElement as HTMLElement;
- if ( display.isElementUnderPDOM( activeElement ) ) {
+ if ( display.isElementUnderPDOM( activeElement, false ) ) {
const uniqueId = activeElement.getAttribute( PDOMUtils.DATA_PDOM_UNIQUE_ID )!;
assert && assert( uniqueId, 'Event target must have a unique ID on its data if it is in the PDOM.' );
Index: js/input/Input.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/input/Input.ts b/js/input/Input.ts
--- a/js/input/Input.ts (revision a0c37f52fc88810fb6bcdce1f31df03ab09b6ad8)
+++ b/js/input/Input.ts (date 1715199538557)
@@ -1124,7 +1124,7 @@
public getRelatedTargetTrail( domEvent: FocusEvent | MouseEvent ): Trail | null {
const relatedTargetElement = domEvent.relatedTarget;
- if ( relatedTargetElement && this.display.isElementUnderPDOM( relatedTargetElement as HTMLElement ) ) {
+ if ( relatedTargetElement && this.display.isElementUnderPDOM( relatedTargetElement as HTMLElement, false ) ) {
const relatedTarget = ( domEvent.relatedTarget as unknown as Element );
assert && assert( relatedTarget instanceof window.Element );
@@ -1154,7 +1154,7 @@
}
else {
const target = domEvent.target;
- if ( target && target instanceof window.Element && this.display.isElementUnderPDOM( target ) ) {
+ if ( target && target instanceof window.Element && this.display.isElementUnderPDOM( target, false ) ) {
const trailIndices = target.getAttribute( PDOMUtils.DATA_PDOM_UNIQUE_ID );
assert && assert( trailIndices, 'should not be null' );
return PDOMInstance.uniqueIdToTrail( this.display, trailIndices! );
@@ -1607,7 +1607,7 @@
// if the event target is within the PDOM the AT is sending a fake pointer event to the document - do not
// dispatch this since the PDOM should only handle Input.PDOM_EVENT_TYPES, and all other pointer input should
// go through the Display div. Otherwise, activation will be duplicated when we handle pointer and PDOM events
- if ( this.display.isElementUnderPDOM( context.domEvent.target as HTMLElement ) ) {
+ if ( this.display.isElementUnderPDOM( context.domEvent.target as HTMLElement, true ) ) {
return;
}
@@ -1636,7 +1636,7 @@
// if the event target is within the PDOM the AT is sending a fake pointer event to the document - do not
// dispatch this since the PDOM should only handle Input.PDOM_EVENT_TYPES, and all other pointer input should
// go through the Display div. Otherwise, activation will be duplicated when we handle pointer and PDOM events
- if ( this.display.isElementUnderPDOM( context.domEvent.target as HTMLElement ) ) {
+ if ( this.display.isElementUnderPDOM( context.domEvent.target as HTMLElement, true ) ) {
return;
}
I made a build with it and asked @KatieWoe or @terracoda to confirm that this fixes it. If it does Ill commit the change. |
@KatieWoe is there anything else you would like to test for this? |
Not at the moment, but if it get's a maintenance release it should probably get some more focus for those sims before going out. |
Ah, right. Thanks for the reminder, lets consider a maintenance release. Since so few sims support iOS VoiceOver, it may not be too time consuming. |
@marlitas let me know that the This MR involves 3 sims that support iOS VoiceOver (according to the website).
Something about iOS VoiceOver changed, and an unfortunate assumption that we made about event targets is no longer true. The sim will crash if the user "clicks" on readable content in the PDOM. The fix is small and the sim list is small enough that I would not use the batch MR process. I estimate 4 hours to apply the patch in each scenery branch, verify, rebuild, see through QA spot check. |
I'm going to add this into phetsims/perennial#430. I am going to cherry pick into the latest version of the published sims: ratio-and-proportion |
All three of these sims are quite different from the commit. I would like to look at this with @jessegreenberg before trying to apply these. So far: 92e8bc6 did not apply I created locally 24672b4904a84a2e46a943d0db26d460df847c55 which ratio and proportion applied. Subject: [PATCH] isElementUnderPDOM can return false if the element is the PDOM root, see https://github.com/phetsims/scenery/issues/1631
(cherry picked from commit 92e8bc694d4c1d91c36d519ccf517a84f46ff6c0)
(cherry picked from commit 24672b4904a84a2e46a943d0db26d460df847c55)
# Conflicts:
# js/input/Input.js
---
Index: js/display/Display.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/display/Display.js b/js/display/Display.js
--- a/js/display/Display.js (revision 90fea3138c516450ad5a004ed54489d64a76b800)
+++ b/js/display/Display.js (date 1738357913057)
@@ -850,6 +850,25 @@
return this._accessible;
}
+ /**
+ * Returns true if the element is in the PDOM. That is only possible if the display is accessible.
+ * @public
+ * @param element
+ * @param allowRoot - If true, the root of the PDOM is also considered to be "under" the PDOM.
+ */
+ isElementUnderPDOM( element, allowRoot ) {
+ if ( !this._accessible ) {
+ return false;
+ }
+
+ const isElementContained = this.pdomRootElement.contains( element );
+ const isNotRootElement = element !== this.pdomRootElement;
+
+ // If allowRoot is true, just return if the element is contained.
+ // Otherwise, also ensure it's not the root element itself.
+ return allowRoot ? isElementContained : ( isElementContained && isNotRootElement );
+ }
+
/**
* Implements a workaround that prevents DOM focus from leaving the Display in FullScreen mode. There is
* a bug in some browsers where DOM focus can be permanently lost if tabbing out of the FullScreen element,
Index: js/input/Input.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/input/Input.js b/js/input/Input.js
--- a/js/input/Input.js (revision 90fea3138c516450ad5a004ed54489d64a76b800)
+++ b/js/input/Input.js (date 1738358075695)
@@ -1100,8 +1100,17 @@
return domEvent[ TARGET_SUBSTITUTE_KEY ][ PDOMUtils.DATA_TRAIL_ID ];
}
else {
- assert && assert( domEvent.target instanceof window.Element );
- return domEvent.target.getAttribute( PDOMUtils.DATA_TRAIL_ID );
+ // assert && assert( domEvent.target instanceof window.Element );
+ // return domEvent.target.getAttribute( PDOMUtils.DATA_TRAIL_ID );
+ const target = domEvent.target;
+ if ( target && target instanceof window.Element && this.display.isElementUnderPDOM( target, false ) ) {
+ const trailIndices = target.getAttribute( PDOMUtils.DATA_TRAIL_ID );
+ assert && assert( trailIndices, 'should not be null' );
+ return PDOMInstance.uniqueIdToTrail( this.display, trailIndices );
+ }
+ else{
+ // TODO:?????
+ }
}
}
@@ -1604,7 +1613,7 @@
// if the event target is within the PDOM the AT is sending a fake pointer event to the document - do not
// dispatch this since the PDOM should only handle Input.PDOM_EVENT_TYPES, and all other pointer input should
// go through the Display div. Otherwise, activation will be duplicated when we handle pointer and PDOM events
- if ( this.isTargetUnderPDOM( event.target ) ) {
+ if ( this.display.isElementUnderPDOM( event.target, true ) ) {
return;
}
@@ -1640,7 +1649,7 @@
// if the event target is within the PDOM the AT is sending a fake pointer event to the document - do not
// dispatch this since the PDOM should only handle Input.PDOM_EVENT_TYPES, and all other pointer input should
// go through the Display div. Otherwise, activation will be duplicated when we handle pointer and PDOM events
- if ( this.isTargetUnderPDOM( event.target ) ) {
+ if ( this.display.isElementUnderPDOM( event.target, true ) ) {
return;
}
|
I edited my progress out of the maintenance state, and can easily get it back with this: // https://github.com/phetsims/scenery/issues/1631
// Fixes: https://github.com/phetsims/scenery/commit/92e8bc694d4c1d91c36d519ccf517a84f46ff6c0
// await m.createPatch( 'scenery', 'https://github.com/phetsims/scenery/issues/1631', 'iOSVoiceOver')
// await m.addNeededPatch( 'ratio-and-proportion', '1.2', 'iOSVoiceOver');
// await m.addNeededPatch( 'john-travoltage', '1.6', 'iOSVoiceOver');
// await m.addNeededPatch( 'gravity-force-lab-basics', '1.1', 'iOSVoiceOver');
// await m.addPatchSHA( 'iOSVoiceOver', '92e8bc694d4c1d91c36d519ccf517a84f46ff6c0')
// await m.addPatchSHA( 'iOSVoiceOver', '24672b4904a84a2e46a943d0db26d460df847c55') |
I could not reproduce this problem on GFL:B and JT. Only for RAP. I'm proceeding with the RC deploy for that sim. |
Ok. RC has been deployed. For QA Testing: Please make sure that the above bug is not reproducible. The easiest way I found it could be reproduced was to swipe to the description of the home screen button (like in the video). Please test the production version of the sim on phet.colorado.edu as you go also to make sure you can see that there is indeed a problem there, and the fix in the RC. I used an ipad with safari browser. |
RaP looks fixed in the MR after a quick check. |
RaP has been pushed to production. Closing |
Test device
iPad
Operating System
iPadOS 17.4.1
Browser
Safari
Problem description
Found during phetsims/qa#1080.
Mobile VO may stop responding to button presses if you try to press a paragraph description rather than a button. This makes using the sim from that point on impossible
Steps to reproduce
Visuals
IMG_5261.MOV
The text was updated successfully, but these errors were encountered: