Changeset 156835 in webkit
- Timestamp:
- Oct 3, 2013 8:21:21 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r156832 r156835 1 2013-10-02 Mario Sanchez Prada <mario.prada@samsung.com> 2 3 [ATK] Expose aria-invalid as a text attribute (not object attribute) 4 https://bugs.webkit.org/show_bug.cgi?id=122015 5 6 Reviewed by Chris Fleizach. 7 8 Updated the aria-invalid.html layout test to make sure that it 9 behaves as defined by the WAI-ARIA specification for values other 10 than 'false', 'true', 'grammar' and 'spelling'. 11 12 * accessibility/aria-invalid.html: Updated test. 13 * accessibility/aria-invalid-expected.txt: Updated expectations. 14 1 15 2013-10-03 Ryosuke Niwa <rniwa@webkit.org> 2 16 -
trunk/LayoutTests/accessibility/aria-invalid-expected.txt
r108373 r156835 1 1 2 2 This tests that aria-invalid causes the right attribute to be returned and it ensures a notification is sent when it changes. 3 3 … … 7 7 PASS accessibilityController.focusedElement.stringAttributeValue('AXInvalid') is 'true' 8 8 PASS accessibilityController.focusedElement.stringAttributeValue('AXInvalid') is 'grammar' 9 PASS accessibilityController.focusedElement.stringAttributeValue('AXInvalid') is 'spelling' 10 PASS accessibilityController.focusedElement.stringAttributeValue('AXInvalid') is 'true' 11 PASS accessibilityController.focusedElement.stringAttributeValue('AXInvalid') is 'false' 9 12 PASS accessibilityController.focusedElement.stringAttributeValue('AXInvalid') is 'false' 10 13 PASS accessibilityController.focusedElement.stringAttributeValue('AXInvalid') is 'false' -
trunk/LayoutTests/accessibility/aria-invalid.html
r155274 r156835 9 9 <input type="text" id="text1" aria-invalid="true"> 10 10 <input type="text" id="text2" aria-invalid="grammar"> 11 <input type="text" id="text3" aria-invalid=""> 12 <input type="text" id="text4"> 11 <input type="text" id="text3" aria-invalid="spelling"> 12 <input type="text" id="text4" aria-invalid="notallowed"> 13 <input type="text" id="text5" aria-invalid="false"> 14 <input type="text" id="text6" aria-invalid=""> 15 <input type="text" id="text7"> 13 16 14 17 <p id="description"></p> … … 39 42 40 43 document.getElementById("text3").focus(); 44 shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXInvalid')", "'spelling'"); 45 46 document.getElementById("text4").focus(); 47 shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXInvalid')", "'true'"); 48 49 document.getElementById("text5").focus(); 41 50 shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXInvalid')", "'false'"); 42 51 43 document.getElementById("text4").focus(); 52 document.getElementById("text6").focus(); 53 shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXInvalid')", "'false'"); 54 55 document.getElementById("text7").focus(); 44 56 shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXInvalid')", "'false'"); 45 57 … … 48 60 shouldBeTrue("addedNotification"); 49 61 50 document.getElementById("text 4").setAttribute("aria-invalid", "spelling");62 document.getElementById("text7").setAttribute("aria-invalid", "spelling"); 51 63 } 52 64 -
trunk/Source/WebCore/ChangeLog
r156831 r156835 1 2013-10-02 Mario Sanchez Prada <mario.prada@samsung.com> 2 3 [ATK] Expose aria-invalid as a text attribute (not object attribute) 4 https://bugs.webkit.org/show_bug.cgi?id=122015 5 6 Reviewed by Chris Fleizach. 7 8 Expose the aria-invalid attribute correctly through a text 9 attribute (through the AtkText interface) instead of using an 10 object, according to what the WAI-ARIA specs says. 11 http://www.w3.org/TR/wai-aria-implementation/#mapping_state-property 12 13 This will be tested by accesibility/aria-invalid.html, which should 14 keep passing after thanks to the changes done in the DRT and WKTR. 15 16 * accessibility/AccessibilityObject.cpp: 17 (WebCore::AccessibilityObject::invalidStatus): Update this method 18 to only return values recognized by the WAI-ARIA specification. 19 20 * accessibility/atk/WebKitAccessibleInterfaceText.cpp: 21 (getAttributeSetForAccessibilityObject): Expose aria-invalid as a 22 custom text attribute 'invalid', following the lead of Firefox. 23 Also register that custom attribute as a AtkTextAttribute. 24 * accessibility/atk/WebKitAccessibleWrapperAtk.cpp: 25 (webkitAccessibleGetAttributes): Remove exposure of aria-invalid 26 as an object attribute from here. 27 1 28 2013-10-03 Zan Dobersek <zdobersek@igalia.com> 2 29 -
trunk/Source/WebCore/accessibility/AccessibilityObject.cpp
r156409 r156835 1344 1344 { 1345 1345 DEFINE_STATIC_LOCAL(const AtomicString, invalidStatusFalse, ("false", AtomicString::ConstructFromLiteral)); 1346 DEFINE_STATIC_LOCAL(const AtomicString, invalidStatusTrue, ("true", AtomicString::ConstructFromLiteral)); 1346 1347 1347 1348 // aria-invalid can return false (default), grammer, spelling, or true. 1348 1349 const AtomicString& ariaInvalid = getAttribute(aria_invalidAttr); 1349 1350 1350 // If empty or not present, it should return false.1351 if (ariaInvalid.isEmpty() )1351 // If 'false', empty or not present, it should return false. 1352 if (ariaInvalid.isEmpty() || equalIgnoringCase(ariaInvalid, invalidStatusFalse)) 1352 1353 return invalidStatusFalse; 1353 1354 1354 return ariaInvalid; 1355 // Only 'true', 'grammar' and 'spelling' are values recognised by the WAI-ARIA 1356 // specification. Any other non empty string should be treated as 'true'. 1357 if (equalIgnoringCase(ariaInvalid, "spelling") || equalIgnoringCase(ariaInvalid, "grammar")) 1358 return ariaInvalid; 1359 return invalidStatusTrue; 1355 1360 } 1356 1361 -
trunk/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp
r156532 r156835 57 57 using namespace WebCore; 58 58 59 // Text attribute to expose the ARIA 'aria-invalid' attribute. Initially initialized 60 // to ATK_TEXT_ATTR_INVALID (which means 'invalid' text attribute'), will later on 61 // hold a reference to the custom registered AtkTextAttribute that we will use. 62 static AtkTextAttribute atkTextAttributeInvalid = ATK_TEXT_ATTR_INVALID; 63 59 64 static AccessibilityObject* core(AtkText* text) 60 65 { … … 294 299 if (!language.isEmpty()) 295 300 result = addToAtkAttributeSet(result, atk_text_attribute_get_name(ATK_TEXT_ATTR_LANGUAGE), language.utf8().data()); 301 302 String invalidStatus = object->invalidStatus().string(); 303 if (invalidStatus != "false") { 304 // Register the custom attribute for 'aria-invalid' if not done yet. 305 if (atkTextAttributeInvalid == ATK_TEXT_ATTR_INVALID) 306 atkTextAttributeInvalid = atk_text_attribute_register("invalid"); 307 308 result = addToAtkAttributeSet(result, atk_text_attribute_get_name(atkTextAttributeInvalid), invalidStatus.utf8().data()); 309 } 296 310 297 311 return result; -
trunk/Source/WebCore/accessibility/atk/WebKitAccessibleWrapperAtk.cpp
r156532 r156835 505 505 if (coreObject->ariaHasPopup()) 506 506 attributeSet = addToAtkAttributeSet(attributeSet, "haspopup", "true"); 507 508 String invalidStatus = coreObject->invalidStatus().string();509 if (!invalidStatus.isEmpty() && invalidStatus != "false")510 attributeSet = addToAtkAttributeSet(attributeSet, "aria-invalid", coreObject->invalidStatus().string().utf8().data());511 507 512 508 AccessibilitySortDirection sortDirection = coreObject->sortDirection(); -
trunk/Tools/ChangeLog
r156803 r156835 1 2013-10-02 Mario Sanchez Prada <mario.prada@samsung.com> 2 3 [ATK] Expose aria-invalid as a text attribute (not object attribute) 4 https://bugs.webkit.org/show_bug.cgi?id=122015 5 6 Reviewed by Chris Fleizach. 7 8 Adapted DRT and WKTR to check the exposure of the aria-invalid 9 attribute as a text attribute, instead of an object attribute. 10 11 Also, done some refactoring of the code to try to keep things 12 simpler and more coherent, by defining new helper functions, 13 simplifying code, moving static variables and functions into 14 unnammed namespaces and so on, without altering the logic other 15 than for checking the text attribute for aria-invalid. 16 17 * DumpRenderTree/atk/AccessibilityUIElementAtk.cpp: 18 (coreAttributeToAtkAttribute): Consider 'invalid' as the name of 19 the attribute exposed by the ATK wrapper, not 'aria-invalid'. 20 Also, never return an empty string if not falling through any of 21 the cases checked here, and return the original attribute instead. 22 (atkAttributeValueToCoreAttributeValue): New helper function to 23 match the attributes values returned by the ATK wrapper with the 24 values expected by the layout tests. Moved the mappings for the 25 values of AXSortDirection here as well. 26 (getAttributeSet): New helper function to retrieve a list of 27 attributes (an AtkAttributeSet) from an AtkObject using the right 28 API depending on whether we want the object attributes or the text 29 attributes (in case the object implements AtkText). 30 (getAttributeSetValueForId): Simplified by using getAttributeSet 31 and atkAttributeValueToCoreAttributeValue. Also, added a new 32 parameter to indicater whether we are interested in object 33 attributes or text attributes. 34 (getAtkAttributeSetAsString): Ditto. 35 (attributesOfElement): Updated to pass the new required parameter 36 to getAtkAttributeSetAsString, indicating that we want the object 37 attributes in this case, for backwards compatibility. 38 (indexRangeInTable): Moved up in the file into the unnammed namespace. 39 (alterCurrentValue): Ditto. 40 (AccessibilityUIElement::stringAttributeValue): After moving most 41 of the code here to the new helper functions, simplified it by 42 just checking whether the required attribute is provided as an 43 object attribute or, if that's not the case, as a text attribute. 44 (AccessibilityUIElement::isAttributeSupported): Ditto. 45 (AccessibilityUIElement::intValue): Updated to pass the new 46 required parameter to getAttributeSetValueForId, indicating that 47 we want the object attributes in this case. 48 (AccessibilityUIElement::hasPopup): Ditto. 49 50 * WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp: 51 (WTR::coreAttributeToAtkAttribute): Same changes than for DRT. 52 (WTR::atkAttributeValueToCoreAttributeValue): Ditto. 53 (WTR::getAttributeSet): Ditto. 54 (WTR::getAttributeSetValueForId): Ditto. 55 (WTR::getAtkAttributeSetAsString): Ditto. 56 (WTR::attributesOfElement): Ditto. 57 (WTR::AccessibilityUIElement::stringAttributeValue): Ditto. 58 (WTR::AccessibilityUIElement::isAttributeSupported): Ditto. 59 (WTR::AccessibilityUIElement::intValue): Ditto. 60 (WTR::AccessibilityUIElement::hasPopup): Ditto. 61 1 62 2013-10-02 Ryosuke Niwa <rniwa@webkit.org> 2 63 -
trunk/Tools/DumpRenderTree/atk/AccessibilityUIElementAtk.cpp
r156551 r156835 2 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 3 3 * Copyright (C) 2009 Jan Michael Alonzo 4 * Copyright (C) 2013 Samsung Electronics. All rights reserved. 4 5 * 5 6 * Redistribution and use in source and binary forms, with or without … … 42 43 #include <wtf/unicode/CharacterNames.h> 43 44 44 static String coreAttributeToAtkAttribute(JSStringRef attribute) 45 namespace { 46 47 enum AtkAttributeType { 48 ObjectAttributeType, 49 TextAttributeType 50 }; 51 52 enum AttributeDomain { 53 CoreDomain = 0, 54 AtkDomain 55 }; 56 57 enum AttributesIndex { 58 // Attribute names. 59 InvalidNameIndex = 0, 60 PlaceholderNameIndex, 61 SortNameIndex, 62 63 // Attribute values. 64 SortAscendingValueIndex, 65 SortDescendingValueIndex, 66 SortUnknownValueIndex, 67 68 NumberOfAttributes 69 }; 70 71 // Attribute names & Values (keep on sync with enum AttributesIndex). 72 const String attributesMap[][2] = { 73 // Attribute names. 74 { "AXInvalid", "invalid" }, 75 { "AXPlaceholderValue", "placeholder-text" } , 76 { "AXSortDirection", "sort" }, 77 78 // Attribute values. 79 { "AXAscendingSortDirection", "ascending" }, 80 { "AXDescendingSortDirection", "descending" }, 81 { "AXUnknownSortDirection", "unknown" } 82 }; 83 84 String coreAttributeToAtkAttribute(JSStringRef attribute) 45 85 { 46 86 size_t bufferSize = JSStringGetMaximumUTF8CStringSize(attribute); … … 49 89 50 90 String attributeString = String::fromUTF8(buffer.get()); 51 if (attributeString == "AXInvalid") 52 return "aria-invalid"; 53 54 if (attributeString == "AXPlaceholderValue") 55 return "placeholder-text"; 56 57 if (attributeString == "AXSortDirection") 58 return "sort"; 59 60 return String(); 61 } 62 63 static String getAttributeSetValueForId(AtkObject* accessible, const char* id) 64 { 65 const char* attributeValue = 0; 66 AtkAttributeSet* attributeSet = atk_object_get_attributes(accessible); 91 for (int i = 0; i < NumberOfAttributes; ++i) { 92 if (attributesMap[i][CoreDomain] == attributeString) 93 return attributesMap[i][AtkDomain]; 94 } 95 96 return attributeString; 97 } 98 99 String atkAttributeValueToCoreAttributeValue(AtkAttributeType type, const String& id, const String& value) 100 { 101 if (type == ObjectAttributeType) { 102 // We need to translate ATK values exposed for 'aria-sort' (e.g. 'ascending') 103 // into those expected by the layout tests (e.g. 'AXAscendingSortDirection'). 104 if (id == attributesMap[SortNameIndex][AtkDomain] && !value.isEmpty()) { 105 if (value == attributesMap[SortAscendingValueIndex][AtkDomain]) 106 return attributesMap[SortAscendingValueIndex][CoreDomain]; 107 if (value == attributesMap[SortDescendingValueIndex][AtkDomain]) 108 return attributesMap[SortDescendingValueIndex][CoreDomain]; 109 110 return attributesMap[SortUnknownValueIndex][CoreDomain]; 111 } 112 } else if (type == TextAttributeType) { 113 // In case of 'aria-invalid' when the attribute empty or has "false" for ATK 114 // it should not be mapped at all, but layout tests will expect 'false'. 115 if (id == attributesMap[InvalidNameIndex][AtkDomain] && value.isEmpty()) 116 return "false"; 117 } 118 119 return value; 120 } 121 122 AtkAttributeSet* getAttributeSet(AtkObject* accessible, AtkAttributeType type) 123 { 124 if (type == ObjectAttributeType) 125 return atk_object_get_attributes(accessible); 126 127 if (type == TextAttributeType) { 128 if (!ATK_IS_TEXT(accessible)) 129 return 0; 130 131 return atk_text_get_default_attributes(ATK_TEXT(accessible)); 132 } 133 134 ASSERT_NOT_REACHED(); 135 return 0; 136 } 137 138 String getAttributeSetValueForId(AtkObject* accessible, AtkAttributeType type, String id) 139 { 140 AtkAttributeSet* attributeSet = getAttributeSet(accessible, type); 141 if (!attributeSet) 142 return String(); 143 144 String attributeValue; 67 145 for (AtkAttributeSet* attributes = attributeSet; attributes; attributes = attributes->next) { 68 146 AtkAttribute* atkAttribute = static_cast<AtkAttribute*>(attributes->data); 69 if ( !strcmp(atkAttribute->name, id)) {70 attributeValue = atkAttribute->value;147 if (id == atkAttribute->name) { 148 attributeValue = String::fromUTF8(atkAttribute->value); 71 149 break; 72 150 } 73 151 } 74 75 String atkAttributeValue = String::fromUTF8(attributeValue);76 152 atk_attribute_set_free(attributeSet); 77 153 78 return atkAttributeValue; 79 } 80 81 static String getAtkAttributeSetAsString(AtkObject* accessible) 82 { 154 return atkAttributeValueToCoreAttributeValue(type, id, attributeValue); 155 } 156 157 String getAtkAttributeSetAsString(AtkObject* accessible, AtkAttributeType type) 158 { 159 AtkAttributeSet* attributeSet = getAttributeSet(accessible, type); 160 if (!attributeSet) 161 return String(); 162 83 163 StringBuilder builder; 84 85 AtkAttributeSet* attributeSet = atk_object_get_attributes(accessible);86 164 for (AtkAttributeSet* attributes = attributeSet; attributes; attributes = attributes->next) { 87 165 AtkAttribute* attribute = static_cast<AtkAttribute*>(attributes->data); … … 96 174 } 97 175 98 staticinline const char* roleToString(AtkRole role)176 inline const char* roleToString(AtkRole role) 99 177 { 100 178 switch (role) { … … 210 288 } 211 289 212 staticinline gchar* replaceCharactersForResults(gchar* str)290 inline gchar* replaceCharactersForResults(gchar* str) 213 291 { 214 292 String uString = String::fromUTF8(str); … … 226 304 } 227 305 228 staticbool checkElementState(PlatformUIElement element, AtkStateType stateType)306 bool checkElementState(PlatformUIElement element, AtkStateType stateType) 229 307 { 230 308 if (!ATK_IS_OBJECT(element)) … … 235 313 } 236 314 237 staticString attributesOfElement(AccessibilityUIElement* element)315 String attributesOfElement(AccessibilityUIElement* element) 238 316 { 239 317 StringBuilder builder; … … 281 359 // We append the ATK specific attributes as a single line at the end. 282 360 builder.append("AXPlatformAttributes: "); 283 builder.append(getAtkAttributeSetAsString(element->platformUIElement() ));361 builder.append(getAtkAttributeSetAsString(element->platformUIElement(), ObjectAttributeType)); 284 362 285 363 return builder.toString(); 286 364 } 287 365 288 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element) 289 : m_element(element) 290 { 291 if (m_element) 292 g_object_ref(m_element); 293 } 294 295 AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other) 296 : m_element(other.m_element) 297 { 298 if (m_element) 299 g_object_ref(m_element); 300 } 301 302 AccessibilityUIElement::~AccessibilityUIElement() 303 { 304 if (m_element) 305 g_object_unref(m_element); 306 } 307 308 void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elements) 309 { 310 // FIXME: implement 311 } 312 313 void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>&) 314 { 315 // FIXME: implement 316 } 317 318 void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& children) 319 { 320 if (!ATK_IS_OBJECT(m_element)) 321 return; 322 323 int count = childrenCount(); 324 for (int i = 0; i < count; i++) { 325 AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i); 326 children.append(AccessibilityUIElement(child)); 327 } 328 } 329 330 void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned start, unsigned end) 331 { 332 if (!ATK_IS_OBJECT(m_element)) 333 return; 334 335 for (unsigned i = start; i < end; i++) { 336 AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i); 337 elementVector.append(AccessibilityUIElement(child)); 338 } 339 } 340 341 int AccessibilityUIElement::rowCount() 342 { 343 if (!ATK_IS_TABLE(m_element)) 344 return 0; 345 346 return atk_table_get_n_rows(ATK_TABLE(m_element)); 347 } 348 349 int AccessibilityUIElement::columnCount() 350 { 351 if (!ATK_IS_TABLE(m_element)) 352 return 0; 353 354 return atk_table_get_n_columns(ATK_TABLE(m_element)); 355 } 356 357 int AccessibilityUIElement::childrenCount() 358 { 359 if (!ATK_IS_OBJECT(m_element)) 360 return 0; 361 362 return atk_object_get_n_accessible_children(ATK_OBJECT(m_element)); 363 } 364 365 AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y) 366 { 367 if (!ATK_IS_COMPONENT(m_element)) 368 return 0; 369 370 return AccessibilityUIElement(atk_component_ref_accessible_at_point(ATK_COMPONENT(m_element), x, y, ATK_XY_WINDOW)); 371 } 372 373 AccessibilityUIElement AccessibilityUIElement::linkedUIElementAtIndex(unsigned index) 374 { 375 // FIXME: implement 376 return 0; 377 } 378 379 AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index) 380 { 381 if (!ATK_IS_OBJECT(m_element)) 382 return 0; 383 384 Vector<AccessibilityUIElement> children; 385 getChildrenWithRange(children, index, index + 1); 386 387 if (children.size() == 1) 388 return children.at(0); 389 390 return 0; 391 } 392 393 unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element) 394 { 395 // FIXME: implement 396 return 0; 397 } 398 399 JSStringRef AccessibilityUIElement::allAttributes() 400 { 401 if (!ATK_IS_OBJECT(m_element)) 402 return JSStringCreateWithCharacters(0, 0); 403 404 return JSStringCreateWithUTF8CString(attributesOfElement(this).utf8().data()); 405 } 406 407 JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements() 408 { 409 // FIXME: implement 410 return JSStringCreateWithCharacters(0, 0); 411 } 412 413 JSStringRef AccessibilityUIElement::attributesOfDocumentLinks() 414 { 415 // FIXME: implement 416 return JSStringCreateWithCharacters(0, 0); 417 } 418 419 AccessibilityUIElement AccessibilityUIElement::titleUIElement() 420 { 421 if (!ATK_IS_OBJECT(m_element)) 422 return 0; 423 424 AtkRelationSet* set = atk_object_ref_relation_set(ATK_OBJECT(m_element)); 425 if (!set) 426 return 0; 427 428 AtkObject* target = 0; 429 int count = atk_relation_set_get_n_relations(set); 430 for (int i = 0; i < count; i++) { 431 AtkRelation* relation = atk_relation_set_get_relation(set, i); 432 if (atk_relation_get_relation_type(relation) == ATK_RELATION_LABELLED_BY) { 433 GPtrArray* targetList = atk_relation_get_target(relation); 434 if (targetList->len) 435 target = static_cast<AtkObject*>(g_ptr_array_index(targetList, 0)); 436 } 437 } 438 439 g_object_unref(set); 440 return target ? AccessibilityUIElement(target) : 0; 441 } 442 443 AccessibilityUIElement AccessibilityUIElement::parentElement() 444 { 445 if (!ATK_IS_OBJECT(m_element)) 446 return 0; 447 448 AtkObject* parent = atk_object_get_parent(ATK_OBJECT(m_element)); 449 return parent ? AccessibilityUIElement(parent) : 0; 450 } 451 452 JSStringRef AccessibilityUIElement::attributesOfChildren() 453 { 454 if (!ATK_IS_OBJECT(m_element)) 455 return JSStringCreateWithCharacters(0, 0); 456 457 Vector<AccessibilityUIElement> children; 458 getChildren(children); 459 460 StringBuilder builder; 461 for (Vector<AccessibilityUIElement>::iterator it = children.begin(); it != children.end(); ++it) { 462 builder.append(attributesOfElement(it)); 463 builder.append("\n------------\n"); 464 } 465 466 return JSStringCreateWithUTF8CString(builder.toString().utf8().data()); 467 } 468 469 JSStringRef AccessibilityUIElement::parameterizedAttributeNames() 470 { 471 // FIXME: implement 472 return JSStringCreateWithCharacters(0, 0); 473 } 474 475 JSStringRef AccessibilityUIElement::role() 476 { 477 if (!ATK_IS_OBJECT(m_element)) 478 return JSStringCreateWithCharacters(0, 0); 479 480 AtkRole role = atk_object_get_role(ATK_OBJECT(m_element)); 481 if (!role) 482 return JSStringCreateWithCharacters(0, 0); 483 484 GOwnPtr<char> roleStringWithPrefix(g_strdup_printf("AXRole: %s", roleToString(role))); 485 return JSStringCreateWithUTF8CString(roleStringWithPrefix.get()); 486 } 487 488 JSStringRef AccessibilityUIElement::subrole() 489 { 490 return 0; 491 } 492 493 JSStringRef AccessibilityUIElement::roleDescription() 494 { 495 return 0; 496 } 497 498 JSStringRef AccessibilityUIElement::title() 499 { 500 if (!ATK_IS_OBJECT(m_element)) 501 return JSStringCreateWithCharacters(0, 0); 502 503 const gchar* name = atk_object_get_name(ATK_OBJECT(m_element)); 504 GOwnPtr<gchar> axTitle(g_strdup_printf("AXTitle: %s", name ? name : "")); 505 506 return JSStringCreateWithUTF8CString(axTitle.get()); 507 } 508 509 JSStringRef AccessibilityUIElement::description() 510 { 511 if (!ATK_IS_OBJECT(m_element)) 512 return JSStringCreateWithCharacters(0, 0); 513 514 const gchar* description = atk_object_get_description(ATK_OBJECT(m_element)); 515 if (!description) 516 return JSStringCreateWithCharacters(0, 0); 517 518 GOwnPtr<gchar> axDesc(g_strdup_printf("AXDescription: %s", description)); 519 520 return JSStringCreateWithUTF8CString(axDesc.get()); 521 } 522 523 JSStringRef AccessibilityUIElement::stringValue() 524 { 525 if (!ATK_IS_TEXT(m_element)) 526 return JSStringCreateWithCharacters(0, 0); 527 528 GOwnPtr<gchar> text(atk_text_get_text(ATK_TEXT(m_element), 0, -1)); 529 GOwnPtr<gchar> textWithReplacedCharacters(replaceCharactersForResults(text.get())); 530 GOwnPtr<gchar> axValue(g_strdup_printf("AXValue: %s", textWithReplacedCharacters.get())); 531 532 return JSStringCreateWithUTF8CString(axValue.get()); 533 } 534 535 JSStringRef AccessibilityUIElement::language() 536 { 537 if (!ATK_IS_OBJECT(m_element)) 538 return JSStringCreateWithCharacters(0, 0); 539 540 const gchar* locale = atk_object_get_object_locale(ATK_OBJECT(m_element)); 541 if (!locale) 542 return JSStringCreateWithCharacters(0, 0); 543 544 GOwnPtr<char> axValue(g_strdup_printf("AXLanguage: %s", locale)); 545 return JSStringCreateWithUTF8CString(axValue.get()); 546 } 547 548 JSStringRef AccessibilityUIElement::helpText() const 549 { 550 // FIXME: We need to provide a proper implementation for this that does 551 // not depend on Mac specific concepts such as ATK_RELATION_DESCRIBED_BY, 552 // once it's implemented (see http://webkit.org/b/121684). 553 return JSStringCreateWithCharacters(0, 0); 554 } 555 556 double AccessibilityUIElement::x() 557 { 558 if (!ATK_IS_COMPONENT(m_element)) 559 return 0; 560 561 int x, y; 562 atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN); 563 564 return x; 565 } 566 567 double AccessibilityUIElement::y() 568 { 569 if (!ATK_IS_COMPONENT(m_element)) 570 return 0; 571 572 int x, y; 573 atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN); 574 575 return y; 576 } 577 578 double AccessibilityUIElement::width() 579 { 580 if (!ATK_IS_COMPONENT(m_element)) 581 return 0; 582 583 int width, height; 584 atk_component_get_size(ATK_COMPONENT(m_element), &width, &height); 585 586 return width; 587 } 588 589 double AccessibilityUIElement::height() 590 { 591 if (!ATK_IS_COMPONENT(m_element)) 592 return 0; 593 594 int width, height; 595 atk_component_get_size(ATK_COMPONENT(m_element), &width, &height); 596 597 return height; 598 } 599 600 double AccessibilityUIElement::clickPointX() 601 { 602 // Note: This is not something we have in ATK. 603 return 0; 604 } 605 606 double AccessibilityUIElement::clickPointY() 607 { 608 // Note: This is not something we have in ATK. 609 return 0; 610 } 611 612 JSStringRef AccessibilityUIElement::orientation() const 613 { 614 if (!ATK_IS_OBJECT(m_element)) 615 return JSStringCreateWithCharacters(0, 0); 616 617 const char* axOrientation = 0; 618 if (checkElementState(m_element, ATK_STATE_HORIZONTAL)) 619 axOrientation = "AXOrientation: AXHorizontalOrientation"; 620 else if (checkElementState(m_element, ATK_STATE_VERTICAL)) 621 axOrientation = "AXOrientation: AXVerticalOrientation"; 622 623 if (!axOrientation) 624 return JSStringCreateWithCharacters(0, 0); 625 626 return JSStringCreateWithUTF8CString(axOrientation); 627 } 628 629 double AccessibilityUIElement::intValue() const 630 { 631 if (!ATK_IS_OBJECT(m_element)) 632 return 0; 633 634 if (ATK_IS_VALUE(m_element)) { 635 GValue value = G_VALUE_INIT; 636 atk_value_get_current_value(ATK_VALUE(m_element), &value); 637 if (!G_VALUE_HOLDS_FLOAT(&value)) 638 return 0; 639 return g_value_get_float(&value); 640 } 641 642 // Consider headings as an special case when returning the "int value" of 643 // an AccessibilityUIElement, so we can reuse some tests to check the level 644 // both for HTML headings and objects with the aria-level attribute. 645 if (atk_object_get_role(ATK_OBJECT(m_element)) == ATK_ROLE_HEADING) { 646 String headingLevel = getAttributeSetValueForId(ATK_OBJECT(m_element), "level"); 647 bool ok; 648 double headingLevelValue = headingLevel.toDouble(&ok); 649 if (ok) 650 return headingLevelValue; 651 } 652 653 return 0; 654 } 655 656 double AccessibilityUIElement::minValue() 657 { 658 if (!ATK_IS_VALUE(m_element)) 659 return 0; 660 661 GValue value = G_VALUE_INIT; 662 atk_value_get_minimum_value(ATK_VALUE(m_element), &value); 663 if (!G_VALUE_HOLDS_FLOAT(&value)) 664 return 0; 665 return g_value_get_float(&value); 666 } 667 668 double AccessibilityUIElement::maxValue() 669 { 670 if (!ATK_IS_VALUE(m_element)) 671 return 0; 672 673 GValue value = G_VALUE_INIT; 674 atk_value_get_maximum_value(ATK_VALUE(m_element), &value); 675 if (!G_VALUE_HOLDS_FLOAT(&value)) 676 return 0; 677 return g_value_get_float(&value); 678 } 679 680 JSStringRef AccessibilityUIElement::valueDescription() 681 { 682 // FIXME: implement after it has been implemented in ATK. 683 // See: https://bugzilla.gnome.org/show_bug.cgi?id=684576 684 return JSStringCreateWithCharacters(0, 0); 685 } 686 687 bool AccessibilityUIElement::isEnabled() 688 { 689 return checkElementState(m_element, ATK_STATE_ENABLED); 690 } 691 692 int AccessibilityUIElement::insertionPointLineNumber() 693 { 694 // FIXME: implement 695 return 0; 696 } 697 698 bool AccessibilityUIElement::isPressActionSupported() 699 { 700 // FIXME: implement 701 return false; 702 } 703 704 bool AccessibilityUIElement::isIncrementActionSupported() 705 { 706 // FIXME: implement 707 return false; 708 } 709 710 bool AccessibilityUIElement::isDecrementActionSupported() 711 { 712 // FIXME: implement 713 return false; 714 } 715 716 bool AccessibilityUIElement::isRequired() const 717 { 718 return checkElementState(m_element, ATK_STATE_REQUIRED); 719 } 720 721 bool AccessibilityUIElement::isFocused() const 722 { 723 if (!ATK_IS_OBJECT(m_element)) 724 return false; 725 726 GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element))); 727 gboolean isFocused = atk_state_set_contains_state(stateSet.get(), ATK_STATE_FOCUSED); 728 729 return isFocused; 730 } 731 732 bool AccessibilityUIElement::isSelected() const 733 { 734 return checkElementState(m_element, ATK_STATE_SELECTED); 735 } 736 737 int AccessibilityUIElement::hierarchicalLevel() const 738 { 739 // FIXME: implement 740 return 0; 741 } 742 743 bool AccessibilityUIElement::ariaIsGrabbed() const 744 { 745 return false; 746 } 747 748 JSStringRef AccessibilityUIElement::ariaDropEffects() const 749 { 750 return 0; 751 } 752 753 bool AccessibilityUIElement::isExpanded() const 754 { 755 if (!ATK_IS_OBJECT(m_element)) 756 return false; 757 758 GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element))); 759 gboolean isExpanded = atk_state_set_contains_state(stateSet.get(), ATK_STATE_EXPANDED); 760 761 return isExpanded; 762 } 763 764 bool AccessibilityUIElement::isChecked() const 765 { 766 if (!ATK_IS_OBJECT(m_element)) 767 return false; 768 769 GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element))); 770 gboolean isChecked = atk_state_set_contains_state(stateSet.get(), ATK_STATE_CHECKED); 771 772 return isChecked; 773 } 774 775 JSStringRef AccessibilityUIElement::attributesOfColumnHeaders() 776 { 777 // FIXME: implement 778 return JSStringCreateWithCharacters(0, 0); 779 } 780 781 JSStringRef AccessibilityUIElement::attributesOfRowHeaders() 782 { 783 // FIXME: implement 784 return JSStringCreateWithCharacters(0, 0); 785 } 786 787 JSStringRef AccessibilityUIElement::attributesOfColumns() 788 { 789 // FIXME: implement 790 return JSStringCreateWithCharacters(0, 0); 791 } 792 793 JSStringRef AccessibilityUIElement::attributesOfRows() 794 { 795 // FIXME: implement 796 return JSStringCreateWithCharacters(0, 0); 797 } 798 799 JSStringRef AccessibilityUIElement::attributesOfVisibleCells() 800 { 801 // FIXME: implement 802 return JSStringCreateWithCharacters(0, 0); 803 } 804 805 JSStringRef AccessibilityUIElement::attributesOfHeader() 806 { 807 // FIXME: implement 808 return JSStringCreateWithCharacters(0, 0); 809 } 810 811 int AccessibilityUIElement::indexInTable() 812 { 813 // FIXME: implement 814 return 0; 815 } 816 817 static JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange) 366 } // namespace 367 368 JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange) 818 369 { 819 370 GOwnPtr<gchar> rangeString(g_strdup("{0, 0}")); … … 853 404 } 854 405 406 void alterCurrentValue(PlatformUIElement element, int factor) 407 { 408 if (!ATK_IS_VALUE(element)) 409 return; 410 411 GValue currentValue = G_VALUE_INIT; 412 atk_value_get_current_value(ATK_VALUE(element), ¤tValue); 413 414 GValue increment = G_VALUE_INIT; 415 atk_value_get_minimum_increment(ATK_VALUE(element), &increment); 416 417 GValue newValue = G_VALUE_INIT; 418 g_value_init(&newValue, G_TYPE_FLOAT); 419 420 g_value_set_float(&newValue, g_value_get_float(¤tValue) + factor * g_value_get_float(&increment)); 421 atk_value_set_current_value(ATK_VALUE(element), &newValue); 422 423 g_value_unset(&newValue); 424 g_value_unset(&increment); 425 g_value_unset(¤tValue); 426 } 427 428 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element) 429 : m_element(element) 430 { 431 if (m_element) 432 g_object_ref(m_element); 433 } 434 435 AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other) 436 : m_element(other.m_element) 437 { 438 if (m_element) 439 g_object_ref(m_element); 440 } 441 442 AccessibilityUIElement::~AccessibilityUIElement() 443 { 444 if (m_element) 445 g_object_unref(m_element); 446 } 447 448 void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elements) 449 { 450 // FIXME: implement 451 } 452 453 void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>&) 454 { 455 // FIXME: implement 456 } 457 458 void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& children) 459 { 460 if (!ATK_IS_OBJECT(m_element)) 461 return; 462 463 int count = childrenCount(); 464 for (int i = 0; i < count; i++) { 465 AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i); 466 children.append(AccessibilityUIElement(child)); 467 } 468 } 469 470 void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned start, unsigned end) 471 { 472 if (!ATK_IS_OBJECT(m_element)) 473 return; 474 475 for (unsigned i = start; i < end; i++) { 476 AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i); 477 elementVector.append(AccessibilityUIElement(child)); 478 } 479 } 480 481 int AccessibilityUIElement::rowCount() 482 { 483 if (!ATK_IS_TABLE(m_element)) 484 return 0; 485 486 return atk_table_get_n_rows(ATK_TABLE(m_element)); 487 } 488 489 int AccessibilityUIElement::columnCount() 490 { 491 if (!ATK_IS_TABLE(m_element)) 492 return 0; 493 494 return atk_table_get_n_columns(ATK_TABLE(m_element)); 495 } 496 497 int AccessibilityUIElement::childrenCount() 498 { 499 if (!ATK_IS_OBJECT(m_element)) 500 return 0; 501 502 return atk_object_get_n_accessible_children(ATK_OBJECT(m_element)); 503 } 504 505 AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y) 506 { 507 if (!ATK_IS_COMPONENT(m_element)) 508 return 0; 509 510 return AccessibilityUIElement(atk_component_ref_accessible_at_point(ATK_COMPONENT(m_element), x, y, ATK_XY_WINDOW)); 511 } 512 513 AccessibilityUIElement AccessibilityUIElement::linkedUIElementAtIndex(unsigned index) 514 { 515 // FIXME: implement 516 return 0; 517 } 518 519 AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index) 520 { 521 if (!ATK_IS_OBJECT(m_element)) 522 return 0; 523 524 Vector<AccessibilityUIElement> children; 525 getChildrenWithRange(children, index, index + 1); 526 527 if (children.size() == 1) 528 return children.at(0); 529 530 return 0; 531 } 532 533 unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element) 534 { 535 // FIXME: implement 536 return 0; 537 } 538 539 JSStringRef AccessibilityUIElement::allAttributes() 540 { 541 if (!ATK_IS_OBJECT(m_element)) 542 return JSStringCreateWithCharacters(0, 0); 543 544 return JSStringCreateWithUTF8CString(attributesOfElement(this).utf8().data()); 545 } 546 547 JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements() 548 { 549 // FIXME: implement 550 return JSStringCreateWithCharacters(0, 0); 551 } 552 553 JSStringRef AccessibilityUIElement::attributesOfDocumentLinks() 554 { 555 // FIXME: implement 556 return JSStringCreateWithCharacters(0, 0); 557 } 558 559 AccessibilityUIElement AccessibilityUIElement::titleUIElement() 560 { 561 if (!ATK_IS_OBJECT(m_element)) 562 return 0; 563 564 AtkRelationSet* set = atk_object_ref_relation_set(ATK_OBJECT(m_element)); 565 if (!set) 566 return 0; 567 568 AtkObject* target = 0; 569 int count = atk_relation_set_get_n_relations(set); 570 for (int i = 0; i < count; i++) { 571 AtkRelation* relation = atk_relation_set_get_relation(set, i); 572 if (atk_relation_get_relation_type(relation) == ATK_RELATION_LABELLED_BY) { 573 GPtrArray* targetList = atk_relation_get_target(relation); 574 if (targetList->len) 575 target = static_cast<AtkObject*>(g_ptr_array_index(targetList, 0)); 576 } 577 } 578 579 g_object_unref(set); 580 return target ? AccessibilityUIElement(target) : 0; 581 } 582 583 AccessibilityUIElement AccessibilityUIElement::parentElement() 584 { 585 if (!ATK_IS_OBJECT(m_element)) 586 return 0; 587 588 AtkObject* parent = atk_object_get_parent(ATK_OBJECT(m_element)); 589 return parent ? AccessibilityUIElement(parent) : 0; 590 } 591 592 JSStringRef AccessibilityUIElement::attributesOfChildren() 593 { 594 if (!ATK_IS_OBJECT(m_element)) 595 return JSStringCreateWithCharacters(0, 0); 596 597 Vector<AccessibilityUIElement> children; 598 getChildren(children); 599 600 StringBuilder builder; 601 for (Vector<AccessibilityUIElement>::iterator it = children.begin(); it != children.end(); ++it) { 602 builder.append(attributesOfElement(it)); 603 builder.append("\n------------\n"); 604 } 605 606 return JSStringCreateWithUTF8CString(builder.toString().utf8().data()); 607 } 608 609 JSStringRef AccessibilityUIElement::parameterizedAttributeNames() 610 { 611 // FIXME: implement 612 return JSStringCreateWithCharacters(0, 0); 613 } 614 615 JSStringRef AccessibilityUIElement::role() 616 { 617 if (!ATK_IS_OBJECT(m_element)) 618 return JSStringCreateWithCharacters(0, 0); 619 620 AtkRole role = atk_object_get_role(ATK_OBJECT(m_element)); 621 if (!role) 622 return JSStringCreateWithCharacters(0, 0); 623 624 GOwnPtr<char> roleStringWithPrefix(g_strdup_printf("AXRole: %s", roleToString(role))); 625 return JSStringCreateWithUTF8CString(roleStringWithPrefix.get()); 626 } 627 628 JSStringRef AccessibilityUIElement::subrole() 629 { 630 return 0; 631 } 632 633 JSStringRef AccessibilityUIElement::roleDescription() 634 { 635 return 0; 636 } 637 638 JSStringRef AccessibilityUIElement::title() 639 { 640 if (!ATK_IS_OBJECT(m_element)) 641 return JSStringCreateWithCharacters(0, 0); 642 643 const gchar* name = atk_object_get_name(ATK_OBJECT(m_element)); 644 GOwnPtr<gchar> axTitle(g_strdup_printf("AXTitle: %s", name ? name : "")); 645 646 return JSStringCreateWithUTF8CString(axTitle.get()); 647 } 648 649 JSStringRef AccessibilityUIElement::description() 650 { 651 if (!ATK_IS_OBJECT(m_element)) 652 return JSStringCreateWithCharacters(0, 0); 653 654 const gchar* description = atk_object_get_description(ATK_OBJECT(m_element)); 655 if (!description) 656 return JSStringCreateWithCharacters(0, 0); 657 658 GOwnPtr<gchar> axDesc(g_strdup_printf("AXDescription: %s", description)); 659 660 return JSStringCreateWithUTF8CString(axDesc.get()); 661 } 662 663 JSStringRef AccessibilityUIElement::stringValue() 664 { 665 if (!ATK_IS_TEXT(m_element)) 666 return JSStringCreateWithCharacters(0, 0); 667 668 GOwnPtr<gchar> text(atk_text_get_text(ATK_TEXT(m_element), 0, -1)); 669 GOwnPtr<gchar> textWithReplacedCharacters(replaceCharactersForResults(text.get())); 670 GOwnPtr<gchar> axValue(g_strdup_printf("AXValue: %s", textWithReplacedCharacters.get())); 671 672 return JSStringCreateWithUTF8CString(axValue.get()); 673 } 674 675 JSStringRef AccessibilityUIElement::language() 676 { 677 if (!ATK_IS_OBJECT(m_element)) 678 return JSStringCreateWithCharacters(0, 0); 679 680 const gchar* locale = atk_object_get_object_locale(ATK_OBJECT(m_element)); 681 if (!locale) 682 return JSStringCreateWithCharacters(0, 0); 683 684 GOwnPtr<char> axValue(g_strdup_printf("AXLanguage: %s", locale)); 685 return JSStringCreateWithUTF8CString(axValue.get()); 686 } 687 688 JSStringRef AccessibilityUIElement::helpText() const 689 { 690 // FIXME: We need to provide a proper implementation for this that does 691 // not depend on Mac specific concepts such as ATK_RELATION_DESCRIBED_BY, 692 // once it's implemented (see http://webkit.org/b/121684). 693 return JSStringCreateWithCharacters(0, 0); 694 } 695 696 double AccessibilityUIElement::x() 697 { 698 if (!ATK_IS_COMPONENT(m_element)) 699 return 0; 700 701 int x, y; 702 atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN); 703 704 return x; 705 } 706 707 double AccessibilityUIElement::y() 708 { 709 if (!ATK_IS_COMPONENT(m_element)) 710 return 0; 711 712 int x, y; 713 atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN); 714 715 return y; 716 } 717 718 double AccessibilityUIElement::width() 719 { 720 if (!ATK_IS_COMPONENT(m_element)) 721 return 0; 722 723 int width, height; 724 atk_component_get_size(ATK_COMPONENT(m_element), &width, &height); 725 726 return width; 727 } 728 729 double AccessibilityUIElement::height() 730 { 731 if (!ATK_IS_COMPONENT(m_element)) 732 return 0; 733 734 int width, height; 735 atk_component_get_size(ATK_COMPONENT(m_element), &width, &height); 736 737 return height; 738 } 739 740 double AccessibilityUIElement::clickPointX() 741 { 742 // Note: This is not something we have in ATK. 743 return 0; 744 } 745 746 double AccessibilityUIElement::clickPointY() 747 { 748 // Note: This is not something we have in ATK. 749 return 0; 750 } 751 752 JSStringRef AccessibilityUIElement::orientation() const 753 { 754 if (!ATK_IS_OBJECT(m_element)) 755 return JSStringCreateWithCharacters(0, 0); 756 757 const char* axOrientation = 0; 758 if (checkElementState(m_element, ATK_STATE_HORIZONTAL)) 759 axOrientation = "AXOrientation: AXHorizontalOrientation"; 760 else if (checkElementState(m_element, ATK_STATE_VERTICAL)) 761 axOrientation = "AXOrientation: AXVerticalOrientation"; 762 763 if (!axOrientation) 764 return JSStringCreateWithCharacters(0, 0); 765 766 return JSStringCreateWithUTF8CString(axOrientation); 767 } 768 769 double AccessibilityUIElement::intValue() const 770 { 771 if (!ATK_IS_OBJECT(m_element)) 772 return 0; 773 774 if (ATK_IS_VALUE(m_element)) { 775 GValue value = G_VALUE_INIT; 776 atk_value_get_current_value(ATK_VALUE(m_element), &value); 777 if (!G_VALUE_HOLDS_FLOAT(&value)) 778 return 0; 779 return g_value_get_float(&value); 780 } 781 782 // Consider headings as an special case when returning the "int value" of 783 // an AccessibilityUIElement, so we can reuse some tests to check the level 784 // both for HTML headings and objects with the aria-level attribute. 785 if (atk_object_get_role(ATK_OBJECT(m_element)) == ATK_ROLE_HEADING) { 786 String headingLevel = getAttributeSetValueForId(ATK_OBJECT(m_element), ObjectAttributeType, "level"); 787 bool ok; 788 double headingLevelValue = headingLevel.toDouble(&ok); 789 if (ok) 790 return headingLevelValue; 791 } 792 793 return 0; 794 } 795 796 double AccessibilityUIElement::minValue() 797 { 798 if (!ATK_IS_VALUE(m_element)) 799 return 0; 800 801 GValue value = G_VALUE_INIT; 802 atk_value_get_minimum_value(ATK_VALUE(m_element), &value); 803 if (!G_VALUE_HOLDS_FLOAT(&value)) 804 return 0; 805 return g_value_get_float(&value); 806 } 807 808 double AccessibilityUIElement::maxValue() 809 { 810 if (!ATK_IS_VALUE(m_element)) 811 return 0; 812 813 GValue value = G_VALUE_INIT; 814 atk_value_get_maximum_value(ATK_VALUE(m_element), &value); 815 if (!G_VALUE_HOLDS_FLOAT(&value)) 816 return 0; 817 return g_value_get_float(&value); 818 } 819 820 JSStringRef AccessibilityUIElement::valueDescription() 821 { 822 // FIXME: implement after it has been implemented in ATK. 823 // See: https://bugzilla.gnome.org/show_bug.cgi?id=684576 824 return JSStringCreateWithCharacters(0, 0); 825 } 826 827 bool AccessibilityUIElement::isEnabled() 828 { 829 return checkElementState(m_element, ATK_STATE_ENABLED); 830 } 831 832 int AccessibilityUIElement::insertionPointLineNumber() 833 { 834 // FIXME: implement 835 return 0; 836 } 837 838 bool AccessibilityUIElement::isPressActionSupported() 839 { 840 // FIXME: implement 841 return false; 842 } 843 844 bool AccessibilityUIElement::isIncrementActionSupported() 845 { 846 // FIXME: implement 847 return false; 848 } 849 850 bool AccessibilityUIElement::isDecrementActionSupported() 851 { 852 // FIXME: implement 853 return false; 854 } 855 856 bool AccessibilityUIElement::isRequired() const 857 { 858 return checkElementState(m_element, ATK_STATE_REQUIRED); 859 } 860 861 bool AccessibilityUIElement::isFocused() const 862 { 863 if (!ATK_IS_OBJECT(m_element)) 864 return false; 865 866 GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element))); 867 gboolean isFocused = atk_state_set_contains_state(stateSet.get(), ATK_STATE_FOCUSED); 868 869 return isFocused; 870 } 871 872 bool AccessibilityUIElement::isSelected() const 873 { 874 return checkElementState(m_element, ATK_STATE_SELECTED); 875 } 876 877 int AccessibilityUIElement::hierarchicalLevel() const 878 { 879 // FIXME: implement 880 return 0; 881 } 882 883 bool AccessibilityUIElement::ariaIsGrabbed() const 884 { 885 return false; 886 } 887 888 JSStringRef AccessibilityUIElement::ariaDropEffects() const 889 { 890 return 0; 891 } 892 893 bool AccessibilityUIElement::isExpanded() const 894 { 895 if (!ATK_IS_OBJECT(m_element)) 896 return false; 897 898 GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element))); 899 gboolean isExpanded = atk_state_set_contains_state(stateSet.get(), ATK_STATE_EXPANDED); 900 901 return isExpanded; 902 } 903 904 bool AccessibilityUIElement::isChecked() const 905 { 906 if (!ATK_IS_OBJECT(m_element)) 907 return false; 908 909 GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element))); 910 gboolean isChecked = atk_state_set_contains_state(stateSet.get(), ATK_STATE_CHECKED); 911 912 return isChecked; 913 } 914 915 JSStringRef AccessibilityUIElement::attributesOfColumnHeaders() 916 { 917 // FIXME: implement 918 return JSStringCreateWithCharacters(0, 0); 919 } 920 921 JSStringRef AccessibilityUIElement::attributesOfRowHeaders() 922 { 923 // FIXME: implement 924 return JSStringCreateWithCharacters(0, 0); 925 } 926 927 JSStringRef AccessibilityUIElement::attributesOfColumns() 928 { 929 // FIXME: implement 930 return JSStringCreateWithCharacters(0, 0); 931 } 932 933 JSStringRef AccessibilityUIElement::attributesOfRows() 934 { 935 // FIXME: implement 936 return JSStringCreateWithCharacters(0, 0); 937 } 938 939 JSStringRef AccessibilityUIElement::attributesOfVisibleCells() 940 { 941 // FIXME: implement 942 return JSStringCreateWithCharacters(0, 0); 943 } 944 945 JSStringRef AccessibilityUIElement::attributesOfHeader() 946 { 947 // FIXME: implement 948 return JSStringCreateWithCharacters(0, 0); 949 } 950 951 int AccessibilityUIElement::indexInTable() 952 { 953 // FIXME: implement 954 return 0; 955 } 956 855 957 JSStringRef AccessibilityUIElement::rowIndexRange() 856 958 { … … 929 1031 930 1032 String atkAttributeName = coreAttributeToAtkAttribute(attribute); 931 if (atkAttributeName.isEmpty()) 932 return JSStringCreateWithCharacters(0, 0); 933 934 String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element), atkAttributeName.utf8().data()); 935 936 // In case of 'aria-invalid' when the attribute empty or has "false" for ATK 937 // according to http://www.w3.org/WAI/PF/aria-implementation/#mapping attribute 938 // is not mapped but layout tests will expect 'false'. 939 if (attributeValue.isEmpty() && atkAttributeName == "aria-invalid") 940 return JSStringCreateWithUTF8CString("false"); 941 942 // We need to translate ATK values exposed for 'aria-sort' (e.g. 'ascending') 943 // into those expected by the layout tests (e.g. 'AXAscendingSortDirection'). 944 if (atkAttributeName == "sort") { 945 if (attributeValue == "ascending") 946 return JSStringCreateWithUTF8CString("AXAscendingSortDirection"); 947 if (attributeValue == "descending") 948 return JSStringCreateWithUTF8CString("AXDescendingSortDirection"); 949 950 return JSStringCreateWithUTF8CString("AXUnknownSortDirection"); 951 } 1033 1034 // Try object attributes first. 1035 String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element), ObjectAttributeType, atkAttributeName); 1036 1037 // Try text attributes if the requested one was not found and we have an AtkText object. 1038 if (attributeValue.isEmpty() && ATK_IS_TEXT(m_element)) 1039 attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element), TextAttributeType, atkAttributeName); 952 1040 953 1041 return JSStringCreateWithUTF8CString(attributeValue.utf8().data()); … … 981 1069 return false; 982 1070 983 String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element), atkAttributeName.utf8().data()); 1071 // For now, an attribute is supported whether it's exposed as a object or a text attribute. 1072 String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element), ObjectAttributeType, atkAttributeName); 1073 if (attributeValue.isEmpty()) 1074 attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element), TextAttributeType, atkAttributeName); 1075 984 1076 return !attributeValue.isEmpty(); 985 }986 987 static void alterCurrentValue(PlatformUIElement element, int factor)988 {989 if (!ATK_IS_VALUE(element))990 return;991 992 GValue currentValue = G_VALUE_INIT;993 atk_value_get_current_value(ATK_VALUE(element), ¤tValue);994 995 GValue increment = G_VALUE_INIT;996 atk_value_get_minimum_increment(ATK_VALUE(element), &increment);997 998 GValue newValue = G_VALUE_INIT;999 g_value_init(&newValue, G_TYPE_FLOAT);1000 1001 g_value_set_float(&newValue, g_value_get_float(¤tValue) + factor * g_value_get_float(&increment));1002 atk_value_set_current_value(ATK_VALUE(element), &newValue);1003 1004 g_value_unset(&newValue);1005 g_value_unset(&increment);1006 g_value_unset(¤tValue);1007 1077 } 1008 1078 … … 1177 1247 return false; 1178 1248 1179 return equalIgnoringCase(getAttributeSetValueForId(ATK_OBJECT(m_element), "haspopup"), "true"); 1249 String hasPopupValue = getAttributeSetValueForId(ATK_OBJECT(m_element), ObjectAttributeType, "haspopup"); 1250 return equalIgnoringCase(hasPopupValue, "true"); 1180 1251 } 1181 1252 -
trunk/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp
r156551 r156835 2 2 * Copyright (C) 2011 Apple Inc. All Rights Reserved. 3 3 * Copyright (C) 2012 Igalia S.L. 4 * Copyright (C) 2013 Samsung Electronics. All rights reserved. 4 5 * 5 6 * Redistribution and use in source and binary forms, with or without … … 46 47 namespace WTR { 47 48 48 static String coreAttributeToAtkAttribute(JSStringRef attribute) 49 namespace { 50 51 enum AtkAttributeType { 52 ObjectAttributeType, 53 TextAttributeType 54 }; 55 56 enum AttributeDomain { 57 CoreDomain = 0, 58 AtkDomain 59 }; 60 61 enum AttributesIndex { 62 // Attribute names. 63 InvalidNameIndex = 0, 64 PlaceholderNameIndex, 65 SortNameIndex, 66 67 // Attribute values. 68 SortAscendingValueIndex, 69 SortDescendingValueIndex, 70 SortUnknownValueIndex, 71 72 NumberOfAttributes 73 }; 74 75 // Attribute names & Values (keep on sync with enum AttributesIndex). 76 const String attributesMap[][2] = { 77 // Attribute names. 78 { "AXInvalid", "invalid" }, 79 { "AXPlaceholderValue", "placeholder-text" } , 80 { "AXSortDirection", "sort" }, 81 82 // Attribute values. 83 { "AXAscendingSortDirection", "ascending" }, 84 { "AXDescendingSortDirection", "descending" }, 85 { "AXUnknownSortDirection", "unknown" } 86 }; 87 88 String coreAttributeToAtkAttribute(JSStringRef attribute) 49 89 { 50 90 size_t bufferSize = JSStringGetMaximumUTF8CStringSize(attribute); … … 53 93 54 94 String attributeString = String::fromUTF8(buffer.get()); 55 if (attributeString == "AXInvalid") 56 return "aria-invalid"; 57 58 if (attributeString == "AXPlaceholderValue") 59 return "placeholder-text"; 60 61 if (attributeString == "AXSortDirection") 62 return "sort"; 63 64 return String(); 65 } 66 67 static String getAttributeSetValueForId(AtkObject* accessible, const char* id) 68 { 69 const char* attributeValue = 0; 70 AtkAttributeSet* attributeSet = atk_object_get_attributes(accessible); 95 for (int i = 0; i < NumberOfAttributes; ++i) { 96 if (attributesMap[i][CoreDomain] == attributeString) 97 return attributesMap[i][AtkDomain]; 98 } 99 100 return attributeString; 101 } 102 103 String atkAttributeValueToCoreAttributeValue(AtkAttributeType type, const String& id, const String& value) 104 { 105 if (type == ObjectAttributeType) { 106 // We need to translate ATK values exposed for 'aria-sort' (e.g. 'ascending') 107 // into those expected by the layout tests (e.g. 'AXAscendingSortDirection'). 108 if (id == attributesMap[SortNameIndex][AtkDomain] && !value.isEmpty()) { 109 if (value == attributesMap[SortAscendingValueIndex][AtkDomain]) 110 return attributesMap[SortAscendingValueIndex][CoreDomain]; 111 if (value == attributesMap[SortDescendingValueIndex][AtkDomain]) 112 return attributesMap[SortDescendingValueIndex][CoreDomain]; 113 114 return attributesMap[SortUnknownValueIndex][CoreDomain]; 115 } 116 } else if (type == TextAttributeType) { 117 // In case of 'aria-invalid' when the attribute empty or has "false" for ATK 118 // it should not be mapped at all, but layout tests will expect 'false'. 119 if (id == attributesMap[InvalidNameIndex][AtkDomain] && value.isEmpty()) 120 return "false"; 121 } 122 123 return value; 124 } 125 126 AtkAttributeSet* getAttributeSet(AtkObject* accessible, AtkAttributeType type) 127 { 128 if (type == ObjectAttributeType) 129 return atk_object_get_attributes(accessible); 130 131 if (type == TextAttributeType) { 132 if (!ATK_IS_TEXT(accessible)) 133 return 0; 134 135 return atk_text_get_default_attributes(ATK_TEXT(accessible)); 136 } 137 138 ASSERT_NOT_REACHED(); 139 return 0; 140 } 141 142 String getAttributeSetValueForId(AtkObject* accessible, AtkAttributeType type, String id) 143 { 144 AtkAttributeSet* attributeSet = getAttributeSet(accessible, type); 145 if (!attributeSet) 146 return String(); 147 148 String attributeValue; 71 149 for (AtkAttributeSet* attributes = attributeSet; attributes; attributes = attributes->next) { 72 150 AtkAttribute* atkAttribute = static_cast<AtkAttribute*>(attributes->data); 73 if ( !strcmp(atkAttribute->name, id)) {74 attributeValue = atkAttribute->value;151 if (id == atkAttribute->name) { 152 attributeValue = String::fromUTF8(atkAttribute->value); 75 153 break; 76 154 } 77 155 } 78 79 String atkAttributeValue = String::fromUTF8(attributeValue);80 156 atk_attribute_set_free(attributeSet); 81 157 82 return atkAttributeValue; 83 } 84 85 static String getAtkAttributeSetAsString(AtkObject* accessible) 86 { 158 return atkAttributeValueToCoreAttributeValue(type, id, attributeValue); 159 } 160 161 String getAtkAttributeSetAsString(AtkObject* accessible, AtkAttributeType type) 162 { 163 AtkAttributeSet* attributeSet = getAttributeSet(accessible, type); 164 if (!attributeSet) 165 return String(); 166 87 167 StringBuilder builder; 88 89 AtkAttributeSet* attributeSet = atk_object_get_attributes(accessible);90 168 for (AtkAttributeSet* attributes = attributeSet; attributes; attributes = attributes->next) { 91 169 AtkAttribute* attribute = static_cast<AtkAttribute*>(attributes->data); … … 100 178 } 101 179 102 staticbool checkElementState(PlatformUIElement element, AtkStateType stateType)180 bool checkElementState(PlatformUIElement element, AtkStateType stateType) 103 181 { 104 182 if (!ATK_IS_OBJECT(element.get())) … … 109 187 } 110 188 111 staticJSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange)189 JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange) 112 190 { 113 191 GOwnPtr<gchar> rangeString(g_strdup("{0, 0}")); … … 147 225 } 148 226 149 staticvoid alterCurrentValue(PlatformUIElement element, int factor)227 void alterCurrentValue(PlatformUIElement element, int factor) 150 228 { 151 229 if (!ATK_IS_VALUE(element.get())) … … 169 247 } 170 248 171 staticgchar* replaceCharactersForResults(gchar* str)249 gchar* replaceCharactersForResults(gchar* str) 172 250 { 173 251 WTF::String uString = WTF::String::fromUTF8(str); … … 185 263 } 186 264 187 staticconst gchar* roleToString(AtkRole role)265 const gchar* roleToString(AtkRole role) 188 266 { 189 267 switch (role) { … … 299 377 } 300 378 301 staticString attributesOfElement(AccessibilityUIElement* element)379 String attributesOfElement(AccessibilityUIElement* element) 302 380 { 303 381 StringBuilder builder; … … 346 424 // We append the ATK specific attributes as a single line at the end. 347 425 builder.append("AXPlatformAttributes: "); 348 builder.append(getAtkAttributeSetAsString(element->platformUIElement().get() ));426 builder.append(getAtkAttributeSetAsString(element->platformUIElement().get(), ObjectAttributeType)); 349 427 350 428 return builder.toString(); 351 429 } 430 431 } // namespace 352 432 353 433 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element) … … 571 651 572 652 String atkAttributeName = coreAttributeToAtkAttribute(attribute); 573 if (atkAttributeName.isNull()) 574 return JSStringCreateWithCharacters(0, 0); 575 576 String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), atkAttributeName.utf8().data()); 577 578 // In case of 'aria-invalid' when the attribute empty or has "false" for ATK 579 // according to http://www.w3.org/WAI/PF/aria-implementation/#mapping attribute 580 // is not mapped but layout tests will expect 'false'. 581 if (attributeValue.isEmpty() && atkAttributeName == "aria-invalid") 582 return JSStringCreateWithUTF8CString("false"); 583 584 // We need to translate ATK values exposed for 'aria-sort' (e.g. 'ascending') 585 // into those expected by the layout tests (e.g. 'AXAscendingSortDirection'). 586 if (atkAttributeName == "sort") { 587 if (attributeValue == "ascending") 588 return JSStringCreateWithUTF8CString("AXAscendingSortDirection"); 589 if (attributeValue == "descending") 590 return JSStringCreateWithUTF8CString("AXDescendingSortDirection"); 591 592 return JSStringCreateWithUTF8CString("AXUnknownSortDirection"); 593 } 653 654 // Try object attributes first. 655 String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, atkAttributeName); 656 657 // Try text attributes if the requested one was not found and we have an AtkText object. 658 if (attributeValue.isEmpty() && ATK_IS_TEXT(m_element.get())) 659 attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), TextAttributeType, atkAttributeName); 594 660 595 661 return JSStringCreateWithUTF8CString(attributeValue.utf8().data()); … … 629 695 return false; 630 696 631 String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), atkAttributeName.utf8().data()); 697 // For now, an attribute is supported whether it's exposed as a object or a text attribute. 698 String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, atkAttributeName); 699 if (attributeValue.isEmpty()) 700 attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), TextAttributeType, atkAttributeName); 701 632 702 return !attributeValue.isEmpty(); 633 703 } … … 808 878 // both for HTML headings and objects with the aria-level attribute. 809 879 if (atk_object_get_role(ATK_OBJECT(m_element.get())) == ATK_ROLE_HEADING) { 810 String headingLevel = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), "level");880 String headingLevel = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "level"); 811 881 bool ok; 812 882 double headingLevelValue = headingLevel.toDouble(&ok); … … 1214 1284 return false; 1215 1285 1216 return equalIgnoringCase(getAttributeSetValueForId(ATK_OBJECT(m_element.get()), "haspopup"), "true"); 1286 String hasPopupValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "haspopup"); 1287 return equalIgnoringCase(hasPopupValue, "true"); 1217 1288 } 1218 1289
Note: See TracChangeset
for help on using the changeset viewer.