Changeset 278683 in webkit
- Timestamp:
- Jun 9, 2021, 5:11:41 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 3 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/accessibility/ios-simulator/heading-text-updates-expected.txt (added)
-
LayoutTests/accessibility/ios-simulator/heading-text-updates.html (added)
-
LayoutTests/accessibility/mac/heading-text-updates-expected.txt (added)
-
LayoutTests/accessibility/mac/heading-text-updates.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r278678 r278683 1 2021-06-09 Andres Gonzalez <andresg_22@apple.com> 2 3 iOS - VoiceOver reads the old heading text when updated with heading.firstChild.data. 4 https://bugs.webkit.org/show_bug.cgi?id=226754 5 6 Reviewed by Chris Fleizach. 7 8 * accessibility/ios-simulator/heading-text-updates-expected.txt: Added. 9 * accessibility/ios-simulator/heading-text-updates.html: Added. 10 * accessibility/mac/heading-text-updates-expected.txt: Added. 11 * accessibility/mac/heading-text-updates.html: Added. 12 1 13 2021-06-09 Devin Rousso <drousso@apple.com> 2 14 -
trunk/Source/WebCore/ChangeLog
r278681 r278683 1 2021-06-09 Andres Gonzalez <andresg_22@apple.com> 2 3 iOS - VoiceOver reads the old heading text when updated with heading.firstChild.data. 4 https://bugs.webkit.org/show_bug.cgi?id=226754 5 rdar://44949563 6 7 Reviewed by Chris Fleizach. 8 9 Tests: accessibility/ios-simulator/heading-text-updates.html 10 accessibility/mac/heading-text-updates.html 11 12 The problem was caused by [WebAccessibilityObjectWrapper _accessibilityTraitsFromAncestors] 13 setting the value and label of static text inside headings. since this 14 method is called only on the initialization of the object, the label is 15 never updated when the text changes. 16 The solution is to move the logic to return the label and value of 17 static text inside headings to the accessibilityLabel and accessibilityValue 18 respectively. 19 20 * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm: 21 (-[WebAccessibilityObjectWrapper _accessibilityTraitsFromAncestors]): 22 (-[WebAccessibilityObjectWrapper accessibilityLabel]): 23 (-[WebAccessibilityObjectWrapper accessibilityValue]): 24 1 25 2021-06-09 Eric Carlson <eric.carlson@apple.com> 2 26 -
trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm
r278253 r278683 662 662 { 663 663 uint64_t traits = 0; 664 AccessibilityRole role = self.axBackingObject->roleValue();665 664 auto* backingObject = self.axBackingObject; 665 666 666 // Trait information also needs to be gathered from the parents above the object. 667 // The parentObject is needed instead of the unignoredParentObject, because a table might be ignored, but information still needs to be gathered from it. 668 for (auto* parent = self.axBackingObject->parentObject(); parent != nil; parent = parent->parentObject()) {667 // The parentObject is needed instead of the unignoredParentObject, because a table might be ignored, but information still needs to be gathered from it. 668 for (auto* parent = backingObject->parentObject(); parent; parent = parent->parentObject()) { 669 669 AccessibilityRole parentRole = parent->roleValue(); 670 670 if (parentRole == AccessibilityRole::WebArea) 671 671 break; 672 672 673 673 switch (parentRole) { 674 674 case AccessibilityRole::Link: … … 678 678 traits |= [self _axVisitedTrait]; 679 679 break; 680 case AccessibilityRole::Heading: {680 case AccessibilityRole::Heading: 681 681 traits |= [self _axHeaderTrait]; 682 // If this object has the header trait, we should set the value683 // to the heading level. If it was a static text element, we need to store684 // the value as the label, because the heading level needs to the value.685 AccessibilityObjectWrapper* wrapper = parent->wrapper();686 if (role == AccessibilityRole::StaticText) {687 // We should only set the text value as the label when there's no688 // alternate text on the heading parent.689 NSString *headingLabel = [wrapper baseAccessibilityDescription];690 if (![headingLabel length])691 [self setAccessibilityLabel:self.axBackingObject->stringValue()];692 else693 [self setAccessibilityLabel:headingLabel];694 }695 [self setAccessibilityValue:[wrapper accessibilityValue]];696 682 break; 697 }698 683 default: 699 684 if ([self _accessibilityIsLandmarkRole:parentRole]) … … 701 686 break; 702 687 } 703 688 704 689 // If this object has fieldset parent, we should add containedByFieldsetTrait to it. 705 690 if (parent->isFieldset()) 706 691 traits |= [self _axContainedByFieldsetTrait]; 707 692 } 708 693 709 694 return traits; 710 695 } … … 1190 1175 return label; 1191 1176 1177 auto* backingObject = self.axBackingObject; 1178 1192 1179 // iOS doesn't distinguish between a title and description field, 1193 1180 // so concatentation will yield the best result. 1194 NSString *axTitle = self.axBackingObject->titleAttributeValue();1195 NSString *axDescription = [self baseAccessibilityDescription];1181 NSString *axTitle = backingObject->titleAttributeValue(); 1182 NSString *axDescription = backingObject->descriptionAttributeValue(); 1196 1183 NSString *landmarkDescription = [self ariaLandmarkRoleDescription]; 1197 1184 NSString *interactiveVideoDescription = [self interactiveVideoDescription]; 1198 1185 1186 // If self is static text inside a heading, the label should be the string 1187 // value of the static text object, except when the heading has alternative 1188 // text, in which case, that alternative text is returned here. 1189 // The reason is that the string value for static text inside a heading is 1190 // used to convey the heading level instead. 1191 if (backingObject->roleValue() == AccessibilityRole::StaticText 1192 && self.accessibilityTraits & self._axHeaderTrait) { 1193 auto* heading = Accessibility::findAncestor(*backingObject, false, [] (const auto& ancestor) { 1194 return ancestor.roleValue() == AccessibilityRole::Heading; 1195 }); 1196 1197 if (heading) { 1198 auto headingLabel = heading->descriptionAttributeValue(); 1199 if (!headingLabel.isEmpty()) 1200 return headingLabel; 1201 return backingObject->stringValue(); 1202 } 1203 } 1204 1199 1205 // We should expose the value of the input type date or time through AXValue instead of AXTitle. 1200 if ( self.axBackingObject->isInputTypePopupButton() && [axTitle isEqualToString:[self accessibilityValue]])1206 if (backingObject->isInputTypePopupButton() && [axTitle isEqualToString:[self accessibilityValue]]) 1201 1207 axTitle = nil; 1202 1208 1203 1209 // Footer is not considered a landmark, but we want the role description. 1204 if ( self.axBackingObject->roleValue() == AccessibilityRole::Footer)1210 if (backingObject->roleValue() == AccessibilityRole::Footer) 1205 1211 landmarkDescription = AXFooterRoleDescriptionText(); 1206 1212 1207 1213 NSMutableString *result = [NSMutableString string]; 1208 if ( self.axBackingObject->roleValue() == AccessibilityRole::HorizontalRule)1214 if (backingObject->roleValue() == AccessibilityRole::HorizontalRule) 1209 1215 appendStringToResult(result, AXHorizontalRuleDescriptionText()); 1210 1216 … … 1212 1218 appendStringToResult(result, axDescription); 1213 1219 if ([self stringValueShouldBeUsedInLabel]) { 1214 NSString *valueLabel = self.axBackingObject->stringValue();1220 NSString *valueLabel = backingObject->stringValue(); 1215 1221 valueLabel = [valueLabel stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 1216 1222 appendStringToResult(result, valueLabel); … … 1218 1224 appendStringToResult(result, landmarkDescription); 1219 1225 appendStringToResult(result, interactiveVideoDescription); 1220 1226 1221 1227 return [result length] ? result : nil; 1222 1228 } … … 1465 1471 if (![self _prepareAccessibilityCall]) 1466 1472 return nil; 1467 1473 1468 1474 // check if the value was overridden 1469 1475 NSString *value = [super accessibilityValue]; 1470 1476 if (value) 1471 1477 return value; 1472 1473 if (self.axBackingObject->supportsCheckedState()) { 1474 switch (self.axBackingObject->checkboxOrRadioValue()) { 1478 1479 auto* backingObject = self.axBackingObject; 1480 if (backingObject->supportsCheckedState()) { 1481 switch (backingObject->checkboxOrRadioValue()) { 1475 1482 case AccessibilityButtonState::Off: 1476 1483 return [NSString stringWithFormat:@"%d", 0]; … … 1483 1490 return [NSString stringWithFormat:@"%d", 0]; 1484 1491 } 1485 1486 if ( self.axBackingObject->isButton() && self.axBackingObject->isPressed())1492 1493 if (backingObject->isButton() && backingObject->isPressed()) 1487 1494 return [NSString stringWithFormat:@"%d", 1]; 1488 1495 1496 // If self has the header trait, value should be the heading level. 1497 if (self.accessibilityTraits & self._axHeaderTrait) { 1498 auto* heading = Accessibility::findAncestor(*backingObject, true, [] (const auto& ancestor) { 1499 return ancestor.roleValue() == AccessibilityRole::Heading; 1500 }); 1501 ASSERT(heading); 1502 1503 if (heading) 1504 return [NSString stringWithFormat:@"%d", heading->headingLevel()]; 1505 } 1506 1489 1507 // rdar://8131388 WebKit should expose the same info as UIKit for its password fields. 1490 if ( self.axBackingObject->isPasswordField() && ![self _accessibilityIsStrongPasswordField]) {1491 int passwordLength = self.axBackingObject->accessibilityPasswordFieldLength();1508 if (backingObject->isPasswordField() && ![self _accessibilityIsStrongPasswordField]) { 1509 int passwordLength = backingObject->accessibilityPasswordFieldLength(); 1492 1510 NSMutableString* string = [NSMutableString string]; 1493 1511 for (int k = 0; k < passwordLength; ++k) … … 1495 1513 return string; 1496 1514 } 1497 1515 1498 1516 // A text control should return its text data as the axValue (per iPhone AX API). 1499 1517 if (![self stringValueShouldBeUsedInLabel]) 1500 return self.axBackingObject->stringValue();1501 1502 if ( self.axBackingObject->isRangeControl()) {1518 return backingObject->stringValue(); 1519 1520 if (backingObject->isRangeControl()) { 1503 1521 // Prefer a valueDescription if provided by the author (through aria-valuetext). 1504 String valueDescription = self.axBackingObject->valueDescription();1522 String valueDescription = backingObject->valueDescription(); 1505 1523 if (!valueDescription.isEmpty()) 1506 1524 return valueDescription; 1507 1525 1508 return [NSString stringWithFormat:@"%.2f", self.axBackingObject->valueForRange()]; 1509 } 1510 1511 if (is<AccessibilityAttachment>(self.axBackingObject) && downcast<AccessibilityAttachment>(self.axBackingObject)->hasProgress()) 1512 return [NSString stringWithFormat:@"%.2f", self.axBackingObject->valueForRange()]; 1513 1514 if (self.axBackingObject->isHeading()) 1515 return [NSString stringWithFormat:@"%d", self.axBackingObject->headingLevel()]; 1516 1526 return [NSString stringWithFormat:@"%.2f", backingObject->valueForRange()]; 1527 } 1528 1529 if (is<AccessibilityAttachment>(backingObject) && downcast<AccessibilityAttachment>(backingObject)->hasProgress()) 1530 return [NSString stringWithFormat:@"%.2f", backingObject->valueForRange()]; 1531 1517 1532 return nil; 1518 1533 }
Note:
See TracChangeset
for help on using the changeset viewer.