WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
wcore-atspi-hyperlink.diff (text/plain), 27.35 KB, created by
Carlos Garcia Campos
on 2021-11-18 04:52:17 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Carlos Garcia Campos
Created:
2021-11-18 04:52:17 PST
Size:
27.35 KB
patch
obsolete
>diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index f650dc122a4a..051257e7f08c 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,28 @@ >+2021-11-04 Carlos Garcia Campos <cgarcia@igalia.com> >+ >+ [GTK][a11y] Add implementation of hyperlink interface when building with ATSPI >+ https://bugs.webkit.org/show_bug.cgi?id=232707 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add hyperlink implementation and make links be handled as replaced objects too, to ensure all hyperlinks are >+ handled the same way. That's consistent with chromium. >+ >+ * SourcesGTK.txt: >+ * accessibility/atspi/AccessibilityObjectAtspi.cpp: >+ (WebCore::AccessibilityObjectAtspi::interfacesForObject): >+ (WebCore::AccessibilityObjectAtspi::path): >+ (WebCore::AccessibilityObjectAtspi::buildInterfaces const): >+ * accessibility/atspi/AccessibilityObjectAtspi.h: >+ * accessibility/atspi/AccessibilityObjectHyperlinkAtspi.cpp: Added. >+ (WebCore::AccessibilityObjectAtspi::url const): >+ (WebCore::AccessibilityObjectAtspi::offsetInParent const): >+ * accessibility/atspi/AccessibilityObjectTextAtspi.cpp: >+ (WebCore::AccessibilityObjectAtspi::characterOffset const): >+ * editing/TextIterator.cpp: >+ (WebCore::isRendererReplacedElement): >+ (WebCore::TextIterator::handleReplacedElement): >+ > 2021-10-26 Carlos Garcia Campos <cgarcia@igalia.com> > > [GTK][a11y] Add implementation of value interface when building with ATSPI >diff --git a/Source/WebCore/SourcesGTK.txt b/Source/WebCore/SourcesGTK.txt >index 477e3156d771..18845cc0217c 100644 >--- a/Source/WebCore/SourcesGTK.txt >+++ b/Source/WebCore/SourcesGTK.txt >@@ -42,6 +42,7 @@ accessibility/atk/WebKitAccessibleUtil.cpp > accessibility/atspi/AccessibilityAtspi.cpp > accessibility/atspi/AccessibilityObjectAtspi.cpp > accessibility/atspi/AccessibilityObjectComponentAtspi.cpp >+accessibility/atspi/AccessibilityObjectHyperlinkAtspi.cpp > accessibility/atspi/AccessibilityObjectTextAtspi.cpp > accessibility/atspi/AccessibilityObjectValueAtspi.cpp > accessibility/atspi/AccessibilityRootAtspi.cpp >diff --git a/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp b/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp >index 08a272b39159..abff5ab7ba26 100644 >--- a/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp >+++ b/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp >@@ -30,6 +30,7 @@ > #include "RenderAncestorIterator.h" > #include "RenderBlock.h" > #include "RenderObject.h" >+#include "TextIterator.h" > #include <glib/gi18n-lib.h> > #include <wtf/MainThread.h> > #include <wtf/UUID.h> >@@ -86,6 +87,9 @@ OptionSet<AccessibilityObjectAtspi::Interface> AccessibilityObjectAtspi::interfa > if (coreObject.supportsRangeValue()) > interfaces.add(Interface::Value); > >+ if (coreObject.isLink() || (isRendererReplacedElement(renderer))) >+ interfaces.add(Interface::Hyperlink); >+ > return interfaces; > } > >@@ -474,6 +478,8 @@ const String& AccessibilityObjectAtspi::path() > interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_text_interface), &s_textFunctions }); > if (m_interfaces.contains(Interface::Value)) > interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_value_interface), &s_valueFunctions }); >+ if (m_interfaces.contains(Interface::Hyperlink)) >+ interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_hyperlink_interface), &s_hyperlinkFunctions }); > m_path = atspiRoot->atspi().registerObject(*this, WTFMove(interfaces)); > } > >@@ -1091,6 +1097,8 @@ void AccessibilityObjectAtspi::buildInterfaces(GVariantBuilder* builder) const > g_variant_builder_add(builder, "s", webkit_text_interface.name); > if (m_interfaces.contains(Interface::Value)) > g_variant_builder_add(builder, "s", webkit_value_interface.name); >+ if (m_interfaces.contains(Interface::Hyperlink)) >+ g_variant_builder_add(builder, "s", webkit_hyperlink_interface.name); > } > > void AccessibilityObjectAtspi::serialize(GVariantBuilder* builder) const >diff --git a/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h b/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h >index 3ca223737267..899c5ec254a2 100644 >--- a/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h >+++ b/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h >@@ -46,7 +46,8 @@ public: > Accessible = 1 << 0, > Component = 1 << 1, > Text = 1 << 2, >- Value = 1 << 3 >+ Value = 1 << 3, >+ Hyperlink = 1 << 4 > }; > const OptionSet<Interface>& interfaces() const { return m_interfaces; } > >@@ -117,6 +118,8 @@ public: > WEBCORE_EXPORT double minimumIncrement() const; > void valueChanged(double); > >+ WEBCORE_EXPORT URL url() const; >+ > private: > explicit AccessibilityObjectAtspi(AXCoreObject*); > >@@ -139,6 +142,7 @@ private: > CString text(int, int) const; > CString textAtOffset(int, TextGranularity, int&, int&) const; > int characterAtOffset(int) const; >+ std::optional<unsigned> characterOffset(UChar, int) const; > IntRect textExtents(int, int, uint32_t) const; > int offsetAtPoint(const IntPoint&, uint32_t) const; > IntPoint boundsForSelection(const VisibleSelection&) const; >@@ -148,12 +152,15 @@ private: > bool scrollToMakeVisible(int, int, uint32_t) const; > bool scrollToPoint(int, int, uint32_t, int, int) const; > >+ unsigned offsetInParent() const; >+ > static OptionSet<Interface> interfacesForObject(AXCoreObject&); > > static GDBusInterfaceVTable s_accessibleFunctions; > static GDBusInterfaceVTable s_componentFunctions; > static GDBusInterfaceVTable s_textFunctions; > static GDBusInterfaceVTable s_valueFunctions; >+ static GDBusInterfaceVTable s_hyperlinkFunctions; > > AXCoreObject* m_axObject { nullptr }; > AXCoreObject* m_coreObject { nullptr }; >diff --git a/Source/WebCore/accessibility/atspi/AccessibilityObjectHyperlinkAtspi.cpp b/Source/WebCore/accessibility/atspi/AccessibilityObjectHyperlinkAtspi.cpp >new file mode 100644 >index 000000000000..639b4033725f >--- /dev/null >+++ b/Source/WebCore/accessibility/atspi/AccessibilityObjectHyperlinkAtspi.cpp >@@ -0,0 +1,115 @@ >+/* >+ * Copyright (C) 2021 Igalia S.L. >+ * >+ * This library is free software; you can redistribute it and/or >+ * modify it under the terms of the GNU Library General Public >+ * License as published by the Free Software Foundation; either >+ * version 2 of the License, or (at your option) any later version. >+ * >+ * This library is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >+ * Library General Public License for more details. >+ * >+ * You should have received a copy of the GNU Library General Public License >+ * along with this library; see the file COPYING.LIB. If not, write to >+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, >+ * Boston, MA 02110-1301, USA. >+ */ >+ >+#include "config.h" >+#include "AccessibilityObjectAtspi.h" >+ >+#if ENABLE(ACCESSIBILITY) && USE(ATSPI) >+ >+#include "AccessibilityRootAtspi.h" >+#include <gio/gio.h> >+#include <wtf/URL.h> >+#include <wtf/unicode/CharacterNames.h> >+ >+namespace WebCore { >+ >+GDBusInterfaceVTable AccessibilityObjectAtspi::s_hyperlinkFunctions = { >+ // method_call >+ [](GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData) { >+ RELEASE_ASSERT(!isMainThread()); >+ auto atspiObject = Ref { *static_cast<AccessibilityObjectAtspi*>(userData) }; >+ atspiObject->updateBackingStore(); >+ >+ if (!g_strcmp0(methodName, "GetObject")) { >+ int index; >+ g_variant_get(parameters, "(i)", &index); >+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(@(so))", !index ? atspiObject->reference() : atspiObject->root()->atspi().nullReference())); >+ } else if (!g_strcmp0(methodName, "GetURI")) { >+ int index; >+ g_variant_get(parameters, "(i)", &index); >+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", !index ? atspiObject->url().string().utf8().data() : "")); >+ } else if (!g_strcmp0(methodName, "IsValid")) >+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", atspiObject->m_axObject ? TRUE : FALSE)); >+ }, >+ // get_property >+ [](GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar* propertyName, GError** error, gpointer userData) -> GVariant* { >+ RELEASE_ASSERT(!isMainThread()); >+ auto atspiObject = Ref { *static_cast<AccessibilityObjectAtspi*>(userData) }; >+ atspiObject->updateBackingStore(); >+ >+ if (!g_strcmp0(propertyName, "NAnchors")) >+ return g_variant_new_int32(1); >+ if (!g_strcmp0(propertyName, "StartIndex")) >+ return g_variant_new_int32(atspiObject->offsetInParent()); >+ if (!g_strcmp0(propertyName, "EndIndex")) >+ return g_variant_new_int32(atspiObject->offsetInParent() + 1); >+ >+ g_set_error(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Unknown property '%s'", propertyName); >+ return nullptr; >+ }, >+ // set_property, >+ nullptr, >+ // padding >+ nullptr >+}; >+ >+URL AccessibilityObjectAtspi::url() const >+{ >+ AXCoreObject* axObject = isMainThread() ? m_coreObject : m_axObject; >+ return axObject ? axObject->url() : URL(); >+} >+ >+unsigned AccessibilityObjectAtspi::offsetInParent() const >+{ >+ return Accessibility::retrieveValueFromMainThread<unsigned>([this]() -> unsigned { >+ if (m_coreObject) >+ m_coreObject->updateBackingStore(); >+ >+ if (!m_coreObject) >+ return 0; >+ >+ auto* parent = m_coreObject->parentObjectUnignored(); >+ if (!parent || !parent->wrapper()) >+ return 0; >+ >+ int index = -1; >+ const auto& children = parent->children(); >+ for (const auto& child : children) { >+ if (child->accessibilityIsIgnored()) >+ continue; >+ >+ auto* wrapper = child->wrapper(); >+ if (!wrapper || !wrapper->interfaces().contains(Interface::Hyperlink)) >+ continue; >+ >+ index++; >+ if (wrapper == this) >+ break; >+ } >+ >+ if (index == -1) >+ return 0; >+ >+ return parent->wrapper()->characterOffset(objectReplacementCharacter, index).value_or(0); >+ }); >+} >+ >+} // namespace WebCore >+ >+#endif // ENABLE(ACCESSIBILITY) && USE(ATSPI) >diff --git a/Source/WebCore/accessibility/atspi/AccessibilityObjectTextAtspi.cpp b/Source/WebCore/accessibility/atspi/AccessibilityObjectTextAtspi.cpp >index a9ae0808800c..37bf42f5ee54 100644 >--- a/Source/WebCore/accessibility/atspi/AccessibilityObjectTextAtspi.cpp >+++ b/Source/WebCore/accessibility/atspi/AccessibilityObjectTextAtspi.cpp >@@ -21,13 +21,18 @@ > #include "AccessibilityObjectAtspi.h" > > #if ENABLE(ACCESSIBILITY) && USE(ATSPI) >+#include "AXObjectCache.h" > #include "AccessibilityAtspiEnums.h" >+#include "AccessibilityObject.h" > #include "AccessibilityObjectInterface.h" >+#include "AccessibilityRootAtspi.h" > #include "Editing.h" > #include "PlatformScreen.h" >+#include "RenderLayer.h" > #include "SurrogatePairAwareTextIterator.h" > #include "TextIterator.h" > #include "VisibleUnits.h" >+#include <gio/gio.h> > > namespace WebCore { > >@@ -484,6 +489,24 @@ int AccessibilityObjectAtspi::characterAtOffset(int offset) const > return g_utf8_get_char(g_utf8_offset_to_pointer(utf8Text.data(), offset)); > } > >+std::optional<unsigned> AccessibilityObjectAtspi::characterOffset(UChar character, int index) const >+{ >+ auto utf16Text = text(); >+ unsigned start = 0; >+ size_t offset; >+ while ((offset = utf16Text.find(character, start)) != notFound) { >+ start = offset + 1; >+ if (--index == -1) >+ break; >+ } >+ >+ if (offset == notFound) >+ return std::nullopt; >+ >+ auto mapping = offsetMapping(utf16Text); >+ return UTF16OffsetToUTF8(mapping, offset); >+} >+ > IntRect AccessibilityObjectAtspi::boundsForRange(unsigned utf16Offset, unsigned length, uint32_t coordinateType) const > { > return Accessibility::retrieveValueFromMainThread<IntRect>([this, utf16Offset, length, coordinateType]() -> IntRect { >diff --git a/Source/WebCore/editing/TextIterator.cpp b/Source/WebCore/editing/TextIterator.cpp >index b94d9bee0eb9..fa0e0bf9bb5a 100644 >--- a/Source/WebCore/editing/TextIterator.cpp >+++ b/Source/WebCore/editing/TextIterator.cpp >@@ -277,6 +277,11 @@ bool isRendererReplacedElement(RenderObject* renderer) > return true; > if (equalLettersIgnoringASCIICase(element.attributeWithoutSynchronization(roleAttr), "img")) > return true; >+#if USE(ATSPI) >+ // Links are also replaced with object replacement character in ATSPI. >+ if (element.isLink()) >+ return true; >+#endif > } > > return false; >@@ -750,7 +755,7 @@ bool TextIterator::handleReplacedElement() > > m_hasEmitted = true; > >- if (m_behaviors.contains(TextIteratorBehavior::EmitsObjectReplacementCharacters) && renderer.isReplaced()) { >+ if (m_behaviors.contains(TextIteratorBehavior::EmitsObjectReplacementCharacters)) { > emitCharacter(objectReplacementCharacter, *m_node->parentNode(), m_node, 0, 1); > // Don't process subtrees for embedded objects. If the text there is required, > // it must be explicitly asked by specifying a range falling inside its boundaries. >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index c69b977c1913..aef3467e8d91 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,19 @@ >+2021-11-04 Carlos Garcia Campos <cgarcia@igalia.com> >+ >+ [GTK][a11y] Add implementation of hyperlink interface when building with ATSPI >+ https://bugs.webkit.org/show_bug.cgi?id=232707 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add unit tests to check hyperlink interface and implement AccessibilityUIElement::url() in WTR. >+ >+ * TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp: >+ (testTextReplacedObjects): >+ (testHyperlinkBasic): >+ (beforeAll): >+ * WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp: >+ (WTR::AccessibilityUIElement::url): >+ > 2021-10-26 Carlos Garcia Campos <cgarcia@igalia.com> > > [GTK][a11y] Add implementation of value interface when building with ATSPI >diff --git a/Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp b/Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp >index 3b238d6b3e08..9fbd51458944 100644 >--- a/Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp >+++ b/Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp >@@ -1533,6 +1533,7 @@ static void testTextReplacedObjects(AccessibilityTest* test, gconstpointer) > "<html>" > " <body>" > " <p>This is <button>button1</button> and <button>button2</button> in paragraph</p>" >+ " <p>This is <a href='#'>link1</a> and <a href='#'>link2</a> in paragraph</p>" > " </body>" > "</html>", > nullptr); >@@ -1543,7 +1544,7 @@ static void testTextReplacedObjects(AccessibilityTest* test, gconstpointer) > > auto documentWeb = test->findDocumentWeb(testApp.get()); > g_assert_true(ATSPI_IS_ACCESSIBLE(documentWeb.get())); >- g_assert_cmpint(atspi_accessible_get_child_count(documentWeb.get(), nullptr), ==, 1); >+ g_assert_cmpint(atspi_accessible_get_child_count(documentWeb.get(), nullptr), ==, 2); > > auto p = adoptGRef(atspi_accessible_get_child_at_index(documentWeb.get(), 0, nullptr)); > g_assert_true(ATSPI_IS_TEXT(p.get())); >@@ -1611,6 +1612,24 @@ static void testTextReplacedObjects(AccessibilityTest* test, gconstpointer) > g_assert_cmpuint(g_hash_table_size(attributes.get()), ==, 0); > g_assert_cmpint(startOffset, ==, 15); > g_assert_cmpint(endOffset, ==, 28); >+ >+ // Links are also replaced elements. >+ p = adoptGRef(atspi_accessible_get_child_at_index(documentWeb.get(), 1, nullptr)); >+ g_assert_true(ATSPI_IS_TEXT(p.get())); >+ g_assert_cmpint(atspi_text_get_character_count(ATSPI_TEXT(p.get()), nullptr), ==, 28); >+ text.reset(atspi_text_get_text(ATSPI_TEXT(p.get()), 0, -1, nullptr)); >+ g_assert_cmpstr(text.get(), ==, "This is \357\277\274 and \357\277\274 in paragraph"); >+ g_assert_cmpint(atspi_accessible_get_child_count(p.get(), nullptr), ==, 2); >+ >+ auto link1 = adoptGRef(atspi_accessible_get_child_at_index(p.get(), 0, nullptr)); >+ g_assert_true(ATSPI_IS_TEXT(link1.get())); >+ text.reset(atspi_text_get_text(ATSPI_TEXT(link1.get()), 0, -1, nullptr)); >+ g_assert_cmpstr(text.get(), ==, "link1"); >+ >+ auto link2 = adoptGRef(atspi_accessible_get_child_at_index(p.get(), 1, nullptr)); >+ g_assert_true(ATSPI_IS_TEXT(link2.get())); >+ text.reset(atspi_text_get_text(ATSPI_TEXT(link2.get()), 0, -1, nullptr)); >+ g_assert_cmpstr(text.get(), ==, "link2"); > #endif > } > >@@ -1665,6 +1684,139 @@ static void testValueBasic(AccessibilityTest* test, gconstpointer) > g_assert_cmpfloat(atspi_value_get_current_value(ATSPI_VALUE(slider.get()), nullptr), ==, 0); > } > >+static void testHyperlinkBasic(AccessibilityTest* test, gconstpointer) >+{ >+ test->showInWindow(800, 600); >+ test->loadHtml( >+ "<html>" >+ " <body>" >+ " <a href='https://www.webkitgtk.org'>WebKitGTK</a>" >+ " <div role='link'>Link</div>" >+ " <p>This is <button>button1</button> and <button>button2</button> in a paragraph</p>" >+ " <p>This is <a href='https://www.webkitgtk.org'>link1</a> and <a href='https://www.gnome.org'>link2</a> in paragraph</p>" >+ " </body>" >+ "</html>", >+ nullptr); >+ test->waitUntilLoadFinished(); >+ >+ auto testApp = test->findTestApplication(); >+ g_assert_true(ATSPI_IS_ACCESSIBLE(testApp.get())); >+ >+ auto documentWeb = test->findDocumentWeb(testApp.get()); >+ g_assert_true(ATSPI_IS_ACCESSIBLE(documentWeb.get())); >+ g_assert_cmpint(atspi_accessible_get_child_count(documentWeb.get(), nullptr), ==, 4); >+ >+ auto section = adoptGRef(atspi_accessible_get_child_at_index(documentWeb.get(), 0, nullptr)); >+ g_assert_true(ATSPI_IS_ACCESSIBLE(section.get())); >+ g_assert_cmpint(atspi_accessible_get_role(section.get(), nullptr), ==, ATSPI_ROLE_SECTION); >+ g_assert_cmpint(atspi_accessible_get_child_count(section.get(), nullptr), ==, 1); >+ >+ auto a = adoptGRef(atspi_accessible_get_child_at_index(section.get(), 0, nullptr)); >+ g_assert_true(ATSPI_IS_ACCESSIBLE(a.get())); >+ g_assert_cmpint(atspi_accessible_get_role(a.get(), nullptr), ==, ATSPI_ROLE_LINK); >+ auto link = adoptGRef(atspi_accessible_get_hyperlink(a.get())); >+ g_assert_true(ATSPI_IS_HYPERLINK(link.get())); >+ g_assert_cmpint(atspi_hyperlink_get_n_anchors(ATSPI_HYPERLINK(link.get()), nullptr), ==, 1); >+ g_assert_true(atspi_hyperlink_is_valid(ATSPI_HYPERLINK(link.get()), nullptr)); >+ g_assert_cmpint(atspi_hyperlink_get_start_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 0); >+#if USE(ATSPI) >+ g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 1); >+#else >+ g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 0); >+#endif >+ GUniquePtr<char> uri(atspi_hyperlink_get_uri(ATSPI_HYPERLINK(link.get()), 0, nullptr)); >+ g_assert_cmpstr(uri.get(), ==, "https://www.webkitgtk.org/"); >+ g_assert_true(atspi_hyperlink_get_object(ATSPI_HYPERLINK(link.get()), 0, nullptr) == a.get()); >+ >+ auto div = adoptGRef(atspi_accessible_get_child_at_index(documentWeb.get(), 1, nullptr)); >+ g_assert_true(ATSPI_IS_ACCESSIBLE(div.get())); >+ g_assert_cmpint(atspi_accessible_get_role(div.get(), nullptr), ==, ATSPI_ROLE_LINK); >+ link = adoptGRef(atspi_accessible_get_hyperlink(div.get())); >+ g_assert_true(ATSPI_IS_HYPERLINK(link.get())); >+ g_assert_cmpint(atspi_hyperlink_get_n_anchors(ATSPI_HYPERLINK(link.get()), nullptr), ==, 1); >+ g_assert_true(atspi_hyperlink_is_valid(ATSPI_HYPERLINK(link.get()), nullptr)); >+#if USE(ATSPI) >+ g_assert_cmpint(atspi_hyperlink_get_start_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 0); >+ g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 1); >+#else >+ g_assert_cmpint(atspi_hyperlink_get_start_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 10); >+ g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 14); >+#endif >+ uri.reset(atspi_hyperlink_get_uri(ATSPI_HYPERLINK(link.get()), 0, nullptr)); >+ g_assert_cmpstr(uri.get(), ==, ""); >+ g_assert_true(atspi_hyperlink_get_object(ATSPI_HYPERLINK(link.get()), 0, nullptr) == div.get()); >+ >+ auto p = adoptGRef(atspi_accessible_get_child_at_index(documentWeb.get(), 2, nullptr)); >+ g_assert_true(ATSPI_IS_ACCESSIBLE(p.get())); >+ g_assert_cmpint(atspi_accessible_get_child_count(p.get(), nullptr), ==, 2); >+ auto button1 = adoptGRef(atspi_accessible_get_child_at_index(p.get(), 0, nullptr)); >+ g_assert_true(ATSPI_IS_ACCESSIBLE(button1.get())); >+ link = adoptGRef(atspi_accessible_get_hyperlink(button1.get())); >+ g_assert_true(ATSPI_IS_HYPERLINK(link.get())); >+ g_assert_cmpint(atspi_hyperlink_get_n_anchors(ATSPI_HYPERLINK(link.get()), nullptr), ==, 1); >+ g_assert_true(atspi_hyperlink_is_valid(ATSPI_HYPERLINK(link.get()), nullptr)); >+ g_assert_cmpint(atspi_hyperlink_get_start_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 8); >+#if USE(ATSPI) >+ g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 9); >+#else >+ g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 16); >+#endif >+ uri.reset(atspi_hyperlink_get_uri(ATSPI_HYPERLINK(link.get()), 0, nullptr)); >+ g_assert_cmpstr(uri.get(), ==, ""); >+ g_assert_true(atspi_hyperlink_get_object(ATSPI_HYPERLINK(link.get()), 0, nullptr) == button1.get()); >+ auto button2 = adoptGRef(atspi_accessible_get_child_at_index(p.get(), 1, nullptr)); >+ g_assert_true(ATSPI_IS_ACCESSIBLE(button2.get())); >+ link = adoptGRef(atspi_accessible_get_hyperlink(button2.get())); >+ g_assert_true(ATSPI_IS_HYPERLINK(link.get())); >+ g_assert_cmpint(atspi_hyperlink_get_n_anchors(ATSPI_HYPERLINK(link.get()), nullptr), ==, 1); >+ g_assert_true(atspi_hyperlink_is_valid(ATSPI_HYPERLINK(link.get()), nullptr)); >+#if USE(ATSPI) >+ g_assert_cmpint(atspi_hyperlink_get_start_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 14); >+ g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 15); >+#else >+ g_assert_cmpint(atspi_hyperlink_get_start_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 21); >+ g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 29); >+#endif >+ uri.reset(atspi_hyperlink_get_uri(ATSPI_HYPERLINK(link.get()), 0, nullptr)); >+ g_assert_cmpstr(uri.get(), ==, ""); >+ g_assert_true(atspi_hyperlink_get_object(ATSPI_HYPERLINK(link.get()), 0, nullptr) == button2.get()); >+ >+ p = adoptGRef(atspi_accessible_get_child_at_index(documentWeb.get(), 3, nullptr)); >+ g_assert_true(ATSPI_IS_ACCESSIBLE(p.get())); >+ g_assert_cmpint(atspi_accessible_get_child_count(p.get(), nullptr), ==, 2); >+ auto link1 = adoptGRef(atspi_accessible_get_child_at_index(p.get(), 0, nullptr)); >+ g_assert_true(ATSPI_IS_ACCESSIBLE(link1.get())); >+ link = adoptGRef(atspi_accessible_get_hyperlink(link1.get())); >+ g_assert_true(ATSPI_IS_HYPERLINK(link.get())); >+ g_assert_cmpint(atspi_hyperlink_get_n_anchors(ATSPI_HYPERLINK(link.get()), nullptr), ==, 1); >+ g_assert_true(atspi_hyperlink_is_valid(ATSPI_HYPERLINK(link.get()), nullptr)); >+ g_assert_cmpint(atspi_hyperlink_get_start_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 8); >+#if USE(ATSPI) >+ g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 9); >+#else >+ g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 13); >+#endif >+ uri.reset(atspi_hyperlink_get_uri(ATSPI_HYPERLINK(link.get()), 0, nullptr)); >+ g_assert_cmpstr(uri.get(), ==, "https://www.webkitgtk.org/"); >+ g_assert_true(atspi_hyperlink_get_object(ATSPI_HYPERLINK(link.get()), 0, nullptr) == link1.get()); >+ auto link2 = adoptGRef(atspi_accessible_get_child_at_index(p.get(), 1, nullptr)); >+ g_assert_true(ATSPI_IS_ACCESSIBLE(link2.get())); >+ link = adoptGRef(atspi_accessible_get_hyperlink(link2.get())); >+ g_assert_true(ATSPI_IS_HYPERLINK(link.get())); >+ g_assert_cmpint(atspi_hyperlink_get_n_anchors(ATSPI_HYPERLINK(link.get()), nullptr), ==, 1); >+ g_assert_true(atspi_hyperlink_is_valid(ATSPI_HYPERLINK(link.get()), nullptr)); >+#if USE(ATSPI) >+ g_assert_cmpint(atspi_hyperlink_get_start_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 14); >+ g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 15); >+#else >+ g_assert_cmpint(atspi_hyperlink_get_start_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 18); >+ g_assert_cmpint(atspi_hyperlink_get_end_index(ATSPI_HYPERLINK(link.get()), nullptr), ==, 23); >+#endif >+ uri.reset(atspi_hyperlink_get_uri(ATSPI_HYPERLINK(link.get()), 0, nullptr)); >+ g_assert_cmpstr(uri.get(), ==, "https://www.gnome.org/"); >+ g_assert_true(atspi_hyperlink_get_object(ATSPI_HYPERLINK(link.get()), 0, nullptr) == link2.get()); >+} >+ > void beforeAll() > { > AccessibilityTest::add("WebKitAccessibility", "accessible/basic-hierarchy", testAccessibleBasicHierarchy); >@@ -1686,6 +1838,7 @@ void beforeAll() > AccessibilityTest::add("WebKitAccessibility", "text/state-changed", testTextStateChanged); > AccessibilityTest::add("WebKitAccessibility", "text/replaced-objects", testTextReplacedObjects); > AccessibilityTest::add("WebKitAccessibility", "value/basic", testValueBasic); >+ AccessibilityTest::add("WebKitAccessibility", "hyperlink/basic", testHyperlinkBasic); > } > > void afterAll() >diff --git a/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp b/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp >index 682fabf52d41..0d587f593871 100644 >--- a/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp >+++ b/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp >@@ -34,6 +34,7 @@ > #include <WebCore/AccessibilityAtspiEnums.h> > #include <WebCore/AccessibilityObjectAtspi.h> > #include <WebKit/WKBundleFrame.h> >+#include <wtf/URL.h> > #include <wtf/text/CString.h> > #include <wtf/text/StringBuilder.h> > #include <wtf/text/StringToIntegerConversion.h> >@@ -1128,7 +1129,24 @@ JSRetainPtr<JSStringRef> AccessibilityUIElement::documentURI() > > JSRetainPtr<JSStringRef> AccessibilityUIElement::url() > { >- return JSStringCreateWithCharacters(0, 0); >+ if (!m_element->interfaces().contains(WebCore::AccessibilityObjectAtspi::Interface::Hyperlink)) >+ return JSStringCreateWithCharacters(0, 0); >+ >+ m_element->updateBackingStore(); >+ auto axURL = m_element->url(); >+ if (axURL.isNull()) >+ return JSStringCreateWithUTF8CString("AXURL: (null)"); >+ >+ if (axURL.isLocalFile()) { >+ // Do not expose absolute paths. >+ auto path = axURL.fileSystemPath(); >+ auto index = path.find("LayoutTests"); >+ if (index != notFound) >+ path = path.substring(index); >+ return OpaqueJSString::tryCreate(makeString("AXURL: ", path)).leakRef(); >+ } >+ >+ return OpaqueJSString::tryCreate(makeString("AXURL: ", axURL.string())).leakRef(); > } > > bool AccessibilityUIElement::addNotificationListener(JSValueRef functionCallback)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
aperez
:
review+
aperez
:
commit-queue-
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 232707
:
443298
|
444661
| 444662