Changeset 286055 in webkit
- Timestamp:
- Nov 19, 2021, 5:35:55 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 9 edited
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/SourcesGTK.txt (modified) (1 diff)
-
Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp (modified) (2 diffs)
-
Source/WebCore/accessibility/atspi/AccessibilityAtspi.h (modified) (2 diffs)
-
Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp (modified) (4 diffs)
-
Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h (modified) (6 diffs)
-
Source/WebCore/accessibility/atspi/AccessibilityObjectHypertextAtspi.cpp (added)
-
Source/WebCore/accessibility/atspi/AccessibilityObjectTextAtspi.cpp (modified) (1 diff)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r286050 r286055 1 2021-11-19 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GTK][a11y] Add implementation of hypertext interface when building with ATSPI 4 https://bugs.webkit.org/show_bug.cgi?id=232708 5 6 Reviewed by Adrian Perez de Castro. 7 8 * SourcesGTK.txt: 9 * accessibility/atspi/AccessibilityAtspi.cpp: 10 (WebCore::AccessibilityAtspi::unregisterObject): 11 (WebCore::AccessibilityAtspi::registerHyperlink): 12 * accessibility/atspi/AccessibilityAtspi.h: 13 * accessibility/atspi/AccessibilityObjectAtspi.cpp: 14 (WebCore::AccessibilityObjectAtspi::interfacesForObject): 15 (WebCore::AccessibilityObjectAtspi::path): 16 (WebCore::AccessibilityObjectAtspi::hyperlinkReference): 17 (WebCore::AccessibilityObjectAtspi::buildInterfaces const): 18 * accessibility/atspi/AccessibilityObjectAtspi.h: 19 * accessibility/atspi/AccessibilityObjectHypertextAtspi.cpp: Added. 20 (WebCore::AccessibilityObjectAtspi::hyperlinkCount const): 21 (WebCore::AccessibilityObjectAtspi::hyperlink const): 22 (WebCore::AccessibilityObjectAtspi::hyperlinkIndex const): 23 * accessibility/atspi/AccessibilityObjectTextAtspi.cpp: 24 (WebCore::AccessibilityObjectAtspi::characterIndex const): 25 1 26 2021-11-19 Carlos Garcia Campos <cgarcia@igalia.com> 2 27 -
trunk/Source/WebCore/SourcesGTK.txt
r286050 r286055 44 44 accessibility/atspi/AccessibilityObjectComponentAtspi.cpp 45 45 accessibility/atspi/AccessibilityObjectHyperlinkAtspi.cpp 46 accessibility/atspi/AccessibilityObjectHypertextAtspi.cpp 46 47 accessibility/atspi/AccessibilityObjectTextAtspi.cpp 47 48 accessibility/atspi/AccessibilityObjectValueAtspi.cpp -
trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp
r285997 r286055 136 136 return; 137 137 138 if (m_atspiHyperlinks.contains(atspiObject.ptr())) { 139 auto registeredObjects = m_atspiHyperlinks.take(atspiObject.ptr()); 140 for (auto id : registeredObjects) 141 g_dbus_connection_unregister_object(m_connection.get(), id); 142 } 143 138 144 g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject->path().utf8().data(), "org.a11y.atspi.Event.Object", "StateChanged", 139 145 g_variant_new("(siiva{sv})", "defunct", TRUE, 0, g_variant_new_string("0"), nullptr), nullptr); … … 145 151 g_dbus_connection_unregister_object(m_connection.get(), id); 146 152 }); 153 } 154 155 String AccessibilityAtspi::registerHyperlink(AccessibilityObjectAtspi& atspiObject, Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>>&& interfaces) 156 { 157 RELEASE_ASSERT(!isMainThread()); 158 if (!m_connection) 159 return { }; 160 161 String path = makeString("/org/a11y/atspi/accessible/", createCanonicalUUIDString().replace('-', '_')); 162 Vector<unsigned, 1> registeredObjects; 163 registeredObjects.reserveInitialCapacity(interfaces.size()); 164 for (const auto& interface : interfaces) { 165 auto id = g_dbus_connection_register_object(m_connection.get(), path.utf8().data(), interface.first, interface.second, &atspiObject, nullptr, nullptr); 166 registeredObjects.uncheckedAppend(id); 167 } 168 m_atspiHyperlinks.add(&atspiObject, WTFMove(registeredObjects)); 169 170 return path; 147 171 } 148 172 -
trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.h
r285997 r286055 53 53 String registerObject(AccessibilityObjectAtspi&, Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>>&&); 54 54 void unregisterObject(AccessibilityObjectAtspi&); 55 String registerHyperlink(AccessibilityObjectAtspi&, Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>>&&); 55 56 56 57 enum class ChildrenChanged { Added, Removed }; … … 79 80 HashMap<AccessibilityRootAtspi*, Vector<unsigned, 2>> m_rootObjects; 80 81 HashMap<AccessibilityObjectAtspi*, Vector<unsigned, 20>> m_atspiObjects; 82 HashMap<AccessibilityObjectAtspi*, Vector<unsigned, 20>> m_atspiHyperlinks; 81 83 unsigned m_cacheID { 0 }; 82 84 HashMap<String, AccessibilityObjectAtspi*> m_cache; -
trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp
r286050 r286055 70 70 else if (!coreObject.isWebArea()) { 71 71 if (coreObject.roleValue() != AccessibilityRole::Table) { 72 interfaces.add(Interface::Hypertext); 72 73 if ((renderer && renderer->childrenInline()) || roleIsTextType(coreObject.roleValue()) || coreObject.isMathToken()) 73 74 interfaces.add(Interface::Text); … … 481 482 if (m_interfaces.contains(Interface::Hyperlink)) 482 483 interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_hyperlink_interface), &s_hyperlinkFunctions }); 484 if (m_interfaces.contains(Interface::Hypertext)) 485 interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_hypertext_interface), &s_hypertextFunctions }); 483 486 m_path = atspiRoot->atspi().registerObject(*this, WTFMove(interfaces)); 484 487 } … … 491 494 RELEASE_ASSERT(!isMainThread()); 492 495 return g_variant_new("(so)", root()->atspi().uniqueName(), path().utf8().data()); 496 } 497 498 GVariant* AccessibilityObjectAtspi::hyperlinkReference() 499 { 500 RELEASE_ASSERT(!isMainThread()); 501 if (m_hyperlinkPath.isNull()) { 502 path(); 503 m_hyperlinkPath = root()->atspi().registerHyperlink(*this, { { const_cast<GDBusInterfaceInfo*>(&webkit_hyperlink_interface), &s_hyperlinkFunctions } }); 504 } 505 506 return g_variant_new("(so)", root()->atspi().uniqueName(), m_hyperlinkPath.utf8().data()); 493 507 } 494 508 … … 1100 1114 if (m_interfaces.contains(Interface::Hyperlink)) 1101 1115 g_variant_builder_add(builder, "s", webkit_hyperlink_interface.name); 1116 if (m_interfaces.contains(Interface::Hypertext)) 1117 g_variant_builder_add(builder, "s", webkit_hypertext_interface.name); 1102 1118 } 1103 1119 -
trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h
r286050 r286055 48 48 Text = 1 << 2, 49 49 Value = 1 << 3, 50 Hyperlink = 1 << 4 50 Hyperlink = 1 << 4, 51 Hypertext = 1 << 5 51 52 }; 52 53 const OptionSet<Interface>& interfaces() const { return m_interfaces; } … … 67 68 const String& path(); 68 69 GVariant* reference(); 70 GVariant* hyperlinkReference(); 69 71 void serialize(GVariantBuilder*) const; 70 72 … … 144 146 int characterAtOffset(int) const; 145 147 std::optional<unsigned> characterOffset(UChar, int) const; 148 std::optional<unsigned> characterIndex(UChar, unsigned) const; 146 149 IntRect textExtents(int, int, uint32_t) const; 147 150 int offsetAtPoint(const IntPoint&, uint32_t) const; … … 155 158 unsigned offsetInParent() const; 156 159 160 unsigned hyperlinkCount() const; 161 AccessibilityObjectAtspi* hyperlink(unsigned) const; 162 std::optional<unsigned> hyperlinkIndex(unsigned) const; 163 157 164 static OptionSet<Interface> interfacesForObject(AXCoreObject&); 158 165 … … 162 169 static GDBusInterfaceVTable s_valueFunctions; 163 170 static GDBusInterfaceVTable s_hyperlinkFunctions; 171 static GDBusInterfaceVTable s_hypertextFunctions; 164 172 165 173 AXCoreObject* m_axObject { nullptr }; … … 170 178 Atomic<bool> m_isRegistered { false }; 171 179 String m_path; 180 String m_hyperlinkPath; 172 181 mutable int m_indexInParent { -1 }; 173 182 mutable Lock m_rootLock; -
trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectTextAtspi.cpp
r286050 r286055 509 509 } 510 510 511 std::optional<unsigned> AccessibilityObjectAtspi::characterIndex(UChar character, unsigned offset) const 512 { 513 auto utf16Text = text(); 514 auto utf8Text = utf16Text.utf8(); 515 if (utf8Text.isNull()) 516 return std::nullopt; 517 518 auto length = g_utf8_strlen(utf8Text.data(), -1); 519 if (offset >= length) 520 return std::nullopt; 521 522 auto mapping = offsetMapping(utf16Text); 523 auto utf16Offset = UTF8OffsetToUTF16(mapping, offset); 524 if (utf16Text[utf16Offset] != character) 525 return std::nullopt; 526 527 unsigned start = 0; 528 int index = -1; 529 size_t position; 530 while ((position = utf16Text.find(character, start)) != notFound) { 531 index++; 532 if (static_cast<unsigned>(position) == utf16Offset) 533 break; 534 start = position + 1; 535 } 536 537 if (index == -1) 538 return std::nullopt; 539 540 return index; 541 } 542 511 543 IntRect AccessibilityObjectAtspi::boundsForRange(unsigned utf16Offset, unsigned length, uint32_t coordinateType) const 512 544 { -
trunk/Tools/ChangeLog
r286054 r286055 1 2021-11-19 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GTK][a11y] Add implementation of hypertext interface when building with ATSPI 4 https://bugs.webkit.org/show_bug.cgi?id=232708 5 6 Reviewed by Adrian Perez de Castro. 7 8 Add unit tests to check hypertext interface. 9 10 * TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp: 11 (testHypertextBasic): 12 (beforeAll): 13 1 14 2021-11-19 Carlos Garcia Campos <cgarcia@igalia.com> 2 15 -
trunk/Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp
r286050 r286055 1818 1818 } 1819 1819 1820 static void testHypertextBasic(AccessibilityTest* test, gconstpointer) 1821 { 1822 test->showInWindow(800, 600); 1823 test->loadHtml( 1824 "<html>" 1825 " <body>" 1826 " <p>This is <button>button</button> and <a href='https://www.webkitgtk.org'>link</a> in a paragraph</p>" 1827 " </body>" 1828 "</html>", 1829 nullptr); 1830 test->waitUntilLoadFinished(); 1831 1832 auto testApp = test->findTestApplication(); 1833 g_assert_true(ATSPI_IS_ACCESSIBLE(testApp.get())); 1834 1835 auto documentWeb = test->findDocumentWeb(testApp.get()); 1836 g_assert_true(ATSPI_IS_ACCESSIBLE(documentWeb.get())); 1837 g_assert_cmpint(atspi_accessible_get_child_count(documentWeb.get(), nullptr), ==, 1); 1838 1839 auto p = adoptGRef(atspi_accessible_get_child_at_index(documentWeb.get(), 0, nullptr)); 1840 g_assert_true(ATSPI_IS_HYPERTEXT(p.get())); 1841 g_assert_cmpint(atspi_hypertext_get_n_links(ATSPI_HYPERTEXT(p.get()), nullptr), ==, 2); 1842 1843 auto link = adoptGRef(atspi_hypertext_get_link(ATSPI_HYPERTEXT(p.get()), 0, nullptr)); 1844 g_assert_true(ATSPI_IS_HYPERLINK(link.get())); 1845 g_assert_cmpint(atspi_hyperlink_get_n_anchors(ATSPI_HYPERLINK(link.get()), nullptr), ==, 1); 1846 g_assert_true(atspi_hyperlink_is_valid(ATSPI_HYPERLINK(link.get()), nullptr)); 1847 g_assert_cmpint(atspi_hyperlink_get_start_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 8); 1848 #if USE(ATSPI) 1849 g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 9); 1850 #else 1851 g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 15); 1852 #endif 1853 GUniquePtr<char> uri(atspi_hyperlink_get_uri(ATSPI_HYPERLINK(link.get()), 0, nullptr)); 1854 g_assert_cmpstr(uri.get(), ==, ""); 1855 auto button = adoptGRef(atspi_accessible_get_child_at_index(p.get(), 0, nullptr)); 1856 g_assert_true(atspi_hyperlink_get_object(ATSPI_HYPERLINK(link.get()), 0, nullptr) == button.get()); 1857 1858 link = adoptGRef(atspi_hypertext_get_link(ATSPI_HYPERTEXT(p.get()), 1, nullptr)); 1859 g_assert_true(ATSPI_IS_HYPERLINK(link.get())); 1860 g_assert_cmpint(atspi_hyperlink_get_n_anchors(ATSPI_HYPERLINK(link.get()), nullptr), ==, 1); 1861 g_assert_true(atspi_hyperlink_is_valid(ATSPI_HYPERLINK(link.get()), nullptr)); 1862 #if USE(ATSPI) 1863 g_assert_cmpint(atspi_hyperlink_get_start_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 14); 1864 g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 15); 1865 #else 1866 g_assert_cmpint(atspi_hyperlink_get_start_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 20); 1867 g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 24); 1868 #endif 1869 uri.reset(atspi_hyperlink_get_uri(ATSPI_HYPERLINK(link.get()), 0, nullptr)); 1870 g_assert_cmpstr(uri.get(), ==, "https://www.webkitgtk.org/"); 1871 auto a = adoptGRef(atspi_accessible_get_child_at_index(p.get(), 1, nullptr)); 1872 g_assert_true(atspi_hyperlink_get_object(ATSPI_HYPERLINK(link.get()), 0, nullptr) == a.get()); 1873 1874 g_assert_cmpint(atspi_hypertext_get_link_index(ATSPI_HYPERTEXT(p.get()), 0, nullptr), ==, -1); 1875 g_assert_cmpint(atspi_hypertext_get_link_index(ATSPI_HYPERTEXT(p.get()), 8, nullptr), ==, 0); 1876 #if USE(ATSPI) 1877 g_assert_cmpint(atspi_hypertext_get_link_index(ATSPI_HYPERTEXT(p.get()), 9, nullptr), ==, -1); 1878 g_assert_cmpint(atspi_hypertext_get_link_index(ATSPI_HYPERTEXT(p.get()), 14, nullptr), ==, 1); 1879 g_assert_cmpint(atspi_hypertext_get_link_index(ATSPI_HYPERTEXT(p.get()), 15, nullptr), ==, -1); 1880 #else 1881 g_assert_cmpint(atspi_hypertext_get_link_index(ATSPI_HYPERTEXT(p.get()), 15, nullptr), ==, -1); 1882 g_assert_cmpint(atspi_hypertext_get_link_index(ATSPI_HYPERTEXT(p.get()), 20, nullptr), ==, 1); 1883 g_assert_cmpint(atspi_hypertext_get_link_index(ATSPI_HYPERTEXT(p.get()), 24, nullptr), ==, -1); 1884 #endif 1885 } 1886 1820 1887 void beforeAll() 1821 1888 { … … 1840 1907 AccessibilityTest::add("WebKitAccessibility", "value/basic", testValueBasic); 1841 1908 AccessibilityTest::add("WebKitAccessibility", "hyperlink/basic", testHyperlinkBasic); 1909 AccessibilityTest::add("WebKitAccessibility", "hypertext/basic", testHypertextBasic); 1842 1910 } 1843 1911
Note:
See TracChangeset
for help on using the changeset viewer.