Apply local patch to chromium accessibility code (#23110)
diff --git a/BUILD.gn b/BUILD.gn
index 95fc681..192675c 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -103,6 +103,12 @@
"//flutter/third_party/txt:txt_unittests",
]
+ # The accessibility library only supports Mac for now.
+ if (is_mac) {
+ public_deps +=
+ [ "//flutter/third_party/accessibility:accessibility_unittests" ]
+ }
+
if (is_fuchsia) {
public_deps += [ "//flutter/shell/platform/fuchsia:tests" ]
}
diff --git a/ci/licenses.sh b/ci/licenses.sh
index 4a139c5..730ba75 100755
--- a/ci/licenses.sh
+++ b/ci/licenses.sh
@@ -122,7 +122,7 @@
local actualLicenseCount
actualLicenseCount="$(tail -n 1 flutter/ci/licenses_golden/licenses_flutter | tr -dc '0-9')"
- local expectedLicenseCount=17 # When changing this number: Update the error message below as well describing all expected license types.
+ local expectedLicenseCount=14 # When changing this number: Update the error message below as well describing all expected license types.
if [[ $actualLicenseCount -ne $expectedLicenseCount ]]; then
echo "=============================== ERROR ==============================="
diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter
index 12543e3..6b4331c 100755
--- a/ci/licenses_golden/licenses_flutter
+++ b/ci/licenses_golden/licenses_flutter
@@ -6,775 +6,6 @@
====================================================================================================
LIBRARY: accessibility
-ORIGIN: ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/ax_generated_tree_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_text_utils_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_id_registry.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_id_registry.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_base.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_base.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_delegate.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_mac.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_mac.mm
-FILE: ../../../flutter/third_party/accessibility/ax/tree_generator.cc
-FILE: ../../../flutter/third_party/accessibility/ax/tree_generator.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_conversions.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_conversions_impl.h
-FILE: ../../../flutter/third_party/accessibility/gfx/mac/coordinate_conversion.h
-FILE: ../../../flutter/third_party/accessibility/gfx/mac/coordinate_conversion.mm
-----------------------------------------------------------------------------------------------------
-Copyright 2014 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/ax/accessibility_features.cc + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/accessibility_features.cc
-FILE: ../../../flutter/third_party/accessibility/ax/accessibility_features.h
-----------------------------------------------------------------------------------------------------
-Copyright (c) 2019 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/ax/accessibility_switches.cc + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/accessibility_switches.cc
-FILE: ../../../flutter/third_party/accessibility/ax/accessibility_switches.h
-----------------------------------------------------------------------------------------------------
-Copyright (c) 2018 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/ax/aura/aura_window_properties.cc + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/aura/aura_window_properties.cc
-FILE: ../../../flutter/third_party/accessibility/ax/aura/aura_window_properties.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_action_handler.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_action_handler.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_event_generator.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_event_generator.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_event_generator_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_mode.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_mode_observer.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_role_properties.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_role_properties.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/atk_util_auralinux_gtk.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_android_constants.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_android_constants.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_auralinux.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_auralinux_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_unittest.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_relation_win.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_relation_win.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_system_caret_win.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_system_caret_win.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_unique_id.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_unique_id.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/checked_math.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/checked_math_impl.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/clamped_math.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/clamped_math_impl.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/math_constants.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/ranges.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_conversions_arm_impl.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_math.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_math_arm_impl.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_math_clang_gcc_impl.h
-FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_math_shared_impl.h
-----------------------------------------------------------------------------------------------------
-Copyright 2017 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/ax/ax_action_data.cc + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/ax_action_data.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_action_data.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_node_position.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_node_position.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_node_position_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_position.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_range.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_relative_bounds.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_relative_bounds.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_combiner.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_combiner.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_combiner_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_fuzzer.cc
-----------------------------------------------------------------------------------------------------
-Copyright 2016 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/ax/ax_export.h + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/ax_export.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_node.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_node.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_node_data.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_node_data.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_serializable_tree.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_serializable_tree.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_serializer.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_serializer.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_serializer_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_source.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_update.h
-----------------------------------------------------------------------------------------------------
-Copyright 2013 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/ax/ax_text_utils.cc + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/ax_text_utils.cc
-FILE: ../../../flutter/third_party/accessibility/base/auto_reset.h
-----------------------------------------------------------------------------------------------------
-Copyright (c) 2011 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/ax/ax_text_utils.h + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/ax_text_utils.h
-FILE: ../../../flutter/third_party/accessibility/ax_build/build_config.h
-FILE: ../../../flutter/third_party/accessibility/base/compiler_specific.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/insets.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/insets_f.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/insets_f.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point_conversions.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point_conversions.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point_f.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point_f.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect_conversions.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect_conversions.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect_f.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect_f.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size_conversions.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size_conversions.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size_f.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size_f.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d_conversions.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d_conversions.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d_f.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d_f.h
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/native_widget_types.h
-FILE: ../../../flutter/third_party/accessibility/gfx/transform.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/transform.h
-----------------------------------------------------------------------------------------------------
-Copyright (c) 2012 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/ax/mojom/ax_action_data.mojom + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/ax_assistant_structure.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_assistant_structure.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_enum_util.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_enum_util.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_enums.mojom
-FILE: ../../../flutter/third_party/accessibility/ax/ax_event.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_event.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_event_bundle_sink.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_language_detection.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_language_detection_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_node_data_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_table_fuzzer.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_table_info.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_table_info.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_table_info_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_id.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_id.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_observer.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_observer.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_source_checker.h
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_action_data.mojom
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_action_data_mojom_traits.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_action_data_mojom_traits.h
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_action_data_mojom_traits_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_assistant_structure.mojom
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_assistant_structure_mojom_traits.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_assistant_structure_mojom_traits.h
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_event.mojom
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_event_mojom_traits.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_event_mojom_traits.h
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_event_mojom_traits_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_node_data.mojom
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_node_data_mojom_traits.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_node_data_mojom_traits.h
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_node_data_mojom_traits_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_relative_bounds.mojom
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_relative_bounds_mojom_traits.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_relative_bounds_mojom_traits.h
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_relative_bounds_mojom_traits_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_tree_data.mojom
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_tree_data_mojom_traits.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_tree_data_mojom_traits.h
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_tree_data_mojom_traits_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_tree_id.mojom
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_tree_id_mojom_traits.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_tree_id_mojom_traits.h
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_tree_id_mojom_traits_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_tree_update.mojom
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_tree_update_mojom_traits.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_tree_update_mojom_traits.h
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_tree_update_mojom_traits_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/atk_util_auralinux_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_test_helper.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_test_helper.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/compute_attributes.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/compute_attributes.h
-FILE: ../../../flutter/third_party/accessibility/ax/run_all_unittests.cc
-FILE: ../../../flutter/third_party/accessibility/base/no_destructor.h
-----------------------------------------------------------------------------------------------------
-Copyright 2018 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/ax/mojom/ax_event_intent.mojom + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/ax_action_handler_base.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_action_handler_base.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_base_export.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_event_intent.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_event_intent.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_param_traits.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_param_traits.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_param_traits_macros.h
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_event_intent.mojom
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_event_intent_mojom_traits.cc
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_event_intent_mojom_traits.h
-FILE: ../../../flutter/third_party/accessibility/ax/mojom/ax_event_intent_mojom_traits_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ichromeaccessible.idl
-FILE: ../../../flutter/third_party/accessibility/ax/platform/uia_registrar_win.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/uia_registrar_win.h
-FILE: ../../../flutter/third_party/accessibility/ax/test_ax_node_helper.cc
-FILE: ../../../flutter/third_party/accessibility/ax/test_ax_node_helper.h
-FILE: ../../../flutter/third_party/accessibility/ax/test_ax_tree_manager.cc
-FILE: ../../../flutter/third_party/accessibility/ax/test_ax_tree_manager.h
-----------------------------------------------------------------------------------------------------
-Copyright 2020 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/ax/platform/ax_fragment_root_delegate_win.h + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/ax_action_target.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_active_popup.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_active_popup.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_clipping_behavior.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_constants.mojom
-FILE: ../../../flutter/third_party/accessibility/ax/ax_coordinate_system.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_enum_util_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_language_detection.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_mode.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_node_position_perftest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_node_text_styles.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_node_text_styles.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_offscreen_result.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_range_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_role_properties_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_manager.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_manager_map.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_manager_map.h
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_source_checker_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_update_forward.h
-FILE: ../../../flutter/third_party/accessibility/ax/null_ax_action_target.cc
-FILE: ../../../flutter/third_party/accessibility/ax/null_ax_action_target.h
-FILE: ../../../flutter/third_party/accessibility/ax/null_ax_action_target_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_fragment_root_delegate_win.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_fragment_root_win.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_fragment_root_win.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_fragment_root_win_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_base_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_delegate_utils_win.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_delegate_utils_win.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_textchildprovider_win.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_textchildprovider_win.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_textchildprovider_win_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_textprovider_win.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_textprovider_win.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_textprovider_win_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_textrangeprovider_win.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_textrangeprovider_win.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_textrangeprovider_win_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_win_unittest.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_text_boundary.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_text_boundary.h
-----------------------------------------------------------------------------------------------------
-Copyright 2019 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_atk_hyperlink.cc + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_atk_hyperlink.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_atk_hyperlink.h
-----------------------------------------------------------------------------------------------------
-Copyright (c) 2017 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/gfx/geometry/insets.cc + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/insets.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/insets_unittest.cc
-----------------------------------------------------------------------------------------------------
-Copyright (c) 2009 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../flutter/third_party/accessibility/gfx/geometry/rect_unittest.cc + ../../../LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/gfx/gfx_export.h
-----------------------------------------------------------------------------------------------------
-Copyright (c) 2013 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
-LIBRARY: accessibility
-ORIGIN: ../../../third_party/icu/scripts/LICENSE
-TYPE: LicenseType.bsd
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_data.cc
-FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_data.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/atk_util_auralinux.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/atk_util_auralinux.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_auralinux.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_win.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_win.h
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_win_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_unique_id_unittest.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/test_ax_node_wrapper.cc
-FILE: ../../../flutter/third_party/accessibility/ax/platform/test_ax_node_wrapper.h
-----------------------------------------------------------------------------------------------------
-Copyright 2015 The Chromium Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================================================
-
-====================================================================================================
LIBRARY: engine
LIBRARY: tonic
LIBRARY: txt
@@ -2243,6 +1474,22 @@
FILE: ../../../flutter/shell/version/version.h
FILE: ../../../flutter/sky/packages/flutter_services/lib/empty.dart
FILE: ../../../flutter/sky/tools/roll/patches/chromium/android_build.patch
+FILE: ../../../flutter/third_party/accessibility/base/color_utils.h
+FILE: ../../../flutter/third_party/accessibility/base/compiler_specific.h
+FILE: ../../../flutter/third_party/accessibility/base/container_utils.h
+FILE: ../../../flutter/third_party/accessibility/base/logging.cc
+FILE: ../../../flutter/third_party/accessibility/base/logging.h
+FILE: ../../../flutter/third_party/accessibility/base/logging_unittests.cc
+FILE: ../../../flutter/third_party/accessibility/base/macros.h
+FILE: ../../../flutter/third_party/accessibility/base/platform/darwin/scoped_nsobject.h
+FILE: ../../../flutter/third_party/accessibility/base/platform/darwin/scoped_nsobject.mm
+FILE: ../../../flutter/third_party/accessibility/base/simple_token.cc
+FILE: ../../../flutter/third_party/accessibility/base/simple_token.h
+FILE: ../../../flutter/third_party/accessibility/base/string_utils.cc
+FILE: ../../../flutter/third_party/accessibility/base/string_utils.h
+FILE: ../../../flutter/third_party/accessibility/base/string_utils_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/transform.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/transform.h
FILE: ../../../flutter/third_party/tonic/common/build_config.h
FILE: ../../../flutter/third_party/tonic/common/log.cc
FILE: ../../../flutter/third_party/tonic/common/log.h
@@ -2377,6 +1624,552 @@
====================================================================================================
====================================================================================================
+LIBRARY: accessibility
+ORIGIN: ../../../LICENSE
+TYPE: LicenseType.bsd
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_id_registry.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_id_registry.h
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node.cc
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node.h
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_base.cc
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_base.h
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_delegate.h
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.h
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_mac.h
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_mac.mm
+FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_conversions.h
+FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_conversions_impl.h
+FILE: ../../../flutter/third_party/accessibility/gfx/mac/coordinate_conversion.h
+FILE: ../../../flutter/third_party/accessibility/gfx/mac/coordinate_conversion.mm
+----------------------------------------------------------------------------------------------------
+Copyright 2014 The Chromium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+====================================================================================================
+
+====================================================================================================
+LIBRARY: accessibility
+ORIGIN: ../../../flutter/third_party/accessibility/ax/ax_action_data.cc + ../../../LICENSE
+TYPE: LicenseType.bsd
+FILE: ../../../flutter/third_party/accessibility/ax/ax_action_data.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_action_data.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_node_position.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_node_position.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_node_position_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_position.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_range.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_relative_bounds.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_relative_bounds.h
+----------------------------------------------------------------------------------------------------
+Copyright 2016 The Chromium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+====================================================================================================
+
+====================================================================================================
+LIBRARY: accessibility
+ORIGIN: ../../../flutter/third_party/accessibility/ax/ax_action_handler_base.cc + ../../../LICENSE
+TYPE: LicenseType.bsd
+FILE: ../../../flutter/third_party/accessibility/ax/ax_action_handler_base.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_action_handler_base.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_base_export.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_event_intent.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_event_intent.h
+FILE: ../../../flutter/third_party/accessibility/ax/test_ax_node_helper.cc
+FILE: ../../../flutter/third_party/accessibility/ax/test_ax_node_helper.h
+FILE: ../../../flutter/third_party/accessibility/ax/test_ax_tree_manager.cc
+FILE: ../../../flutter/third_party/accessibility/ax/test_ax_tree_manager.h
+----------------------------------------------------------------------------------------------------
+Copyright 2020 The Chromium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+====================================================================================================
+
+====================================================================================================
+LIBRARY: accessibility
+ORIGIN: ../../../flutter/third_party/accessibility/ax/ax_export.h + ../../../LICENSE
+TYPE: LicenseType.bsd
+FILE: ../../../flutter/third_party/accessibility/ax/ax_export.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_node.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_node.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_node_data.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_node_data.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_update.h
+----------------------------------------------------------------------------------------------------
+Copyright 2013 The Chromium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+====================================================================================================
+
+====================================================================================================
+LIBRARY: accessibility
+ORIGIN: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_base_unittest.cc + ../../../LICENSE
+TYPE: LicenseType.bsd
+FILE: ../../../flutter/third_party/accessibility/ax/ax_clipping_behavior.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_constants.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_coordinate_system.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_enum_util_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_mode.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_node_text_styles.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_node_text_styles.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_offscreen_result.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_range_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_role_properties_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_manager.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_manager_map.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_manager_map.h
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_base_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_text_boundary.cc
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_text_boundary.h
+----------------------------------------------------------------------------------------------------
+Copyright 2019 The Chromium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+====================================================================================================
+
+====================================================================================================
+LIBRARY: accessibility
+ORIGIN: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.cc + ../../../LICENSE
+TYPE: LicenseType.bsd
+FILE: ../../../flutter/third_party/accessibility/ax/ax_enum_util.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_enum_util.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_enums.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_node_data_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_table_info.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_table_info.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_table_info_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_id.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_id.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_observer.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_observer.h
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.cc
+FILE: ../../../flutter/third_party/accessibility/ax/platform/compute_attributes.cc
+FILE: ../../../flutter/third_party/accessibility/ax/platform/compute_attributes.h
+FILE: ../../../flutter/third_party/accessibility/base/no_destructor.h
+----------------------------------------------------------------------------------------------------
+Copyright 2018 The Chromium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+====================================================================================================
+
+====================================================================================================
+LIBRARY: accessibility
+ORIGIN: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_unittest.cc + ../../../LICENSE
+TYPE: LicenseType.bsd
+FILE: ../../../flutter/third_party/accessibility/ax/ax_action_handler.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_action_handler.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_event_generator.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_event_generator.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_event_generator_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_mode.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_mode_observer.h
+FILE: ../../../flutter/third_party/accessibility/ax/ax_role_properties.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_role_properties.h
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_platform_node_unittest.h
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_unique_id.cc
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_unique_id.h
+FILE: ../../../flutter/third_party/accessibility/base/numerics/checked_math.h
+FILE: ../../../flutter/third_party/accessibility/base/numerics/checked_math_impl.h
+FILE: ../../../flutter/third_party/accessibility/base/numerics/clamped_math.h
+FILE: ../../../flutter/third_party/accessibility/base/numerics/clamped_math_impl.h
+FILE: ../../../flutter/third_party/accessibility/base/numerics/math_constants.h
+FILE: ../../../flutter/third_party/accessibility/base/numerics/ranges.h
+FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_conversions_arm_impl.h
+FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_math.h
+FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_math_arm_impl.h
+FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_math_clang_gcc_impl.h
+FILE: ../../../flutter/third_party/accessibility/base/numerics/safe_math_shared_impl.h
+----------------------------------------------------------------------------------------------------
+Copyright 2017 The Chromium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+====================================================================================================
+
+====================================================================================================
+LIBRARY: accessibility
+ORIGIN: ../../../flutter/third_party/accessibility/ax_build/build_config.h + ../../../LICENSE
+TYPE: LicenseType.bsd
+FILE: ../../../flutter/third_party/accessibility/ax_build/build_config.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/insets.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/insets_f.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/insets_f.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point_conversions.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point_conversions.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point_f.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point_f.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/point_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect_conversions.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect_conversions.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect_f.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect_f.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size_conversions.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size_conversions.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size_f.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size_f.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/size_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d_conversions.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d_conversions.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d_f.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d_f.h
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/vector2d_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/native_widget_types.h
+----------------------------------------------------------------------------------------------------
+Copyright (c) 2012 The Chromium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+====================================================================================================
+
+====================================================================================================
+LIBRARY: accessibility
+ORIGIN: ../../../flutter/third_party/accessibility/base/auto_reset.h + ../../../LICENSE
+TYPE: LicenseType.bsd
+FILE: ../../../flutter/third_party/accessibility/base/auto_reset.h
+----------------------------------------------------------------------------------------------------
+Copyright (c) 2011 The Chromium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+====================================================================================================
+
+====================================================================================================
+LIBRARY: accessibility
+ORIGIN: ../../../flutter/third_party/accessibility/gfx/geometry/insets.cc + ../../../LICENSE
+TYPE: LicenseType.bsd
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/insets.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/insets_unittest.cc
+----------------------------------------------------------------------------------------------------
+Copyright (c) 2009 The Chromium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+====================================================================================================
+
+====================================================================================================
+LIBRARY: accessibility
+ORIGIN: ../../../flutter/third_party/accessibility/gfx/geometry/rect_unittest.cc + ../../../LICENSE
+TYPE: LicenseType.bsd
+FILE: ../../../flutter/third_party/accessibility/gfx/geometry/rect_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/gfx/gfx_export.h
+----------------------------------------------------------------------------------------------------
+Copyright (c) 2013 The Chromium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+====================================================================================================
+
+====================================================================================================
+LIBRARY: accessibility
+ORIGIN: ../../../third_party/icu/scripts/LICENSE
+TYPE: LicenseType.bsd
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_data.cc
+FILE: ../../../flutter/third_party/accessibility/ax/ax_tree_data.h
+FILE: ../../../flutter/third_party/accessibility/ax/platform/ax_unique_id_unittest.cc
+FILE: ../../../flutter/third_party/accessibility/ax/platform/test_ax_node_wrapper.cc
+FILE: ../../../flutter/third_party/accessibility/ax/platform/test_ax_node_wrapper.h
+----------------------------------------------------------------------------------------------------
+Copyright 2015 The Chromium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+====================================================================================================
+
+====================================================================================================
LIBRARY: txt
ORIGIN: ../../../flutter/third_party/txt/LICENSE
TYPE: LicenseType.apache
@@ -2678,4 +2471,4 @@
See the License for the specific language governing permissions and
limitations under the License.
====================================================================================================
-Total license count: 17
+Total license count: 14
diff --git a/testing/run_tests.py b/testing/run_tests.py
index 4a0831d..9cdd1e6 100755
--- a/testing/run_tests.py
+++ b/testing/run_tests.py
@@ -150,6 +150,10 @@
RunEngineExecutable(build_dir, 'testing_unittests', filter, shuffle_flags)
+ # The accessibility library only supports Mac for now.
+ if IsMac():
+ RunEngineExecutable(build_dir, 'accessibility_unittests', filter, shuffle_flags)
+
# These unit-tests are Objective-C and can only run on Darwin.
if IsMac():
RunEngineExecutable(build_dir, 'flutter_channels_unittests', filter, shuffle_flags)
diff --git a/third_party/accessibility/ax/BUILD.gn b/third_party/accessibility/ax/BUILD.gn
index 3203df9..e3f0761 100644
--- a/third_party/accessibility/ax/BUILD.gn
+++ b/third_party/accessibility/ax/BUILD.gn
@@ -1,136 +1,74 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
+# Copyright 2013 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//build/config/features.gni")
-import("//build/config/linux/pkg_config.gni")
-import("//build/config/ui.gni")
-import("//mojo/public/tools/bindings/mojom.gni")
-import("//testing/libfuzzer/fuzzer_test.gni")
-import("//testing/test.gni")
-import("//tools/json_schema_compiler/json_schema_api.gni")
-import("//ui/base/ui_features.gni")
+import("//flutter/common/config.gni")
-if (is_android) {
- import("//build/config/android/rules.gni")
-}
-
-if (is_win) {
- import("//build/toolchain/win/midl.gni")
-}
-
-# Reset sources_assignment_filter for the BUILD.gn file to prevent
-# regression during the migration of Chromium away from the feature.
-# See docs/no_sources_assignment_filter.md for more information.
-# TODO(crbug.com/1018739): remove this when migration is done.
-set_sources_assignment_filter([])
-
-mojom("ax_constants_mojo") {
- sources = [ "ax_constants.mojom" ]
-}
-
-mojom_component("ax_enums_mojo") {
- sources = [ "ax_enums.mojom" ]
-
- macro_prefix = "UI_ACCESSIBILITY_AX_MOJOM"
- output_prefix = "ui_accessibility_ax_mojom"
-}
-
-# A tiny subset of accessibility code that's allowed to be
-# included by Blink. The rule of thumb (for now) is that it's
-# anything platform-neutral (no platform/ directory) that
-# relates to a single accessibility node (no trees, etc.).
-component("ax_base") {
- defines = [ "AX_BASE_IMPLEMENTATION" ]
+source_set("ax") {
+ visibility = [ "//flutter/third_party/accessibility/*" ]
+ include_dirs = [ "//flutter/third_party/accessibility" ]
sources = [
- "accessibility_features.cc",
- "accessibility_features.h",
- "accessibility_switches.cc",
- "accessibility_switches.h",
- "ax_base_export.h",
- "ax_enum_util.cc",
- "ax_enum_util.h",
- "ax_event.cc",
- "ax_event.h",
- "ax_event_intent.cc",
- "ax_event_intent.h",
- "ax_mode.cc",
- "ax_mode.h",
- "ax_node_data.cc",
- "ax_node_data.h",
- "ax_node_text_styles.cc",
- "ax_node_text_styles.h",
- "ax_relative_bounds.cc",
- "ax_relative_bounds.h",
- "ax_role_properties.cc",
- "ax_role_properties.h",
- "ax_tree_id.cc",
- "ax_tree_id.h",
+ "platform/ax_platform_node.cc",
+ "platform/ax_platform_node.h",
+ "platform/ax_platform_node_base.cc",
+ "platform/ax_platform_node_base.h",
+ "platform/ax_platform_node_delegate.h",
+ "platform/ax_platform_node_delegate_base.cc",
+ "platform/ax_platform_node_delegate_base.h",
+ "platform/ax_platform_text_boundary.cc",
+ "platform/ax_platform_text_boundary.h",
+ "platform/ax_unique_id.cc",
+ "platform/ax_unique_id.h",
+ "platform/compute_attributes.cc",
+ "platform/compute_attributes.h",
]
- public_deps = [
- ":ax_constants_mojo",
- ":ax_enums_mojo",
- "//base",
- "//base:i18n",
- "//base/util/values:values_util",
- "//ui/base",
- "//ui/gfx",
- "//ui/gfx/geometry",
- "//ui/strings",
- ]
-}
-
-#if (is_win) {
-# midl("ichromeaccessible") {
-# sources = [
-# "platform/ichromeaccessible.idl",
-# ]
-# }
-#}
-
-component("accessibility") {
- defines = [ "AX_IMPLEMENTATION" ]
-
- sources = [
+ sources += [
"ax_action_data.cc",
"ax_action_data.h",
"ax_action_handler.cc",
"ax_action_handler.h",
"ax_action_handler_base.cc",
"ax_action_handler_base.h",
- "ax_action_target.h",
- "ax_active_popup.cc",
- "ax_active_popup.h",
+ "ax_base_export.h",
"ax_clipping_behavior.h",
+ "ax_constants.h",
"ax_coordinate_system.h",
- "ax_event_bundle_sink.h",
+ "ax_enum_util.cc",
+ "ax_enum_util.h",
+ "ax_enums.h",
"ax_event_generator.cc",
"ax_event_generator.h",
+ "ax_event_intent.cc",
+ "ax_event_intent.h",
"ax_export.h",
- "ax_language_detection.cc",
- "ax_language_detection.h",
+ "ax_mode.cc",
+ "ax_mode.h",
"ax_mode_observer.h",
"ax_node.cc",
"ax_node.h",
+ "ax_node_data.cc",
+ "ax_node_data.h",
"ax_node_position.cc",
"ax_node_position.h",
+ "ax_node_text_styles.cc",
+ "ax_node_text_styles.h",
"ax_offscreen_result.h",
"ax_position.h",
"ax_range.h",
- "ax_serializable_tree.cc",
- "ax_serializable_tree.h",
+ "ax_relative_bounds.cc",
+ "ax_relative_bounds.h",
+ "ax_role_properties.cc",
+ "ax_role_properties.h",
"ax_table_info.cc",
"ax_table_info.h",
- "ax_text_utils.cc",
- "ax_text_utils.h",
"ax_tree.cc",
"ax_tree.h",
- "ax_tree_combiner.cc",
- "ax_tree_combiner.h",
"ax_tree_data.cc",
"ax_tree_data.h",
+ "ax_tree_id.cc",
+ "ax_tree_id.h",
"ax_tree_id_registry.cc",
"ax_tree_id_registry.h",
"ax_tree_manager.h",
@@ -138,194 +76,19 @@
"ax_tree_manager_map.h",
"ax_tree_observer.cc",
"ax_tree_observer.h",
- "ax_tree_serializer.cc",
- "ax_tree_serializer.h",
- "ax_tree_source.h",
- "ax_tree_source_checker.h",
"ax_tree_update.h",
- "ax_tree_update_forward.h",
- "null_ax_action_target.cc",
- "null_ax_action_target.h",
]
- deps = [
- "//base/util/values:values_util",
- "//third_party/cld_3/src/src:cld_3",
- ]
+ if (is_mac) {
+ sources += [
+ "platform/ax_platform_node_mac.h",
+ "platform/ax_platform_node_mac.mm",
+ ]
+ }
public_deps = [
- ":ax_base",
- "//ui/accessibility/platform",
- ]
-
- # Allows the files from //ui/accessibility/platform includes headers
- # from this directory.
- allow_circular_includes_from = [ "//ui/accessibility/platform" ]
-
- if (!is_ios) {
- sources += [
- "ax_param_traits.cc",
- "ax_param_traits.h",
- "ax_param_traits_macros.h",
- ]
-
- public_deps += [
- "//ipc",
- "//ui/gfx/ipc/skia",
- ]
- }
-
- if (use_aura) {
- sources += [
- "aura/aura_window_properties.cc",
- "aura/aura_window_properties.h",
- ]
-
- public_deps += [ "//ui/aura" ]
- }
-}
-
-source_set("ax_assistant") {
- sources = [
- "ax_assistant_structure.cc",
- "ax_assistant_structure.h",
- ]
-
- deps = [ ":accessibility" ]
-}
-
-static_library("test_support") {
- testonly = true
- sources = [
- "test_ax_node_helper.cc",
- "test_ax_node_helper.h",
- "test_ax_tree_manager.cc",
- "test_ax_tree_manager.h",
- "tree_generator.cc",
- "tree_generator.h",
- ]
-
- if (has_native_accessibility) {
- sources += [
- "platform/test_ax_node_wrapper.cc",
- "platform/test_ax_node_wrapper.h",
- ]
- }
-
- deps = [ ":accessibility" ]
-}
-
-test("accessibility_unittests") {
- testonly = true
- sources = [
- "ax_enum_util_unittest.cc",
- "ax_event_generator_unittest.cc",
- "ax_generated_tree_unittest.cc",
- "ax_language_detection_unittest.cc",
- "ax_node_data_unittest.cc",
- "ax_node_position_unittest.cc",
- "ax_range_unittest.cc",
- "ax_role_properties_unittest.cc",
- "ax_table_info_unittest.cc",
- "ax_text_utils_unittest.cc",
- "ax_tree_combiner_unittest.cc",
- "ax_tree_serializer_unittest.cc",
- "ax_tree_source_checker_unittest.cc",
- "ax_tree_unittest.cc",
- "mojom/ax_action_data_mojom_traits_unittest.cc",
- "mojom/ax_event_intent_mojom_traits_unittest.cc",
- "mojom/ax_event_mojom_traits_unittest.cc",
- "mojom/ax_node_data_mojom_traits_unittest.cc",
- "mojom/ax_relative_bounds_mojom_traits_unittest.cc",
- "mojom/ax_tree_data_mojom_traits_unittest.cc",
- "mojom/ax_tree_id_mojom_traits_unittest.cc",
- "mojom/ax_tree_update_mojom_traits_unittest.cc",
- "null_ax_action_target_unittest.cc",
- "platform/ax_platform_node_unittest.cc",
- "platform/ax_platform_node_unittest.h",
- "platform/ax_unique_id_unittest.cc",
- "run_all_unittests.cc",
- ]
-
- deps = [
- ":accessibility",
- ":test_support",
- "//base/test:test_support",
- "//ipc",
- "//mojo/core/embedder",
- "//mojo/core/test:test_support",
- "//mojo/public/cpp/test_support:test_utils",
- "//skia",
- "//testing/gmock",
- "//testing/gtest",
- "//ui/accessibility/mojom",
- "//ui/gfx:test_support",
- ]
-
- if (has_native_accessibility) {
- # This test depends heavily on NativeViewAccessible, which is only
- # implemented on these platforms.
- sources += [ "platform/ax_platform_node_base_unittest.cc" ]
-
- if (is_win) {
- sources += [
- "platform/ax_fragment_root_win_unittest.cc",
- "platform/ax_platform_node_textchildprovider_win_unittest.cc",
- "platform/ax_platform_node_textprovider_win_unittest.cc",
- "platform/ax_platform_node_textrangeprovider_win_unittest.cc",
- "platform/ax_platform_node_win_unittest.cc",
- "platform/ax_platform_node_win_unittest.h",
- ]
-
- deps += [
- "//third_party/iaccessible2",
- "//ui/accessibility/platform:ichromeaccessible",
- ]
-
- libs = [
- "oleacc.lib",
- "uiautomationcore.lib",
- ]
- }
-
- if (use_atk) {
- sources += [
- "platform/atk_util_auralinux_unittest.cc",
- "platform/ax_platform_node_auralinux_unittest.cc",
- ]
-
- configs += [ "//build/config/linux/atk" ]
- }
- }
-}
-
-fuzzer_test("ax_tree_fuzzer") {
- sources = [ "ax_tree_fuzzer.cc" ]
-
- deps = [ ":accessibility" ]
-}
-
-fuzzer_test("ax_table_fuzzer") {
- sources = [ "ax_table_fuzzer.cc" ]
-
- deps = [ ":accessibility" ]
-
- seed_corpus = "fuzz_corpus"
-}
-
-test("accessibility_perftests") {
- testonly = true
- sources = [ "ax_node_position_perftest.cc" ]
-
- deps = [
- ":test_support",
- "//base",
- "//base/test:test_support",
- "//mojo/core/test:run_all_unittests",
- "//skia",
- "//testing/gmock",
- "//testing/gtest",
- "//testing/perf",
- "//ui/accessibility/mojom",
+ "//flutter/third_party/accessibility/ax_build",
+ "//flutter/third_party/accessibility/base",
+ "//flutter/third_party/accessibility/gfx",
]
}
diff --git a/third_party/accessibility/ax/OWNERS b/third_party/accessibility/ax/OWNERS
deleted file mode 100644
index eb3d99c..0000000
--- a/third_party/accessibility/ax/OWNERS
+++ /dev/null
@@ -1,18 +0,0 @@
-dmazzoni@chromium.org
-dtseng@chromium.org
-aboxhall@chromium.org
-nektar@chromium.org
-dougt@chromium.org
-aleventhal@chromium.org
-katie@chromium.org
-
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
-
-per-file *_param_traits*.*=set noparent
-per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
-
-per-file ax_language_detection*=chrishall@chromium.org
-
-# TEAM: chromium-accessibility@chromium.org
-# COMPONENT: Internals>Accessibility
diff --git a/third_party/accessibility/ax/PRESUBMIT.py b/third_party/accessibility/ax/PRESUBMIT.py
deleted file mode 100644
index d71a8f9..0000000
--- a/third_party/accessibility/ax/PRESUBMIT.py
+++ /dev/null
@@ -1,257 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Presubmit script for ui/accessibility."""
-
-import os, re, json
-
-AX_MOJOM = 'ui/accessibility/ax_enums.mojom'
-AUTOMATION_IDL = 'extensions/common/api/automation.idl'
-
-AX_JS_FILE = 'chrome/browser/resources/accessibility/accessibility.js'
-AX_MODE_HEADER = 'ui/accessibility/ax_mode.h'
-
-def InitialLowerCamelCase(unix_name):
- words = unix_name.split('_')
- return words[0] + ''.join(word.capitalize() for word in words[1:])
-
-def CamelToLowerHacker(str):
- out = ''
- for i in range(len(str)):
- if str[i] >= 'A' and str[i] <= 'Z' and out:
- out += '_'
- out += str[i]
- return out.lower()
-
-# Given a full path to an IDL or MOJOM file containing enum definitions,
-# parse the file for enums and return a dict mapping the enum name
-# to a list of values for that enum.
-def GetEnumsFromFile(fullpath):
- enum_name = None
- enums = {}
- for line in open(fullpath).readlines():
- # Strip out comments
- line = re.sub('//.*', '', line)
-
- # Look for lines of the form "enum ENUM_NAME {" and get the enum_name
- m = re.search('enum ([\w]+) {', line)
- if m:
- enum_name = m.group(1)
- continue
-
- # Look for a "}" character signifying the end of an enum
- if line.find('}') >= 0:
- enum_name = None
- continue
-
- if not enum_name:
- continue
-
- # If we're inside an enum definition, add the first string consisting of
- # alphanumerics plus underscore ("\w") to the list of values for that enum.
- m = re.search('([\w]+)', line)
- if m:
- enums.setdefault(enum_name, [])
- enum_value = m.group(1)
- if (enum_value[0] == 'k' and
- enum_value[1] == enum_value[1].upper()):
- enum_value = CamelToLowerHacker(enum_value[1:])
- if enum_value == 'none' or enum_value == 'last':
- continue
- if enum_value == 'active_descendant_changed':
- enum_value = 'activedescendantchanged'
- enums[enum_name].append(enum_value)
-
- return enums
-
-def CheckMatchingEnum(ax_enums,
- ax_enum_name,
- automation_enums,
- automation_enum_name,
- errs,
- output_api,
- strict_ordering=False):
- if ax_enum_name not in ax_enums:
- errs.append(output_api.PresubmitError(
- 'Expected %s to have an enum named %s' % (AX_MOJOM, ax_enum_name)))
- return
- if automation_enum_name not in automation_enums:
- errs.append(output_api.PresubmitError(
- 'Expected %s to have an enum named %s' % (
- AUTOMATION_IDL, automation_enum_name)))
- return
- src = ax_enums[ax_enum_name]
- dst = automation_enums[automation_enum_name]
- if strict_ordering and len(src) != len(dst):
- errs.append(output_api.PresubmitError(
- 'Expected %s to have the same number of items as %s' % (
- automation_enum_name, ax_enum_name)))
- return
-
- if strict_ordering:
- for index, value in enumerate(src):
- lower_value = InitialLowerCamelCase(value)
- if lower_value != dst[index]:
- errs.append(output_api.PresubmitError(
- ('At index %s in enums, unexpected ordering around %s.%s ' +
- 'and %s.%s in %s and %s') % (
- index, ax_enum_name, lower_value,
- automation_enum_name, dst[index],
- AX_MOJOM, AUTOMATION_IDL)))
- return
- return
-
- for value in src:
- lower_value = InitialLowerCamelCase(value)
- if lower_value in dst:
- dst.remove(lower_value) # Any remaining at end are extra and a mismatch.
- else:
- errs.append(output_api.PresubmitError(
- 'Found %s.%s in %s, but did not find %s.%s in %s' % (
- ax_enum_name, value, AX_MOJOM,
- automation_enum_name, InitialLowerCamelCase(value),
- AUTOMATION_IDL)))
- # Should be no remaining items
- for value in dst:
- errs.append(output_api.PresubmitError(
- 'Found %s.%s in %s, but did not find %s.%s in %s' % (
- automation_enum_name, value, AUTOMATION_IDL,
- ax_enum_name, InitialLowerCamelCase(value),
- AX_MOJOM)))
-
-def CheckEnumsMatch(input_api, output_api):
- repo_root = input_api.change.RepositoryRoot()
- ax_enums = GetEnumsFromFile(os.path.join(repo_root, AX_MOJOM))
- automation_enums = GetEnumsFromFile(os.path.join(repo_root, AUTOMATION_IDL))
-
- # Focused state only exists in automation.
- automation_enums['StateType'].remove('focused')
- # Offscreen state only exists in automation.
- automation_enums['StateType'].remove('offscreen')
-
- errs = []
- CheckMatchingEnum(ax_enums, 'Role', automation_enums, 'RoleType', errs,
- output_api)
- CheckMatchingEnum(ax_enums, 'State', automation_enums, 'StateType', errs,
- output_api, strict_ordering=True)
- CheckMatchingEnum(ax_enums, 'Action', automation_enums, 'ActionType', errs,
- output_api, strict_ordering=True)
- CheckMatchingEnum(ax_enums, 'Event', automation_enums, 'EventType', errs,
- output_api)
- CheckMatchingEnum(ax_enums, 'NameFrom', automation_enums, 'NameFromType',
- errs, output_api)
- CheckMatchingEnum(ax_enums, 'DescriptionFrom', automation_enums,
- 'DescriptionFromType', errs, output_api)
- CheckMatchingEnum(ax_enums, 'Restriction', automation_enums,
- 'Restriction', errs, output_api)
- CheckMatchingEnum(ax_enums, 'DefaultActionVerb', automation_enums,
- 'DefaultActionVerb', errs, output_api)
- CheckMatchingEnum(ax_enums, 'MarkerType', automation_enums,
- 'MarkerType', errs, output_api)
- CheckMatchingEnum(ax_enums, 'Command', automation_enums,
- 'EventCommandType', errs, output_api)
- CheckMatchingEnum(ax_enums, 'TextBoundary', automation_enums,
- 'EventTextBoundaryType', errs, output_api)
- CheckMatchingEnum(ax_enums, 'MoveDirection', automation_enums,
- 'EventMoveDirectionType', errs, output_api)
- CheckMatchingEnum(ax_enums, 'SortDirection', automation_enums,
- 'SortDirectionType', errs, output_api)
- return errs
-
-# Given a full path to c++ header, return an array of the first static
-# constexpr defined. (Note there can be more than one defined in a C++
-# header)
-def GetConstexprFromFile(fullpath):
- values = []
- for line in open(fullpath).readlines():
- # Strip out comments
- line = re.sub('//.*', '', line)
-
- # Look for lines of the form "static constexpr <type> NAME "
- m = re.search('static constexpr [\w]+ ([\w]+)', line)
- if m:
- value = m.group(1)
- # Skip first/last sentinels
- if value == 'kFirstModeFlag' or value == 'kLastModeFlag':
- continue
- values.append(value)
-
- return values
-
-# Given a full path to js file, return the AXMode consts
-# defined
-def GetAccessibilityModesFromFile(fullpath):
- values = []
- inside = False
- for line in open(fullpath).readlines():
- # Strip out comments
- line = re.sub('//.*', '', line)
-
- # Look for the block of code that defines AXMode
- m = re.search('const AXMode = {', line)
- if m:
- inside = True
- continue
-
- # Look for a "}" character signifying the end of an enum
- if line.find('};') >= 0:
- return values
-
- if not inside:
- continue
-
- m = re.search('([\w]+):', line)
- if m:
- values.append(m.group(1))
- continue
-
- # getters
- m = re.search('get ([\w]+)\(\)', line)
- if m:
- values.append(m.group(1))
- return values
-
-# Make sure that the modes defined in the C++ header match those defined in
-# the js file. Note that this doesn't guarantee that the values are the same,
-# but does make sure if we add or remove we can signal to the developer that
-# they should be aware that this dependency exists.
-def CheckModesMatch(input_api, output_api):
- errs = []
- repo_root = input_api.change.RepositoryRoot()
-
- ax_modes_in_header = GetConstexprFromFile(
- os.path.join(repo_root,AX_MODE_HEADER))
- ax_modes_in_js = GetAccessibilityModesFromFile(
- os.path.join(repo_root, AX_JS_FILE))
-
- for value in ax_modes_in_header:
- if value not in ax_modes_in_js:
- errs.append(output_api.PresubmitError(
- 'Found %s in %s, but did not find %s in %s' % (
- value, AX_MODE_HEADER, value, AX_JS_FILE)))
- return errs
-
-def CheckChangeOnUpload(input_api, output_api):
- errs = []
- for path in input_api.LocalPaths():
- path = path.replace('\\', '/')
- if AX_MOJOM == path:
- errs.extend(CheckEnumsMatch(input_api, output_api))
-
- if AX_MODE_HEADER == path:
- errs.extend(CheckModesMatch(input_api, output_api))
-
- return errs
-
-def CheckChangeOnCommit(input_api, output_api):
- errs = []
- for path in input_api.LocalPaths():
- path = path.replace('\\', '/')
- if AX_MOJOM == path:
- errs.extend(CheckEnumsMatch(input_api, output_api))
-
- if AX_MODE_HEADER == path:
- errs.extend(CheckModesMatch(input_api, output_api))
-
- return errs
diff --git a/third_party/accessibility/ax/accessibility_features.cc b/third_party/accessibility/ax/accessibility_features.cc
deleted file mode 100644
index 9702d43..0000000
--- a/third_party/accessibility/ax/accessibility_features.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/accessibility_features.h"
-
-#include "base/feature_list.h"
-#include "build/build_config.h"
-
-namespace features {
-
-// Allow use of ARIA roles from https://github.com/w3c/annotation-aria draft.
-const base::Feature kEnableAccessibilityExposeARIAAnnotations{
- "AccessibilityExposeARIAAnnotations", base::FEATURE_DISABLED_BY_DEFAULT};
-
-bool IsAccessibilityExposeARIAAnnotationsEnabled() {
- return base::FeatureList::IsEnabled(
- ::features::kEnableAccessibilityExposeARIAAnnotations);
-}
-
-// Enable exposing "display: none" nodes to the browser process AXTree
-const base::Feature kEnableAccessibilityExposeDisplayNone{
- "AccessibilityExposeDisplayNone", base::FEATURE_DISABLED_BY_DEFAULT};
-
-bool IsAccessibilityExposeDisplayNoneEnabled() {
- return base::FeatureList::IsEnabled(
- ::features::kEnableAccessibilityExposeDisplayNone);
-}
-
-// Enable exposing the <html> element to the browser process AXTree
-// (as an ignored node).
-const base::Feature kEnableAccessibilityExposeHTMLElement{
- "AccessibilityExposeHTMLElement", base::FEATURE_DISABLED_BY_DEFAULT};
-
-bool IsAccessibilityExposeHTMLElementEnabled() {
- return base::FeatureList::IsEnabled(
- ::features::kEnableAccessibilityExposeHTMLElement);
-}
-
-// Enable language detection to determine language used in page text, exposed
-// on the browser process AXTree.
-const base::Feature kEnableAccessibilityLanguageDetection{
- "AccessibilityLanguageDetection", base::FEATURE_DISABLED_BY_DEFAULT};
-
-bool IsAccessibilityLanguageDetectionEnabled() {
- return base::FeatureList::IsEnabled(
- ::features::kEnableAccessibilityLanguageDetection);
-}
-
-// Serializes accessibility information from the Views tree and deserializes it
-// into an AXTree in the browser process.
-const base::Feature kEnableAccessibilityTreeForViews{
- "AccessibilityTreeForViews", base::FEATURE_DISABLED_BY_DEFAULT};
-
-bool IsAccessibilityTreeForViewsEnabled() {
- return base::FeatureList::IsEnabled(
- ::features::kEnableAccessibilityTreeForViews);
-}
-
-const base::Feature kAccessibilityFocusHighlight{
- "AccessibilityFocusHighlight", base::FEATURE_ENABLED_BY_DEFAULT};
-
-bool IsAccessibilityFocusHighlightEnabled() {
- return base::FeatureList::IsEnabled(::features::kAccessibilityFocusHighlight);
-}
-
-#if defined(OS_WIN)
-const base::Feature kIChromeAccessible{"IChromeAccessible",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
-bool IsIChromeAccessibleEnabled() {
- return base::FeatureList::IsEnabled(::features::kIChromeAccessible);
-}
-#endif // defined(OS_WIN)
-
-#if defined(OS_CHROMEOS)
-const base::Feature kAccessibilityCursorColor{"AccessibilityCursorColor",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
-bool IsAccessibilityCursorColorEnabled() {
- return base::FeatureList::IsEnabled(::features::kAccessibilityCursorColor);
-}
-#endif // defined(OS_CHROMEOS)
-
-const base::Feature kAugmentExistingImageLabels{
- "AugmentExistingImageLabels", base::FEATURE_DISABLED_BY_DEFAULT};
-
-bool IsAugmentExistingImageLabelsEnabled() {
- return base::FeatureList::IsEnabled(::features::kAugmentExistingImageLabels);
-}
-
-} // namespace features
diff --git a/third_party/accessibility/ax/accessibility_features.h b/third_party/accessibility/ax/accessibility_features.h
deleted file mode 100644
index d6f7a2d..0000000
--- a/third_party/accessibility/ax/accessibility_features.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Define all the base::Features used by ui/accessibility.
-#ifndef UI_ACCESSIBILITY_ACCESSIBILITY_FEATURES_H_
-#define UI_ACCESSIBILITY_ACCESSIBILITY_FEATURES_H_
-
-#include "base/feature_list.h"
-#include "build/build_config.h"
-#include "ui/accessibility/ax_base_export.h"
-
-namespace features {
-
-AX_BASE_EXPORT extern const base::Feature
- kEnableAccessibilityExposeARIAAnnotations;
-
-// Returns true if ARIA annotations should be exposed to the browser AX Tree.
-AX_BASE_EXPORT bool IsAccessibilityExposeARIAAnnotationsEnabled();
-
-AX_BASE_EXPORT extern const base::Feature kEnableAccessibilityExposeDisplayNone;
-
-// Returns true if "display: none" nodes should be exposed to the
-// browser process AXTree.
-AX_BASE_EXPORT bool IsAccessibilityExposeDisplayNoneEnabled();
-
-AX_BASE_EXPORT extern const base::Feature kEnableAccessibilityExposeHTMLElement;
-
-// Returns true if the <html> element should be exposed to the
-// browser process AXTree (as an ignored node).
-AX_BASE_EXPORT bool IsAccessibilityExposeHTMLElementEnabled();
-
-AX_BASE_EXPORT extern const base::Feature kEnableAccessibilityLanguageDetection;
-
-// Return true if language detection should be used to determine the language
-// of text content in page and exposed to the browser process AXTree.
-AX_BASE_EXPORT bool IsAccessibilityLanguageDetectionEnabled();
-
-// Serializes accessibility information from the Views tree and deserializes it
-// into an AXTree in the browser process.
-AX_BASE_EXPORT extern const base::Feature kEnableAccessibilityTreeForViews;
-
-// Returns true if the Views tree is exposed using an AXTree in the browser
-// process. Returns false if the Views tree is exposed to accessibility
-// directly.
-AX_BASE_EXPORT bool IsAccessibilityTreeForViewsEnabled();
-
-AX_BASE_EXPORT extern const base::Feature kAccessibilityFocusHighlight;
-
-// Returns true if the accessibility focus highlight feature is enabled,
-// which draws a visual highlight around the focused element on the page
-// briefly whenever focus changes.
-AX_BASE_EXPORT bool IsAccessibilityFocusHighlightEnabled();
-
-#if defined(OS_WIN)
-// Enables an experimental Chrome-specific accessibility COM API
-AX_BASE_EXPORT extern const base::Feature kIChromeAccessible;
-
-// Returns true if the IChromeAccessible COM API is enabled.
-AX_BASE_EXPORT bool IsIChromeAccessibleEnabled();
-
-#endif // defined(OS_WIN)
-
-#if defined(OS_CHROMEOS)
-AX_BASE_EXPORT extern const base::Feature kAccessibilityCursorColor;
-
-// Returns true if the accessibility cursor color feature is enabled, letting
-// users pick a custom cursor color.
-AX_BASE_EXPORT bool IsAccessibilityCursorColorEnabled();
-#endif // defined(OS_CHROMEOS)
-
-// Enables Get Image Descriptions to augment existing images labels,
-// rather than only provide descriptions for completely unlabeled images.
-AX_BASE_EXPORT extern const base::Feature kAugmentExistingImageLabels;
-
-// Returns true if augmenting existing image labels is enabled.
-AX_BASE_EXPORT bool IsAugmentExistingImageLabelsEnabled();
-
-} // namespace features
-
-#endif // UI_ACCESSIBILITY_ACCESSIBILITY_FEATURES_H_
diff --git a/third_party/accessibility/ax/accessibility_switches.cc b/third_party/accessibility/ax/accessibility_switches.cc
deleted file mode 100644
index 07dafef..0000000
--- a/third_party/accessibility/ax/accessibility_switches.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/accessibility_switches.h"
-
-#include "base/command_line.h"
-#include "build/build_config.h"
-
-namespace switches {
-
-// Shows additional automatic click features that haven't launched yet.
-const char kEnableExperimentalAccessibilityAutoclick[] =
- "enable-experimental-accessibility-autoclick";
-
-// Enables support for visually debugging the accessibility labels
-// feature, which provides images descriptions for screen reader users.
-const char kEnableExperimentalAccessibilityLabelsDebugging[] =
- "enable-experimental-accessibility-labels-debugging";
-
-// Enables language detection on in-page text content which is then exposed to
-// assistive technology such as screen readers.
-const char kEnableExperimentalAccessibilityLanguageDetection[] =
- "enable-experimental-accessibility-language-detection";
-
-// Enables language detection for dynamic content which is then exposed to
-// assistive technology such as screen readers.
-const char kEnableExperimentalAccessibilityLanguageDetectionDynamic[] =
- "enable-experimental-accessibility-language-detection-dynamic";
-
-// Enables in progress Switch Access features for text input.
-const char kEnableExperimentalAccessibilitySwitchAccessText[] =
- "enable-experimental-accessibility-switch-access-text";
-
-// Enables annotations feature that hasn't launched yet.
-const char kEnableExperimentalAccessibilityChromeVoxAnnotations[] =
- "enable-experimental-accessibility-chromevox-annotations";
-
-// Disables ChromeVox language switching feature.
-const char kDisableExperimentalAccessibilityChromeVoxLanguageSwitching[] =
- "disable-experimental-accessibility-chromevox-language-switching";
-
-// Disables ChromeVox search menus feature.
-const char kDisableExperimentalAccessibilityChromeVoxSearchMenus[] =
- "disable-experimental-accessibility-chromevox-search-menus";
-
-// Enables interactive tutorial for ChromeVox.
-const char kEnableExperimentalAccessibilityChromeVoxTutorial[] =
- "enable-experimental-accessibility-chromevox-tutorial";
-
-// Enables Switch Access point scanning. This feature hasn't launched yet.
-const char kEnableSwitchAccessPointScanning[] =
- "enable-switch-access-point-scanning";
-
-bool IsExperimentalAccessibilityLanguageDetectionEnabled() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetection);
-}
-
-bool IsExperimentalAccessibilityLanguageDetectionDynamicEnabled() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetectionDynamic);
-}
-
-bool IsExperimentalAccessibilitySwitchAccessTextEnabled() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- ::switches::kEnableExperimentalAccessibilitySwitchAccessText);
-}
-
-bool IsSwitchAccessPointScanningEnabled() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- ::switches::kEnableSwitchAccessPointScanning);
-}
-
-#if defined(OS_WIN)
-// Enables UI Automation platform API in addition to the IAccessible API.
-const char kEnableExperimentalUIAutomation[] =
- "enable-experimental-ui-automation";
-#endif
-
-bool IsExperimentalAccessibilityPlatformUIAEnabled() {
-#if defined(OS_WIN)
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- ::switches::kEnableExperimentalUIAutomation);
-#else
- return false;
-#endif
-}
-
-// Optionally disable AXMenuList, which makes the internal pop-up menu
-// UI for a select element directly accessible.
-const char kDisableAXMenuList[] = "disable-ax-menu-list";
-
-} // namespace switches
diff --git a/third_party/accessibility/ax/accessibility_switches.h b/third_party/accessibility/ax/accessibility_switches.h
deleted file mode 100644
index 0a9f3ab..0000000
--- a/third_party/accessibility/ax/accessibility_switches.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Define all the command-line switches used by ui/accessibility.
-#ifndef UI_ACCESSIBILITY_ACCESSIBILITY_SWITCHES_H_
-#define UI_ACCESSIBILITY_ACCESSIBILITY_SWITCHES_H_
-
-#include "build/build_config.h"
-#include "ui/accessibility/ax_base_export.h"
-
-namespace switches {
-
-AX_BASE_EXPORT extern const char kEnableExperimentalAccessibilityAutoclick[];
-AX_BASE_EXPORT extern const char
- kEnableExperimentalAccessibilityLabelsDebugging[];
-AX_BASE_EXPORT extern const char
- kEnableExperimentalAccessibilityLanguageDetection[];
-AX_BASE_EXPORT extern const char
- kEnableExperimentalAccessibilityLanguageDetectionDynamic[];
-AX_BASE_EXPORT extern const char
- kEnableExperimentalAccessibilitySwitchAccessText[];
-AX_BASE_EXPORT extern const char
- kEnableExperimentalAccessibilityChromeVoxAnnotations[];
-AX_BASE_EXPORT extern const char
- kDisableExperimentalAccessibilityChromeVoxLanguageSwitching[];
-AX_BASE_EXPORT extern const char
- kDisableExperimentalAccessibilityChromeVoxSearchMenus[];
-AX_BASE_EXPORT extern const char
- kEnableExperimentalAccessibilityChromeVoxTutorial[];
-AX_BASE_EXPORT extern const char kEnableSwitchAccessPointScanning[];
-
-// Returns true if experimental accessibility language detection is enabled.
-AX_BASE_EXPORT bool IsExperimentalAccessibilityLanguageDetectionEnabled();
-
-// Returns true if experimental accessibility language detection support for
-// dynamic content is enabled.
-AX_BASE_EXPORT bool
-IsExperimentalAccessibilityLanguageDetectionDynamicEnabled();
-
-// Returns true if experimental accessibility Switch Access text is enabled.
-AX_BASE_EXPORT bool IsExperimentalAccessibilitySwitchAccessTextEnabled();
-
-#if defined(OS_WIN)
-AX_BASE_EXPORT extern const char kEnableExperimentalUIAutomation[];
-#endif
-
-// Returns true if experimental support for UIAutomation is enabled.
-AX_BASE_EXPORT bool IsExperimentalAccessibilityPlatformUIAEnabled();
-
-// Returns true if Switch Access point scanning is enabled.
-AX_BASE_EXPORT bool IsSwitchAccessPointScanningEnabled();
-
-// Optionally disable AXMenuList, which makes the internal pop-up menu
-// UI for a select element directly accessible.
-AX_BASE_EXPORT extern const char kDisableAXMenuList[];
-
-} // namespace switches
-
-#endif // UI_ACCESSIBILITY_ACCESSIBILITY_SWITCHES_H_
diff --git a/third_party/accessibility/ax/aura/aura_window_properties.cc b/third_party/accessibility/ax/aura/aura_window_properties.cc
deleted file mode 100644
index a9473d8..0000000
--- a/third_party/accessibility/ax/aura/aura_window_properties.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/aura/aura_window_properties.h"
-
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/base/class_property.h"
-
-DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AX_EXPORT, ax::mojom::Role)
-
-namespace ui {
-
-DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kChildAXTreeID, nullptr)
-
-DEFINE_UI_CLASS_PROPERTY_KEY(ax::mojom::Role,
- kAXRoleOverride,
- ax::mojom::Role::kNone)
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/aura/aura_window_properties.h b/third_party/accessibility/ax/aura/aura_window_properties.h
deleted file mode 100644
index 9fa2b82..0000000
--- a/third_party/accessibility/ax/aura/aura_window_properties.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AURA_AURA_WINDOW_PROPERTIES_H_
-#define UI_ACCESSIBILITY_AURA_AURA_WINDOW_PROPERTIES_H_
-
-#include <string>
-
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/aura/window.h"
-
-namespace ui {
-
-// Value is a serialized |ui::AXTreeID| because code in //ui/aura/mus needs
-// to serialize the window property, but //ui/aura cannot depend on
-// //ui/accessibility and hence cannot know about the type ui::AXTreeID.
-// TODO(dmazzoni): Convert from string to base::UnguessableToken.
-AX_EXPORT extern const aura::WindowProperty<std::string*>* const kChildAXTreeID;
-
-AX_EXPORT extern const aura::WindowProperty<ax::mojom::Role>* const
- kAXRoleOverride;
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AURA_AURA_WINDOW_PROPERTIES_H_
diff --git a/third_party/accessibility/ax/ax_action_data.cc b/third_party/accessibility/ax/ax_action_data.cc
index 4e9ab6f..b07cc43 100644
--- a/third_party/accessibility/ax/ax_action_data.cc
+++ b/third_party/accessibility/ax/ax_action_data.cc
@@ -2,14 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_action_data.h"
+#include "ax_action_data.h"
-#include "ui/accessibility/ax_enums.mojom.h"
+#include "ax_enums.h"
namespace ui {
-// Mojo enums are initialized here so the header can include the much smaller
-// mojom-forward.h header.
AXActionData::AXActionData()
: action(ax::mojom::Action::kNone),
hit_test_event_to_fire(ax::mojom::Event::kNone),
diff --git a/third_party/accessibility/ax/ax_action_data.h b/third_party/accessibility/ax/ax_action_data.h
index 1527ae9..7e7f0a9 100644
--- a/third_party/accessibility/ax/ax_action_data.h
+++ b/third_party/accessibility/ax/ax_action_data.h
@@ -5,10 +5,11 @@
#ifndef UI_ACCESSIBILITY_AX_ACTION_DATA_H_
#define UI_ACCESSIBILITY_AX_ACTION_DATA_H_
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/gfx/geometry/rect.h"
+#include "ax_enums.h"
+#include "ax_export.h"
+#include "ax_tree_id.h"
+#include "gfx/geometry/point.h"
+#include "gfx/geometry/rect.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_action_handler.cc b/third_party/accessibility/ax/ax_action_handler.cc
index 3ac9ce8..5fea9ab 100644
--- a/third_party/accessibility/ax/ax_action_handler.cc
+++ b/third_party/accessibility/ax/ax_action_handler.cc
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_action_handler.h"
+#include "ax_action_handler.h"
-#include "ui/accessibility/ax_tree_id_registry.h"
+#include "ax_tree_id_registry.h"
namespace ui {
AXActionHandler::AXActionHandler()
: AXActionHandlerBase(
- AXTreeIDRegistry::GetInstance()->GetOrCreateAXTreeID(this)) {}
+ AXTreeIDRegistry::GetInstance().GetOrCreateAXTreeID(this)) {}
} // namespace ui
diff --git a/third_party/accessibility/ax/ax_action_handler.h b/third_party/accessibility/ax/ax_action_handler.h
index d999a0e..7b07aae 100644
--- a/third_party/accessibility/ax/ax_action_handler.h
+++ b/third_party/accessibility/ax/ax_action_handler.h
@@ -5,8 +5,8 @@
#ifndef UI_ACCESSIBILITY_AX_ACTION_HANDLER_H_
#define UI_ACCESSIBILITY_AX_ACTION_HANDLER_H_
-#include "ui/accessibility/ax_action_handler_base.h"
-#include "ui/accessibility/ax_export.h"
+#include "ax_action_handler_base.h"
+#include "ax_export.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_action_handler_base.cc b/third_party/accessibility/ax/ax_action_handler_base.cc
index 43edc1e..3c7eac9 100644
--- a/third_party/accessibility/ax/ax_action_handler_base.cc
+++ b/third_party/accessibility/ax/ax_action_handler_base.cc
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_action_handler_base.h"
+#include "ax_action_handler_base.h"
-#include "ui/accessibility/ax_tree_id_registry.h"
+#include "ax_tree_id_registry.h"
+#include "base/logging.h"
namespace ui {
@@ -19,14 +20,14 @@
: tree_id_(ax_tree_id) {}
AXActionHandlerBase::~AXActionHandlerBase() {
- AXTreeIDRegistry::GetInstance()->RemoveAXTreeID(tree_id_);
+ AXTreeIDRegistry::GetInstance().RemoveAXTreeID(tree_id_);
}
void AXActionHandlerBase::SetAXTreeID(AXTreeID new_ax_tree_id) {
- DCHECK_NE(new_ax_tree_id, ui::AXTreeIDUnknown());
- AXTreeIDRegistry::GetInstance()->RemoveAXTreeID(tree_id_);
+ BASE_DCHECK(new_ax_tree_id != ui::AXTreeIDUnknown());
+ AXTreeIDRegistry::GetInstance().RemoveAXTreeID(tree_id_);
tree_id_ = new_ax_tree_id;
- AXTreeIDRegistry::GetInstance()->SetAXTreeID(tree_id_, this);
+ AXTreeIDRegistry::GetInstance().SetAXTreeID(tree_id_, this);
}
} // namespace ui
diff --git a/third_party/accessibility/ax/ax_action_handler_base.h b/third_party/accessibility/ax/ax_action_handler_base.h
index 2e2b5b0..864ec02 100644
--- a/third_party/accessibility/ax/ax_action_handler_base.h
+++ b/third_party/accessibility/ax/ax_action_handler_base.h
@@ -5,8 +5,8 @@
#ifndef UI_ACCESSIBILITY_AX_ACTION_HANDLER_BASE_H_
#define UI_ACCESSIBILITY_AX_ACTION_HANDLER_BASE_H_
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_tree_id.h"
+#include "ax_export.h"
+#include "ax_tree_id.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_action_target.h b/third_party/accessibility/ax/ax_action_target.h
deleted file mode 100644
index fe2797a..0000000
--- a/third_party/accessibility/ax/ax_action_target.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_ACTION_TARGET_H_
-#define UI_ACCESSIBILITY_AX_ACTION_TARGET_H_
-
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace ui {
-
-// AXActionTarget is an abstract interface that can be used to carry out
-// accessibility actions on nodes from an AXTreeSource without knowing the
-// concrete class of that AXTreeSource.
-class AXActionTarget {
- public:
- virtual ~AXActionTarget() = default;
-
- enum class Type { kNull, kBlink, kPdf };
- virtual Type GetType() const = 0;
-
- virtual bool ClearAccessibilityFocus() const = 0;
- virtual bool Click() const = 0;
- virtual bool Decrement() const = 0;
- virtual bool Increment() const = 0;
- virtual bool Focus() const = 0;
- virtual gfx::Rect GetRelativeBounds() const = 0;
- virtual gfx::Point GetScrollOffset() const = 0;
- virtual gfx::Point MinimumScrollOffset() const = 0;
- virtual gfx::Point MaximumScrollOffset() const = 0;
- virtual bool SetAccessibilityFocus() const = 0;
- virtual void SetScrollOffset(const gfx::Point& point) const = 0;
- virtual bool SetSelected(bool selected) const = 0;
- virtual bool SetSelection(const AXActionTarget* anchor_object,
- int anchor_offset,
- const AXActionTarget* focus_object,
- int focus_offset) const = 0;
- virtual bool SetSequentialFocusNavigationStartingPoint() const = 0;
- virtual bool SetValue(const std::string& value) const = 0;
- virtual bool ShowContextMenu() const = 0;
- // Make this object visible by scrolling as many nested scrollable views as
- // needed.
- virtual bool ScrollToMakeVisible() const = 0;
- // Same, but if the whole object can't be made visible, try for this subrect,
- // in local coordinates.
- virtual bool ScrollToMakeVisibleWithSubFocus(
- const gfx::Rect& rect,
- ax::mojom::ScrollAlignment horizontal_scroll_alignment,
- ax::mojom::ScrollAlignment vertical_scroll_alignment,
- ax::mojom::ScrollBehavior scroll_behavior) const = 0;
- // Scroll this object to a given point in global coordinates of the top-level
- // window.
- virtual bool ScrollToGlobalPoint(const gfx::Point& point) const = 0;
-
- protected:
- AXActionTarget() = default;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_ACTION_TARGET_H_
diff --git a/third_party/accessibility/ax/ax_active_popup.cc b/third_party/accessibility/ax/ax_active_popup.cc
deleted file mode 100644
index 570838f..0000000
--- a/third_party/accessibility/ax/ax_active_popup.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_active_popup.h"
-
-namespace ui {
-// Represents a global storage for the view accessibility for an
-// autofill popup. It is a singleton wrapper around the ax unique id of the
-// autofill popup. This singleton is used for communicating the live status of
-// the autofill popup between web contents and views.
-// The assumption here is that only one autofill popup can exist at a time.
-static base::NoDestructor<base::Optional<int32_t>> g_active_popup_ax_unique_id;
-
-base::Optional<int32_t> GetActivePopupAxUniqueId() {
- return *g_active_popup_ax_unique_id;
-}
-
-void SetActivePopupAxUniqueId(base::Optional<int32_t> ax_unique_id) {
- // When an instance of autofill popup hides, the caller of popup hide should
- // make sure g_active_popup_ax_unique_id is cleared. The assumption is that
- // there can only be one active autofill popup existing at a time. If on
- // popup showing, we encounter g_active_popup_ax_unique_id is already set,
- // this would indicate two autofill popups are showing at the same time or
- // previous on popup hide call did not clear the variable, so we should fail
- // DCHECK here.
- DCHECK(!GetActivePopupAxUniqueId());
-
- *g_active_popup_ax_unique_id = ax_unique_id;
-}
-
-void ClearActivePopupAxUniqueId() {
- *g_active_popup_ax_unique_id = base::nullopt;
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_active_popup.h b/third_party/accessibility/ax/ax_active_popup.h
deleted file mode 100644
index 111c8c5..0000000
--- a/third_party/accessibility/ax/ax_active_popup.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_ACTIVE_POPUP_H_
-#define UI_ACCESSIBILITY_AX_ACTIVE_POPUP_H_
-
-#include "base/macros.h"
-#include "base/no_destructor.h"
-#include "base/optional.h"
-#include "ui/accessibility/ax_export.h"
-
-namespace ui {
-AX_EXPORT base::Optional<int32_t> GetActivePopupAxUniqueId();
-
-AX_EXPORT void SetActivePopupAxUniqueId(base::Optional<int32_t> ax_unique_id);
-
-AX_EXPORT void ClearActivePopupAxUniqueId();
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_ACTIVE_POPUP_H_
diff --git a/third_party/accessibility/ax/ax_assistant_structure.cc b/third_party/accessibility/ax/ax_assistant_structure.cc
deleted file mode 100644
index 1d34198..0000000
--- a/third_party/accessibility/ax/ax_assistant_structure.cc
+++ /dev/null
@@ -1,473 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_assistant_structure.h"
-
-#include <string>
-
-#include "base/logging.h"
-#include "base/optional.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_serializable_tree.h"
-#include "ui/accessibility/platform/ax_android_constants.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/range/range.h"
-#include "ui/gfx/transform.h"
-
-namespace ui {
-
-namespace {
-
-bool HasFocusableChild(const AXNode* node) {
- for (size_t i = 0; i < node->GetUnignoredChildCount(); ++i) {
- AXNode* child = node->GetUnignoredChildAtIndex(i);
- if (child->data().HasState(ax::mojom::State::kFocusable) ||
- HasFocusableChild(child)) {
- return true;
- }
- }
- return false;
-}
-
-bool HasOnlyTextChildren(const AXNode* node) {
- for (size_t i = 0; i < node->GetUnignoredChildCount(); ++i) {
- AXNode* child = node->GetUnignoredChildAtIndex(i);
- if (!child->IsText())
- return false;
- }
- return true;
-}
-
-// TODO(muyuanli): share with BrowserAccessibility.
-bool IsSimpleTextControl(const AXNode* node, uint32_t state) {
- return (node->data().role == ax::mojom::Role::kTextField ||
- node->data().role == ax::mojom::Role::kTextFieldWithComboBox ||
- node->data().role == ax::mojom::Role::kSearchBox ||
- node->data().HasBoolAttribute(
- ax::mojom::BoolAttribute::kEditableRoot)) &&
- !node->data().HasState(ax::mojom::State::kRichlyEditable);
-}
-
-bool IsRichTextEditable(const AXNode* node) {
- const AXNode* parent = node->GetUnignoredParent();
- return node->data().HasState(ax::mojom::State::kRichlyEditable) &&
- (!parent ||
- !parent->data().HasState(ax::mojom::State::kRichlyEditable));
-}
-
-bool IsNativeTextControl(const AXNode* node) {
- const std::string& html_tag =
- node->data().GetStringAttribute(ax::mojom::StringAttribute::kHtmlTag);
- if (html_tag == "input") {
- std::string input_type;
- if (!node->data().GetHtmlAttribute("type", &input_type))
- return true;
- return input_type.empty() || input_type == "email" ||
- input_type == "password" || input_type == "search" ||
- input_type == "tel" || input_type == "text" || input_type == "url" ||
- input_type == "number";
- }
- return html_tag == "textarea";
-}
-
-bool IsLeaf(const AXNode* node) {
- if (node->children().empty())
- return true;
-
- if (IsNativeTextControl(node) || node->IsText()) {
- return true;
- }
-
- switch (node->data().role) {
- case ax::mojom::Role::kImage:
- case ax::mojom::Role::kMeter:
- case ax::mojom::Role::kScrollBar:
- case ax::mojom::Role::kSlider:
- case ax::mojom::Role::kSplitter:
- case ax::mojom::Role::kProgressIndicator:
- case ax::mojom::Role::kDate:
- case ax::mojom::Role::kDateTime:
- case ax::mojom::Role::kInputTime:
- return true;
- default:
- return false;
- }
-}
-
-base::string16 GetInnerText(const AXNode* node) {
- if (node->IsText()) {
- return node->data().GetString16Attribute(ax::mojom::StringAttribute::kName);
- }
- base::string16 text;
- for (size_t i = 0; i < node->GetUnignoredChildCount(); ++i) {
- AXNode* child = node->GetUnignoredChildAtIndex(i);
- text += GetInnerText(child);
- }
- return text;
-}
-
-base::string16 GetValue(const AXNode* node, bool show_password) {
- base::string16 value =
- node->data().GetString16Attribute(ax::mojom::StringAttribute::kValue);
-
- if (value.empty() &&
- (IsSimpleTextControl(node, node->data().state) ||
- IsRichTextEditable(node)) &&
- !IsNativeTextControl(node)) {
- value = GetInnerText(node);
- }
-
- if (node->data().HasState(ax::mojom::State::kProtected)) {
- if (!show_password) {
- value = base::string16(value.size(), kSecurePasswordBullet);
- }
- }
-
- return value;
-}
-
-bool HasOnlyTextAndImageChildren(const AXNode* node) {
- for (size_t i = 0; i < node->GetUnignoredChildCount(); ++i) {
- AXNode* child = node->GetUnignoredChildAtIndex(i);
- if (!child->IsText() && !ui::IsImage(child->data().role)) {
- return false;
- }
- }
- return true;
-}
-
-bool IsFocusable(const AXNode* node) {
- if (node->data().role == ax::mojom::Role::kIframe ||
- node->data().role == ax::mojom::Role::kIframePresentational ||
- (node->data().role == ax::mojom::Role::kRootWebArea &&
- node->GetUnignoredParent())) {
- return node->data().HasStringAttribute(ax::mojom::StringAttribute::kName);
- }
- return node->data().HasState(ax::mojom::State::kFocusable);
-}
-
-base::string16 GetText(const AXNode* node, bool show_password) {
- if (node->data().role == ax::mojom::Role::kWebArea ||
- node->data().role == ax::mojom::Role::kIframe ||
- node->data().role == ax::mojom::Role::kIframePresentational) {
- return base::string16();
- }
-
- ax::mojom::NameFrom name_from = static_cast<ax::mojom::NameFrom>(
- node->data().GetIntAttribute(ax::mojom::IntAttribute::kNameFrom));
- if (ui::IsListItem(node->data().role) &&
- name_from == ax::mojom::NameFrom::kContents) {
- if (!node->children().empty() && !HasOnlyTextChildren(node))
- return base::string16();
- }
-
- base::string16 value = GetValue(node, show_password);
-
- if (!value.empty()) {
- if (node->data().HasState(ax::mojom::State::kEditable))
- return value;
-
- switch (node->data().role) {
- case ax::mojom::Role::kComboBoxMenuButton:
- case ax::mojom::Role::kTextFieldWithComboBox:
- case ax::mojom::Role::kPopUpButton:
- case ax::mojom::Role::kTextField:
- return value;
- default:
- break;
- }
- }
-
- if (node->data().role == ax::mojom::Role::kColorWell) {
- unsigned int color = static_cast<unsigned int>(
- node->data().GetIntAttribute(ax::mojom::IntAttribute::kColorValue));
- unsigned int red = color >> 16 & 0xFF;
- unsigned int green = color >> 8 & 0xFF;
- unsigned int blue = color >> 0 & 0xFF;
- return base::UTF8ToUTF16(
- base::StringPrintf("#%02X%02X%02X", red, green, blue));
- }
-
- base::string16 text =
- node->data().GetString16Attribute(ax::mojom::StringAttribute::kName);
- base::string16 description = node->data().GetString16Attribute(
- ax::mojom::StringAttribute::kDescription);
- if (!description.empty()) {
- if (!text.empty())
- text += base::ASCIIToUTF16(" ");
- text += description;
- }
-
- if (text.empty())
- text = value;
-
- if (node->data().role == ax::mojom::Role::kRootWebArea)
- return text;
-
- if (text.empty() &&
- (HasOnlyTextChildren(node) ||
- (IsFocusable(node) && HasOnlyTextAndImageChildren(node)))) {
- for (size_t i = 0; i < node->GetUnignoredChildCount(); ++i) {
- AXNode* child = node->GetUnignoredChildAtIndex(i);
- text += GetText(child, show_password);
- }
- }
-
- if (text.empty() && (ui::IsLink(node->data().role) ||
- node->data().role == ax::mojom::Role::kImage)) {
- base::string16 url =
- node->data().GetString16Attribute(ax::mojom::StringAttribute::kUrl);
- text = AXUrlBaseText(url);
- }
- return text;
-}
-
-// Get string representation of ax::mojom::Role. We are not using ToString() in
-// ax_enums.h since the names are subject to change in the future and
-// we are only interested in a subset of the roles.
-base::Optional<std::string> AXRoleToString(ax::mojom::Role role) {
- switch (role) {
- case ax::mojom::Role::kArticle:
- return base::Optional<std::string>("article");
- case ax::mojom::Role::kBanner:
- return base::Optional<std::string>("banner");
- case ax::mojom::Role::kCaption:
- return base::Optional<std::string>("caption");
- case ax::mojom::Role::kComplementary:
- return base::Optional<std::string>("complementary");
- case ax::mojom::Role::kDate:
- return base::Optional<std::string>("date");
- case ax::mojom::Role::kDateTime:
- return base::Optional<std::string>("date_time");
- case ax::mojom::Role::kDefinition:
- return base::Optional<std::string>("definition");
- case ax::mojom::Role::kDetails:
- return base::Optional<std::string>("details");
- case ax::mojom::Role::kDocument:
- return base::Optional<std::string>("document");
- case ax::mojom::Role::kFeed:
- return base::Optional<std::string>("feed");
- case ax::mojom::Role::kHeading:
- return base::Optional<std::string>("heading");
- case ax::mojom::Role::kIframe:
- return base::Optional<std::string>("iframe");
- case ax::mojom::Role::kIframePresentational:
- return base::Optional<std::string>("iframe_presentational");
- case ax::mojom::Role::kList:
- return base::Optional<std::string>("list");
- case ax::mojom::Role::kListItem:
- return base::Optional<std::string>("list_item");
- case ax::mojom::Role::kMain:
- return base::Optional<std::string>("main");
- case ax::mojom::Role::kParagraph:
- return base::Optional<std::string>("paragraph");
- default:
- return base::Optional<std::string>();
- }
-}
-
-AssistantNode* AddChild(AssistantTree* tree) {
- auto node = std::make_unique<AssistantNode>();
- tree->nodes.push_back(std::move(node));
- return tree->nodes.back().get();
-}
-
-struct WalkAXTreeConfig {
- bool should_select_leaf;
- const bool show_password;
-};
-
-void WalkAXTreeDepthFirst(const AXNode* node,
- const gfx::Rect& rect,
- const AXTreeUpdate& update,
- const AXTree* tree,
- WalkAXTreeConfig* config,
- AssistantTree* assistant_tree,
- AssistantNode* result) {
- result->text = GetText(node, config->show_password);
- result->class_name =
- AXRoleToAndroidClassName(node->data().role, node->GetUnignoredParent());
- result->role = AXRoleToString(node->data().role);
-
- result->text_size = -1.0;
- result->bgcolor = 0;
- result->color = 0;
- result->bold = 0;
- result->italic = 0;
- result->line_through = 0;
- result->underline = 0;
-
- if (node->data().HasFloatAttribute(ax::mojom::FloatAttribute::kFontSize)) {
- gfx::RectF text_size_rect(
- 0, 0, 1,
- node->data().GetFloatAttribute(ax::mojom::FloatAttribute::kFontSize));
- gfx::Rect scaled_text_size_rect =
- gfx::ToEnclosingRect(tree->RelativeToTreeBounds(node, text_size_rect));
- result->text_size = scaled_text_size_rect.height();
-
- result->color =
- node->data().GetIntAttribute(ax::mojom::IntAttribute::kColor);
- result->bgcolor =
- node->data().GetIntAttribute(ax::mojom::IntAttribute::kBackgroundColor);
- result->bold = node->data().HasTextStyle(ax::mojom::TextStyle::kBold);
- result->italic = node->data().HasTextStyle(ax::mojom::TextStyle::kItalic);
- result->line_through =
- node->data().HasTextStyle(ax::mojom::TextStyle::kLineThrough);
- result->underline =
- node->data().HasTextStyle(ax::mojom::TextStyle::kUnderline);
- }
-
- const gfx::Rect& absolute_rect =
- gfx::ToEnclosingRect(tree->GetTreeBounds(node));
- gfx::Rect parent_relative_rect = absolute_rect;
- bool is_root = !node->GetUnignoredParent();
- if (!is_root) {
- parent_relative_rect.Offset(-rect.OffsetFromOrigin());
- }
- result->rect = gfx::Rect(parent_relative_rect.x(), parent_relative_rect.y(),
- absolute_rect.width(), absolute_rect.height());
-
- if (IsLeaf(node) && update.has_tree_data) {
- int start_selection = 0;
- int end_selection = 0;
- AXTree::Selection unignored_selection = tree->GetUnignoredSelection();
- if (unignored_selection.anchor_object_id == node->id()) {
- start_selection = unignored_selection.anchor_offset;
- config->should_select_leaf = true;
- }
-
- if (config->should_select_leaf) {
- end_selection =
- static_cast<int32_t>(GetText(node, config->show_password).length());
- }
-
- if (unignored_selection.focus_object_id == node->id()) {
- end_selection = unignored_selection.focus_offset;
- config->should_select_leaf = false;
- }
- if (end_selection > 0)
- result->selection =
- base::make_optional<gfx::Range>(start_selection, end_selection);
- }
-
- for (size_t i = 0; i < node->GetUnignoredChildCount(); ++i) {
- AXNode* child = node->GetUnignoredChildAtIndex(i);
- auto* n = AddChild(assistant_tree);
- result->children_indices.push_back(assistant_tree->nodes.size() - 1);
- WalkAXTreeDepthFirst(child, absolute_rect, update, tree, config,
- assistant_tree, n);
- }
-}
-
-} // namespace
-
-AssistantNode::AssistantNode() = default;
-AssistantNode::AssistantNode(const AssistantNode& other) = default;
-AssistantNode::~AssistantNode() = default;
-
-AssistantTree::AssistantTree() = default;
-AssistantTree::~AssistantTree() = default;
-
-AssistantTree::AssistantTree(const AssistantTree& other) {
- for (const auto& node : other.nodes)
- nodes.emplace_back(std::make_unique<AssistantNode>(*node));
-}
-
-std::unique_ptr<AssistantTree> CreateAssistantTree(const AXTreeUpdate& update,
- bool show_password) {
- auto tree = std::make_unique<AXSerializableTree>();
- auto assistant_tree = std::make_unique<AssistantTree>();
- auto* root = AddChild(assistant_tree.get());
- if (!tree->Unserialize(update))
- LOG(FATAL) << tree->error();
- WalkAXTreeConfig config{
- false, // should_select_leaf
- show_password // show_password
- };
- WalkAXTreeDepthFirst(tree->root(), gfx::Rect(), update, tree.get(), &config,
- assistant_tree.get(), root);
- return assistant_tree;
-}
-
-base::string16 AXUrlBaseText(base::string16 url) {
- // Given a url like http://foo.com/bar/baz.png, just return the
- // base text, e.g., "baz".
- int trailing_slashes = 0;
- while (url.size() - trailing_slashes > 0 &&
- url[url.size() - trailing_slashes - 1] == '/') {
- trailing_slashes++;
- }
- if (trailing_slashes)
- url = url.substr(0, url.size() - trailing_slashes);
- size_t slash_index = url.rfind('/');
- if (slash_index != std::string::npos)
- url = url.substr(slash_index + 1);
- size_t dot_index = url.rfind('.');
- if (dot_index != std::string::npos)
- url = url.substr(0, dot_index);
- return url;
-}
-
-const char* AXRoleToAndroidClassName(ax::mojom::Role role, bool has_parent) {
- switch (role) {
- case ax::mojom::Role::kSearchBox:
- case ax::mojom::Role::kSpinButton:
- case ax::mojom::Role::kTextField:
- case ax::mojom::Role::kTextFieldWithComboBox:
- return kAXEditTextClassname;
- case ax::mojom::Role::kSlider:
- return kAXSeekBarClassname;
- case ax::mojom::Role::kColorWell:
- case ax::mojom::Role::kComboBoxMenuButton:
- case ax::mojom::Role::kDate:
- case ax::mojom::Role::kPopUpButton:
- case ax::mojom::Role::kInputTime:
- return kAXSpinnerClassname;
- case ax::mojom::Role::kButton:
- case ax::mojom::Role::kPdfActionableHighlight:
- return kAXButtonClassname;
- case ax::mojom::Role::kCheckBox:
- case ax::mojom::Role::kSwitch:
- return kAXCheckBoxClassname;
- case ax::mojom::Role::kRadioButton:
- return kAXRadioButtonClassname;
- case ax::mojom::Role::kToggleButton:
- return kAXToggleButtonClassname;
- case ax::mojom::Role::kCanvas:
- case ax::mojom::Role::kImage:
- case ax::mojom::Role::kSvgRoot:
- return kAXImageClassname;
- case ax::mojom::Role::kMeter:
- case ax::mojom::Role::kProgressIndicator:
- return kAXProgressBarClassname;
- case ax::mojom::Role::kTabList:
- return kAXTabWidgetClassname;
- case ax::mojom::Role::kGrid:
- case ax::mojom::Role::kTreeGrid:
- case ax::mojom::Role::kTable:
- return kAXGridViewClassname;
- case ax::mojom::Role::kList:
- case ax::mojom::Role::kListBox:
- case ax::mojom::Role::kDescriptionList:
- return kAXListViewClassname;
- case ax::mojom::Role::kDialog:
- return kAXDialogClassname;
- case ax::mojom::Role::kRootWebArea:
- return has_parent ? kAXViewClassname : kAXWebViewClassname;
- case ax::mojom::Role::kMenuItem:
- case ax::mojom::Role::kMenuItemCheckBox:
- case ax::mojom::Role::kMenuItemRadio:
- return kAXMenuItemClassname;
- case ax::mojom::Role::kStaticText:
- return kAXTextViewClassname;
- default:
- return kAXViewClassname;
- }
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_assistant_structure.h b/third_party/accessibility/ax/ax_assistant_structure.h
deleted file mode 100644
index 7ec9a49..0000000
--- a/third_party/accessibility/ax/ax_assistant_structure.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_ASSISTANT_STRUCTURE_H_
-#define UI_ACCESSIBILITY_AX_ASSISTANT_STRUCTURE_H_
-
-#include <cstdint>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/optional.h"
-#include "base/strings/string16.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_tree_update.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/range/range.h"
-
-namespace ui {
-
-struct AssistantNode {
- AssistantNode();
- AssistantNode(const AssistantNode& other);
- AssistantNode& operator=(const AssistantNode&) = delete;
- ~AssistantNode();
-
- std::vector<int32_t> children_indices;
-
- // Geometry of the view in pixels
- gfx::Rect rect;
-
- // Text of the view.
- base::string16 text;
-
- // Text properties
- float text_size;
- uint32_t color;
- uint32_t bgcolor;
- bool bold;
- bool italic;
- bool underline;
- bool line_through;
-
- // Selected portion of the text.
- base::Optional<gfx::Range> selection;
-
- // Fake Android view class name of the element. Each node is assigned
- // a closest approximation of Android's views to keep the server happy.
- std::string class_name;
-
- // Accessibility functionality of the node inferred from DOM or based on HTML
- // role attribute.
- base::Optional<std::string> role;
-};
-
-struct AssistantTree {
- AssistantTree();
- AssistantTree(const AssistantTree& other);
- AssistantTree& operator=(const AssistantTree&) = delete;
- ~AssistantTree();
-
- std::vector<std::unique_ptr<AssistantNode>> nodes;
-};
-
-std::unique_ptr<AssistantTree> CreateAssistantTree(const AXTreeUpdate& update,
- bool show_password);
-
-base::string16 AXUrlBaseText(base::string16 url);
-const char* AXRoleToAndroidClassName(ax::mojom::Role role, bool has_parent);
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_ASSISTANT_STRUCTURE_H_
diff --git a/third_party/accessibility/ax/ax_constants.mojom b/third_party/accessibility/ax/ax_constants.h
similarity index 76%
rename from third_party/accessibility/ax/ax_constants.mojom
rename to third_party/accessibility/ax/ax_constants.h
index a63389b..87bb404 100644
--- a/third_party/accessibility/ax/ax_constants.mojom
+++ b/third_party/accessibility/ax/ax_constants.h
@@ -2,7 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-module ax.mojom;
+#include <stdint.h>
+
+namespace ax {
+
+namespace mojom {
// https://www.w3.org/TR/wai-aria-1.1/#aria-rowcount
// https://www.w3.org/TR/wai-aria-1.1/#aria-colcount
@@ -10,4 +14,8 @@
// value of aria-(rowcount|colcount) to -1 to indicate that the value should not
// be calculated by the user agent.
// See: AXTableInfo
-const int32 kUnknownAriaColumnOrRowCount = -1;
+const int32_t kUnknownAriaColumnOrRowCount = -1;
+
+} // namespace mojom
+
+} // namespace ax
diff --git a/third_party/accessibility/ax/ax_enum_util.cc b/third_party/accessibility/ax/ax_enum_util.cc
index f17e077..daa93b6 100644
--- a/third_party/accessibility/ax/ax_enum_util.cc
+++ b/third_party/accessibility/ax/ax_enum_util.cc
@@ -2,12 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_enum_util.h"
-
-#include "ui/accessibility/ax_enums.mojom.h"
-
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/strings/grit/ui_strings.h"
+#include "ax_enum_util.h"
namespace ui {
@@ -1352,33 +1347,6 @@
return "";
}
-std::string ToLocalizedString(ax::mojom::DefaultActionVerb action_verb) {
- switch (action_verb) {
- case ax::mojom::DefaultActionVerb::kNone:
- return "";
- case ax::mojom::DefaultActionVerb::kActivate:
- return l10n_util::GetStringUTF8(IDS_AX_ACTIVATE_ACTION_VERB);
- case ax::mojom::DefaultActionVerb::kCheck:
- return l10n_util::GetStringUTF8(IDS_AX_CHECK_ACTION_VERB);
- case ax::mojom::DefaultActionVerb::kClick:
- return l10n_util::GetStringUTF8(IDS_AX_CLICK_ACTION_VERB);
- case ax::mojom::DefaultActionVerb::kClickAncestor:
- return l10n_util::GetStringUTF8(IDS_AX_CLICK_ANCESTOR_ACTION_VERB);
- case ax::mojom::DefaultActionVerb::kJump:
- return l10n_util::GetStringUTF8(IDS_AX_JUMP_ACTION_VERB);
- case ax::mojom::DefaultActionVerb::kOpen:
- return l10n_util::GetStringUTF8(IDS_AX_OPEN_ACTION_VERB);
- case ax::mojom::DefaultActionVerb::kPress:
- return l10n_util::GetStringUTF8(IDS_AX_PRESS_ACTION_VERB);
- case ax::mojom::DefaultActionVerb::kSelect:
- return l10n_util::GetStringUTF8(IDS_AX_SELECT_ACTION_VERB);
- case ax::mojom::DefaultActionVerb::kUncheck:
- return l10n_util::GetStringUTF8(IDS_AX_UNCHECK_ACTION_VERB);
- }
-
- return "";
-}
-
ax::mojom::DefaultActionVerb ParseDefaultActionVerb(
const char* default_action_verb) {
if (0 == strcmp(default_action_verb, "none"))
diff --git a/third_party/accessibility/ax/ax_enum_util.h b/third_party/accessibility/ax/ax_enum_util.h
index 154a26e..c2ba4c7 100644
--- a/third_party/accessibility/ax/ax_enum_util.h
+++ b/third_party/accessibility/ax/ax_enum_util.h
@@ -7,8 +7,8 @@
#include <string>
-#include "ui/accessibility/ax_base_export.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
+#include "ax_base_export.h"
+#include "ax_enums.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_enum_util_unittest.cc b/third_party/accessibility/ax/ax_enum_util_unittest.cc
index b0b0c7d..8f64916 100644
--- a/third_party/accessibility/ax/ax_enum_util_unittest.cc
+++ b/third_party/accessibility/ax/ax_enum_util_unittest.cc
@@ -2,14 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_enum_util.h"
+#include "ax_enum_util.h"
#include <string>
#include <vector>
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node_data.h"
+#include "gtest/gtest.h"
+
+#include "ax_enums.h"
+#include "ax_node_data.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_enums.mojom b/third_party/accessibility/ax/ax_enums.h
similarity index 86%
rename from third_party/accessibility/ax/ax_enums.mojom
rename to third_party/accessibility/ax/ax_enums.h
index 3b3c56d..1a444cd 100644
--- a/third_party/accessibility/ax/ax_enums.mojom
+++ b/third_party/accessibility/ax/ax_enums.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Must also be kept in sync with extensions/common/api/automation.idl.
-module ax.mojom;
+#ifndef UI_ACCESSIBILITY_AX_ENUMS_H_
+#define UI_ACCESSIBILITY_AX_ENUMS_H_
// For new entries to the following four enums, also add to
// extensions/common/api/automation.idl. This is enforced
@@ -24,8 +24,11 @@
//
// If unspecified, the attribute is used across web and native on multiple
// platforms.
+namespace ax {
-enum Event {
+namespace mojom {
+
+enum class Event {
kNone,
kActiveDescendantChanged,
kAlert,
@@ -79,9 +82,9 @@
kShow, // Native / Automation
kStateChanged, // Native / Automation
kTextChanged,
- kWindowActivated, // Native
- kWindowDeactivated, // Native
- kWindowVisibilityChanged, // Native
+ kWindowActivated, // Native
+ kWindowDeactivated, // Native
+ kWindowVisibilityChanged, // Native
kTextSelectionChanged,
kTooltipClosed,
kTooltipOpened,
@@ -89,6 +92,8 @@
// explicitly fire an accessibility event,
// only implicitly due to the change.
kValueChanged,
+ kMinValue = kNone,
+ kMaxValue = kValueChanged,
};
// Accessibility object roles.
@@ -103,7 +108,7 @@
// Web: this attribute is only used in web content.
//
// Native: this attribute is only used in native UI.
-enum Role {
+enum class Role {
kNone,
kAbbr,
kAlert,
@@ -252,7 +257,7 @@
kNote,
kPane,
kParagraph,
- kPdfActionableHighlight, // PDF specific highlight role.
+ kPdfActionableHighlight, // PDF specific highlight role.
kPluginObject,
kPopUpButton,
kPortal,
@@ -305,9 +310,11 @@
kWebArea,
kWebView,
kWindow,
+ kMinValue = kNone,
+ kMaxValue = kWindow,
};
-enum State {
+enum class State {
kNone,
kAutofillAvailable,
kCollapsed,
@@ -330,12 +337,14 @@
// Grows vertically, e.g. menu or combo box.
kVertical,
kVisited,
+ kMinValue = kNone,
+ kMaxValue = kVisited,
};
// An action to be taken on an accessibility node.
// In contrast to |AXDefaultActionVerb|, these describe what happens to the
// object, e.g. "FOCUS".
-enum Action {
+enum class Action {
kNone,
// Request image annotations for all the eligible images on a page.
@@ -431,34 +440,44 @@
// Send an event signaling the end of a test.
kSignalEndOfTest,
kShowTooltip,
+ // Used for looping through the enum, This must be the last value of this
+ // enum.
+ kMinValue = kNone,
+ kMaxValue = kShowTooltip,
};
-enum ActionFlags {
+enum class ActionFlags {
kNone,
kRequestImages,
kRequestInlineTextBoxes,
+ kMinValue = kNone,
+ kMaxValue = kRequestInlineTextBoxes,
};
// A list of valid values for the horizontal and vertical scroll alignment
// arguments in |AXActionData|. These values control where a node is scrolled
// in the viewport.
-enum ScrollAlignment {
+enum class ScrollAlignment {
kNone,
kScrollAlignmentCenter,
kScrollAlignmentTop,
kScrollAlignmentBottom,
kScrollAlignmentLeft,
kScrollAlignmentRight,
- kScrollAlignmentClosestEdge
+ kScrollAlignmentClosestEdge,
+ kMinValue = kNone,
+ kMaxValue = kScrollAlignmentClosestEdge,
};
// A list of valid values for the scroll behavior argument to argument in
// |AXActionData|. These values control whether a node is scrolled in the
// viewport if it is already visible.
-enum ScrollBehavior {
+enum class ScrollBehavior {
kNone,
kDoNotScrollIfVisible,
kScrollIfVisible,
+ kMinValue = kNone,
+ kMaxValue = kScrollIfVisible,
};
// A list of valid values for the |AXIntAttribute| |default_action_verb|.
@@ -467,7 +486,7 @@
// In contrast to |AXAction|, these describe what the user can do on the
// object, e.g. "PRESS", not what happens to the object as a result.
// Only one verb can be used at a time to describe the default action.
-enum DefaultActionVerb {
+enum class DefaultActionVerb {
kNone,
kActivate,
kCheck,
@@ -484,18 +503,22 @@
kPress,
kSelect,
kUncheck,
+ kMinValue = kNone,
+ kMaxValue = kUncheck,
};
// A change to the accessibility tree.
-enum Mutation {
+enum class Mutation {
kNone,
kNodeCreated,
kSubtreeCreated,
kNodeChanged,
kNodeRemoved,
+ kMinValue = kNone,
+ kMaxValue = kNodeRemoved,
};
-enum StringAttribute {
+enum class StringAttribute {
kNone,
kAccessKey,
// Only used when invalid_state == invalid_state_other.
@@ -530,9 +553,11 @@
kTooltip,
kUrl,
kValue,
+ kMinValue = kNone,
+ kMaxValue = kValue,
};
-enum IntAttribute {
+enum class IntAttribute {
kNone,
kDefaultActionVerb,
// Scrollable container attributes.
@@ -667,9 +692,11 @@
// unrelated to the accessibility node ID, or the ID attribute for an
// HTML element - it's an ID used to uniquely identify nodes in Blink.
kDOMNodeId,
+ kMinValue = kNone,
+ kMaxValue = kDOMNodeId,
};
-enum FloatAttribute {
+enum class FloatAttribute {
kNone,
// Range attributes.
kValueForRange,
@@ -688,6 +715,8 @@
// The text indent of the text, in mm.
kTextIndent,
+ kMinValue = kNone,
+ kMaxValue = kTextIndent,
};
// These attributes can take three states:
@@ -698,7 +727,7 @@
//
// Finally, note that different tree sources can use all three states for a
// given attribute, while another tree source only uses two.
-enum BoolAttribute {
+enum class BoolAttribute {
kNone,
// Generic busy state, does not have to be on a live region.
@@ -763,9 +792,11 @@
// True if the node has any ARIA attributes set.
kHasAriaAttribute,
+ kMinValue = kNone,
+ kMaxValue = kHasAriaAttribute,
};
-enum IntListAttribute {
+enum class IntListAttribute {
kNone,
// Ids of nodes that are children of this node logically, but are
// not children of this node in the tree structure. As an example,
@@ -812,26 +843,32 @@
// items. Developer can expose those actions as custom actions. Currently
// custom actions are used only in Android window.
kCustomActionIds,
+ kMinValue = kNone,
+ kMaxValue = kCustomActionIds,
};
-enum StringListAttribute {
+enum class StringListAttribute {
kNone,
// Descriptions for custom actions. This must be aligned with
// custom_action_ids.
kCustomActionDescriptions,
+ kMinValue = kNone,
+ kMaxValue = kCustomActionDescriptions,
};
-enum ListStyle {
+enum class ListStyle {
kNone,
kCircle,
kDisc,
kImage,
kNumeric,
kSquare,
- kOther, // Language specific ordering (alpha, roman, cjk-ideographic, etc...)
+ kOther, // Language specific ordering (alpha, roman, cjk-ideographic, etc...)
+ kMinValue = kNone,
+ kMaxValue = kOther,
};
-enum MarkerType {
+enum class MarkerType {
kNone = 0,
kSpelling = 1,
kGrammar = 2,
@@ -840,35 +877,41 @@
// purposes
kActiveSuggestion = 16,
kSuggestion = 32,
+ kMinValue = kNone,
+ kMaxValue = kSuggestion,
};
// Describes a move direction in the accessibility tree that is independent of
// the left-to-right or right-to-left direction of the text. For example, a
// forward movement will always move to the next node in depth-first pre-order
// traversal.
-enum MoveDirection {
+enum class MoveDirection {
kForward,
kBackward,
- kNone = kForward
+ kNone = kForward,
+ kMinValue = kForward,
+ kMaxValue = kBackward,
};
// Describes the edit or selection command that resulted in a selection or a
// text changed event.
-enum Command {
+enum class Command {
kClearSelection,
kCut,
kDelete,
kDictate,
kExtendSelection, // The existing selection has been extended or shrunk.
- kFormat, // The text attributes, such as font size, have changed.
+ kFormat, // The text attributes, such as font size, have changed.
kInsert,
- kMarker, // A document marker has been added or removed.
+ kMarker, // A document marker has been added or removed.
kMoveSelection, // The selection has been moved by a specific granularity.
kPaste,
kReplace,
kSetSelection, // A completely new selection has been set.
kType,
- kNone = kType
+ kNone = kType,
+ kMinValue = kClearSelection,
+ kMaxValue = kType,
};
// Defines a set of text boundaries in the accessibility tree.
@@ -882,7 +925,7 @@
// e.g. at the start or end of a text field.
//
// TODO(nektar): Split TextBoundary into TextUnit and TextBoundary.
-enum TextBoundary {
+enum class TextBoundary {
kCharacter,
kFormat,
kLineEnd,
@@ -902,53 +945,65 @@
kWordEnd,
kWordStart,
kWordStartOrEnd,
- kNone = kObject
+ kNone = kObject,
+ kMinValue = kCharacter,
+ kMaxValue = kWordStartOrEnd,
};
// Types of text alignment according to the IAccessible2 Object Attributes spec.
-enum TextAlign {
+enum class TextAlign {
kNone,
kLeft,
kRight,
kCenter,
kJustify,
+ kMinValue = kNone,
+ kMaxValue = kJustify,
};
-enum WritingDirection {
+enum class WritingDirection {
kNone,
kLtr,
kRtl,
kTtb,
kBtt,
+ kMinValue = kNone,
+ kMaxValue = kBtt,
};
-enum TextPosition {
+enum class TextPosition {
kNone,
kSubscript,
kSuperscript,
+ kMinValue = kNone,
+ kMaxValue = kSuperscript,
};
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.ui.accessibility
-enum TextStyle {
+enum class TextStyle {
kBold,
kItalic,
kUnderline,
kLineThrough,
kOverline,
- kNone
+ kNone,
+ kMinValue = kBold,
+ kMaxValue = kNone,
};
-enum TextDecorationStyle {
+enum class TextDecorationStyle {
kNone,
kDotted,
kDashed,
kSolid,
kDouble,
kWavy,
+ kMinValue = kNone,
+ kMaxValue = kWavy,
};
-enum AriaCurrentState {
+enum class AriaCurrentState {
kNone,
kFalse,
kTrue,
@@ -958,9 +1013,11 @@
kUnclippedLocation,
kDate,
kTime,
+ kMinValue = kNone,
+ kMaxValue = kTime,
};
-enum HasPopup {
+enum class HasPopup {
kFalse = 0,
kTrue,
kMenu,
@@ -968,72 +1025,88 @@
kTree,
kGrid,
kDialog,
- kNone = kFalse
+ kNone = kFalse,
+ kMinValue = kNone,
+ kMaxValue = kDialog,
};
-enum InvalidState {
+enum class InvalidState {
kNone,
kFalse,
kTrue,
kOther,
+ kMinValue = kNone,
+ kMaxValue = kOther,
};
// Input restriction associated with an object.
// No value for a control means it is enabled.
// Use read_only for a textbox that allows focus/selection but not input.
// Use disabled for a control or group of controls that disallows input.
-enum Restriction {
+enum class Restriction {
kNone,
kReadOnly,
kDisabled,
+ kMinValue = kNone,
+ kMaxValue = kDisabled,
};
-enum CheckedState {
+enum class CheckedState {
kNone,
kFalse,
kTrue,
kMixed,
+ kMinValue = kNone,
+ kMaxValue = kMixed,
};
-enum SortDirection {
+enum class SortDirection {
kNone,
kUnsorted,
kAscending,
kDescending,
kOther,
+ kMinValue = kNone,
+ kMaxValue = kOther,
};
-enum NameFrom {
+enum class NameFrom {
kNone,
kUninitialized,
kAttribute, // E.g. aria-label.
kAttributeExplicitlyEmpty,
kCaption, // E.g. in the case of a table, from a caption element.
kContents,
- kPlaceholder, // E.g. from an HTML placeholder attribute on a text field.
- kRelatedElement, // E.g. from a figcaption Element in a figure.
- kTitle, // E.g. <input type="text" title="title">.
- kValue, // E.g. <input type="button" value="Button's name">.
+ kPlaceholder, // E.g. from an HTML placeholder attribute on a text field.
+ kRelatedElement, // E.g. from a figcaption Element in a figure.
+ kTitle, // E.g. <input type="text" title="title">.
+ kValue, // E.g. <input type="button" value="Button's name">.
+ kMinValue = kNone,
+ kMaxValue = kValue,
};
-enum DescriptionFrom {
+enum class DescriptionFrom {
kNone,
kUninitialized,
kAttribute,
kContents,
kRelatedElement,
kTitle,
+ kMinValue = kNone,
+ kMaxValue = kTitle,
};
-enum EventFrom {
+enum class EventFrom {
kNone,
kUser,
kPage,
kAction,
+ kMinValue = kNone,
+ kMaxValue = kAction,
};
// Touch gestures on Chrome OS.
-enum Gesture {
+enum class Gesture {
kNone,
kClick,
kSwipeLeft1,
@@ -1056,16 +1129,20 @@
kTap3,
kTap4,
kTouchExplore,
+ kMinValue = kNone,
+ kMaxValue = kTouchExplore,
};
-enum TextAffinity {
+enum class TextAffinity {
kNone,
kDownstream,
kUpstream,
+ kMinValue = kNone,
+ kMaxValue = kUpstream,
};
// Compares two nodes in an accessibility tree in pre-order traversal.
-enum TreeOrder {
+enum class TreeOrder {
kNone,
// Not in the same tree, or other error.
kUndefined,
@@ -1078,15 +1155,19 @@
// First node is after the second one.
kAfter,
+ kMinValue = kNone,
+ kMaxValue = kAfter,
};
-// For internal use by ui::AXTreeID / ax::mojom::AXTreeID.
-enum AXTreeIDType {
+// For internal use by ui::AXTreeID / ui::AXTreeID.
+enum class AXTreeIDType {
kUnknown, // The Tree ID is unknown.
kToken, // Every other tree ID must have a valid unguessable token.
+ kMinValue = kUnknown,
+ kMaxValue = kToken,
};
-enum ImageAnnotationStatus {
+enum class ImageAnnotationStatus {
// Not an image, or image annotation feature not enabled.
kNone,
@@ -1124,13 +1205,23 @@
// The annotation process failed, e.g. unable to contact the server,
// request timed out, etc.
kAnnotationProcessFailed,
+ kMinValue = kNone,
+ kMaxValue = kAnnotationProcessFailed,
};
-enum Dropeffect {
+enum class Dropeffect {
kNone,
kCopy,
kExecute,
kLink,
kMove,
kPopup,
+ kMinValue = kNone,
+ kMaxValue = kPopup,
};
+
+} // namespace mojom
+
+} // namespace ax
+
+#endif // UI_ACCESSIBILITY_AX_ENUMS_H_
diff --git a/third_party/accessibility/ax/ax_event.cc b/third_party/accessibility/ax/ax_event.cc
deleted file mode 100644
index ecb80d9..0000000
--- a/third_party/accessibility/ax/ax_event.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_event.h"
-
-#include "base/strings/string_number_conversions.h"
-#include "ui/accessibility/ax_enum_util.h"
-
-namespace ui {
-
-AXEvent::AXEvent() = default;
-
-AXEvent::AXEvent(AXNodeData::AXID id,
- ax::mojom::Event event_type,
- ax::mojom::EventFrom event_from,
- const std::vector<AXEventIntent>& event_intents,
- int action_request_id)
- : id(id),
- event_type(event_type),
- event_from(event_from),
- event_intents(event_intents),
- action_request_id(action_request_id) {}
-
-AXEvent::~AXEvent() = default;
-
-AXEvent::AXEvent(const AXEvent& event) = default;
-
-AXEvent& AXEvent::operator=(const AXEvent& event) = default;
-
-std::string AXEvent::ToString() const {
- std::string result = "AXEvent ";
-
- result += ui::ToString(event_type);
- result += " on node id=" + base::NumberToString(id);
- if (event_from != ax::mojom::EventFrom::kNone)
- result += std::string(" from ") + ui::ToString(event_from);
- if (!event_intents.empty()) {
- result += " caused by [ ";
- for (const AXEventIntent& intent : event_intents) {
- result += intent.ToString() + ' ';
- }
- result += ']';
- }
- if (action_request_id)
- result += " action_request_id=" + base::NumberToString(action_request_id);
- return result;
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_event.h b/third_party/accessibility/ax/ax_event.h
deleted file mode 100644
index 86869b6..0000000
--- a/third_party/accessibility/ax/ax_event.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_EVENT_H_
-#define UI_ACCESSIBILITY_AX_EVENT_H_
-
-#include <string>
-#include <vector>
-
-#include "ui/accessibility/ax_base_export.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_event_intent.h"
-#include "ui/accessibility/ax_node_data.h"
-
-namespace ui {
-
-struct AX_BASE_EXPORT AXEvent final {
- AXEvent();
- AXEvent(AXNodeData::AXID id,
- ax::mojom::Event event_type,
- ax::mojom::EventFrom event_from = ax::mojom::EventFrom::kNone,
- const std::vector<AXEventIntent>& event_intents = {},
- int action_request_id = -1);
- virtual ~AXEvent();
- AXEvent(const AXEvent& event);
- AXEvent& operator=(const AXEvent& event);
-
- // The id of the node in the AXTree that the event should be fired on.
- AXNodeData::AXID id = AXNodeData::kInvalidAXID;
-
- // The type of event.
- ax::mojom::Event event_type = ax::mojom::Event::kNone;
-
- // The source of the event.
- ax::mojom::EventFrom event_from = ax::mojom::EventFrom::kNone;
-
- // Describes what caused an accessibility event to be raised. For example, in
- // the case of a selection changed event, the selection could have been
- // extended to the beginning of the previous word, or it could have been moved
- // to the end of the next line. Note that there could be multiple causes that
- // resulted in an event.
- std::vector<AXEventIntent> event_intents;
-
- // The action request ID that was passed in if this event was fired in
- // direct response to a ax::mojom::Action.
- int action_request_id = -1;
-
- // Returns a string representation of this data, for debugging.
- std::string ToString() const;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_EVENT_H_
diff --git a/third_party/accessibility/ax/ax_event_bundle_sink.h b/third_party/accessibility/ax/ax_event_bundle_sink.h
deleted file mode 100644
index 95d6e8a..0000000
--- a/third_party/accessibility/ax/ax_event_bundle_sink.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_EVENT_BUNDLE_SINK_H_
-#define UI_ACCESSIBILITY_AX_EVENT_BUNDLE_SINK_H_
-
-#include <vector>
-
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_tree_update.h"
-
-namespace gfx {
-class Point;
-} // namespace gfx
-
-namespace ui {
-
-struct AXEvent;
-class AXTreeID;
-
-// Interface for a consumer of groups of AXEvents.
-class AX_EXPORT AXEventBundleSink {
- public:
- // |tree_id|: ID of the accessibility tree that the events apply to.
- // |updates|: Zero or more updates to the accessibility tree to apply first.
- // |mouse location|: Current mouse location in screen coordinates.
- // |events|: Zero or more events to fire after the updates have been applied.
- // Callers may wish to std::move() into the vector params to avoid copies.
- virtual void DispatchAccessibilityEvents(const AXTreeID& tree_id,
- std::vector<AXTreeUpdate> updates,
- const gfx::Point& mouse_location,
- std::vector<AXEvent> events) = 0;
-
- protected:
- virtual ~AXEventBundleSink() {}
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_EVENT_BUNDLE_SINK_H_
diff --git a/third_party/accessibility/ax/ax_event_generator.cc b/third_party/accessibility/ax/ax_event_generator.cc
index 26aa1dc..03f2a44 100644
--- a/third_party/accessibility/ax/ax_event_generator.cc
+++ b/third_party/accessibility/ax/ax_event_generator.cc
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_event_generator.h"
+#include "ax_event_generator.h"
#include <algorithm>
-#include "base/stl_util.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_role_properties.h"
+#include "ax_enums.h"
+#include "ax_node.h"
+#include "ax_role_properties.h"
+#include "base/container_utils.h"
namespace ui {
namespace {
@@ -96,7 +96,7 @@
AXEventGenerator::TargetedEvent::TargetedEvent(AXNode* node,
const EventParams& event_params)
: node(node), event_params(event_params) {
- DCHECK(node);
+ BASE_DCHECK(node);
}
bool AXEventGenerator::EventParams::operator==(const EventParams& rhs) {
@@ -141,7 +141,7 @@
}
AXEventGenerator::TargetedEvent AXEventGenerator::Iterator::operator*() const {
- DCHECK(map_iter_ != map_.end() && set_iter_ != map_iter_->second.end());
+ BASE_DCHECK(map_iter_ != map_.end() && set_iter_ != map_iter_->second.end());
return AXEventGenerator::TargetedEvent(map_iter_->first, *set_iter_);
}
@@ -149,21 +149,21 @@
AXEventGenerator::AXEventGenerator(AXTree* tree) : tree_(tree) {
if (tree_)
- tree_event_observer_.Add(tree_);
+ tree_->AddObserver(this);
}
AXEventGenerator::~AXEventGenerator() = default;
void AXEventGenerator::SetTree(AXTree* new_tree) {
if (tree_)
- tree_event_observer_.Remove(tree_);
+ tree_->RemoveObserver(this);
tree_ = new_tree;
if (tree_)
- tree_event_observer_.Add(tree_);
+ tree_->AddObserver(this);
}
void AXEventGenerator::ReleaseTree() {
- tree_event_observer_.RemoveAll();
+ tree_->RemoveObserver(this);
tree_ = nullptr;
}
@@ -172,7 +172,7 @@
}
void AXEventGenerator::AddEvent(AXNode* node, AXEventGenerator::Event event) {
- DCHECK(node);
+ BASE_DCHECK(node);
if (node->data().role == ax::mojom::Role::kInlineTextBox)
return;
@@ -185,7 +185,7 @@
void AXEventGenerator::OnNodeDataChanged(AXTree* tree,
const AXNodeData& old_node_data,
const AXNodeData& new_node_data) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
// Fire CHILDREN_CHANGED events when the list of children updates.
// Internally we store inline text box nodes as children of a static text
// node or a line break node, which enables us to determine character bounds
@@ -204,7 +204,7 @@
AXNode* node,
ax::mojom::Role old_role,
ax::mojom::Role new_role) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
AddEvent(node, Event::ROLE_CHANGED);
}
@@ -212,7 +212,7 @@
AXNode* node,
ax::mojom::State state,
bool new_value) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
if (state != ax::mojom::State::kIgnored) {
AddEvent(node, Event::STATE_CHANGED);
@@ -260,7 +260,7 @@
ax::mojom::StringAttribute attr,
const std::string& old_value,
const std::string& new_value) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
switch (attr) {
case ax::mojom::StringAttribute::kAccessKey:
@@ -334,7 +334,7 @@
ax::mojom::IntAttribute attr,
int32_t old_value,
int32_t new_value) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
switch (attr) {
case ax::mojom::IntAttribute::kActivedescendantId:
@@ -433,7 +433,7 @@
ax::mojom::FloatAttribute attr,
float old_value,
float new_value) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
switch (attr) {
case ax::mojom::FloatAttribute::kMaxValueForRange:
@@ -470,7 +470,7 @@
AXNode* node,
ax::mojom::BoolAttribute attr,
bool new_value) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
switch (attr) {
case ax::mojom::BoolAttribute::kBusy:
@@ -509,7 +509,7 @@
ax::mojom::IntListAttribute attr,
const std::vector<int32_t>& old_value,
const std::vector<int32_t>& new_value) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
switch (attr) {
case ax::mojom::IntListAttribute::kControlsIds:
@@ -551,7 +551,7 @@
void AXEventGenerator::OnTreeDataChanged(AXTree* tree,
const AXTreeData& old_tree_data,
const AXTreeData& new_tree_data) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
if (new_tree_data.loaded && !old_tree_data.loaded &&
ShouldFireLoadEvents(tree->root())) {
@@ -573,28 +573,28 @@
}
void AXEventGenerator::OnNodeWillBeDeleted(AXTree* tree, AXNode* node) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
tree_events_.erase(node);
}
void AXEventGenerator::OnSubtreeWillBeDeleted(AXTree* tree, AXNode* node) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
}
void AXEventGenerator::OnNodeWillBeReparented(AXTree* tree, AXNode* node) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
tree_events_.erase(node);
}
void AXEventGenerator::OnSubtreeWillBeReparented(AXTree* tree, AXNode* node) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
}
void AXEventGenerator::OnAtomicUpdateFinished(
AXTree* tree,
bool root_changed,
const std::vector<Change>& changes) {
- DCHECK_EQ(tree_, tree);
+ BASE_DCHECK(tree_ == tree);
if (root_changed && ShouldFireLoadEvents(tree->root())) {
if (tree->data().loaded)
@@ -718,7 +718,7 @@
AXNode* node,
std::map<AXNode*, IgnoredChangedStatesBitset>&
ancestor_ignored_changed_map) {
- DCHECK(node);
+ BASE_DCHECK(node);
// Recursively compute and cache ancestor ignored changed results in
// |ancestor_ignored_changed_map|, if |node|'s ancestors have become ignored
@@ -1049,7 +1049,7 @@
case AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED:
return "WIN_IACCESSIBLE_STATE_CHANGED";
}
- NOTREACHED();
+ BASE_UNREACHABLE();
}
} // namespace ui
diff --git a/third_party/accessibility/ax/ax_event_generator.h b/third_party/accessibility/ax/ax_event_generator.h
index 85f3209..24b882f 100644
--- a/third_party/accessibility/ax/ax_event_generator.h
+++ b/third_party/accessibility/ax/ax_event_generator.h
@@ -11,11 +11,10 @@
#include <set>
#include <vector>
-#include "base/scoped_observer.h"
-#include "ui/accessibility/ax_event_intent.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_tree.h"
-#include "ui/accessibility/ax_tree_observer.h"
+#include "ax_event_intent.h"
+#include "ax_export.h"
+#include "ax_tree.h"
+#include "ax_tree_observer.h"
namespace ui {
@@ -290,10 +289,6 @@
std::vector<AXNode*> active_descendant_changed_;
bool always_fire_load_complete_ = false;
-
- // Please make sure that this ScopedObserver is always declared last in order
- // to prevent any use-after-free.
- ScopedObserver<AXTree, AXTreeObserver> tree_event_observer_{this};
};
AX_EXPORT std::ostream& operator<<(std::ostream& os,
diff --git a/third_party/accessibility/ax/ax_event_generator_unittest.cc b/third_party/accessibility/ax/ax_event_generator_unittest.cc
index e7d7e24..dcb39db 100644
--- a/third_party/accessibility/ax/ax_event_generator_unittest.cc
+++ b/third_party/accessibility/ax/ax_event_generator_unittest.cc
@@ -2,40 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_event_generator.h"
+#include "ax_event_generator.h"
-#include "testing/gmock/include/gmock/gmock-matchers.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_serializable_tree.h"
-#include "ui/accessibility/ax_tree_serializer.h"
+#include "base/logging.h"
+#include "gtest/gtest.h"
+
+#include "ax_enums.h"
+#include "ax_node.h"
namespace ui {
-// Required by gmock to print TargetedEvent in a human-readable way.
-void PrintTo(const AXEventGenerator::TargetedEvent& event, std::ostream* os) {
- *os << event.event_params.event << " on " << event.node->id();
-}
-
namespace {
-using testing::Matches;
-using testing::PrintToString;
-using testing::UnorderedElementsAre;
-
-// TODO(gilmanmh): Improve printing of test failure messages when the expected
-// values are themselves matchers (e.g. Not(3)).
-MATCHER_P2(HasEventAtNode,
- expected_event_type,
- expected_node_id,
- std::string(negation ? "does not have" : "has") + " " +
- PrintToString(expected_event_type) + " on " +
- PrintToString(expected_node_id)) {
- const auto& event = arg;
- return Matches(expected_event_type)(event.event_params.event) &&
- Matches(expected_node_id)(event.node->id());
+bool HasEvent(AXEventGenerator& src,
+ AXEventGenerator::Event event_type,
+ int32_t id) {
+ for (const auto& targeted_event : src) {
+ if (targeted_event.event_params.event == event_type &&
+ targeted_event.node->id() == id)
+ return true;
+ }
+ return false;
}
} // namespace
@@ -54,8 +41,8 @@
load_complete_update.tree_data.loaded = true;
ASSERT_TRUE(tree.Unserialize(load_complete_update));
- EXPECT_THAT(event_generator, UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::LOAD_COMPLETE, 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::LOAD_COMPLETE, 1));
}
TEST(AXEventGeneratorTest, LoadCompleteNewTree) {
@@ -78,10 +65,10 @@
load_complete_update.tree_data.loaded = true;
ASSERT_TRUE(tree.Unserialize(load_complete_update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::LOAD_COMPLETE, 2),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 2)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::LOAD_COMPLETE, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 2));
// Load complete should not be emitted for sizeless roots.
load_complete_update.root_id = 3;
@@ -92,9 +79,8 @@
load_complete_update.tree_data.loaded = true;
ASSERT_TRUE(tree.Unserialize(load_complete_update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 3)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 3));
// TODO(accessibility): http://crbug.com/888758
// Load complete should not be emitted for chrome-search URLs.
@@ -109,10 +95,10 @@
load_complete_update.tree_data.loaded = true;
ASSERT_TRUE(tree.Unserialize(load_complete_update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::LOAD_COMPLETE, 4),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 4)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::LOAD_COMPLETE, 4));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 4));
}
TEST(AXEventGeneratorTest, LoadStart) {
@@ -135,10 +121,10 @@
load_start_update.tree_data.loaded = false;
ASSERT_TRUE(tree.Unserialize(load_start_update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::LOAD_START, 2),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 2)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::LOAD_START, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 2));
}
TEST(AXEventGeneratorTest, DocumentSelectionChanged) {
@@ -156,9 +142,8 @@
update.tree_data.sel_focus_offset = 2;
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::DOCUMENT_SELECTION_CHANGED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::DOCUMENT_SELECTION_CHANGED, 1));
}
TEST(AXEventGeneratorTest, DocumentTitleChanged) {
@@ -175,9 +160,8 @@
update.tree_data.title = "After";
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::DOCUMENT_TITLE_CHANGED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::DOCUMENT_TITLE_CHANGED, 1));
}
TEST(AXEventGeneratorTest, ExpandedAndRowCount) {
@@ -204,18 +188,20 @@
update.nodes[3].state = 0;
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::COLLAPSED, 4),
- HasEventAtNode(AXEventGenerator::Event::EXPANDED, 3),
- HasEventAtNode(AXEventGenerator::Event::ROW_COUNT_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::STATE_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
- 3),
- HasEventAtNode(AXEventGenerator::Event::STATE_CHANGED, 4),
- HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
- 4)));
+ EXPECT_TRUE(HasEvent(event_generator, AXEventGenerator::Event::COLLAPSED, 4));
+ EXPECT_TRUE(HasEvent(event_generator, AXEventGenerator::Event::EXPANDED, 3));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::ROW_COUNT_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::STATE_CHANGED, 3));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+ 3));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::STATE_CHANGED, 4));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+ 4));
}
TEST(AXEventGeneratorTest, SelectedAndSelectedChildren) {
@@ -247,16 +233,18 @@
update.nodes[3].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::SELECTED_CHILDREN_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::SELECTED_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
- 3),
- HasEventAtNode(AXEventGenerator::Event::SELECTED_CHANGED, 4),
- HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
- 4)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::SELECTED_CHILDREN_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SELECTED_CHANGED, 3));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+ 3));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SELECTED_CHANGED, 4));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+ 4));
}
TEST(AXEventGeneratorTest, StringValueChanged) {
@@ -276,8 +264,8 @@
"After");
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator, UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::VALUE_CHANGED, 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::VALUE_CHANGED, 1));
}
TEST(AXEventGeneratorTest, FloatValueChanged) {
@@ -297,8 +285,8 @@
2.0);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator, UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::VALUE_CHANGED, 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::VALUE_CHANGED, 1));
}
TEST(AXEventGeneratorTest, InvalidStatusChanged) {
@@ -315,9 +303,8 @@
AXTreeUpdate update = initial_state;
update.nodes[0].SetInvalidState(ax::mojom::InvalidState::kTrue);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::INVALID_STATUS_CHANGED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::INVALID_STATUS_CHANGED, 1));
}
TEST(AXEventGeneratorTest, AddLiveRegionAttribute) {
@@ -332,28 +319,25 @@
update.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kLiveStatus,
"polite");
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::LIVE_STATUS_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::LIVE_REGION_CREATED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::LIVE_STATUS_CHANGED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::LIVE_REGION_CREATED, 1));
event_generator.ClearEvents();
update.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kLiveStatus,
"assertive");
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::LIVE_STATUS_CHANGED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::LIVE_STATUS_CHANGED, 1));
event_generator.ClearEvents();
update.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kLiveStatus,
"off");
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::LIVE_STATUS_CHANGED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::LIVE_STATUS_CHANGED, 1));
}
TEST(AXEventGeneratorTest, CheckedStateChanged) {
@@ -368,12 +352,11 @@
AXTreeUpdate update = initial_state;
update.nodes[0].SetCheckedState(ax::mojom::CheckedState::kTrue);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHECKED_STATE_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
- 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::CHECKED_STATE_CHANGED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+ 1));
}
TEST(AXEventGeneratorTest, ActiveDescendantChanged) {
@@ -398,11 +381,10 @@
update.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
3);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::RELATED_NODE_CHANGED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::RELATED_NODE_CHANGED, 1));
}
TEST(AXEventGeneratorTest, CreateAlertAndLiveRegion) {
@@ -434,16 +416,18 @@
update.nodes[3].role = ax::mojom::Role::kAlertDialog;
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::ALERT, 3),
- HasEventAtNode(AXEventGenerator::Event::ALERT, 4),
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::LIVE_REGION_CREATED, 2),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 2),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 3),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 4)));
+ EXPECT_TRUE(HasEvent(event_generator, AXEventGenerator::Event::ALERT, 3));
+ EXPECT_TRUE(HasEvent(event_generator, AXEventGenerator::Event::ALERT, 4));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::LIVE_REGION_CREATED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 3));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 4));
}
TEST(AXEventGeneratorTest, LiveRegionChanged) {
@@ -485,14 +469,16 @@
"After 2");
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::LIVE_REGION_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::LIVE_REGION_NODE_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::LIVE_REGION_NODE_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::NAME_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::NAME_CHANGED, 3)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::LIVE_REGION_CHANGED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::LIVE_REGION_NODE_CHANGED, 2));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::LIVE_REGION_NODE_CHANGED, 3));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::NAME_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::NAME_CHANGED, 3));
}
TEST(AXEventGeneratorTest, LiveRegionOnlyTextChanges) {
@@ -529,13 +515,13 @@
// Note that we do NOT expect a LIVE_REGION_CHANGED event here, because
// the name did not change.
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHECKED_STATE_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
- 3),
- HasEventAtNode(AXEventGenerator::Event::DESCRIPTION_CHANGED, 2)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::CHECKED_STATE_CHANGED, 3));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+ 3));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::DESCRIPTION_CHANGED, 2));
}
TEST(AXEventGeneratorTest, BusyLiveRegionChanged) {
@@ -579,10 +565,10 @@
"After 2");
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::NAME_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::NAME_CHANGED, 3)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::NAME_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::NAME_CHANGED, 3));
}
TEST(AXEventGeneratorTest, AddChild) {
@@ -601,10 +587,10 @@
update.nodes[2].id = 3;
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 3)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 3));
}
TEST(AXEventGeneratorTest, RemoveChild) {
@@ -625,9 +611,8 @@
update.nodes[0].child_ids.push_back(2);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::CHILDREN_CHANGED, 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 1));
}
TEST(AXEventGeneratorTest, ReorderChildren) {
@@ -648,9 +633,8 @@
update.nodes[0].child_ids.push_back(2);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::CHILDREN_CHANGED, 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 1));
}
TEST(AXEventGeneratorTest, ScrollHorizontalPositionChanged) {
@@ -664,10 +648,9 @@
AXTreeUpdate update = initial_state;
update.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kScrollX, 10);
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::SCROLL_HORIZONTAL_POSITION_CHANGED, 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator,
+ AXEventGenerator::Event::SCROLL_HORIZONTAL_POSITION_CHANGED, 1));
}
TEST(AXEventGeneratorTest, ScrollVerticalPositionChanged) {
@@ -681,10 +664,9 @@
AXTreeUpdate update = initial_state;
update.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kScrollY, 10);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::SCROLL_VERTICAL_POSITION_CHANGED, 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator,
+ AXEventGenerator::Event::SCROLL_VERTICAL_POSITION_CHANGED, 1));
}
TEST(AXEventGeneratorTest, TextAttributeChanged) {
@@ -766,25 +748,38 @@
"sans");
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 4),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 5),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 6),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 7),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 8),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 9),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 10),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 11),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 12),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 13),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 14),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 15),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 16),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 17)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 2));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 3));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 4));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 5));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 6));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 7));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 8));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 9));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 10));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 11));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 12));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 13));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 14));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 15));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 16));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 17));
}
TEST(AXEventGeneratorTest, ObjectAttributeChanged) {
@@ -803,16 +798,16 @@
update.nodes[2].AddFloatAttribute(ax::mojom::FloatAttribute::kTextIndent,
10.0f);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(
- AXEventGenerator::Event::ATK_TEXT_OBJECT_ATTRIBUTE_CHANGED, 2),
- HasEventAtNode(
- AXEventGenerator::Event::ATK_TEXT_OBJECT_ATTRIBUTE_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::OBJECT_ATTRIBUTE_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::OBJECT_ATTRIBUTE_CHANGED,
- 3)));
+ EXPECT_TRUE(
+ HasEvent(event_generator,
+ AXEventGenerator::Event::ATK_TEXT_OBJECT_ATTRIBUTE_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator,
+ AXEventGenerator::Event::ATK_TEXT_OBJECT_ATTRIBUTE_CHANGED, 3));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::OBJECT_ATTRIBUTE_CHANGED, 2));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::OBJECT_ATTRIBUTE_CHANGED, 3));
}
TEST(AXEventGeneratorTest, OtherAttributeChanged) {
@@ -845,15 +840,18 @@
update.nodes[5].AddIntListAttribute(ax::mojom::IntListAttribute::kControlsIds,
ids);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CONTROLS_CHANGED, 6),
- HasEventAtNode(AXEventGenerator::Event::LANGUAGE_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 4),
- HasEventAtNode(AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED, 5),
- HasEventAtNode(AXEventGenerator::Event::RELATED_NODE_CHANGED, 6)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CONTROLS_CHANGED, 6));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::LANGUAGE_CHANGED, 2));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED, 3));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::TEXT_ATTRIBUTE_CHANGED, 4));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED, 5));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::RELATED_NODE_CHANGED, 6));
}
TEST(AXEventGeneratorTest, NameChanged) {
@@ -870,8 +868,8 @@
update.nodes[1].AddStringAttribute(ax::mojom::StringAttribute::kName,
"Hello");
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator, UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::NAME_CHANGED, 2)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::NAME_CHANGED, 2));
}
TEST(AXEventGeneratorTest, DescriptionChanged) {
@@ -886,9 +884,8 @@
update.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kDescription,
"Hello");
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::DESCRIPTION_CHANGED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::DESCRIPTION_CHANGED, 1));
}
TEST(AXEventGeneratorTest, RoleChanged) {
@@ -902,8 +899,8 @@
AXTreeUpdate update = initial_state;
update.nodes[0].role = ax::mojom::Role::kCheckBox;
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator, UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::ROLE_CHANGED, 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::ROLE_CHANGED, 1));
}
TEST(AXEventGeneratorTest, MenuItemSelected) {
@@ -928,12 +925,12 @@
update.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
3);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::MENU_ITEM_SELECTED, 3),
- HasEventAtNode(AXEventGenerator::Event::RELATED_NODE_CHANGED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::MENU_ITEM_SELECTED, 3));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::RELATED_NODE_CHANGED, 1));
}
TEST(AXEventGeneratorTest, NodeBecomesIgnored) {
@@ -962,10 +959,10 @@
AXTreeUpdate update = initial_state;
update.nodes[3].AddState(ax::mojom::State::kIgnored);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 4)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 4));
}
TEST(AXEventGeneratorTest, NodeBecomesIgnored2) {
@@ -998,10 +995,10 @@
update.nodes.pop_back();
update.nodes[3].child_ids.clear();
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 4)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 4));
}
TEST(AXEventGeneratorTest, NodeBecomesUnignored) {
@@ -1031,11 +1028,12 @@
AXTreeUpdate update = initial_state;
update.nodes[3].state = 0;
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 4),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 4)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 4));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 4));
}
TEST(AXEventGeneratorTest, NodeBecomesUnignored2) {
@@ -1069,11 +1067,12 @@
update.nodes.pop_back();
update.nodes[3].child_ids.clear();
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 4),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 4)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 4));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 4));
}
TEST(AXEventGeneratorTest, SubtreeBecomesUnignored) {
@@ -1098,11 +1097,12 @@
update.nodes[1].RemoveState(ax::mojom::State::kIgnored);
update.nodes[2].RemoveState(ax::mojom::State::kIgnored);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 2),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 2)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 2));
}
TEST(AXEventGeneratorTest, TwoNodesSwapIgnored) {
@@ -1126,12 +1126,14 @@
update.nodes[1].AddState(ax::mojom::State::kIgnored);
update.nodes[2].RemoveState(ax::mojom::State::kIgnored);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 3)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 3));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 3));
}
TEST(AXEventGeneratorTest, TwoNodesSwapIgnored2) {
@@ -1155,12 +1157,14 @@
update.nodes[1].RemoveState(ax::mojom::State::kIgnored);
update.nodes[2].AddState(ax::mojom::State::kIgnored);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 2)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 3));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 2));
}
TEST(AXEventGeneratorTest, IgnoredChangedFiredOnAncestorOnly1) {
@@ -1197,11 +1201,12 @@
update.nodes[1].AddState(ax::mojom::State::kIgnored);
update.nodes[2].RemoveState(ax::mojom::State::kIgnored);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 3)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 3));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 3));
}
TEST(AXEventGeneratorTest, IgnoredChangedFiredOnAncestorOnly2) {
@@ -1245,12 +1250,14 @@
update.nodes[2].AddState(ax::mojom::State::kIgnored);
update.nodes[3].RemoveState(ax::mojom::State::kIgnored);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 4),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 4)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 3));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 4));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 4));
}
TEST(AXEventGeneratorTest, IgnoredChangedFiredOnAncestorOnly3) {
@@ -1295,12 +1302,14 @@
update.nodes[2].RemoveState(ax::mojom::State::kIgnored);
update.nodes[3].AddState(ax::mojom::State::kIgnored);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 3)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 3));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 3));
}
TEST(AXEventGeneratorTest, IgnoredChangedFiredOnAncestorOnly4) {
@@ -1376,14 +1385,18 @@
update.nodes[6].RemoveState(ax::mojom::State::kIgnored);
update.nodes[7].AddState(ax::mojom::State::kIgnored);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 5),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 6),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 7),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 6),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 7),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 8)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 5));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 6));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 7));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 6));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 7));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 8));
}
TEST(AXEventGeneratorTest, IgnoredChangedFiredOnAncestorOnly5) {
@@ -1459,12 +1472,14 @@
update.nodes[6].AddState(ax::mojom::State::kIgnored);
update.nodes[7].AddState(ax::mojom::State::kIgnored);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 5),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 6),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 6)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 5));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 6));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 6));
}
TEST(AXEventGeneratorTest, IgnoredChangedFiredOnAncestorOnly6) {
@@ -1540,14 +1555,18 @@
update.nodes[6].RemoveState(ax::mojom::State::kIgnored);
update.nodes[7].AddState(ax::mojom::State::kIgnored);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 5),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 1),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 6),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 7),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 8)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 5));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 6));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 7));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 8));
}
TEST(AXEventGeneratorTest, IgnoredChangedFiredOnAncestorOnly7) {
@@ -1613,11 +1632,12 @@
update.nodes[2].AddState(ax::mojom::State::kIgnored);
update.nodes[3].AddState(ax::mojom::State::kIgnored);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 1),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 3)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 3));
}
TEST(AXEventGeneratorTest, IgnoredChangedFiredOnAncestorOnly8) {
@@ -1694,12 +1714,14 @@
update.nodes[5].RemoveState(ax::mojom::State::kIgnored);
update.nodes[6].AddState(ax::mojom::State::kIgnored);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 2),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::IGNORED_CHANGED, 7)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CHILDREN_CHANGED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SUBTREE_CREATED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::IGNORED_CHANGED, 7));
}
TEST(AXEventGeneratorTest, ActiveDescendantChangeOnDescendant) {
@@ -1733,11 +1755,10 @@
AXTreeUpdate update = initial_state;
update.node_id_to_clear = 2;
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::RELATED_NODE_CHANGED, 3)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED, 3));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::RELATED_NODE_CHANGED, 3));
}
TEST(AXEventGeneratorTest, ImageAnnotationChanged) {
@@ -1752,9 +1773,8 @@
update.nodes[0].AddStringAttribute(
ax::mojom::StringAttribute::kImageAnnotation, "Hello");
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::IMAGE_ANNOTATION_CHANGED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::IMAGE_ANNOTATION_CHANGED, 1));
}
TEST(AXEventGeneratorTest, ImageAnnotationStatusChanged) {
@@ -1770,9 +1790,8 @@
ax::mojom::ImageAnnotationStatus::kAnnotationSucceeded);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::IMAGE_ANNOTATION_CHANGED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::IMAGE_ANNOTATION_CHANGED, 1));
}
TEST(AXEventGeneratorTest, StringPropertyChanges) {
@@ -1810,14 +1829,16 @@
AXTreeUpdate update = initial_state;
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::ACCESS_KEY_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::CLASS_NAME_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::KEY_SHORTCUTS_CHANGED, 4),
- HasEventAtNode(AXEventGenerator::Event::LANGUAGE_CHANGED, 5),
- HasEventAtNode(AXEventGenerator::Event::PLACEHOLDER_CHANGED, 6)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::ACCESS_KEY_CHANGED, 2));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::CLASS_NAME_CHANGED, 3));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::KEY_SHORTCUTS_CHANGED, 4));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::LANGUAGE_CHANGED, 5));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::PLACEHOLDER_CHANGED, 6));
}
TEST(AXEventGeneratorTest, IntPropertyChanges) {
@@ -1851,13 +1872,12 @@
AXTreeUpdate update = initial_state;
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::HIERARCHICAL_LEVEL_CHANGED,
- 2),
- HasEventAtNode(AXEventGenerator::Event::POSITION_IN_SET_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::SET_SIZE_CHANGED, 4)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::HIERARCHICAL_LEVEL_CHANGED, 2));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::POSITION_IN_SET_CHANGED, 3));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::SET_SIZE_CHANGED, 4));
}
TEST(AXEventGeneratorTest, IntListPropertyChanges) {
@@ -1893,17 +1913,22 @@
AXTreeUpdate update = initial_state;
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::DESCRIBED_BY_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::FLOW_FROM_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::FLOW_FROM_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::FLOW_TO_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::LABELED_BY_CHANGED, 4),
- HasEventAtNode(AXEventGenerator::Event::RELATED_NODE_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::RELATED_NODE_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::RELATED_NODE_CHANGED, 4)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::DESCRIBED_BY_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::FLOW_FROM_CHANGED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::FLOW_FROM_CHANGED, 2));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::FLOW_TO_CHANGED, 3));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::LABELED_BY_CHANGED, 4));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::RELATED_NODE_CHANGED, 2));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::RELATED_NODE_CHANGED, 3));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::RELATED_NODE_CHANGED, 4));
}
TEST(AXEventGeneratorTest, AriaBusyChanged) {
@@ -1920,13 +1945,13 @@
update.nodes[0].AddBoolAttribute(ax::mojom::BoolAttribute::kBusy, false);
ASSERT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::BUSY_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::LAYOUT_INVALIDATED, 1),
- HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
- 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::BUSY_CHANGED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::LAYOUT_INVALIDATED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+ 1));
}
TEST(AXEventGeneratorTest, MultiselectableStateChanged) {
@@ -1942,14 +1967,14 @@
update.nodes[0].AddState(ax::mojom::State::kMultiselectable);
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::MULTISELECTABLE_STATE_CHANGED,
- 1),
- HasEventAtNode(AXEventGenerator::Event::STATE_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
- 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::MULTISELECTABLE_STATE_CHANGED,
+ 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::STATE_CHANGED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+ 1));
}
TEST(AXEventGeneratorTest, RequiredStateChanged) {
@@ -1965,13 +1990,13 @@
update.nodes[0].AddState(ax::mojom::State::kRequired);
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::REQUIRED_STATE_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::STATE_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
- 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::REQUIRED_STATE_CHANGED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::STATE_CHANGED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+ 1));
}
TEST(AXEventGeneratorTest, FlowToChanged) {
@@ -2002,14 +2027,16 @@
{4, 5, 6});
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::FLOW_FROM_CHANGED, 3),
- HasEventAtNode(AXEventGenerator::Event::FLOW_FROM_CHANGED, 5),
- HasEventAtNode(AXEventGenerator::Event::FLOW_FROM_CHANGED, 6),
- HasEventAtNode(AXEventGenerator::Event::FLOW_TO_CHANGED, 2),
- HasEventAtNode(AXEventGenerator::Event::RELATED_NODE_CHANGED, 2)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::FLOW_FROM_CHANGED, 3));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::FLOW_FROM_CHANGED, 5));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::FLOW_FROM_CHANGED, 6));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::FLOW_TO_CHANGED, 2));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::RELATED_NODE_CHANGED, 2));
}
TEST(AXEventGeneratorTest, ControlsChanged) {
@@ -2028,11 +2055,10 @@
update.nodes[0].AddIntListAttribute(ax::mojom::IntListAttribute::kControlsIds,
ids);
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::CONTROLS_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::RELATED_NODE_CHANGED, 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::CONTROLS_CHANGED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::RELATED_NODE_CHANGED, 1));
}
TEST(AXEventGeneratorTest, AtomicChanged) {
@@ -2047,9 +2073,8 @@
update.nodes[0].AddBoolAttribute(ax::mojom::BoolAttribute::kLiveAtomic, true);
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::ATOMIC_CHANGED, 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::ATOMIC_CHANGED, 1));
}
TEST(AXEventGeneratorTest, DropeffectChanged) {
@@ -2064,9 +2089,8 @@
update.nodes[0].AddDropeffect(ax::mojom::Dropeffect::kCopy);
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::DROPEFFECT_CHANGED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::DROPEFFECT_CHANGED, 1));
}
TEST(AXEventGeneratorTest, GrabbedChanged) {
@@ -2081,9 +2105,8 @@
update.nodes[0].AddBoolAttribute(ax::mojom::BoolAttribute::kGrabbed, true);
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::GRABBED_CHANGED, 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::GRABBED_CHANGED, 1));
}
TEST(AXEventGeneratorTest, HasPopupChanged) {
@@ -2098,12 +2121,11 @@
update.nodes[0].SetHasPopup(ax::mojom::HasPopup::kTrue);
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::HASPOPUP_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
- 1)));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::HASPOPUP_CHANGED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+ 1));
}
TEST(AXEventGeneratorTest, LiveRelevantChanged) {
@@ -2119,9 +2141,8 @@
update.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kLiveRelevant,
"all");
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(event_generator,
- UnorderedElementsAre(HasEventAtNode(
- AXEventGenerator::Event::LIVE_RELEVANT_CHANGED, 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::LIVE_RELEVANT_CHANGED, 1));
}
TEST(AXEventGeneratorTest, MultilineStateChanged) {
@@ -2136,13 +2157,13 @@
update.nodes[0].AddState(ax::mojom::State::kMultiline);
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_THAT(
- event_generator,
- UnorderedElementsAre(
- HasEventAtNode(AXEventGenerator::Event::MULTILINE_STATE_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::STATE_CHANGED, 1),
- HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
- 1)));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::MULTILINE_STATE_CHANGED, 1));
+ EXPECT_TRUE(
+ HasEvent(event_generator, AXEventGenerator::Event::STATE_CHANGED, 1));
+ EXPECT_TRUE(HasEvent(event_generator,
+ AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+ 1));
}
} // namespace ui
diff --git a/third_party/accessibility/ax/ax_event_intent.cc b/third_party/accessibility/ax/ax_event_intent.cc
index cb167a5..6c57148 100644
--- a/third_party/accessibility/ax/ax_event_intent.cc
+++ b/third_party/accessibility/ax/ax_event_intent.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_event_intent.h"
+#include "ax_event_intent.h"
-#include "ui/accessibility/ax_enum_util.h"
+#include "ax_enum_util.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_event_intent.h b/third_party/accessibility/ax/ax_event_intent.h
index 6734c7e..6ecfec1 100644
--- a/third_party/accessibility/ax/ax_event_intent.h
+++ b/third_party/accessibility/ax/ax_event_intent.h
@@ -7,8 +7,8 @@
#include <string>
-#include "ui/accessibility/ax_base_export.h"
-#include "ui/accessibility/ax_enums.mojom.h"
+#include "ax_base_export.h"
+#include "ax_enums.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_generated_tree_unittest.cc b/third_party/accessibility/ax/ax_generated_tree_unittest.cc
deleted file mode 100644
index 3c180fa..0000000
--- a/third_party/accessibility/ax/ax_generated_tree_unittest.cc
+++ /dev/null
@@ -1,451 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <numeric>
-
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_event_generator.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_serializable_tree.h"
-#include "ui/accessibility/ax_tree.h"
-#include "ui/accessibility/ax_tree_serializer.h"
-#include "ui/accessibility/tree_generator.h"
-
-namespace ui {
-namespace {
-
-// A function to turn a tree into a string, capturing only the node ids
-// and their relationship to one another.
-//
-// The string format is kind of like an S-expression, with each expression
-// being either a node id, or a node id followed by a subexpression
-// representing its children.
-//
-// Examples:
-//
-// (1) is a tree with a single node with id 1.
-// (1 (2 3)) is a tree with 1 as the root, and 2 and 3 as its children.
-// (1 (2 (3))) has 1 as the root, 2 as its child, and then 3 as the child of 2.
-// (1 (2 (3x))) is the same with node 3 ignored.
-std::string TreeToStringHelper(const AXNode* node) {
- std::string result = base::NumberToString(node->id());
- if (node->IsIgnored())
- result += "x";
- if (node->children().empty())
- return result;
- const auto add_children = [](const std::string& str, const auto* node) {
- return str + " " + TreeToStringHelper(node);
- };
- return result + " (" +
- std::accumulate(node->children().cbegin() + 1, node->children().cend(),
- TreeToStringHelper(node->children().front()),
- add_children) +
- ")";
-}
-
-std::string TreeToString(const AXTree& tree) {
- return "(" + TreeToStringHelper(tree.root()) + ")";
-}
-
-AXTreeUpdate SerializeEntireTree(AXSerializableTree& tree) {
- std::unique_ptr<AXTreeSource<const AXNode*, AXNodeData, AXTreeData>>
- tree_source(tree.CreateTreeSource());
- AXTreeSerializer<const AXNode*, AXNodeData, AXTreeData> serializer(
- tree_source.get());
- AXTreeUpdate update;
- CHECK(serializer.SerializeChanges(tree.root(), &update));
- return update;
-}
-
-// Create an AXTreeUpdate consisting of only those nodes from
-// |tree0| that changed their ignored status in |tree1|.
-AXTreeUpdate MakeTreeUpdateFromIgnoredChanges(AXSerializableTree& tree0,
- AXSerializableTree& tree1) {
- AXTreeUpdate update = SerializeEntireTree(tree1);
- AXTreeUpdate result;
- for (size_t i = 0; i < update.nodes.size(); i++) {
- AXNode* tree0_node = tree0.GetFromId(update.nodes[i].id);
- AXNode* tree1_node = tree1.GetFromId(update.nodes[i].id);
- if (tree0_node->IsIgnored() != tree1_node->IsIgnored())
- result.nodes.push_back(update.nodes[i]);
- }
- return result;
-}
-
-void SerializeUnignoredNodes(AXNode* node, AXTreeUpdate* update) {
- AXNodeData data = node->data();
- data.child_ids.clear();
- for (size_t i = 0; i < node->GetUnignoredChildCount(); i++) {
- AXNode* child = node->GetUnignoredChildAtIndex(i);
- data.child_ids.push_back(child->id());
- }
- update->nodes.push_back(data);
- for (size_t i = 0; i < node->GetUnignoredChildCount(); i++) {
- AXNode* child = node->GetUnignoredChildAtIndex(i);
- SerializeUnignoredNodes(child, update);
- }
-}
-
-void MakeTreeOfUnignoredNodesOnly(AXSerializableTree& src,
- AXSerializableTree* dst) {
- AXTreeUpdate update;
- update.root_id = src.root()->id();
- SerializeUnignoredNodes(src.root(), &update);
- CHECK(dst->Unserialize(update));
-}
-
-} // anonymous namespace
-
-// Test the TreeGenerator class by building all possible trees with
-// 3 nodes and the ids [1...3], with no permutations of ids.
-TEST(AXGeneratedTreeTest, TestTreeGeneratorNoPermutations) {
- int tree_size = 3;
- TreeGenerator generator(tree_size, false);
- // clang-format off
- const char* EXPECTED_TREES[] = {
- "(1)",
- "(1 (2))",
- "(1 (2 3))",
- "(1 (2 (3)))",
- };
- // clang-format on
-
- int n = generator.UniqueTreeCount();
- ASSERT_EQ(static_cast<int>(base::size(EXPECTED_TREES)), n);
-
- for (int i = 0; i < n; ++i) {
- AXTree tree;
- generator.BuildUniqueTree(i, &tree);
- std::string str = TreeToString(tree);
- EXPECT_EQ(EXPECTED_TREES[i], str);
- }
-}
-
-// Test generating trees with permutations of ignored nodes.
-TEST(AXGeneratedTreeTest, TestGeneratingTreesWithIgnoredNodes) {
- int tree_size = 3;
- TreeGenerator generator(tree_size, false);
- // clang-format off
- const char* EXPECTED_TREES[] = {
- "(1)",
- "(1 (2))",
- "(1 (2x))",
- "(1 (2 3))",
- "(1 (2x 3))",
- "(1 (2 3x))",
- "(1 (2x 3x))",
- "(1 (2 (3)))",
- "(1 (2x (3)))",
- "(1 (2 (3x)))",
- "(1 (2x (3x)))",
- };
- // clang-format on
-
- int n = generator.UniqueTreeCount();
- int expected_index = 0;
- for (int i = 0; i < n; ++i) {
- int ignored_permutation_count =
- generator.IgnoredPermutationCountPerUniqueTree(i);
- for (int j = 0; j < ignored_permutation_count; j++) {
- AXTree tree;
- generator.BuildUniqueTreeWithIgnoredNodes(i, j, &tree);
- std::string str = TreeToString(tree);
- EXPECT_EQ(EXPECTED_TREES[expected_index++], str);
- }
- }
- EXPECT_EQ(11, expected_index);
-}
-
-// Test the TreeGenerator class by building all possible trees with
-// 3 nodes and the ids [1...3] permuted in any order.
-TEST(AXGeneratedTreeTest, TestTreeGeneratorWithPermutations) {
- int tree_size = 3;
- TreeGenerator generator(tree_size, true);
- // clang-format off
- const char* EXPECTED_TREES[] = {
- "(1)",
- "(1 (2))",
- "(2 (1))",
- "(1 (2 3))",
- "(2 (1 3))",
- "(3 (1 2))",
- "(1 (3 2))",
- "(2 (3 1))",
- "(3 (2 1))",
- "(1 (2 (3)))",
- "(2 (1 (3)))",
- "(3 (1 (2)))",
- "(1 (3 (2)))",
- "(2 (3 (1)))",
- "(3 (2 (1)))",
- };
- // clang-format on
-
- int n = generator.UniqueTreeCount();
- ASSERT_EQ(static_cast<int>(base::size(EXPECTED_TREES)), n);
-
- for (int i = 0; i < n; i++) {
- AXTree tree;
- generator.BuildUniqueTree(i, &tree);
- std::string str = TreeToString(tree);
- EXPECT_EQ(EXPECTED_TREES[i], str);
- }
-}
-
-// Test mutating every possible tree with <n> nodes to every other possible
-// tree with <n> nodes, where <n> is 4 in release mode and 3 in debug mode
-// (for speed). For each possible combination of trees, we also vary which
-// node we serialize first.
-//
-// For every possible scenario, we check that the AXTreeUpdate is valid,
-// that the destination tree can unserialize it and create a valid tree,
-// and that after updating all nodes the resulting tree now matches the
-// intended tree.
-TEST(AXGeneratedTreeTest, SerializeGeneratedTrees) {
- // Do a more exhaustive test in release mode. If you're modifying
- // the algorithm you may want to try even larger tree sizes if you
- // can afford the time.
-#ifdef NDEBUG
- int max_tree_size = 4;
-#else
- LOG(WARNING) << "Debug build, only testing trees with 3 nodes and not 4.";
- int max_tree_size = 3;
-#endif
-
- TreeGenerator generator0(max_tree_size, false);
- int n0 = generator0.UniqueTreeCount();
-
- TreeGenerator generator1(max_tree_size, true);
- int n1 = generator1.UniqueTreeCount();
-
- for (int i = 0; i < n0; i++) {
- // Build the first tree, tree0.
- AXSerializableTree tree0;
- generator0.BuildUniqueTree(i, &tree0);
- SCOPED_TRACE("tree0 is " + TreeToString(tree0));
-
- for (int j = 0; j < n1; j++) {
- // Build the second tree, tree1.
- AXSerializableTree tree1;
- generator1.BuildUniqueTree(j, &tree1);
- SCOPED_TRACE("tree1 is " + TreeToString(tree1));
-
- int tree_size = tree1.size();
-
- // Now iterate over which node to update first, |k|.
- for (int k = 0; k < tree_size; k++) {
- // Iterate over a node to invalidate, |l| (zero means no invalidation).
- for (int l = 0; l <= tree_size; l++) {
- SCOPED_TRACE("i=" + base::NumberToString(i) +
- " j=" + base::NumberToString(j) +
- " k=" + base::NumberToString(k) +
- " l=" + base::NumberToString(l));
-
- // Start by serializing tree0 and unserializing it into a new
- // empty tree |dst_tree|.
- std::unique_ptr<AXTreeSource<const AXNode*, AXNodeData, AXTreeData>>
- tree0_source(tree0.CreateTreeSource());
- AXTreeSerializer<const AXNode*, AXNodeData, AXTreeData> serializer(
- tree0_source.get());
- AXTreeUpdate update0;
- ASSERT_TRUE(serializer.SerializeChanges(tree0.root(), &update0));
-
- AXTree dst_tree;
- ASSERT_TRUE(dst_tree.Unserialize(update0));
-
- // At this point, |dst_tree| should now be identical to |tree0|.
- EXPECT_EQ(TreeToString(tree0), TreeToString(dst_tree));
-
- // Next, pretend that tree0 turned into tree1.
- std::unique_ptr<AXTreeSource<const AXNode*, AXNodeData, AXTreeData>>
- tree1_source(tree1.CreateTreeSource());
- serializer.ChangeTreeSourceForTesting(tree1_source.get());
-
- // Invalidate a subtree rooted at one of the nodes.
- if (l > 0)
- serializer.InvalidateSubtree(tree1.GetFromId(l));
-
- // Serialize a sequence of updates to |dst_tree| to match.
- for (int k_index = 0; k_index < tree_size; ++k_index) {
- int id = 1 + (k + k_index) % tree_size;
- AXTreeUpdate update;
- ASSERT_TRUE(
- serializer.SerializeChanges(tree1.GetFromId(id), &update));
- ASSERT_TRUE(dst_tree.Unserialize(update));
- }
-
- // After the sequence of updates, |dst_tree| should now be
- // identical to |tree1|.
- EXPECT_EQ(TreeToString(tree1), TreeToString(dst_tree));
- }
- }
- }
- }
-}
-
-TEST(AXGeneratedTreeTest, GeneratedTreesWithIgnoredNodes) {
- int max_tree_size = 5;
-
- TreeGenerator generator(max_tree_size, false);
- int unique_tree_count = generator.UniqueTreeCount();
-
- // Loop over every possible tree up to a certain size.
- for (int tree_index = 0; tree_index < unique_tree_count; tree_index++) {
- // Try each permutation of nodes other than the root being ignored.
- // We'll call this tree the "fat" tree because it has redundant
- // ignored nodes.
- int ignored_permutation_count =
- generator.IgnoredPermutationCountPerUniqueTree(tree_index);
- for (int perm_index0 = 0; perm_index0 < ignored_permutation_count;
- perm_index0++) {
- AXSerializableTree fat_tree;
- generator.BuildUniqueTreeWithIgnoredNodes(tree_index, perm_index0,
- &fat_tree);
- SCOPED_TRACE("fat_tree is " + TreeToString(fat_tree));
-
- // Create a second tree, also with each permutations of nodes
- // other than the root being ignored.
- for (int perm_index1 = 1; perm_index1 < ignored_permutation_count;
- perm_index1++) {
- AXSerializableTree fat_tree1;
- generator.BuildUniqueTreeWithIgnoredNodes(tree_index, perm_index1,
- &fat_tree1);
- SCOPED_TRACE("fat_tree1 is " + TreeToString(fat_tree1));
-
- // Make a source and destination tree using only the unignored nodes.
- // We call this one the "skinny" tree.
- AXSerializableTree skinny_tree;
- MakeTreeOfUnignoredNodesOnly(fat_tree, &skinny_tree);
- AXSerializableTree skinny_tree1;
- MakeTreeOfUnignoredNodesOnly(fat_tree1, &skinny_tree1);
-
- // Now, turn fat_tree into fat_tree1, and record the generated events.
- AXEventGenerator event_generator(&fat_tree);
- AXTreeUpdate update =
- MakeTreeUpdateFromIgnoredChanges(fat_tree, fat_tree1);
- ASSERT_TRUE(fat_tree.Unserialize(update));
- EXPECT_EQ(TreeToString(fat_tree), TreeToString(fat_tree1));
-
- // Capture the events generated.
- std::map<AXNode::AXID, std::set<AXEventGenerator::Event>> actual_events;
- for (const AXEventGenerator::TargetedEvent& event : event_generator) {
- if (event.node->IsIgnored() ||
- event.event_params.event ==
- AXEventGenerator::Event::IGNORED_CHANGED) {
- continue;
- }
-
- actual_events[event.node->id()].insert(event.event_params.event);
- }
-
- // Now, turn skinny_tree into skinny_tree1 and compare
- // the generated events.
- AXEventGenerator skinny_event_generator(&skinny_tree);
- AXTreeUpdate skinny_update = SerializeEntireTree(skinny_tree1);
- ASSERT_TRUE(skinny_tree.Unserialize(skinny_update));
- EXPECT_EQ(TreeToString(skinny_tree), TreeToString(skinny_tree1));
-
- std::map<AXNode::AXID, std::set<AXEventGenerator::Event>>
- expected_events;
- for (const AXEventGenerator::TargetedEvent& event :
- skinny_event_generator)
- expected_events[event.node->id()].insert(event.event_params.event);
-
- for (auto& entry : expected_events) {
- AXNode::AXID node_id = entry.first;
- for (auto& event_type : entry.second) {
- EXPECT_TRUE(actual_events[node_id].find(event_type) !=
- actual_events[node_id].end())
- << "Expected " << event_type << " on node " << node_id;
- }
- }
-
- for (auto& entry : actual_events) {
- AXNode::AXID node_id = entry.first;
- for (auto& event_type : entry.second) {
- EXPECT_TRUE(expected_events[node_id].find(event_type) !=
- expected_events[node_id].end())
- << "Unexpected " << event_type << " on node " << node_id;
- }
- }
-
- // For each node in skinny_tree (the tree with only the unignored
- // nodes), check the node in fat_tree (the tree with ignored nodes).
- // Make sure that the parents, children, and siblings are all computed
- // correctly.
- AXTreeUpdate skinny_tree_serialized = SerializeEntireTree(skinny_tree);
- for (size_t i = 0; i < skinny_tree_serialized.nodes.size(); i++) {
- AXNode::AXID id = skinny_tree_serialized.nodes[i].id;
-
- AXNode* skinny_tree_node = skinny_tree.GetFromId(id);
- AXNode* fat_tree_node = fat_tree.GetFromId(id);
-
- SCOPED_TRACE("Testing node ID " + base::NumberToString(id));
-
- // Check children.
- EXPECT_EQ(skinny_tree_node->children().size(),
- fat_tree_node->GetUnignoredChildCount());
-
- // Check child IDs.
- for (size_t j = 0; j < skinny_tree_node->children().size(); j++) {
- AXNode* skinny_tree_child = skinny_tree_node->children()[j];
- AXNode* fat_tree_child = fat_tree_node->GetUnignoredChildAtIndex(j);
- EXPECT_TRUE(skinny_tree_child);
- EXPECT_TRUE(fat_tree_child);
- if (fat_tree_child)
- EXPECT_EQ(skinny_tree_child->id(), fat_tree_child->id());
- }
-
- // Check parent.
- if (skinny_tree_node->parent()) {
- EXPECT_EQ(skinny_tree_node->parent()->id(),
- fat_tree_node->GetUnignoredParent()->id());
- } else {
- EXPECT_FALSE(fat_tree_node->GetUnignoredParent());
- }
-
- // Check index in parent.
- EXPECT_EQ(skinny_tree_node->index_in_parent(),
- fat_tree_node->GetUnignoredIndexInParent());
-
- // Unignored previous sibling.
- size_t index_in_parent = skinny_tree_node->index_in_parent();
- size_t num_siblings =
- skinny_tree_node->parent()
- ? skinny_tree_node->parent()->children().size()
- : 1;
- if (index_in_parent > 0) {
- AXNode* skinny_tree_previous_sibling =
- skinny_tree_node->parent()->children()[index_in_parent - 1];
- AXNode* fat_tree_previous_sibling =
- fat_tree_node->GetPreviousUnignoredSibling();
- EXPECT_TRUE(fat_tree_previous_sibling);
- if (fat_tree_previous_sibling) {
- EXPECT_EQ(skinny_tree_previous_sibling->id(),
- fat_tree_previous_sibling->id());
- }
- }
-
- // Unignored next sibling.
- if (index_in_parent < num_siblings - 1) {
- AXNode* skinny_tree_next_sibling =
- skinny_tree_node->parent()->children()[index_in_parent + 1];
- AXNode* fat_tree_next_sibling =
- fat_tree_node->GetNextUnignoredSibling();
- EXPECT_TRUE(fat_tree_next_sibling);
- if (fat_tree_next_sibling) {
- EXPECT_EQ(skinny_tree_next_sibling->id(),
- fat_tree_next_sibling->id());
- }
- }
- }
- }
- }
- }
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_language_detection.cc b/third_party/accessibility/ax/ax_language_detection.cc
deleted file mode 100644
index 433eae3..0000000
--- a/third_party/accessibility/ax/ax_language_detection.cc
+++ /dev/null
@@ -1,524 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_language_detection.h"
-#include <algorithm>
-#include <functional>
-
-#include "base/command_line.h"
-#include "base/i18n/unicodestring.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/trace_event/trace_event.h"
-#include "ui/accessibility/accessibility_features.h"
-#include "ui/accessibility/accessibility_switches.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_tree.h"
-
-namespace ui {
-
-namespace {
-// This is the maximum number of languages we assign per page, so only the top
-// 3 languages on the top will be assigned to any node.
-const int kMaxDetectedLanguagesPerPage = 3;
-
-// This is the maximum number of languages that cld3 will detect for each
-// input we give it, 3 was recommended to us by the ML team as a good
-// starting point.
-const int kMaxDetectedLanguagesPerSpan = 3;
-
-const int kShortTextIdentifierMinByteLength = 1;
-// TODO(https://crbug.com/971360): Determine appropriate value for
-// |kShortTextIdentifierMaxByteLength|.
-const int kShortTextIdentifierMaxByteLength = 1000;
-} // namespace
-
-using Result = chrome_lang_id::NNetLanguageIdentifier::Result;
-using SpanInfo = chrome_lang_id::NNetLanguageIdentifier::SpanInfo;
-
-AXLanguageInfo::AXLanguageInfo() = default;
-AXLanguageInfo::~AXLanguageInfo() = default;
-
-AXLanguageInfoStats::AXLanguageInfoStats()
- : top_results_valid_(false),
- disable_metric_clearing_(false),
- count_detection_attempted_(0),
- count_detection_results_(0),
- count_labelled_(0),
- count_labelled_with_top_result_(0),
- count_overridden_(0) {}
-
-AXLanguageInfoStats::~AXLanguageInfoStats() = default;
-
-void AXLanguageInfoStats::Add(const std::vector<std::string>& languages) {
- // Count this as a successful detection with results.
- ++count_detection_results_;
-
- // Assign languages with higher probability a higher score.
- // TODO(chrishall): consider more complex scoring
- int score = kMaxDetectedLanguagesPerSpan;
- for (const auto& lang : languages) {
- lang_counts_[lang] += score;
-
- // Record the highest scoring detected languages for each node.
- if (score == kMaxDetectedLanguagesPerSpan)
- unique_top_lang_detected_.insert(lang);
-
- --score;
- }
-
- InvalidateTopResults();
-}
-
-int AXLanguageInfoStats::GetScore(const std::string& lang) const {
- const auto& lang_count_it = lang_counts_.find(lang);
- if (lang_count_it == lang_counts_.end()) {
- return 0;
- }
- return lang_count_it->second;
-}
-
-void AXLanguageInfoStats::InvalidateTopResults() {
- top_results_valid_ = false;
-}
-
-// Check if a given language is within the top results.
-bool AXLanguageInfoStats::CheckLanguageWithinTop(const std::string& lang) {
- if (!top_results_valid_) {
- GenerateTopResults();
- }
-
- for (const auto& item : top_results_) {
- if (lang == item.second) {
- return true;
- }
- }
-
- return false;
-}
-
-void AXLanguageInfoStats::GenerateTopResults() {
- top_results_.clear();
-
- for (const auto& item : lang_counts_) {
- top_results_.emplace_back(item.second, item.first);
- }
-
- // Since we store the pair as (score, language) the default operator> on pairs
- // does our sort appropriately.
- // Sort in descending order.
- std::sort(top_results_.begin(), top_results_.end(), std::greater<>());
-
- // Resize down to remove all values greater than the N we are considering.
- // TODO(chrishall): In the event of a tie, we want to include more than N.
- top_results_.resize(kMaxDetectedLanguagesPerPage);
-
- top_results_valid_ = true;
-}
-
-void AXLanguageInfoStats::RecordLabelStatistics(
- const std::string& labelled_lang,
- const std::string& author_lang,
- bool labelled_with_first_result) {
- // Count the number of nodes we labelled, and the number we labelled with
- // our highest confidence result.
- ++count_labelled_;
-
- if (labelled_with_first_result)
- ++count_labelled_with_top_result_;
-
- // Record if we assigned a language that disagrees with the author
- // provided language for that node.
- if (author_lang != labelled_lang)
- ++count_overridden_;
-}
-
-void AXLanguageInfoStats::RecordDetectionAttempt() {
- ++count_detection_attempted_;
-}
-
-void AXLanguageInfoStats::ReportMetrics() {
- // Only report statistics for pages which had detected results.
- if (!count_detection_attempted_)
- return;
-
- // 50 buckets exponentially covering the range from 1 to 1000.
- base::UmaHistogramCustomCounts(
- "Accessibility.LanguageDetection.CountDetectionAttempted",
- count_detection_attempted_, 1, 1000, 50);
-
- int percentage_detected =
- count_detection_results_ * 100 / count_detection_attempted_;
- base::UmaHistogramPercentage(
- "Accessibility.LanguageDetection.PercentageLanguageDetected",
- percentage_detected);
-
- // 50 buckets exponentially covering the range from 1 to 1000.
- base::UmaHistogramCustomCounts(
- "Accessibility.LanguageDetection.CountLabelled", count_labelled_, 1, 1000,
- 50);
-
- // If no nodes were labelled, then the percentage labelled with the top result
- // doesn't make sense to report.
- if (count_labelled_) {
- int percentage_top =
- count_labelled_with_top_result_ * 100 / count_labelled_;
- base::UmaHistogramPercentage(
- "Accessibility.LanguageDetection.PercentageLabelledWithTop",
- percentage_top);
-
- int percentage_overridden = count_overridden_ * 100 / count_labelled_;
- base::UmaHistogramPercentage(
- "Accessibility.LanguageDetection.PercentageOverridden",
- percentage_overridden);
- }
-
- // Exact count from 0 to 15, overflow is then truncated to 15.
- base::UmaHistogramExactLinear("Accessibility.LanguageDetection.LangsPerPage",
- unique_top_lang_detected_.size(), 15);
-
- // TODO(chrishall): Consider adding timing metrics for performance, consider:
- // - detect step.
- // - label step.
- // - total initial static detection & label timing.
- // - total incremental dynamic detection & label timing.
-
- // Reset statistics for metrics.
- ClearMetrics();
-}
-
-void AXLanguageInfoStats::ClearMetrics() {
- // Do not clear metrics if we are specifically testing metrics.
- if (disable_metric_clearing_)
- return;
-
- unique_top_lang_detected_.clear();
- count_detection_attempted_ = 0;
- count_detection_results_ = 0;
- count_labelled_ = 0;
- count_labelled_with_top_result_ = 0;
- count_overridden_ = 0;
-}
-
-AXLanguageDetectionManager::AXLanguageDetectionManager(AXTree* tree)
- : short_text_language_identifier_(kShortTextIdentifierMinByteLength,
- kShortTextIdentifierMaxByteLength),
- tree_(tree) {}
-
-AXLanguageDetectionManager::~AXLanguageDetectionManager() = default;
-
-bool AXLanguageDetectionManager::IsStaticLanguageDetectionEnabled() {
- // Static language detection can be enabled by either:
- // 1) The general language detection feature flag which gates both static and
- // dynamic language detection (feature flag for experiment), or
- // 2) The Static specific flag (user controlled switch).
- return features::IsAccessibilityLanguageDetectionEnabled() ||
- ::switches::IsExperimentalAccessibilityLanguageDetectionEnabled();
-}
-
-bool AXLanguageDetectionManager::IsDynamicLanguageDetectionEnabled() {
- // Dynamic language detection can be enabled by either:
- // 1) The general language detection feature flag which gates both static and
- // dynamic language detection (feature flag for experiment), or
- // 2) The Dynamic specific flag (user controlled switch).
- return features::IsAccessibilityLanguageDetectionEnabled() ||
- ::switches::
- IsExperimentalAccessibilityLanguageDetectionDynamicEnabled();
-}
-
-void AXLanguageDetectionManager::RegisterLanguageDetectionObserver() {
- // Do not perform dynamic language detection unless explicitly enabled.
- if (!IsDynamicLanguageDetectionEnabled()) {
- return;
- }
-
- // Construct our new Observer as requested.
- // If there is already an Observer on this Manager then this will destroy it.
- language_detection_observer_.reset(new AXLanguageDetectionObserver(tree_));
-}
-
-// Detect languages for each node.
-void AXLanguageDetectionManager::DetectLanguages() {
- TRACE_EVENT0("accessibility", "AXLanguageInfo::DetectLanguages");
-
- if (!IsStaticLanguageDetectionEnabled()) {
- return;
- }
-
- DetectLanguagesForSubtree(tree_->root());
-}
-
-// Detect languages for a subtree rooted at the given subtree_root.
-// Will not check feature flag.
-void AXLanguageDetectionManager::DetectLanguagesForSubtree(
- AXNode* subtree_root) {
- // Only perform detection for kStaticText nodes.
- //
- // Do not visit the children of kStaticText nodes as they don't have
- // interesting children for language detection.
- //
- // Since kInlineTextBox(es) contain text from their parent, any detection on
- // them is redundant. Instead they can inherit the detected language.
- if (subtree_root->data().role == ax::mojom::Role::kStaticText) {
- DetectLanguagesForNode(subtree_root);
- } else {
- // Otherwise, recurse into children for detection.
- for (AXNode* child : subtree_root->children()) {
- DetectLanguagesForSubtree(child);
- }
- }
-}
-
-// Detect languages for a single node.
-// Will not descend into children.
-// Will not check feature flag.
-void AXLanguageDetectionManager::DetectLanguagesForNode(AXNode* node) {
- // Count this detection attempt.
- lang_info_stats_.RecordDetectionAttempt();
-
- // TODO(chrishall): implement strategy for nodes which are too small to get
- // reliable language detection results. Consider combination of
- // concatenation and bubbling up results.
- auto text = node->GetStringAttribute(ax::mojom::StringAttribute::kName);
-
- // FindTopNMostFreqLangs() will pad the results with
- // |NNetLanguageIdentifier::kUnknown| in order to reach the requested number
- // of languages, this means we cannot rely on the results' length and we
- // have to filter the results.
- const std::vector<Result> results =
- language_identifier_.FindTopNMostFreqLangs(text,
- kMaxDetectedLanguagesPerSpan);
-
- std::vector<std::string> reliable_results;
-
- for (const auto& res : results) {
- // The output of FindTopNMostFreqLangs() is already sorted by byte count,
- // this seems good enough for now.
- // Only consider results which are 'reliable', this will also remove
- // 'unknown'.
- if (res.is_reliable) {
- reliable_results.push_back(res.language);
- }
- }
-
- // Only allocate a(n) LanguageInfo if we have results worth keeping.
- if (reliable_results.size()) {
- AXLanguageInfo* lang_info = node->GetLanguageInfo();
- if (lang_info) {
- // Clear previously detected and labelled languages.
- lang_info->detected_languages.clear();
- lang_info->language.clear();
- } else {
- node->SetLanguageInfo(std::make_unique<AXLanguageInfo>());
- lang_info = node->GetLanguageInfo();
- }
-
- // Keep these results.
- lang_info->detected_languages = std::move(reliable_results);
-
- // Update statistics to take these results into account.
- lang_info_stats_.Add(lang_info->detected_languages);
- }
-}
-
-// Label languages for each node. This relies on DetectLanguages having already
-// been run.
-void AXLanguageDetectionManager::LabelLanguages() {
- TRACE_EVENT0("accessibility", "AXLanguageInfo::LabelLanguages");
-
- if (!IsStaticLanguageDetectionEnabled()) {
- return;
- }
-
- LabelLanguagesForSubtree(tree_->root());
-
- // TODO(chrishall): consider refactoring to have a more clearly named entry
- // point for static language detection.
- //
- // LabelLanguages is only called for the initial run of language detection for
- // static content, this call to ReportMetrics therefore covers only the work
- // we performed in response to a page load complete event.
- lang_info_stats_.ReportMetrics();
-}
-
-// Label languages for each node in the subtree rooted at the given
-// subtree_root. Will not check feature flag.
-void AXLanguageDetectionManager::LabelLanguagesForSubtree(
- AXNode* subtree_root) {
- LabelLanguagesForNode(subtree_root);
-
- // Recurse into children to continue labelling.
- for (AXNode* child : subtree_root->children()) {
- LabelLanguagesForSubtree(child);
- }
-}
-
-// Label languages for a single node.
-// Will not descend into children.
-// Will not check feature flag.
-void AXLanguageDetectionManager::LabelLanguagesForNode(AXNode* node) {
- AXLanguageInfo* lang_info = node->GetLanguageInfo();
- if (!lang_info)
- return;
-
- // There is no work to do if we already have an assigned (non-empty) language.
- if (lang_info->language.size())
- return;
-
- // Assign the highest probability language which is both:
- // 1) reliably detected for this node, and
- // 2) one of the top (kMaxDetectedLanguagesPerPage) languages on this page.
- //
- // This helps guard against false positives for nodes which have noisy
- // language detection results in isolation.
- //
- // Note that we assign a language even if it is the same as the author's
- // annotation. This may not be needed in practice. In theory this would help
- // if the author later on changed the language annotation to be incorrect, but
- // this seems unlikely to occur in practice.
- //
- // TODO(chrishall): consider optimisation: only assign language if it
- // disagrees with author's language annotation.
- bool labelled_with_first_result = true;
- for (const auto& lang : lang_info->detected_languages) {
- if (lang_info_stats_.CheckLanguageWithinTop(lang)) {
- lang_info->language = lang;
-
- const std::string& author_lang = node->GetInheritedStringAttribute(
- ax::mojom::StringAttribute::kLanguage);
- lang_info_stats_.RecordLabelStatistics(lang, author_lang,
- labelled_with_first_result);
-
- // After assigning a label we no longer need detected languages.
- // NB: clearing this invalidates the reference `lang`, so we must do this
- // last and then immediately return.
- lang_info->detected_languages.clear();
-
- return;
- }
- labelled_with_first_result = false;
- }
-
- // If we didn't label a language, then we can discard all language detection
- // information for this node.
- node->ClearLanguageInfo();
-}
-
-std::vector<AXLanguageSpan>
-AXLanguageDetectionManager::GetLanguageAnnotationForStringAttribute(
- const AXNode& node,
- ax::mojom::StringAttribute attr) {
- std::vector<AXLanguageSpan> language_annotation;
- if (!node.HasStringAttribute(attr))
- return language_annotation;
-
- std::string attr_value = node.GetStringAttribute(attr);
-
- // Use author-provided language if present.
- if (node.HasStringAttribute(ax::mojom::StringAttribute::kLanguage)) {
- // Use author-provided language if present.
- language_annotation.push_back(AXLanguageSpan{
- 0 /* start_index */, attr_value.length() /* end_index */,
- node.GetStringAttribute(
- ax::mojom::StringAttribute::kLanguage) /* language */,
- 1 /* probability */});
- return language_annotation;
- }
- // Calculate top 3 languages.
- // TODO(akihiroota): What's a reasonable number of languages to have
- // cld_3 find? Should vary.
- std::vector<Result> top_languages =
- short_text_language_identifier_.FindTopNMostFreqLangs(
- attr_value, kMaxDetectedLanguagesPerPage);
- // Create vector of AXLanguageSpans.
- for (const auto& result : top_languages) {
- const std::vector<SpanInfo>& ranges = result.byte_ranges;
- for (const auto& span_info : ranges) {
- language_annotation.push_back(
- AXLanguageSpan{span_info.start_index, span_info.end_index,
- result.language, span_info.probability});
- }
- }
- // Sort Language Annotations by increasing start index. LanguageAnnotations
- // with lower start index should appear earlier in the vector.
- std::sort(
- language_annotation.begin(), language_annotation.end(),
- [](const AXLanguageSpan& left, const AXLanguageSpan& right) -> bool {
- return left.start_index <= right.start_index;
- });
- // Ensure that AXLanguageSpans do not overlap.
- for (size_t i = 0; i < language_annotation.size(); ++i) {
- if (i > 0) {
- DCHECK(language_annotation[i].start_index <=
- language_annotation[i - 1].end_index);
- }
- }
- return language_annotation;
-}
-
-AXLanguageDetectionObserver::AXLanguageDetectionObserver(AXTree* tree)
- : tree_(tree) {
- // We expect the feature flag to have be checked before this Observer is
- // constructed, this should have been checked by
- // RegisterLanguageDetectionObserver.
- DCHECK(AXLanguageDetectionManager::IsDynamicLanguageDetectionEnabled());
-
- tree_->AddObserver(this);
-}
-
-AXLanguageDetectionObserver::~AXLanguageDetectionObserver() {
- tree_->RemoveObserver(this);
-}
-
-void AXLanguageDetectionObserver::OnAtomicUpdateFinished(
- ui::AXTree* tree,
- bool root_changed,
- const std::vector<Change>& changes) {
- // TODO(chrishall): We likely want to re-consider updating or resetting
- // AXLanguageInfoStats over time to better support detection on long running
- // pages.
-
- // TODO(chrishall): To support pruning deleted node data from stats we should
- // consider implementing OnNodeWillBeDeleted. Other options available include:
- // 1) move lang info from AXNode into a map on AXTree so that we can fetch
- // based on id in here
- // 2) AXLanguageInfo destructor could remove itself
-
- // TODO(chrishall): Possible optimisation: only run detect/label for certain
- // change.type(s)), at least NODE_CREATED, NODE_CHANGED, and SUBTREE_CREATED.
-
- DCHECK(tree->language_detection_manager);
-
- // Perform Detect and Label for each node changed or created.
- // We currently only consider nodes with a role of kStaticText for detection.
- //
- // Note that language inheritance is now handled by AXNode::GetLanguage.
- //
- // Note that since Label no longer handles language inheritance, we only need
- // to call Label and Detect on the nodes that changed and don't need to
- // recurse.
- //
- // We do this in two passes because Detect updates page level statistics which
- // are later used by Label in order to make more accurate decisions.
-
- for (auto& change : changes) {
- if (change.node->data().role == ax::mojom::Role::kStaticText) {
- tree->language_detection_manager->DetectLanguagesForNode(change.node);
- }
- }
-
- for (auto& change : changes) {
- if (change.node->data().role == ax::mojom::Role::kStaticText) {
- tree->language_detection_manager->LabelLanguagesForNode(change.node);
- }
- }
-
- // OnAtomicUpdateFinished is used for dynamic language detection, this call to
- // ReportMetrics covers only the work we have performed in response to one
- // update to the AXTree.
- tree->language_detection_manager->lang_info_stats_.ReportMetrics();
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_language_detection.h b/third_party/accessibility/ax/ax_language_detection.h
deleted file mode 100644
index 035530a..0000000
--- a/third_party/accessibility/ax/ax_language_detection.h
+++ /dev/null
@@ -1,318 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_LANGUAGE_DETECTION_H_
-#define UI_ACCESSIBILITY_AX_LANGUAGE_DETECTION_H_
-
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-#include <vector>
-
-#include "base/macros.h"
-#include "third_party/cld_3/src/src/nnet_language_identifier.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_tree_observer.h"
-
-namespace ui {
-
-class AXNode;
-class AXTree;
-
-// This module implements language detection enabling Chrome to automatically
-// detect the language for runs of text within the page.
-//
-// Node-level language detection runs once per page after the load complete
-// event. This involves two passes:
-// *Detect* walks the tree from the given root using cld3 to detect up to 3
-// potential languages per node. A ranked list is created enumerating
-// all potential languages on a page.
-// *Label* re-walks the tree, assigning a language to each node considering
-// the potential languages from the detect phase, page level
-// statistics, and the assigned languages of ancestor nodes.
-//
-// Optionally an embedder may run *sub-node* language detection which attempts
-// to assign languages for runs of text within a node, potentially down to the
-// individual character level. This is useful in cases where a single paragraph
-// involves switching between multiple languages, and where the speech engine
-// doesn't automatically switch voices to handle different character sets.
-// Due to the potentially small lengths of text runs involved this tends to be
-// lower in accuracy, and works best when a node is composed of multiple
-// languages with easily distinguishable scripts.
-
-// AXLanguageInfo represents the local language detection data for all text
-// within an AXNode. Stored on AXNode.
-struct AX_EXPORT AXLanguageInfo {
- AXLanguageInfo();
- ~AXLanguageInfo();
-
- // This is the final language we have assigned for this node during the
- // 'label' step, it is the result of merging:
- // a) The detected language for this node
- // b) The declared lang attribute on this node
- // c) the (recursive) language of the parent (detected or declared).
- //
- // This will be the empty string if no language was assigned during label
- // phase.
- //
- // IETF BCP 47 Language code (rfc5646).
- // examples:
- // 'de'
- // 'de-DE'
- // 'en'
- // 'en-US'
- // 'es-ES'
- //
- // This should not be read directly by clients of AXNode, instead clients
- // should call AXNode::GetLanguage().
- // TODO(chrishall): consider renaming this to `assigned_language`.
- std::string language;
-
- // Detected languages for this node sorted as returned by
- // FindTopNMostFreqLangs, which sorts in decreasing order of probability,
- // filtered to remove any unreliable results.
- std::vector<std::string> detected_languages;
-};
-
-// Each AXLanguageSpan contains a language, a probability, and start and end
-// indices. The indices are used to specify the substring that contains the
-// associated language. The string which the indices are relative to is not
-// included in this structure.
-// Also, the indices are relative to a Utf8 string.
-// See documentation on GetLanguageAnnotationForStringAttribute for details
-// on how to associate this object with a string.
-struct AX_EXPORT AXLanguageSpan {
- int start_index;
- int end_index;
- std::string language;
- float probability;
-};
-
-// A single AXLanguageInfoStats instance is stored on each AXTree and contains
-// statistics on detected languages for all the AXNodes in that tree.
-//
-// We rely on these tree-level statistics when labelling individual nodes, to
-// provide extra signals to increase our confidence in assigning a detected
-// language.
-//
-// These tree level statistics are also used to send reports on the language
-// detection feature to enable tuning.
-//
-// The Label step will only assign a detected language to a node if that
-// language is one of the most frequent languages on the page.
-//
-// For example, if a single node has detected_languages (in order of probability
-// assigned by cld_3): da-DK, en-AU, fr-FR, but the page statistics overall
-// indicate that the page is generally in en-AU and ja-JP, it is more likely to
-// be a mis-recognition of Danish than an accurate assignment, so we assign
-// en-AU instead of da-DK.
-class AX_EXPORT AXLanguageInfoStats {
- public:
- AXLanguageInfoStats();
- ~AXLanguageInfoStats();
-
- // Each AXLanguageInfoStats is tied to a specific AXTree, copying is safe but
- // logically doesn't make sense.
- AXLanguageInfoStats(const AXLanguageInfoStats&) = delete;
- AXLanguageInfoStats& operator=(const AXLanguageInfoStats&) = delete;
-
- // Adjust our statistics to add provided detected languages.
- void Add(const std::vector<std::string>& languages);
-
- // Fetch the score for a given language.
- int GetScore(const std::string& lang) const;
-
- // Check if a given language is within the top results.
- bool CheckLanguageWithinTop(const std::string& lang);
-
- // Record statistics based on how we labelled a node.
- // We consider the language we labelled the node with, the language the author
- // assigned, and whether or not we assigned our highest confidence detection
- // result.
- void RecordLabelStatistics(const std::string& labelled_lang,
- const std::string& author_lang,
- bool labelled_with_first_result);
-
- // Update metrics to reflect we attempted to detect language for a node.
- void RecordDetectionAttempt();
-
- // Report metrics to UMA.
- // Reports statistics since last run, run once detect & label iteration.
- // If successful, will reset statistics.
- void ReportMetrics();
-
- private:
- // Allow access from a fixture only used in testing.
- friend class AXLanguageDetectionTestFixture;
-
- // Store a count of the occurrences of a given language.
- std::unordered_map<std::string, int> lang_counts_;
-
- // Cache of last calculated top language results.
- // A vector of pairs of (score, language) sorted by descending score.
- std::vector<std::pair<int, std::string>> top_results_;
-
- // Boolean recording that we have not mutated the statistics since last
- // calculating top results, setting this to false will cause recalculation
- // when the results are next fetched.
- bool top_results_valid_;
-
- // Invalidate the top results cache.
- void InvalidateTopResults();
-
- // Compute the top results and store them in cache.
- void GenerateTopResults();
-
- // TODO(chrishall): Do we want this for testing? or is it better to only test
- // the generated metrics by inspecting the histogram?
- // Boolean used for testing metrics only, disables clearing of metrics.
- bool disable_metric_clearing_;
- void ClearMetrics();
-
- // *** Statistics recorded for metric reporting. ***
- // All statistics represent a single iteration of language detection and are
- // reset after each successful call of ReportMetrics.
-
- // The number of nodes we attempted detection on.
- int count_detection_attempted_;
-
- // The number of nodes we got detection results for.
- int count_detection_results_;
-
- // The number of nodes we assigned a label to.
- int count_labelled_;
-
- // The number of nodes we assigned a label to which was the highest confident
- // detected language.
- int count_labelled_with_top_result_;
-
- // The number of times we labelled a language which disagreed with the node's
- // author provided language annotation.
- //
- // If we have
- // <div lang='en'><span>...</span><span>...</span></div>
- // and we detect and label both spans as having language 'fr', then we count
- // this as `2` overrides.
- int count_overridden_;
-
- // Set of top language detected for every node, used to generate the unique
- // number of detected languages metric (LangsPerPage).
- std::unordered_set<std::string> unique_top_lang_detected_;
-};
-
-// AXLanguageDetectionObserver is registered as a change observer on an AXTree
-// and will run language detection after each update to the tree.
-//
-// We have kept this observer separate from the AXLanguageDetectionManager as we
-// are aiming to launch language detection in two phases and wanted to try keep
-// the code paths somewhat separate.
-//
-// TODO(chrishall): After both features have launched we could consider merging
-// AXLanguageDetectionObserver into AXLanguageDetectionManager.
-//
-// TODO(chrishall): Investigate the cost of using AXTreeObserver, given that it
-// has many empty virtual methods which are called for every AXTree change and
-// we are only currently interested in OnAtomicUpdateFinished.
-class AX_EXPORT AXLanguageDetectionObserver : public ui::AXTreeObserver {
- public:
- // Observer constructor will register itself with the provided AXTree.
- AXLanguageDetectionObserver(AXTree* tree);
-
- // Observer destructor will remove itself as an observer from the AXTree.
- ~AXLanguageDetectionObserver() override;
-
- // AXLanguageDetectionObserver contains a pointer so copying is non-trivial.
- AXLanguageDetectionObserver(const AXLanguageDetectionObserver&) = delete;
- AXLanguageDetectionObserver& operator=(const AXLanguageDetectionObserver&) =
- delete;
-
- private:
- void OnAtomicUpdateFinished(ui::AXTree* tree,
- bool root_changed,
- const std::vector<Change>& changes) override;
-
- // Non-owning pointer to AXTree, used to de-register observer on destruction.
- AXTree* const tree_;
-};
-
-// AXLanguageDetectionManager manages all of the context needed for language
-// detection within an AXTree.
-class AX_EXPORT AXLanguageDetectionManager {
- public:
- // Construct an AXLanguageDetectionManager for the specified tree.
- explicit AXLanguageDetectionManager(AXTree* tree);
- ~AXLanguageDetectionManager();
-
- // AXLanguageDetectionManager contains pointers so copying is non-trivial.
- AXLanguageDetectionManager(const AXLanguageDetectionManager&) = delete;
- AXLanguageDetectionManager& operator=(const AXLanguageDetectionManager&) =
- delete;
-
- // Detect languages for each node in the tree managed by this manager.
- // This is the first pass in detection and labelling.
- // This only detects the language, it does not label it, for that see
- // LabelLanguageForSubtree.
- void DetectLanguages();
-
- // Label languages for each node in the tree manager by this manager.
- // This is the second pass in detection and labelling.
- // This will label the language, but relies on the earlier detection phase
- // having already completed.
- void LabelLanguages();
-
- // Sub-node language detection for a given string attribute.
- // For example, if a node has name: "My name is Fred", then calling
- // GetLanguageAnnotationForStringAttribute(*node, ax::mojom::StringAttribute::
- // kName) would return language detection information about "My name is Fred".
- std::vector<AXLanguageSpan> GetLanguageAnnotationForStringAttribute(
- const AXNode& node,
- ax::mojom::StringAttribute attr);
-
- // Construct and register a dynamic content change observer for this manager.
- void RegisterLanguageDetectionObserver();
-
- private:
- friend class AXLanguageDetectionObserver;
-
- // Allow access from a fixture only used in testing.
- friend class AXLanguageDetectionTestFixture;
-
- // Helper methods to test if language detection features are enabled.
- static bool IsStaticLanguageDetectionEnabled();
- static bool IsDynamicLanguageDetectionEnabled();
-
- // Perform detection for subtree rooted at subtree_root.
- void DetectLanguagesForSubtree(AXNode* subtree_root);
- // Perform detection for node. Will not descend into children.
- void DetectLanguagesForNode(AXNode* node);
- // Perform labelling for subtree rooted at subtree_root.
- void LabelLanguagesForSubtree(AXNode* subtree_root);
- // Perform labelling for node. Will not descend into children.
- void LabelLanguagesForNode(AXNode* node);
-
- // This language identifier is constructed with a default minimum byte length
- // of chrome_lang_id::NNetLanguageIdentifier::kMinNumBytesToConsider and is
- // used for detecting page-level languages.
- chrome_lang_id::NNetLanguageIdentifier language_identifier_;
-
- // This language identifier is constructed with a minimum byte length of
- // kShortTextIdentifierMinByteLength so it can be used for detecting languages
- // of shorter text (e.g. one character).
- chrome_lang_id::NNetLanguageIdentifier short_text_language_identifier_;
-
- // The observer to support dynamic content language detection.
- std::unique_ptr<AXLanguageDetectionObserver> language_detection_observer_;
-
- // Non-owning back pointer to the tree which owns this manager.
- AXTree* tree_;
-
- AXLanguageInfoStats lang_info_stats_;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_LANGUAGE_DETECTION_H_
diff --git a/third_party/accessibility/ax/ax_language_detection_unittest.cc b/third_party/accessibility/ax/ax_language_detection_unittest.cc
deleted file mode 100644
index 6b4bc53..0000000
--- a/third_party/accessibility/ax/ax_language_detection_unittest.cc
+++ /dev/null
@@ -1,1759 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_language_detection.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-
-#include "base/command_line.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/accessibility_features.h"
-#include "ui/accessibility/accessibility_switches.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_tree.h"
-
-namespace ui {
-
-const std::string kTextEnglish =
- "This is text created using Google Translate, it is unlikely to be "
- "idiomatic in the given target language. This text is only used to "
- "test language detection";
-
-const std::string kTextFrench =
- "Ce texte a été créé avec Google Translate, il est peu probable qu'il "
- "soit idiomatique dans la langue cible indiquée Ce texte est "
- "uniquement utilisé pour tester la détection de la langue.";
-
-const std::string kTextGerman =
- "Dies ist ein mit Google Translate erstellter Text. Es ist "
- "unwahrscheinlich, dass er in der angegebenen Zielsprache idiomatisch "
- "ist. Dieser Text wird nur zum Testen der Spracherkennung verwendet.";
-
-const std::string kTextSpanish =
- "Este es un texto creado usando Google Translate, es poco probable que sea "
- "idiomático en el idioma de destino dado. Este texto solo se usa para "
- "probar la detección de idioma.";
-
-// This test fixture is a friend of classes in ax_language_detection.h in order
-// to enable testing of internals.
-//
-// When used with TEST_F, the test body is a subclass of this fixture, so we
-// need to re-expose any members through this fixture in order for them to
-// be accessible from within the test body.
-class AXLanguageDetectionTestFixture : public testing::Test {
- public:
- AXLanguageDetectionTestFixture() = default;
- ~AXLanguageDetectionTestFixture() override = default;
-
- AXLanguageDetectionTestFixture(const AXLanguageDetectionTestFixture&) =
- delete;
- AXLanguageDetectionTestFixture& operator=(
- const AXLanguageDetectionTestFixture&) = delete;
-
- protected:
- bool IsStaticLanguageDetectionEnabled() {
- return AXLanguageDetectionManager::IsStaticLanguageDetectionEnabled();
- }
-
- bool IsDynamicLanguageDetectionEnabled() {
- return AXLanguageDetectionManager::IsDynamicLanguageDetectionEnabled();
- }
-
- AXLanguageDetectionObserver* getObserver(AXTree& tree) {
- return tree.language_detection_manager->language_detection_observer_.get();
- }
-
- int get_score(AXTree& tree, const std::string& lang) {
- return tree.language_detection_manager->lang_info_stats_.GetScore(lang);
- }
-
- // Accessors for testing metric data.
- void disable_metric_clearing(AXTree& tree) {
- tree.language_detection_manager->lang_info_stats_.disable_metric_clearing_ =
- true;
- }
-
- int count_detection_attempted(AXTree& tree) const {
- return tree.language_detection_manager->lang_info_stats_
- .count_detection_attempted_;
- }
-
- int count_detection_results(AXTree& tree) const {
- return tree.language_detection_manager->lang_info_stats_
- .count_detection_results_;
- }
-
- int count_labelled(AXTree& tree) const {
- return tree.language_detection_manager->lang_info_stats_.count_labelled_;
- }
-
- int count_labelled_with_top_result(AXTree& tree) const {
- return tree.language_detection_manager->lang_info_stats_
- .count_labelled_with_top_result_;
- }
-
- int count_overridden(AXTree& tree) const {
- return tree.language_detection_manager->lang_info_stats_.count_overridden_;
- }
-
- const std::unordered_set<std::string>& unique_top_lang_detected(
- AXTree& tree) const {
- return tree.language_detection_manager->lang_info_stats_
- .unique_top_lang_detected_;
- }
-};
-
-class AXLanguageDetectionTestStaticContent
- : public AXLanguageDetectionTestFixture {
- public:
- AXLanguageDetectionTestStaticContent() = default;
- ~AXLanguageDetectionTestStaticContent() override = default;
-
- AXLanguageDetectionTestStaticContent(
- const AXLanguageDetectionTestStaticContent&) = delete;
- AXLanguageDetectionTestStaticContent& operator=(
- const AXLanguageDetectionTestStaticContent&) = delete;
-
- void SetUp() override {
- AXLanguageDetectionTestFixture::SetUp();
-
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetection);
- }
-};
-
-class AXLanguageDetectionTestDynamicContent
- : public AXLanguageDetectionTestStaticContent {
- public:
- AXLanguageDetectionTestDynamicContent() = default;
- ~AXLanguageDetectionTestDynamicContent() override = default;
-
- AXLanguageDetectionTestDynamicContent(
- const AXLanguageDetectionTestDynamicContent&) = delete;
- AXLanguageDetectionTestDynamicContent& operator=(
- const AXLanguageDetectionTestDynamicContent&) = delete;
-
- void SetUp() override {
- AXLanguageDetectionTestStaticContent::SetUp();
-
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetectionDynamic);
- }
-};
-
-TEST_F(AXLanguageDetectionTestFixture, StaticContentFeatureFlag) {
- // TODO(crbug/889370): Remove this test once this feature is stable
- EXPECT_FALSE(
- ::switches::IsExperimentalAccessibilityLanguageDetectionEnabled());
- EXPECT_FALSE(IsStaticLanguageDetectionEnabled());
-
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetection);
-
- EXPECT_TRUE(
- ::switches::IsExperimentalAccessibilityLanguageDetectionEnabled());
- EXPECT_TRUE(IsStaticLanguageDetectionEnabled());
-}
-
-TEST_F(AXLanguageDetectionTestFixture, DynamicContentFeatureFlag) {
- // TODO(crbug/889370): Remove this test once this feature is stable
- EXPECT_FALSE(
- ::switches::IsExperimentalAccessibilityLanguageDetectionDynamicEnabled());
- EXPECT_FALSE(IsDynamicLanguageDetectionEnabled());
-
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetectionDynamic);
-
- EXPECT_TRUE(
- ::switches::IsExperimentalAccessibilityLanguageDetectionDynamicEnabled());
- EXPECT_TRUE(IsDynamicLanguageDetectionEnabled());
-}
-
-TEST_F(AXLanguageDetectionTestFixture, FeatureFlag) {
- // TODO(crbug/889370): Remove this test once this feature is stable
- EXPECT_FALSE(IsStaticLanguageDetectionEnabled());
- EXPECT_FALSE(IsDynamicLanguageDetectionEnabled());
-
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitWithFeatures(
- {features::kEnableAccessibilityLanguageDetection}, {});
-
- EXPECT_TRUE(IsStaticLanguageDetectionEnabled());
- EXPECT_TRUE(IsDynamicLanguageDetectionEnabled());
-}
-
-TEST(AXLanguageDetectionTest, LangAttrInheritanceFeatureFlagOff) {
- // Test lang attribute inheritance when feature flag is off.
- //
- // Lang attribute inheritance is handled by GetLanguage.
- //
- // Tree:
- // 1
- // 2 3
- // 4
- // 5
- //
- // 1 - English lang attribute
- // 2 - French lang attribute
- //
- // Expected:
- // 3 - inherit English from 1
- // 4 - inherit French from 2
- // 5 - inherit Frnech from 4/2
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(5);
-
- {
- AXNodeData& node1 = initial_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(2);
- node1.child_ids[0] = 2;
- node1.child_ids[1] = 3;
- node1.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "en");
- }
-
- {
- AXNodeData& node2 = initial_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kGenericContainer;
- node2.child_ids.resize(1);
- node2.child_ids[0] = 4;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "fr");
- }
-
- {
- AXNodeData& node3 = initial_state.nodes[2];
- node3.id = 3;
- node3.role = ax::mojom::Role::kStaticText;
- }
-
- {
- AXNodeData& node4 = initial_state.nodes[3];
- node4.id = 4;
- node4.role = ax::mojom::Role::kStaticText;
- node4.child_ids.resize(1);
- node4.child_ids[0] = 5;
- }
-
- {
- AXNodeData& node5 = initial_state.nodes[4];
- node5.id = 5;
- node5.role = ax::mojom::Role::kInlineTextBox;
- }
-
- AXTree tree(initial_state);
- ASSERT_NE(tree.language_detection_manager, nullptr);
- tree.language_detection_manager->DetectLanguages();
- tree.language_detection_manager->LabelLanguages();
-
- {
- AXNode* node1 = tree.GetFromId(1);
- EXPECT_EQ(node1->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node1->GetLanguage(), "en");
- }
-
- {
- AXNode* node2 = tree.GetFromId(2);
- EXPECT_EQ(node2->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node2->GetLanguage(), "fr");
- }
-
- {
- AXNode* node3 = tree.GetFromId(3);
- EXPECT_EQ(node3->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node3->GetLanguage(), "en");
- }
-
- {
- AXNode* node4 = tree.GetFromId(4);
- EXPECT_EQ(node4->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node4->GetLanguage(), "fr");
- }
-
- {
- AXNode* node5 = tree.GetFromId(5);
- EXPECT_EQ(node5->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node5->GetLanguage(), "fr");
- }
-}
-
-TEST(AXLanguageDetectionTest, LangAttrInheritanceFeatureFlagOn) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetection);
-
- // Test lang attribute inheritance in the absence of any detected language.
- //
- // Lang attribute inheritance is handled by the Label step.
- //
- // Tree:
- // 1
- // 2 3
- // 4
- // 5
- //
- // 1 - English lang attribute
- // 2 - French lang attribute
- //
- // Expected:
- // 3 - inherit English from 1
- // 4 - inherit French from 2
- // 5 - inherit Frnech from 4/2
-
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(5);
-
- {
- AXNodeData& node1 = initial_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(2);
- node1.child_ids[0] = 2;
- node1.child_ids[1] = 3;
- node1.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "en");
- }
-
- {
- AXNodeData& node2 = initial_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kGenericContainer;
- node2.child_ids.resize(1);
- node2.child_ids[0] = 4;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "fr");
- }
-
- {
- AXNodeData& node3 = initial_state.nodes[2];
- node3.id = 3;
- node3.role = ax::mojom::Role::kStaticText;
- }
-
- {
- AXNodeData& node4 = initial_state.nodes[3];
- node4.id = 4;
- node4.role = ax::mojom::Role::kStaticText;
- node4.child_ids.resize(1);
- node4.child_ids[0] = 5;
- }
-
- {
- AXNodeData& node5 = initial_state.nodes[4];
- node5.id = 5;
- node5.role = ax::mojom::Role::kInlineTextBox;
- }
-
- AXTree tree(initial_state);
- ASSERT_NE(tree.language_detection_manager, nullptr);
- tree.language_detection_manager->DetectLanguages();
- tree.language_detection_manager->LabelLanguages();
-
- {
- AXNode* node1 = tree.GetFromId(1);
- // No detection for non text nodes.
- EXPECT_EQ(node1->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node1->GetLanguage(), "en");
- }
-
- {
- AXNode* node2 = tree.GetFromId(2);
- EXPECT_EQ(node2->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node2->GetLanguage(), "fr");
- }
-
- {
- AXNode* node3 = tree.GetFromId(3);
- // Inherited languages are not stored in lang info.
- EXPECT_EQ(node3->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node3->GetLanguage(), "en");
- }
-
- {
- AXNode* node4 = tree.GetFromId(4);
- // Inherited languages are not stored in lang info.
- EXPECT_EQ(node4->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node4->GetLanguage(), "fr");
- }
-
- {
- AXNode* node5 = tree.GetFromId(5);
- // Inherited languages are not stored in lang info.
- EXPECT_EQ(node5->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node5->GetLanguage(), "fr");
- }
-}
-
-// Tests that AXNode::GetLanguage() terminates when there is no lang attribute.
-TEST_F(AXLanguageDetectionTestStaticContent, GetLanguageBoringTree) {
- // This test checks the behaviour of Detect, Label, and GetLanguage on a
- // 'boring' tree.
- //
- // The tree built here contains no lang attributes, nor does it contain any
- // text to perform detection on.
- //
- // Tree:
- // 1
- // 2 3
- // 4
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(4);
- initial_state.nodes[0].id = 1;
- initial_state.nodes[0].child_ids.resize(2);
- initial_state.nodes[0].child_ids[0] = 2;
- initial_state.nodes[0].child_ids[1] = 3;
- initial_state.nodes[1].id = 2;
- initial_state.nodes[1].child_ids.resize(1);
- initial_state.nodes[1].child_ids[0] = 4;
- initial_state.nodes[2].id = 3;
- initial_state.nodes[3].id = 4;
-
- AXTree tree(initial_state);
- ASSERT_NE(tree.language_detection_manager, nullptr);
- tree.language_detection_manager->DetectLanguages();
- tree.language_detection_manager->LabelLanguages();
-
- // Check that tree parenting conforms to expected shape.
- AXNode* node1 = tree.GetFromId(1);
- EXPECT_EQ(node1->parent(), nullptr);
-
- AXNode* node2 = tree.GetFromId(2);
- ASSERT_EQ(node2->parent(), node1);
- EXPECT_EQ(node2->parent()->parent(), nullptr);
-
- AXNode* node3 = tree.GetFromId(3);
- ASSERT_EQ(node3->parent(), node1);
- EXPECT_EQ(node3->parent()->parent(), nullptr);
-
- AXNode* node4 = tree.GetFromId(4);
- ASSERT_EQ(node4->parent(), node2);
- ASSERT_EQ(node4->parent()->parent(), node1);
- EXPECT_EQ(node4->parent()->parent()->parent(), nullptr);
-
- EXPECT_EQ(node1->GetLanguage(), "");
- EXPECT_EQ(node2->GetLanguage(), "");
- EXPECT_EQ(node3->GetLanguage(), "");
- EXPECT_EQ(node4->GetLanguage(), "");
-}
-
-TEST_F(AXLanguageDetectionTestStaticContent, Basic) {
- // Tree:
- // 1
- // 2 3
- // 4
- // 5
- //
- // 1 - German lang attribute, no text
- // 2 - French lang attribute, no text
- // 3 - no attribute, French text
- // 4 - no attribute, English text
- // 5 - no attribute, no text
- //
- // Expected:
- // 3 - French detected
- // 4 - English detected
- // 5 - inherit English from 4
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(5);
-
- {
- AXNodeData& node1 = initial_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(2);
- node1.child_ids[0] = 2;
- node1.child_ids[1] = 3;
- node1.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "de");
- }
-
- {
- AXNodeData& node2 = initial_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kGenericContainer;
- node2.child_ids.resize(1);
- node2.child_ids[0] = 4;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "fr");
- }
-
- {
- AXNodeData& node3 = initial_state.nodes[2];
- node3.id = 3;
- node3.role = ax::mojom::Role::kStaticText;
- node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextFrench);
- }
-
- {
- AXNodeData& node4 = initial_state.nodes[3];
- node4.id = 4;
- node4.child_ids.resize(1);
- node4.child_ids[0] = 5;
- node4.role = ax::mojom::Role::kStaticText;
- node4.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish);
- }
-
- {
- AXNodeData& node5 = initial_state.nodes[4];
- node5.id = 5;
- node5.role = ax::mojom::Role::kInlineTextBox;
- node5.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish);
- }
-
- AXTree tree(initial_state);
- ASSERT_NE(tree.language_detection_manager, nullptr);
- tree.language_detection_manager->DetectLanguages();
- tree.language_detection_manager->LabelLanguages();
-
- {
- AXNode* node1 = tree.GetFromId(1);
- // node1 is not a text node, so no lang info should be attached.
- EXPECT_EQ(node1->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node1->GetLanguage(), "de");
- }
-
- {
- AXNode* node2 = tree.GetFromId(2);
- // node2 is not a text node, so no lang info should be attached.
- EXPECT_EQ(node2->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node2->GetLanguage(), "fr");
- }
-
- {
- AXNode* node3 = tree.GetFromId(3);
- EXPECT_TRUE(node3->IsText());
- EXPECT_NE(node3->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node3->GetLanguage(), "fr");
- }
-
- {
- AXNode* node4 = tree.GetFromId(4);
- EXPECT_TRUE(node4->IsText());
- EXPECT_NE(node4->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node4->GetLanguage(), "en");
- }
-
- {
- AXNode* node5 = tree.GetFromId(5);
- EXPECT_TRUE(node5->IsText());
- // Inherited languages are not stored in lang info.
- EXPECT_EQ(node5->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node5->GetLanguage(), "en");
- }
-}
-
-TEST_F(AXLanguageDetectionTestStaticContent, MetricCollection) {
- // Tree:
- // 1
- // 2 3 4 5 6
- //
- // 1 - German lang attribute, no text
- // 2 - no attribute, German text
- // 3 - no attribute, French text
- // 4 - no attribute, English text
- // 5 - no attribute, Spanish text
- // 6 - no attribute, text too short to get detection results.
- //
- // Expected:
- // 2 - German detected
- // 3 - French detected
- // 4 - English detected
- // 5 - Spanish detected
- // 6 - too short for results
- //
- // only 3 of these languages can be labelled due to heuristics.
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(6);
-
- {
- AXNodeData& node1 = initial_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(5);
- node1.child_ids[0] = 2;
- node1.child_ids[1] = 3;
- node1.child_ids[2] = 4;
- node1.child_ids[3] = 5;
- node1.child_ids[4] = 6;
- node1.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "de");
- }
-
- {
- AXNodeData& node2 = initial_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kStaticText;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman);
- }
-
- {
- AXNodeData& node3 = initial_state.nodes[2];
- node3.id = 3;
- node3.role = ax::mojom::Role::kStaticText;
- node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextFrench);
- }
-
- {
- AXNodeData& node4 = initial_state.nodes[3];
- node4.id = 4;
- node4.role = ax::mojom::Role::kStaticText;
- node4.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish);
- }
-
- {
- AXNodeData& node5 = initial_state.nodes[4];
- node5.id = 5;
- node5.role = ax::mojom::Role::kStaticText;
- node5.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextSpanish);
- }
-
- {
- AXNodeData& node6 = initial_state.nodes[5];
- node6.id = 6;
- node6.role = ax::mojom::Role::kStaticText;
- node6.AddStringAttribute(ax::mojom::StringAttribute::kName,
- "too short for detection.");
- }
-
- AXTree tree(initial_state);
- ASSERT_NE(tree.language_detection_manager, nullptr);
-
- // Specifically disable clearing of metrics.
- disable_metric_clearing(tree);
- // Our histogram for testing.
- base::HistogramTester histograms;
-
- tree.language_detection_manager->DetectLanguages();
- tree.language_detection_manager->LabelLanguages();
-
- // All 4 of our languages should have been detected for one node each, scoring
- // a maximum 3 points.
- EXPECT_EQ(3, get_score(tree, "de"));
- EXPECT_EQ(3, get_score(tree, "en"));
- EXPECT_EQ(3, get_score(tree, "fr"));
- EXPECT_EQ(3, get_score(tree, "es"));
-
- // 5 nodes (2, 3, 4, 5, 6) should have had detection attempted.
- EXPECT_EQ(5, count_detection_attempted(tree));
- histograms.ExpectUniqueSample(
- "Accessibility.LanguageDetection.CountDetectionAttempted", 5, 1);
-
- // 4 nodes (2, 3, 4, 5) should have had detection results.
- EXPECT_EQ(4, count_detection_results(tree));
- // 5 nodes attempted, 4 got results = 4*100/5 = 80%
- histograms.ExpectUniqueSample(
- "Accessibility.LanguageDetection.PercentageLanguageDetected", 80, 1);
-
- // 3 nodes (any of 2, 3, 4, 5) should have been labelled.
- EXPECT_EQ(3, count_labelled(tree));
- histograms.ExpectUniqueSample("Accessibility.LanguageDetection.CountLabelled",
- 3, 1);
-
- // 3 nodes (any of 2, 3, 4, 5) should have been given top label.
- EXPECT_EQ(3, count_labelled_with_top_result(tree));
- // 3 nodes labelled, all of them given top result = 100%.
- histograms.ExpectUniqueSample(
- "Accessibility.LanguageDetection.PercentageLabelledWithTop", 100, 1);
-
- // 3 nodes (3, 4, 5) should have been labelled to disagree with node1 author
- // provided language.
- EXPECT_EQ(3, count_overridden(tree));
- // 3 nodes labelled, all 3 disagree with node1 = 100%.
- histograms.ExpectUniqueSample(
- "Accessibility.LanguageDetection.PercentageOverridden", 100, 1);
-
- // There should be 4 unique languages (de, en, fr, es).
- {
- const auto& top_lang = unique_top_lang_detected(tree);
- const std::unordered_set<std::string> expected_top_lang = {"de", "en", "es",
- "fr"};
- EXPECT_EQ(top_lang, expected_top_lang);
- }
- histograms.ExpectUniqueSample("Accessibility.LanguageDetection.LangsPerPage",
- 4, 1);
-}
-
-TEST_F(AXLanguageDetectionTestStaticContent, DetectOnly) {
- // This tests a Detect step without any matching Label step.
- //
- // Tree:
- // 1
- // 2 3
- // 4
- // 5
- //
- // 1 - German lang attribute, no text
- // 2 - French lang attribute, no text
- // 3 - no attribute, French text
- // 4 - no attribute, English text
- // 5 - no attribute, no text
- //
- // Expected:
- // 3 - French detected, never labelled, so still inherits German from 1
- // 4 - English detected, never labelled, so still inherits French from 2
- // 5 - English inherited from 4, still inherits French from 4
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(5);
-
- {
- AXNodeData& node1 = initial_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(2);
- node1.child_ids[0] = 2;
- node1.child_ids[1] = 3;
- node1.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "de");
- }
-
- {
- AXNodeData& node2 = initial_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kGenericContainer;
- node2.child_ids.resize(1);
- node2.child_ids[0] = 4;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "fr");
- }
-
- {
- AXNodeData& node3 = initial_state.nodes[2];
- node3.id = 3;
- node3.role = ax::mojom::Role::kStaticText;
- node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextFrench);
- }
-
- {
- AXNodeData& node4 = initial_state.nodes[3];
- node4.id = 4;
- node4.child_ids.resize(1);
- node4.child_ids[0] = 5;
- node4.role = ax::mojom::Role::kStaticText;
- node4.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish);
- }
-
- {
- AXNodeData& node5 = initial_state.nodes[4];
- node5.id = 5;
- node5.role = ax::mojom::Role::kInlineTextBox;
- node5.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish);
- }
-
- AXTree tree(initial_state);
- ASSERT_NE(tree.language_detection_manager, nullptr);
- tree.language_detection_manager->DetectLanguages();
- // Purposefully not calling Label so we can test Detect in isolation.
-
- {
- AXNode* node1 = tree.GetFromId(1);
- // node1 is not a text node, so no lang info should be attached.
- EXPECT_EQ(node1->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node1->GetLanguage(), "de");
- }
-
- {
- AXNode* node2 = tree.GetFromId(2);
- // node2 is not a text node, so no lang info should be attached.
- EXPECT_EQ(node2->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node2->GetLanguage(), "fr");
- }
-
- {
- AXNode* node3 = tree.GetFromId(3);
- EXPECT_TRUE(node3->IsText());
- ASSERT_NE(node3->GetLanguageInfo(), nullptr);
- ASSERT_GT(node3->GetLanguageInfo()->detected_languages.size(), (unsigned)0);
- ASSERT_EQ(node3->GetLanguageInfo()->detected_languages[0], "fr");
- EXPECT_TRUE(node3->GetLanguageInfo()->language.empty());
- EXPECT_EQ(node3->GetLanguage(), "de");
- }
-
- {
- AXNode* node4 = tree.GetFromId(4);
- EXPECT_TRUE(node4->IsText());
- ASSERT_NE(node4->GetLanguageInfo(), nullptr);
- ASSERT_GT(node4->GetLanguageInfo()->detected_languages.size(), (unsigned)0);
- ASSERT_EQ(node4->GetLanguageInfo()->detected_languages[0], "en");
- EXPECT_TRUE(node4->GetLanguageInfo()->language.empty());
- EXPECT_EQ(node4->GetLanguage(), "fr");
- }
-
- {
- AXNode* node5 = tree.GetFromId(5);
- EXPECT_TRUE(node5->IsText());
- // Inherited languages are not stored in lang info.
- ASSERT_EQ(node5->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node5->GetLanguage(), "fr");
- }
-}
-
-TEST_F(AXLanguageDetectionTestStaticContent, kLanguageUntouched) {
- // This test is to ensure that the kLanguage string attribute is not updated
- // during language detection and labelling, even when it disagrees with the
- // detected language.
-
- // Built tree:
- // 1
- // 2 3
- //
- // 1 - German lang attribute, no text
- // 2 - English lang attribute, French text
- // 3 - French lang attribute, English text
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(3);
-
- {
- AXNodeData& node1 = initial_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(2);
- node1.child_ids[0] = 2;
- node1.child_ids[1] = 3;
- node1.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "de");
- }
-
- {
- AXNodeData& node2 = initial_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kStaticText;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "en");
- node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextFrench);
- }
-
- {
- AXNodeData& node3 = initial_state.nodes[2];
- node3.id = 3;
- node3.role = ax::mojom::Role::kStaticText;
- node3.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "fr");
- node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish);
- }
-
- AXTree tree(initial_state);
- ASSERT_NE(tree.language_detection_manager, nullptr);
- tree.language_detection_manager->DetectLanguages();
- tree.language_detection_manager->LabelLanguages();
-
- {
- AXNode* node1 = tree.GetFromId(1);
- ASSERT_EQ(node1->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node1->GetLanguage(), "de");
- }
-
- {
- // French should be detected, original English attr should be untouched.
- AXNode* node2 = tree.GetFromId(2);
- ASSERT_NE(node2->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node2->GetLanguageInfo()->language, "fr");
- EXPECT_EQ(node2->GetStringAttribute(ax::mojom::StringAttribute::kLanguage),
- "en");
- EXPECT_EQ(node2->GetLanguage(), "fr");
- }
-
- {
- // English should be detected, original French attr should be untouched.
- AXNode* node3 = tree.GetFromId(3);
- ASSERT_NE(node3->GetLanguageInfo(), nullptr);
- EXPECT_EQ(node3->GetLanguageInfo()->language, "en");
- EXPECT_EQ(node3->GetStringAttribute(ax::mojom::StringAttribute::kLanguage),
- "fr");
- EXPECT_EQ(node3->GetLanguage(), "en");
- }
-}
-
-// Test RegisterLanguageDetectionObserver correctly respects the command line
-// flags.
-TEST_F(AXLanguageDetectionTestFixture, ObserverRegistrationObeysFlag) {
- // Enable only the flag controlling static language detection.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetection);
-
- // Construct empty tree and check initialisation.
- AXTree tree;
- ASSERT_NE(tree.language_detection_manager, nullptr);
- ASSERT_EQ(getObserver(tree), nullptr);
-
- // Try registration without enabling Dynamic feature flag, should be a no-op.
- tree.language_detection_manager->RegisterLanguageDetectionObserver();
-
- ASSERT_EQ(getObserver(tree), nullptr);
-
- // Now enable the dynamic feature flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetectionDynamic);
-
- // Try registration again, this should construct and register observer as flag
- // is now enabled.
- tree.language_detection_manager->RegisterLanguageDetectionObserver();
-
- // Check our observer was constructed.
- ASSERT_NE(getObserver(tree), nullptr);
-
- // Check our observer was registered in our tree.
- ASSERT_TRUE(tree.HasObserver(getObserver(tree)));
-}
-
-// Test RegisterLanguageDetectionObserver correctly respects the feature flag.
-TEST_F(AXLanguageDetectionTestFixture, ObserverRegistrationObeysFeatureFlag) {
- // Construct empty tree and check initialisation.
- AXTree tree;
- ASSERT_NE(tree.language_detection_manager, nullptr);
- ASSERT_EQ(getObserver(tree), nullptr);
-
- // Try registration without enabling Dynamic feature flag, should be a no-op.
- tree.language_detection_manager->RegisterLanguageDetectionObserver();
-
- ASSERT_EQ(getObserver(tree), nullptr);
-
- // Enable general feature flag which gates both Static and Dynamic features.
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitWithFeatures(
- {features::kEnableAccessibilityLanguageDetection}, {});
-
- // Try registration again, this should now construct and register an observer.
- tree.language_detection_manager->RegisterLanguageDetectionObserver();
-
- // Check our observer was constructed.
- ASSERT_NE(getObserver(tree), nullptr);
-
- // Check our observer was registered in our tree.
- ASSERT_TRUE(tree.HasObserver(getObserver(tree)));
-}
-
-TEST_F(AXLanguageDetectionTestDynamicContent, Basic) {
- // Tree:
- // 1
- // 2
- //
- // 1 - kStaticText - English text.
- // 2 - kInlineTextBox - English text.
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(2);
-
- // TODO(chrishall): Create more realistic kStaticText with multiple
- // kInlineTextBox(es) children. Look at the real-world behaviour of
- // kStaticText, kInlineText and kLineBreak around empty divs and empty lines
- // within paragraphs of text.
-
- {
- AXNodeData& node1 = initial_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kStaticText;
- node1.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish);
- node1.child_ids.resize(1);
- node1.child_ids[0] = 2;
- }
-
- {
- AXNodeData& node2 = initial_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kInlineTextBox;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish);
- }
-
- AXTree tree(initial_state);
- ASSERT_NE(tree.language_detection_manager, nullptr);
-
- // Manually run initial language detection and labelling.
- tree.language_detection_manager->DetectLanguages();
- tree.language_detection_manager->LabelLanguages();
-
- // Quickly verify "before" state
- {
- AXNode* node1 = tree.GetFromId(1);
- ASSERT_NE(node1, nullptr);
- ASSERT_NE(node1->GetLanguageInfo(), nullptr);
- ASSERT_EQ(node1->GetLanguage(), "en");
-
- AXNode* node2 = tree.GetFromId(2);
- ASSERT_NE(node2, nullptr);
- // Inherited language not stored in lang info.
- ASSERT_EQ(node2->GetLanguageInfo(), nullptr);
- // Should still inherit language from parent.
- ASSERT_EQ(node2->GetLanguage(), "en");
- }
-
- // Manually register observer.
- AXLanguageDetectionObserver observer(&tree);
-
- // Observer constructor is responsible for attaching itself to tree.
- ASSERT_TRUE(tree.HasObserver(&observer));
-
- // Dynamic update
- //
- // New tree:
- // 1
- // 2
- //
- // 1 - Text changed to German.
- // 2 - Text changed to German.
- AXTreeUpdate update_state;
- update_state.root_id = 1;
- update_state.nodes.resize(2);
-
- // Change text to German.
- {
- AXNodeData& node1 = update_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kStaticText;
- node1.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman);
- node1.child_ids.resize(1);
- node1.child_ids[0] = 2;
- }
-
- {
- AXNodeData& node2 = update_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kInlineTextBox;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman);
- }
-
- // Perform update.
- ASSERT_TRUE(tree.Unserialize(update_state));
-
- // Check language detection was re-run on new content.
- {
- AXNode* node1 = tree.GetFromId(1);
- ASSERT_NE(node1, nullptr);
- ASSERT_NE(node1->GetLanguageInfo(), nullptr);
- ASSERT_EQ(node1->GetLanguage(), "de");
- }
-
- {
- AXNode* node2 = tree.GetFromId(2);
- ASSERT_NE(node2, nullptr);
- // Inherited language not stored in lang info.
- ASSERT_EQ(node2->GetLanguageInfo(), nullptr);
- // Should inherit new language from parent.
- ASSERT_EQ(node2->GetLanguage(), "de");
- }
-}
-
-TEST_F(AXLanguageDetectionTestDynamicContent, MetricCollection) {
- // Tree:
- // 1
- // 2 3
- //
- // 1 - kGenericContainer, French lang attribute.
- // 2 - kStaticText - English text.
- // 3 - kSTaticText - German text.
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(3);
-
- // TODO(chrishall): Create more realistic kStaticText with multiple
- // kInlineTextBox(es) children. Look at the real-world behaviour of
- // kStaticText, kInlineText and kLineBreak around empty divs and empty lines
- // within paragraphs of text.
-
- {
- AXNodeData& node1 = initial_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(2);
- node1.child_ids[0] = 2;
- node1.child_ids[1] = 3;
- node1.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "fr");
- }
-
- {
- AXNodeData& node2 = initial_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kStaticText;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish);
- }
-
- {
- AXNodeData& node3 = initial_state.nodes[2];
- node3.id = 3;
- node3.role = ax::mojom::Role::kStaticText;
- node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman);
- }
-
- AXTree tree(initial_state);
- ASSERT_NE(tree.language_detection_manager, nullptr);
-
- // Manually run initial language detection and labelling.
- tree.language_detection_manager->DetectLanguages();
- tree.language_detection_manager->LabelLanguages();
-
- // Quickly verify "before" metrics were cleared.
- EXPECT_EQ(0, count_detection_attempted(tree));
-
- // Specifically disable clearing of metrics for dynamic only.
- disable_metric_clearing(tree);
- // Our histogram for testing.
- base::HistogramTester histograms;
-
- // Manually register observer.
- AXLanguageDetectionObserver observer(&tree);
-
- // Observer constructor is responsible for attaching itself to tree.
- ASSERT_TRUE(tree.HasObserver(&observer));
-
- // Dynamic update
- //
- // New tree:
- // 1
- // 2 3 4
- //
- // 1 - no change.
- // 2 - Text changed to French.
- // 3 - no change.
- // 4 - new kStaticText node, Spanish text.
- AXTreeUpdate update_state;
- update_state.root_id = 1;
- update_state.nodes.resize(3);
-
- // Change text to German.
- {
- AXNodeData& node1 = update_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(3);
- node1.child_ids[0] = 2;
- node1.child_ids[1] = 3;
- node1.child_ids[2] = 4;
- node1.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "fr");
- }
-
- {
- AXNodeData& node2 = update_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kStaticText;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextFrench);
- }
-
- {
- AXNodeData& node4 = update_state.nodes[2];
- node4.id = 4;
- node4.role = ax::mojom::Role::kStaticText;
- node4.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextSpanish);
- }
-
- // Perform update.
- ASSERT_TRUE(tree.Unserialize(update_state));
-
- // Check "after" metrics.
- // note that the metrics were cleared after static work had finished, so these
- // metrics only reflect the dynamic work.
-
- // All 4 of our languages should have been detected for one node each, scoring
- // a maximum 3 points.
- EXPECT_EQ(3, get_score(tree, "de"));
- EXPECT_EQ(3, get_score(tree, "en"));
- EXPECT_EQ(3, get_score(tree, "fr"));
- EXPECT_EQ(3, get_score(tree, "es"));
-
- // 2 nodes (2, 4) should have had detection attempted.
- EXPECT_EQ(2, count_detection_attempted(tree));
- histograms.ExpectUniqueSample(
- "Accessibility.LanguageDetection.CountDetectionAttempted", 2, 1);
-
- // 2 nodes (2, 4) should have had detection results
- EXPECT_EQ(2, count_detection_results(tree));
- histograms.ExpectUniqueSample(
- "Accessibility.LanguageDetection.PercentageLanguageDetected", 100, 1);
-
- // 2 nodes (2, 4) should have been labelled
- EXPECT_EQ(2, count_labelled(tree));
- histograms.ExpectUniqueSample("Accessibility.LanguageDetection.CountLabelled",
- 2, 1);
-
- // 2 nodes (2, 4) should have been given top label
- EXPECT_EQ(2, count_labelled_with_top_result(tree));
- histograms.ExpectUniqueSample(
- "Accessibility.LanguageDetection.PercentageLabelledWithTop", 100, 1);
-
- // 1 nodes (4) should have been labelled to disagree with node1 author
- // provided language.
- EXPECT_EQ(1, count_overridden(tree));
- // 2 nodes were labelled, 1 disagreed with node1 = 50%.
- histograms.ExpectUniqueSample(
- "Accessibility.LanguageDetection.PercentageOverridden", 50, 1);
-
- // There should be 2 unique languages (fr, es).
- {
- auto top_lang = unique_top_lang_detected(tree);
- const std::unordered_set<std::string> expected_top_lang = {"es", "fr"};
- EXPECT_EQ(top_lang, expected_top_lang);
- }
- // There should be a single (unique, 1) value for '2' unique languages.
- histograms.ExpectUniqueSample("Accessibility.LanguageDetection.LangsPerPage",
- 2, 1);
-}
-
-TEST_F(AXLanguageDetectionTestDynamicContent, MultipleUpdates) {
- // This test runs language detection a total of 3 times, once for the initial
- // 'static' content, and then twice for 'dynamic' updates.
-
- // Tree:
- // 1
- // 2
- //
- // 1 - GenericContainer
- // 2 - English text
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(2);
-
- {
- AXNodeData& node1 = initial_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(1);
- node1.child_ids[0] = 2;
- }
-
- {
- AXNodeData& node2 = initial_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kStaticText;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextEnglish);
- }
-
- AXTree tree(initial_state);
- ASSERT_NE(tree.language_detection_manager, nullptr);
-
- // Run initial language detection and labelling.
- tree.language_detection_manager->DetectLanguages();
- tree.language_detection_manager->LabelLanguages();
-
- // Quickly verify "before" state
- {
- AXNode* node1 = tree.GetFromId(1);
- ASSERT_NE(node1, nullptr);
- ASSERT_EQ(node1->GetLanguage(), "");
-
- AXNode* node2 = tree.GetFromId(2);
- ASSERT_NE(node2, nullptr);
- ASSERT_EQ(node2->GetLanguage(), "en");
- }
-
- // Register dynamic content observer.
- tree.language_detection_manager->RegisterLanguageDetectionObserver();
- ASSERT_NE(getObserver(tree), nullptr);
- ASSERT_TRUE(tree.HasObserver(getObserver(tree)));
-
- // First update
- {
- // Dynamic update
- //
- // New tree layout will be:
- // 1
- // 2 3
- //
- // 1 - GenericContainer, unchanged
- // 2 - changed to German text
- // 3 - new child, French text
- AXTreeUpdate update_state;
- update_state.root_id = 1;
- update_state.nodes.resize(3);
-
- // Update node1 to include new child node3.
- {
- AXNodeData& node1 = update_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(2);
- node1.child_ids[0] = 2;
- node1.child_ids[1] = 3;
- }
-
- // Change node2 text to German
- {
- AXNodeData& node2 = update_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kStaticText;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman);
- }
-
- // Add new node3 with French text.
- {
- AXNodeData& node3 = update_state.nodes[2];
- node3.id = 3;
- node3.role = ax::mojom::Role::kStaticText;
- node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextFrench);
- }
-
- // Perform update.
- ASSERT_TRUE(tree.Unserialize(update_state));
-
- {
- AXNode* node1 = tree.GetFromId(1);
- ASSERT_NE(node1, nullptr);
- ASSERT_EQ(node1->GetLanguage(), "");
- }
-
- {
- // Detection should have been re-run on node2, detecting German.
- AXNode* node2 = tree.GetFromId(2);
- ASSERT_NE(node2, nullptr);
- ASSERT_EQ(node2->GetLanguage(), "de");
- }
-
- {
- // New node3 should have detected French.
- AXNode* node3 = tree.GetFromId(3);
- ASSERT_NE(node3, nullptr);
- ASSERT_EQ(node3->GetLanguage(), "fr");
- }
- }
-
- // Second update
- {
- // Dynamic update
- //
- // New tree layout will be:
- // 1
- // 2 x
- //
- // 1 - GenericContainer, unchanged
- // 2 - changed to French text
- // 3 - deleted
- AXTreeUpdate update_state;
- update_state.root_id = 1;
- update_state.nodes.resize(2);
-
- // Update node1 to delete child node3.
- {
- AXNodeData& node1 = update_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(1);
- node1.child_ids[0] = 2;
- }
-
- // Change node2 text to French
- {
- AXNodeData& node2 = update_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kStaticText;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextFrench);
- }
-
- // Perform update.
- ASSERT_TRUE(tree.Unserialize(update_state));
-
- {
- AXNode* node1 = tree.GetFromId(1);
- ASSERT_NE(node1, nullptr);
- ASSERT_EQ(node1->GetLanguage(), "");
- }
-
- {
- // Detection should have been re-run on node2, detecting French.
- AXNode* node2 = tree.GetFromId(2);
- ASSERT_NE(node2, nullptr);
- ASSERT_EQ(node2->GetLanguage(), "fr");
- }
-
- {
- // Node3 should be no more.
- AXNode* node3 = tree.GetFromId(3);
- ASSERT_EQ(node3, nullptr);
- }
- }
-
- // Third update.
- {
- // Dynamic update
- //
- // New tree layout will be:
- // 1
- // 2 3
- //
- // 1 - GenericContainer, unchanged
- // 2 - French text, unchanged
- // 3 - new node, German text
- AXTreeUpdate update_state;
- update_state.root_id = 1;
- update_state.nodes.resize(2);
-
- // Update node1 to include new child node3.
- {
- AXNodeData& node1 = update_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(2);
- node1.child_ids[0] = 2;
- node1.child_ids[1] = 3;
- }
-
- // Add new node3 with German text.
- {
- AXNodeData& node3 = update_state.nodes[1];
- node3.id = 3;
- node3.role = ax::mojom::Role::kStaticText;
- node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman);
- }
-
- // Perform update.
- ASSERT_TRUE(tree.Unserialize(update_state));
-
- {
- AXNode* node1 = tree.GetFromId(1);
- ASSERT_NE(node1, nullptr);
- ASSERT_EQ(node1->GetLanguage(), "");
- }
-
- {
- AXNode* node2 = tree.GetFromId(2);
- ASSERT_NE(node2, nullptr);
- ASSERT_EQ(node2->GetLanguage(), "fr");
- }
-
- {
- AXNode* node3 = tree.GetFromId(3);
- ASSERT_NE(node3, nullptr);
- ASSERT_EQ(node3->GetLanguage(), "de");
- }
- }
-}
-
-TEST_F(AXLanguageDetectionTestDynamicContent, NewRoot) {
- // Artificial test change which changes the root node.
-
- // Tree:
- // 1
- //
- // 1 - GenericContainer
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(1);
-
- {
- AXNodeData& node1 = initial_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- }
-
- AXTree tree(initial_state);
- ASSERT_NE(tree.language_detection_manager, nullptr);
-
- // Run initial language detection and labelling.
- tree.language_detection_manager->DetectLanguages();
- tree.language_detection_manager->LabelLanguages();
-
- // Register dynamic content observer.
- tree.language_detection_manager->RegisterLanguageDetectionObserver();
- ASSERT_NE(getObserver(tree), nullptr);
- ASSERT_TRUE(tree.HasObserver(getObserver(tree)));
-
- // New Tree:
- // 2
- // 2 - new root, German text
-
- AXTreeUpdate update_state;
- update_state.root_id = 2;
- update_state.nodes.resize(1);
-
- {
- AXNodeData& node2 = update_state.nodes[0];
- node2.id = 2;
- node2.role = ax::mojom::Role::kStaticText;
- node2.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman);
- }
-
- // Perform update.
- ASSERT_TRUE(tree.Unserialize(update_state));
-
- {
- AXNode* node2 = tree.GetFromId(2);
- ASSERT_NE(node2, nullptr);
- ASSERT_EQ(node2->GetLanguage(), "de");
- }
-}
-
-TEST_F(AXLanguageDetectionTestDynamicContent, ChainOfNewNodes) {
- // Artificial test which adds two new nodes in a 'chain', simultaneously
- // adding a child of the root and a grandchild of the root.
-
- // Tree:
- // 1
- //
- // 1 - GenericContainer
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(1);
-
- {
- AXNodeData& node1 = initial_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- }
-
- AXTree tree(initial_state);
- ASSERT_NE(tree.language_detection_manager, nullptr);
-
- // Run initial language detection and labelling.
- tree.language_detection_manager->DetectLanguages();
- tree.language_detection_manager->LabelLanguages();
-
- // Register dynamic content observer.
- tree.language_detection_manager->RegisterLanguageDetectionObserver();
- ASSERT_NE(getObserver(tree), nullptr);
- ASSERT_TRUE(tree.HasObserver(getObserver(tree)));
-
- // New Tree:
- // 1
- // 2
- // 3
- // 1 - generic container
- // 2 - generic container
- // 3 - German text
-
- AXTreeUpdate update_state;
- update_state.root_id = 1;
- update_state.nodes.resize(3);
-
- {
- AXNodeData& node1 = update_state.nodes[0];
- node1.id = 1;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.child_ids.resize(1);
- node1.child_ids[0] = 2;
- }
-
- {
- AXNodeData& node2 = update_state.nodes[1];
- node2.id = 2;
- node2.role = ax::mojom::Role::kGenericContainer;
- node2.child_ids.resize(1);
- node2.child_ids[0] = 3;
- }
-
- {
- AXNodeData& node3 = update_state.nodes[2];
- node3.id = 3;
- node3.role = ax::mojom::Role::kStaticText;
- node3.AddStringAttribute(ax::mojom::StringAttribute::kName, kTextGerman);
- }
-
- // Perform update.
- ASSERT_TRUE(tree.Unserialize(update_state));
-
- {
- AXNode* node3 = tree.GetFromId(3);
- ASSERT_NE(node3, nullptr);
- ASSERT_EQ(node3->GetLanguage(), "de");
- }
-}
-
-TEST(AXLanguageDetectionTest, AXLanguageInfoStatsBasic) {
- AXLanguageInfoStats stats;
-
- {
- std::vector<std::string> detected_languages;
- detected_languages.push_back("en");
- detected_languages.push_back("fr");
- detected_languages.push_back("ja");
- stats.Add(detected_languages);
- }
-
- ASSERT_EQ(stats.GetScore("en"), 3);
- ASSERT_EQ(stats.GetScore("fr"), 2);
- ASSERT_EQ(stats.GetScore("ja"), 1);
-
- EXPECT_TRUE(stats.CheckLanguageWithinTop("en"));
- EXPECT_TRUE(stats.CheckLanguageWithinTop("fr"));
- EXPECT_TRUE(stats.CheckLanguageWithinTop("ja"));
-
- {
- std::vector<std::string> detected_languages;
- detected_languages.push_back("en");
- detected_languages.push_back("de");
- detected_languages.push_back("fr");
- stats.Add(detected_languages);
- }
-
- ASSERT_EQ(stats.GetScore("en"), 6);
- ASSERT_EQ(stats.GetScore("fr"), 3);
- ASSERT_EQ(stats.GetScore("de"), 2);
- ASSERT_EQ(stats.GetScore("ja"), 1);
-
- EXPECT_TRUE(stats.CheckLanguageWithinTop("en"));
- EXPECT_TRUE(stats.CheckLanguageWithinTop("fr"));
- EXPECT_TRUE(stats.CheckLanguageWithinTop("de"));
-
- EXPECT_FALSE(stats.CheckLanguageWithinTop("ja"));
-
- {
- std::vector<std::string> detected_languages;
- detected_languages.push_back("fr");
- stats.Add(detected_languages);
- }
-
- ASSERT_EQ(stats.GetScore("en"), 6);
- ASSERT_EQ(stats.GetScore("fr"), 6);
- ASSERT_EQ(stats.GetScore("de"), 2);
- ASSERT_EQ(stats.GetScore("ja"), 1);
-
- EXPECT_TRUE(stats.CheckLanguageWithinTop("en"));
- EXPECT_TRUE(stats.CheckLanguageWithinTop("fr"));
- EXPECT_TRUE(stats.CheckLanguageWithinTop("de"));
-
- EXPECT_FALSE(stats.CheckLanguageWithinTop("ja"));
-
- {
- std::vector<std::string> detected_languages;
- detected_languages.push_back("ja");
- detected_languages.push_back("qq");
- detected_languages.push_back("zz");
- stats.Add(detected_languages);
- }
-
- ASSERT_EQ(stats.GetScore("en"), 6);
- ASSERT_EQ(stats.GetScore("fr"), 6);
- ASSERT_EQ(stats.GetScore("ja"), 4);
- ASSERT_EQ(stats.GetScore("de"), 2);
- ASSERT_EQ(stats.GetScore("qq"), 2);
- ASSERT_EQ(stats.GetScore("zz"), 1);
-
- EXPECT_TRUE(stats.CheckLanguageWithinTop("en"));
- EXPECT_TRUE(stats.CheckLanguageWithinTop("fr"));
- EXPECT_TRUE(stats.CheckLanguageWithinTop("ja"));
-
- EXPECT_FALSE(stats.CheckLanguageWithinTop("de"));
- EXPECT_FALSE(stats.CheckLanguageWithinTop("qq"));
- EXPECT_FALSE(stats.CheckLanguageWithinTop("zz"));
-}
-
-TEST(AXLanguageDetectionTest, ShortLanguageDetectorLabeledTest) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetection);
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(2);
- initial_state.nodes[0].id = 1;
- initial_state.nodes[0].child_ids = {2};
- initial_state.nodes[1].id = 2;
- initial_state.nodes[1].AddStringAttribute(ax::mojom::StringAttribute::kName,
- "Hello");
- initial_state.nodes[1].AddStringAttribute(
- ax::mojom::StringAttribute::kLanguage, "en");
- AXTree tree(initial_state);
-
- AXNode* item = tree.GetFromId(2);
- std::vector<AXLanguageSpan> annotation;
- ASSERT_NE(tree.language_detection_manager, nullptr);
- // Empty output.
- annotation =
- tree.language_detection_manager->GetLanguageAnnotationForStringAttribute(
- *item, ax::mojom::StringAttribute::kInnerHtml);
- ASSERT_EQ(0, (int)annotation.size());
- // Returns single AXLanguageSpan.
- annotation =
- tree.language_detection_manager->GetLanguageAnnotationForStringAttribute(
- *item, ax::mojom::StringAttribute::kName);
- ASSERT_EQ(1, (int)annotation.size());
- AXLanguageSpan* lang_span = &annotation[0];
- ASSERT_EQ("en", lang_span->language);
- std::string name =
- item->GetStringAttribute(ax::mojom::StringAttribute::kName);
- ASSERT_EQ("Hello",
- name.substr(lang_span->start_index,
- lang_span->end_index - lang_span->start_index));
-}
-
-TEST(AXLanguageDetectionTest, ShortLanguageDetectorCharacterTest) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetection);
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(2);
- initial_state.nodes[0].id = 1;
- initial_state.nodes[0].child_ids = {2};
- initial_state.nodes[1].id = 2;
- initial_state.nodes[1].AddStringAttribute(ax::mojom::StringAttribute::kName,
- "δ");
- AXTree tree(initial_state);
-
- AXNode* item = tree.GetFromId(2);
- std::vector<AXLanguageSpan> annotation;
- ASSERT_NE(tree.language_detection_manager, nullptr);
- // Returns single LanguageSpan.
- annotation =
- tree.language_detection_manager->GetLanguageAnnotationForStringAttribute(
- *item, ax::mojom::StringAttribute::kName);
- ASSERT_EQ(1, (int)annotation.size());
- AXLanguageSpan* lang_span = &annotation[0];
- ASSERT_EQ("el", lang_span->language);
- std::string name =
- item->GetStringAttribute(ax::mojom::StringAttribute::kName);
- ASSERT_EQ("δ", name.substr(lang_span->start_index,
- lang_span->end_index - lang_span->start_index));
-}
-
-TEST(AXLanguageDetectionTest, ShortLanguageDetectorMultipleLanguagesTest) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetection);
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(2);
- initial_state.nodes[0].id = 1;
- initial_state.nodes[0].child_ids = {2};
- initial_state.nodes[1].id = 2;
- initial_state.nodes[1].AddStringAttribute(
- ax::mojom::StringAttribute::kName,
- "This text should be read in English. 차에 한하여 중임할 수. Followed "
- "by English.");
- AXTree tree(initial_state);
-
- AXNode* item = tree.GetFromId(2);
- ASSERT_NE(tree.language_detection_manager, nullptr);
- std::vector<AXLanguageSpan> annotation =
- tree.language_detection_manager->GetLanguageAnnotationForStringAttribute(
- *item, ax::mojom::StringAttribute::kName);
- ASSERT_EQ(3, (int)annotation.size());
- std::string name =
- item->GetStringAttribute(ax::mojom::StringAttribute::kName);
- AXLanguageSpan* lang_span = &annotation[0];
- ASSERT_EQ("This text should be read in English. ",
- name.substr(lang_span->start_index,
- lang_span->end_index - lang_span->start_index));
- lang_span = &annotation[1];
- ASSERT_EQ("차에 한하여 중임할 수. ",
- name.substr(lang_span->start_index,
- lang_span->end_index - lang_span->start_index));
- lang_span = &annotation[2];
- ASSERT_EQ("Followed by English.",
- name.substr(lang_span->start_index,
- lang_span->end_index - lang_span->start_index));
-}
-
-// Assert that GetLanguageAnnotationForStringAttribute works for attributes
-// other than kName.
-TEST(AXLanguageDetectionTest, DetectLanguagesForRoleTest) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- ::switches::kEnableExperimentalAccessibilityLanguageDetection);
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(1);
- initial_state.nodes[0].id = 1;
- initial_state.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kValue,
- "どうぞよろしくお願いします.");
- AXTree tree(initial_state);
-
- AXNode* item = tree.GetFromId(1);
- ASSERT_NE(tree.language_detection_manager, nullptr);
- std::vector<AXLanguageSpan> annotation =
- tree.language_detection_manager->GetLanguageAnnotationForStringAttribute(
- *item, ax::mojom::StringAttribute::kValue);
- ASSERT_EQ(1, (int)annotation.size());
- std::string value =
- item->GetStringAttribute(ax::mojom::StringAttribute::kValue);
- AXLanguageSpan* lang_span = &annotation[0];
- ASSERT_EQ("どうぞよろしくお願いします.",
- value.substr(lang_span->start_index,
- lang_span->end_index - lang_span->start_index));
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_mode.cc b/third_party/accessibility/ax/ax_mode.cc
index 7919464..8c69148 100644
--- a/third_party/accessibility/ax/ax_mode.cc
+++ b/third_party/accessibility/ax/ax_mode.cc
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_mode.h"
+#include "ax_mode.h"
#include <vector>
-#include "base/strings/string_util.h"
+#include "base/logging.h"
+#include "base/string_utils.h"
namespace ui {
@@ -46,11 +47,12 @@
break;
}
- DCHECK(flag_name);
+ BASE_DCHECK(flag_name);
if (has_mode(mode_flag))
tokens.push_back(flag_name);
}
+
return base::JoinString(tokens, " | ");
}
diff --git a/third_party/accessibility/ax/ax_mode.h b/third_party/accessibility/ax/ax_mode.h
index e358666..ca7767f 100644
--- a/third_party/accessibility/ax/ax_mode.h
+++ b/third_party/accessibility/ax/ax_mode.h
@@ -10,7 +10,7 @@
#include <ostream>
#include <string>
-#include "ui/accessibility/ax_base_export.h"
+#include "ax_base_export.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_mode_observer.h b/third_party/accessibility/ax/ax_mode_observer.h
index 36127ef..2b0b398 100644
--- a/third_party/accessibility/ax/ax_mode_observer.h
+++ b/third_party/accessibility/ax/ax_mode_observer.h
@@ -5,8 +5,8 @@
#ifndef UI_ACCESSIBILITY_AX_MODE_OBSERVER_H_
#define UI_ACCESSIBILITY_AX_MODE_OBSERVER_H_
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_mode.h"
+#include "ax_export.h"
+#include "ax_mode.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_node.cc b/third_party/accessibility/ax/ax_node.cc
index da368ef..9649177 100644
--- a/third_party/accessibility/ax/ax_node.cc
+++ b/third_party/accessibility/ax/ax_node.cc
@@ -2,21 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_node.h"
+#include "ax_node.h"
#include <algorithm>
#include <utility>
-#include "base/strings/string16.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "build/build_config.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_language_detection.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_table_info.h"
-#include "ui/accessibility/ax_tree.h"
-#include "ui/gfx/transform.h"
+#include "ax_enums.h"
+#include "ax_role_properties.h"
+#include "ax_table_info.h"
+#include "ax_tree.h"
+#include "base/color_utils.h"
+#include "base/string_utils.h"
namespace ui {
@@ -37,8 +33,8 @@
AXNode::~AXNode() = default;
size_t AXNode::GetUnignoredChildCount() const {
- // TODO(nektar): Should DCHECK if the node is not ignored.
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ // TODO(nektar): Should BASE_DCHECK if the node is not ignored.
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
return unignored_child_count_;
}
@@ -47,7 +43,7 @@
}
AXNode* AXNode::GetUnignoredChildAtIndex(size_t index) const {
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
size_t count = 0;
for (auto it = UnignoredChildrenBegin(); it != UnignoredChildrenEnd(); ++it) {
if (count == index)
@@ -58,7 +54,7 @@
}
AXNode* AXNode::GetUnignoredParent() const {
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
AXNode* result = parent();
while (result && result->IsIgnored())
result = result->parent();
@@ -66,22 +62,22 @@
}
size_t AXNode::GetUnignoredIndexInParent() const {
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
return unignored_index_in_parent_;
}
size_t AXNode::GetIndexInParent() const {
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
return index_in_parent_;
}
AXNode* AXNode::GetFirstUnignoredChild() const {
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
return ComputeFirstUnignoredChildRecursive();
}
AXNode* AXNode::GetLastUnignoredChild() const {
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
return ComputeLastUnignoredChildRecursive();
}
@@ -155,7 +151,7 @@
// 2 <-- [5] --> 4
// 5 <-- [4] --> null
AXNode* AXNode::GetNextUnignoredSibling() const {
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
const AXNode* current = this;
// If there are children of the |current| node still to consider.
@@ -224,7 +220,7 @@
//
// See the documentation for |GetNextUnignoredSibling| for more details.
AXNode* AXNode::GetPreviousUnignoredSibling() const {
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
const AXNode* current = this;
// If there are children of the |current| node still to consider.
@@ -311,12 +307,12 @@
}
AXNode::UnignoredChildIterator AXNode::UnignoredChildrenBegin() const {
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
return UnignoredChildIterator(this, GetFirstUnignoredChild());
}
AXNode::UnignoredChildIterator AXNode::UnignoredChildrenEnd() const {
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
return UnignoredChildIterator(this, nullptr);
}
@@ -338,7 +334,7 @@
// The previous (direct) sibling, ignored or unignored.
AXNode* AXNode::GetPreviousSibling() const {
// Root nodes lack a parent, their index_in_parent should be 0.
- DCHECK(!parent() ? index_in_parent() == 0 : true);
+ BASE_DCHECK(!parent() ? index_in_parent() == 0 : true);
size_t index = index_in_parent();
if (index == 0)
return nullptr;
@@ -431,10 +427,10 @@
void AXNode::ComputeLineStartOffsets(std::vector<int>* line_offsets,
int* start_offset) const {
- DCHECK(line_offsets);
- DCHECK(start_offset);
+ BASE_DCHECK(line_offsets);
+ BASE_DCHECK(start_offset);
for (const AXNode* child : children()) {
- DCHECK(child);
+ BASE_DCHECK(child);
if (!child->children().empty()) {
child->ComputeLineStartOffsets(line_offsets, start_offset);
continue;
@@ -449,7 +445,7 @@
line_offsets->push_back(*start_offset);
}
- base::string16 text =
+ std::u16string text =
child->data().GetString16Attribute(ax::mojom::StringAttribute::kName);
*start_offset += static_cast<int>(text.length());
}
@@ -466,23 +462,11 @@
return base::EmptyString();
}
-base::string16 AXNode::GetInheritedString16Attribute(
+std::u16string AXNode::GetInheritedString16Attribute(
ax::mojom::StringAttribute attribute) const {
return base::UTF8ToUTF16(GetInheritedStringAttribute(attribute));
}
-AXLanguageInfo* AXNode::GetLanguageInfo() const {
- return language_info_.get();
-}
-
-void AXNode::SetLanguageInfo(std::unique_ptr<AXLanguageInfo> lang_info) {
- language_info_ = std::move(lang_info);
-}
-
-void AXNode::ClearLanguageInfo() {
- language_info_.reset();
-}
-
std::string AXNode::GetInnerText() const {
// If a text field has no descendants, then we compute its inner text from its
// value or its placeholder. Otherwise we prefer to look at its descendant
@@ -544,21 +528,6 @@
}
std::string AXNode::GetLanguage() const {
- // Walk up tree considering both detected and author declared languages.
- for (const AXNode* cur = this; cur; cur = cur->parent()) {
- // If language detection has assigned a language then we prefer that.
- const AXLanguageInfo* lang_info = cur->GetLanguageInfo();
- if (lang_info && !lang_info->language.empty()) {
- return lang_info->language;
- }
-
- // If the page author has declared a language attribute we fallback to that.
- const AXNodeData& data = cur->data();
- if (data.HasStringAttribute(ax::mojom::StringAttribute::kLanguage)) {
- return data.GetStringAttribute(ax::mojom::StringAttribute::kLanguage);
- }
- }
-
return std::string();
}
@@ -570,46 +539,46 @@
return IsTableLike(data().role);
}
-base::Optional<int> AXNode::GetTableColCount() const {
+std::optional<int> AXNode::GetTableColCount() const {
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
- return int{table_info->col_count};
+ return std::nullopt;
+ return static_cast<int>(table_info->col_count);
}
-base::Optional<int> AXNode::GetTableRowCount() const {
+std::optional<int> AXNode::GetTableRowCount() const {
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
- return int{table_info->row_count};
+ return std::nullopt;
+ return static_cast<int>(table_info->row_count);
}
-base::Optional<int> AXNode::GetTableAriaColCount() const {
+std::optional<int> AXNode::GetTableAriaColCount() const {
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
- return base::make_optional(table_info->aria_col_count);
+ return std::nullopt;
+ return std::make_optional(table_info->aria_col_count);
}
-base::Optional<int> AXNode::GetTableAriaRowCount() const {
+std::optional<int> AXNode::GetTableAriaRowCount() const {
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
- return base::make_optional(table_info->aria_row_count);
+ return std::nullopt;
+ return std::make_optional(table_info->aria_row_count);
}
-base::Optional<int> AXNode::GetTableCellCount() const {
+std::optional<int> AXNode::GetTableCellCount() const {
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
+ return std::nullopt;
return static_cast<int>(table_info->unique_cell_ids.size());
}
-base::Optional<bool> AXNode::GetTableHasColumnOrRowHeaderNode() const {
+std::optional<bool> AXNode::GetTableHasColumnOrRowHeaderNode() const {
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
+ return std::nullopt;
return !table_info->all_headers.empty();
}
@@ -620,11 +589,13 @@
return nullptr;
// There is a table but there is no cell with the given index.
- if (index < 0 || size_t{index} >= table_info->unique_cell_ids.size()) {
+ if (index < 0 ||
+ static_cast<size_t>(index) >= table_info->unique_cell_ids.size()) {
return nullptr;
}
- return tree_->GetFromId(table_info->unique_cell_ids[size_t{index}]);
+ return tree_->GetFromId(
+ table_info->unique_cell_ids[static_cast<size_t>(index)]);
}
AXNode* AXNode::GetTableCaption() const {
@@ -641,13 +612,15 @@
return nullptr;
// There is a table but the given coordinates are outside the table.
- if (row_index < 0 || size_t{row_index} >= table_info->row_count ||
- col_index < 0 || size_t{col_index} >= table_info->col_count) {
+ if (row_index < 0 ||
+ static_cast<size_t>(row_index) >= table_info->row_count ||
+ col_index < 0 ||
+ static_cast<size_t>(col_index) >= table_info->col_count) {
return nullptr;
}
- return tree_->GetFromId(
- table_info->cell_ids[size_t{row_index}][size_t{col_index}]);
+ return tree_->GetFromId(table_info->cell_ids[static_cast<size_t>(row_index)]
+ [static_cast<size_t>(col_index)]);
}
std::vector<AXNode::AXID> AXNode::GetTableColHeaderNodeIds() const {
@@ -672,10 +645,11 @@
if (!table_info)
return std::vector<AXNode::AXID>();
- if (col_index < 0 || size_t{col_index} >= table_info->col_count)
+ if (col_index < 0 || static_cast<size_t>(col_index) >= table_info->col_count)
return std::vector<AXNode::AXID>();
- return std::vector<AXNode::AXID>(table_info->col_headers[size_t{col_index}]);
+ return std::vector<AXNode::AXID>(
+ table_info->col_headers[static_cast<size_t>(col_index)]);
}
std::vector<AXNode::AXID> AXNode::GetTableRowHeaderNodeIds(
@@ -684,10 +658,11 @@
if (!table_info)
return std::vector<AXNode::AXID>();
- if (row_index < 0 || size_t{row_index} >= table_info->row_count)
+ if (row_index < 0 || static_cast<size_t>(row_index) >= table_info->row_count)
return std::vector<AXNode::AXID>();
- return std::vector<AXNode::AXID>(table_info->row_headers[size_t{row_index}]);
+ return std::vector<AXNode::AXID>(
+ table_info->row_headers[static_cast<size_t>(row_index)]);
}
std::vector<AXNode::AXID> AXNode::GetTableUniqueCellIds() const {
@@ -715,18 +690,18 @@
return ui::IsTableRow(data().role);
}
-base::Optional<int> AXNode::GetTableRowRowIndex() const {
+std::optional<int> AXNode::GetTableRowRowIndex() const {
if (!IsTableRow())
- return base::nullopt;
+ return std::nullopt;
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
+ return std::nullopt;
const auto& iter = table_info->row_id_to_index.find(id());
if (iter == table_info->row_id_to_index.end())
- return base::nullopt;
- return int{iter->second};
+ return std::nullopt;
+ return static_cast<int>(iter->second);
}
std::vector<AXNode::AXID> AXNode::GetTableRowNodeIds() const {
@@ -751,13 +726,13 @@
return ui::IsTableColumn(data().role);
}
-base::Optional<int> AXNode::GetTableColColIndex() const {
+std::optional<int> AXNode::GetTableColColIndex() const {
if (!IsTableColumn())
- return base::nullopt;
+ return std::nullopt;
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
+ return std::nullopt;
int index = 0;
for (const AXNode* node : table_info->extra_mac_nodes) {
@@ -778,48 +753,48 @@
return IsCellOrTableHeader(data().role);
}
-base::Optional<int> AXNode::GetTableCellIndex() const {
+std::optional<int> AXNode::GetTableCellIndex() const {
if (!IsTableCellOrHeader())
- return base::nullopt;
+ return std::nullopt;
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
+ return std::nullopt;
const auto& iter = table_info->cell_id_to_index.find(id());
if (iter != table_info->cell_id_to_index.end())
- return int{iter->second};
- return base::nullopt;
+ return static_cast<int>(iter->second);
+ return std::nullopt;
}
-base::Optional<int> AXNode::GetTableCellColIndex() const {
+std::optional<int> AXNode::GetTableCellColIndex() const {
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
+ return std::nullopt;
- base::Optional<int> index = GetTableCellIndex();
+ std::optional<int> index = GetTableCellIndex();
if (!index)
- return base::nullopt;
+ return std::nullopt;
- return int{table_info->cell_data_vector[*index].col_index};
+ return static_cast<int>(table_info->cell_data_vector[*index].col_index);
}
-base::Optional<int> AXNode::GetTableCellRowIndex() const {
+std::optional<int> AXNode::GetTableCellRowIndex() const {
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
+ return std::nullopt;
- base::Optional<int> index = GetTableCellIndex();
+ std::optional<int> index = GetTableCellIndex();
if (!index)
- return base::nullopt;
+ return std::nullopt;
- return int{table_info->cell_data_vector[*index].row_index};
+ return static_cast<int>(table_info->cell_data_vector[*index].row_index);
}
-base::Optional<int> AXNode::GetTableCellColSpan() const {
+std::optional<int> AXNode::GetTableCellColSpan() const {
// If it's not a table cell, don't return a col span.
if (!IsTableCellOrHeader())
- return base::nullopt;
+ return std::nullopt;
// Otherwise, try to return a colspan, with 1 as the default if it's not
// specified.
@@ -829,10 +804,10 @@
return 1;
}
-base::Optional<int> AXNode::GetTableCellRowSpan() const {
+std::optional<int> AXNode::GetTableCellRowSpan() const {
// If it's not a table cell, don't return a row span.
if (!IsTableCellOrHeader())
- return base::nullopt;
+ return std::nullopt;
// Otherwise, try to return a row span, with 1 as the default if it's not
// specified.
@@ -842,28 +817,28 @@
return 1;
}
-base::Optional<int> AXNode::GetTableCellAriaColIndex() const {
+std::optional<int> AXNode::GetTableCellAriaColIndex() const {
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
+ return std::nullopt;
- base::Optional<int> index = GetTableCellIndex();
+ std::optional<int> index = GetTableCellIndex();
if (!index)
- return base::nullopt;
+ return std::nullopt;
- return int{table_info->cell_data_vector[*index].aria_col_index};
+ return static_cast<int>(table_info->cell_data_vector[*index].aria_col_index);
}
-base::Optional<int> AXNode::GetTableCellAriaRowIndex() const {
+std::optional<int> AXNode::GetTableCellAriaRowIndex() const {
const AXTableInfo* table_info = GetAncestorTableInfo();
if (!table_info)
- return base::nullopt;
+ return std::nullopt;
- base::Optional<int> index = GetTableCellIndex();
+ std::optional<int> index = GetTableCellIndex();
if (!index)
- return base::nullopt;
+ return std::nullopt;
- return int{table_info->cell_data_vector[*index].aria_row_index};
+ return static_cast<int>(table_info->cell_data_vector[*index].aria_row_index);
}
std::vector<AXNode::AXID> AXNode::GetTableCellColHeaderNodeIds() const {
@@ -878,7 +853,7 @@
}
void AXNode::GetTableCellColHeaders(std::vector<AXNode*>* col_headers) const {
- DCHECK(col_headers);
+ BASE_DCHECK(col_headers);
std::vector<int32_t> col_header_ids = GetTableCellColHeaderNodeIds();
IdVectorToNodeVector(col_header_ids, col_headers);
@@ -896,7 +871,7 @@
}
void AXNode::GetTableCellRowHeaders(std::vector<AXNode*>* row_headers) const {
- DCHECK(row_headers);
+ BASE_DCHECK(row_headers);
std::vector<int32_t> row_header_ids = GetTableCellRowHeaderNodeIds();
IdVectorToNodeVector(row_header_ids, row_headers);
@@ -947,7 +922,7 @@
}
}
-base::Optional<int> AXNode::GetHierarchicalLevel() const {
+std::optional<int> AXNode::GetHierarchicalLevel() const {
int hierarchical_level =
GetIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel);
@@ -957,7 +932,7 @@
if (hierarchical_level > 0)
return hierarchical_level;
- return base::nullopt;
+ return std::nullopt;
}
bool AXNode::IsOrderedSetItem() const {
@@ -969,12 +944,12 @@
}
// Uses AXTree's cache to calculate node's PosInSet.
-base::Optional<int> AXNode::GetPosInSet() {
+std::optional<int> AXNode::GetPosInSet() {
return tree_->GetPosInSet(*this);
}
// Uses AXTree's cache to calculate node's SetSize.
-base::Optional<int> AXNode::GetSetSize() {
+std::optional<int> AXNode::GetSetSize() {
return tree_->GetSetSize(*this);
}
@@ -1064,7 +1039,7 @@
}
AXNode* AXNode::ComputeLastUnignoredChildRecursive() const {
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
if (children().empty())
return nullptr;
@@ -1081,7 +1056,7 @@
}
AXNode* AXNode::ComputeFirstUnignoredChildRecursive() const {
- DCHECK(!tree_->GetTreeUpdateInProgressState());
+ BASE_DCHECK(!tree_->GetTreeUpdateInProgressState());
for (size_t i = 0; i < children().size(); i++) {
AXNode* child = children_[i];
if (!child->IsIgnored())
diff --git a/third_party/accessibility/ax/ax_node.h b/third_party/accessibility/ax/ax_node.h
index c59d00d..b476924 100644
--- a/third_party/accessibility/ax/ax_node.h
+++ b/third_party/accessibility/ax/ax_node.h
@@ -6,22 +6,24 @@
#define UI_ACCESSIBILITY_AX_NODE_H_
#include <stdint.h>
+#include <optional>
#include <memory>
#include <ostream>
#include <string>
#include <vector>
-#include "base/optional.h"
-#include "build/build_config.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_tree_id.h"
+#include "ax_build/build_config.h"
+#include "ax_export.h"
+#include "ax_node_data.h"
+#include "ax_tree_id.h"
+#include "base/logging.h"
+#include "gfx/geometry/rect.h"
+#include "gfx/transform.h"
namespace ui {
class AXTableInfo;
-struct AXLanguageInfo;
// One node in an AXTree.
class AX_EXPORT AXNode final {
@@ -29,9 +31,10 @@
// Defines the type used for AXNode IDs.
using AXID = int32_t;
+ // TODO(chunhtai): I modified this to be -1 so it can work with flutter.
// If a node is not yet or no longer valid, its ID should have a value of
// kInvalidAXID.
- static constexpr AXID kInvalidAXID = 0;
+ static constexpr AXID kInvalidAXID = -1;
// Interface to the tree class that owns an AXNode. We use this instead
// of letting AXNode have a pointer to its AXTree directly so that we're
@@ -56,8 +59,8 @@
// See AXTree::GetFromId.
virtual AXNode* GetFromId(int32_t id) const = 0;
- virtual base::Optional<int> GetPosInSet(const AXNode& node) = 0;
- virtual base::Optional<int> GetSetSize(const AXNode& node) = 0;
+ virtual std::optional<int> GetPosInSet(const AXNode& node) = 0;
+ virtual std::optional<int> GetSetSize(const AXNode& node) = 0;
virtual Selection GetUnignoredSelection() const = 0;
virtual bool GetTreeUpdateInProgressState() const = 0;
@@ -235,10 +238,10 @@
}
bool GetString16Attribute(ax::mojom::StringAttribute attribute,
- base::string16* value) const {
+ std::u16string* value) const {
return data().GetString16Attribute(attribute, value);
}
- base::string16 GetString16Attribute(
+ std::u16string GetString16Attribute(
ax::mojom::StringAttribute attribute) const {
return data().GetString16Attribute(attribute);
}
@@ -267,7 +270,7 @@
return data().GetStringListAttribute(attribute, value);
}
- bool GetHtmlAttribute(const char* attribute, base::string16* value) const {
+ bool GetHtmlAttribute(const char* attribute, std::u16string* value) const {
return data().GetHtmlAttribute(attribute, value);
}
bool GetHtmlAttribute(const char* attribute, std::string* value) const {
@@ -275,13 +278,13 @@
}
// Return the hierarchical level if supported.
- base::Optional<int> GetHierarchicalLevel() const;
+ std::optional<int> GetHierarchicalLevel() const;
// PosInSet and SetSize public methods.
bool IsOrderedSetItem() const;
bool IsOrderedSet() const;
- base::Optional<int> GetPosInSet();
- base::Optional<int> GetSetSize();
+ std::optional<int> GetPosInSet();
+ std::optional<int> GetSetSize();
// Helpers for GetPosInSet and GetSetSize.
// Returns true if the role of ordered set matches the role of item.
@@ -294,9 +297,8 @@
const std::string& GetInheritedStringAttribute(
ax::mojom::StringAttribute attribute) const;
- base::string16 GetInheritedString16Attribute(
+ std::u16string GetInheritedString16Attribute(
ax::mojom::StringAttribute attribute) const;
-
// Returns the text of this node and all descendant nodes; including text
// found in embedded objects.
//
@@ -315,7 +317,6 @@
// Returns empty string if no appropriate language was found.
std::string GetLanguage() const;
- //
// Helper functions for tables, table rows, and table cells.
// Most of these functions construct and cache an AXTableInfo behind
// the scenes to infer many properties of tables.
@@ -332,15 +333,15 @@
// of the table is row 0, column 0, cell index 0 - but that same cell
// has a minimum ARIA row index of 1 and column index of 1.
//
- // The below methods return base::nullopt if the AXNode they are called on is
+ // The below methods return std::nullopt if the AXNode they are called on is
// not inside a table.
bool IsTable() const;
- base::Optional<int> GetTableColCount() const;
- base::Optional<int> GetTableRowCount() const;
- base::Optional<int> GetTableAriaColCount() const;
- base::Optional<int> GetTableAriaRowCount() const;
- base::Optional<int> GetTableCellCount() const;
- base::Optional<bool> GetTableHasColumnOrRowHeaderNode() const;
+ std::optional<int> GetTableColCount() const;
+ std::optional<int> GetTableRowCount() const;
+ std::optional<int> GetTableAriaColCount() const;
+ std::optional<int> GetTableAriaRowCount() const;
+ std::optional<int> GetTableCellCount() const;
+ std::optional<bool> GetTableHasColumnOrRowHeaderNode() const;
AXNode* GetTableCaption() const;
AXNode* GetTableCellFromIndex(int index) const;
AXNode* GetTableCellFromCoords(int row_index, int col_index) const;
@@ -358,25 +359,25 @@
// Table row-like nodes.
bool IsTableRow() const;
- base::Optional<int> GetTableRowRowIndex() const;
+ std::optional<int> GetTableRowRowIndex() const;
// Get the node ids that represent rows in a table.
std::vector<AXNode::AXID> GetTableRowNodeIds() const;
#if defined(OS_APPLE)
// Table column-like nodes. These nodes are only present on macOS.
bool IsTableColumn() const;
- base::Optional<int> GetTableColColIndex() const;
+ std::optional<int> GetTableColColIndex() const;
#endif // defined(OS_APPLE)
// Table cell-like nodes.
bool IsTableCellOrHeader() const;
- base::Optional<int> GetTableCellIndex() const;
- base::Optional<int> GetTableCellColIndex() const;
- base::Optional<int> GetTableCellRowIndex() const;
- base::Optional<int> GetTableCellColSpan() const;
- base::Optional<int> GetTableCellRowSpan() const;
- base::Optional<int> GetTableCellAriaColIndex() const;
- base::Optional<int> GetTableCellAriaRowIndex() const;
+ std::optional<int> GetTableCellIndex() const;
+ std::optional<int> GetTableCellColIndex() const;
+ std::optional<int> GetTableCellRowIndex() const;
+ std::optional<int> GetTableCellColSpan() const;
+ std::optional<int> GetTableCellRowSpan() const;
+ std::optional<int> GetTableCellAriaColIndex() const;
+ std::optional<int> GetTableCellAriaRowIndex() const;
std::vector<AXNode::AXID> GetTableCellColHeaderNodeIds() const;
std::vector<AXNode::AXID> GetTableCellRowHeaderNodeIds() const;
void GetTableCellColHeaders(std::vector<AXNode*>* col_headers) const;
@@ -386,21 +387,6 @@
bool IsCellOrHeaderOfARIATable() const;
bool IsCellOrHeaderOfARIAGrid() const;
- // Return an object containing information about the languages detected on
- // this node.
- // Callers should not retain this pointer, instead they should request it
- // every time it is needed.
- //
- // Returns nullptr if the node has no language info.
- AXLanguageInfo* GetLanguageInfo() const;
-
- // This should only be called by LabelLanguageForSubtree and is used as part
- // of the language detection feature.
- void SetLanguageInfo(std::unique_ptr<AXLanguageInfo> lang_info);
-
- // Destroy the language info for this node.
- void ClearLanguageInfo();
-
// Returns true if node is a group and is a direct descendant of a set-like
// element.
bool IsEmbeddedGroup() const;
@@ -466,9 +452,6 @@
AXNode* const parent_;
std::vector<AXNode*> children_;
AXNodeData data_;
-
- // Stores the detected language computed from the node's text.
- std::unique_ptr<AXLanguageInfo> language_info_;
};
AX_EXPORT std::ostream& operator<<(std::ostream& stream, const AXNode& node);
@@ -595,7 +578,7 @@
PreviousSibling,
FirstChild,
LastChild>::get() const {
- DCHECK(child_);
+ BASE_DCHECK(child_);
return child_;
}
@@ -609,7 +592,7 @@
PreviousSibling,
FirstChild,
LastChild>::operator*() const {
- DCHECK(child_);
+ BASE_DCHECK(child_);
return *child_;
}
@@ -623,7 +606,7 @@
PreviousSibling,
FirstChild,
LastChild>::operator->() const {
- DCHECK(child_);
+ BASE_DCHECK(child_);
return child_;
}
diff --git a/third_party/accessibility/ax/ax_node_data.cc b/third_party/accessibility/ax/ax_node_data.cc
index aa82703..3f7f260 100644
--- a/third_party/accessibility/ax/ax_node_data.cc
+++ b/third_party/accessibility/ax/ax_node_data.cc
@@ -2,24 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_node_data.h"
+#include "ax_node_data.h"
#include <stddef.h>
-
#include <algorithm>
#include <set>
#include <utility>
+#include "ax_enum_util.h"
+#include "ax_role_properties.h"
+#include "base/container_utils.h"
+#include "base/logging.h"
#include "base/no_destructor.h"
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_enum_util.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/gfx/transform.h"
+#include "base/string_utils.h"
namespace ui {
@@ -172,7 +167,7 @@
return false;
}
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
}
@@ -205,7 +200,7 @@
return false;
}
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
}
@@ -325,7 +320,7 @@
int* value) const {
auto iter = FindInVectorOfPairs(attribute, int_attributes);
if (iter != int_attributes.end()) {
- *value = int{iter->second};
+ *value = static_cast<int>(iter->second);
return true;
}
@@ -355,16 +350,16 @@
return false;
}
-base::string16 AXNodeData::GetString16Attribute(
+std::u16string AXNodeData::GetString16Attribute(
ax::mojom::StringAttribute attribute) const {
std::string value_utf8;
if (!GetStringAttribute(attribute, &value_utf8))
- return base::string16();
+ return std::u16string();
return base::UTF8ToUTF16(value_utf8);
}
bool AXNodeData::GetString16Attribute(ax::mojom::StringAttribute attribute,
- base::string16* value) const {
+ std::u16string* value) const {
std::string value_utf8;
if (!GetStringAttribute(attribute, &value_utf8))
return false;
@@ -440,7 +435,7 @@
}
bool AXNodeData::GetHtmlAttribute(const char* html_attr,
- base::string16* value) const {
+ std::u16string* value) const {
std::string value_utf8;
if (!GetHtmlAttribute(html_attr, &value_utf8))
return false;
@@ -450,14 +445,14 @@
void AXNodeData::AddStringAttribute(ax::mojom::StringAttribute attribute,
const std::string& value) {
- DCHECK_NE(attribute, ax::mojom::StringAttribute::kNone);
+ BASE_DCHECK(attribute != ax::mojom::StringAttribute::kNone);
if (HasStringAttribute(attribute))
RemoveStringAttribute(attribute);
string_attributes.push_back(std::make_pair(attribute, value));
}
void AXNodeData::AddIntAttribute(ax::mojom::IntAttribute attribute, int value) {
- DCHECK_NE(attribute, ax::mojom::IntAttribute::kNone);
+ BASE_DCHECK(attribute != ax::mojom::IntAttribute::kNone);
if (HasIntAttribute(attribute))
RemoveIntAttribute(attribute);
int_attributes.push_back(std::make_pair(attribute, value));
@@ -465,7 +460,7 @@
void AXNodeData::AddFloatAttribute(ax::mojom::FloatAttribute attribute,
float value) {
- DCHECK_NE(attribute, ax::mojom::FloatAttribute::kNone);
+ BASE_DCHECK(attribute != ax::mojom::FloatAttribute::kNone);
if (HasFloatAttribute(attribute))
RemoveFloatAttribute(attribute);
float_attributes.push_back(std::make_pair(attribute, value));
@@ -473,7 +468,7 @@
void AXNodeData::AddBoolAttribute(ax::mojom::BoolAttribute attribute,
bool value) {
- DCHECK_NE(attribute, ax::mojom::BoolAttribute::kNone);
+ BASE_DCHECK(attribute != ax::mojom::BoolAttribute::kNone);
if (HasBoolAttribute(attribute))
RemoveBoolAttribute(attribute);
bool_attributes.push_back(std::make_pair(attribute, value));
@@ -481,7 +476,7 @@
void AXNodeData::AddIntListAttribute(ax::mojom::IntListAttribute attribute,
const std::vector<int32_t>& value) {
- DCHECK_NE(attribute, ax::mojom::IntListAttribute::kNone);
+ BASE_DCHECK(attribute != ax::mojom::IntListAttribute::kNone);
if (HasIntListAttribute(attribute))
RemoveIntListAttribute(attribute);
intlist_attributes.push_back(std::make_pair(attribute, value));
@@ -490,42 +485,42 @@
void AXNodeData::AddStringListAttribute(
ax::mojom::StringListAttribute attribute,
const std::vector<std::string>& value) {
- DCHECK_NE(attribute, ax::mojom::StringListAttribute::kNone);
+ BASE_DCHECK(attribute != ax::mojom::StringListAttribute::kNone);
if (HasStringListAttribute(attribute))
RemoveStringListAttribute(attribute);
stringlist_attributes.push_back(std::make_pair(attribute, value));
}
void AXNodeData::RemoveStringAttribute(ax::mojom::StringAttribute attribute) {
- DCHECK_NE(attribute, ax::mojom::StringAttribute::kNone);
+ BASE_DCHECK(attribute != ax::mojom::StringAttribute::kNone);
base::EraseIf(string_attributes, [attribute](const auto& string_attribute) {
return string_attribute.first == attribute;
});
}
void AXNodeData::RemoveIntAttribute(ax::mojom::IntAttribute attribute) {
- DCHECK_NE(attribute, ax::mojom::IntAttribute::kNone);
+ BASE_DCHECK(attribute != ax::mojom::IntAttribute::kNone);
base::EraseIf(int_attributes, [attribute](const auto& int_attribute) {
return int_attribute.first == attribute;
});
}
void AXNodeData::RemoveFloatAttribute(ax::mojom::FloatAttribute attribute) {
- DCHECK_NE(attribute, ax::mojom::FloatAttribute::kNone);
+ BASE_DCHECK(attribute != ax::mojom::FloatAttribute::kNone);
base::EraseIf(float_attributes, [attribute](const auto& float_attribute) {
return float_attribute.first == attribute;
});
}
void AXNodeData::RemoveBoolAttribute(ax::mojom::BoolAttribute attribute) {
- DCHECK_NE(attribute, ax::mojom::BoolAttribute::kNone);
+ BASE_DCHECK(attribute != ax::mojom::BoolAttribute::kNone);
base::EraseIf(bool_attributes, [attribute](const auto& bool_attribute) {
return bool_attribute.first == attribute;
});
}
void AXNodeData::RemoveIntListAttribute(ax::mojom::IntListAttribute attribute) {
- DCHECK_NE(attribute, ax::mojom::IntListAttribute::kNone);
+ BASE_DCHECK(attribute != ax::mojom::IntListAttribute::kNone);
base::EraseIf(intlist_attributes, [attribute](const auto& intlist_attribute) {
return intlist_attribute.first == attribute;
});
@@ -533,7 +528,7 @@
void AXNodeData::RemoveStringListAttribute(
ax::mojom::StringListAttribute attribute) {
- DCHECK_NE(attribute, ax::mojom::StringListAttribute::kNone);
+ BASE_DCHECK(attribute != ax::mojom::StringListAttribute::kNone);
base::EraseIf(stringlist_attributes,
[attribute](const auto& stringlist_attribute) {
return stringlist_attribute.first == attribute;
@@ -571,9 +566,13 @@
}
void AXNodeData::SetName(const std::string& name) {
- DCHECK_NE(role, ax::mojom::Role::kNone)
- << "A valid role is required before setting the name attribute, because "
- "the role is used for setting the required NameFrom attribute.";
+ if (role == ax::mojom::Role::kNone) {
+ BASE_LOG()
+ << "A valid role is required before setting the name attribute, "
+ "because "
+ "the role is used for setting the required NameFrom attribute.";
+ BASE_UNREACHABLE();
+ }
auto iter = std::find_if(string_attributes.begin(), string_attributes.end(),
[](const auto& string_attribute) {
@@ -609,7 +608,7 @@
}
}
-void AXNodeData::SetName(const base::string16& name) {
+void AXNodeData::SetName(const std::u16string& name) {
SetName(base::UTF16ToUTF8(name));
}
@@ -621,7 +620,7 @@
AddStringAttribute(ax::mojom::StringAttribute::kDescription, description);
}
-void AXNodeData::SetDescription(const base::string16& description) {
+void AXNodeData::SetDescription(const std::u16string& description) {
SetDescription(base::UTF16ToUTF8(description));
}
@@ -629,7 +628,7 @@
AddStringAttribute(ax::mojom::StringAttribute::kValue, value);
}
-void AXNodeData::SetValue(const base::string16& value) {
+void AXNodeData::SetValue(const std::u16string& value) {
SetValue(base::UTF16ToUTF8(value));
}
@@ -654,25 +653,25 @@
}
void AXNodeData::AddState(ax::mojom::State state_enum) {
- DCHECK_GT(static_cast<int>(state_enum),
- static_cast<int>(ax::mojom::State::kNone));
- DCHECK_LE(static_cast<int>(state_enum),
- static_cast<int>(ax::mojom::State::kMaxValue));
+ BASE_DCHECK(static_cast<int>(state_enum) >
+ static_cast<int>(ax::mojom::State::kNone));
+ BASE_DCHECK(static_cast<int>(state_enum) <=
+ static_cast<int>(ax::mojom::State::kMaxValue));
state = ModifyFlag(state, static_cast<uint32_t>(state_enum), true);
}
void AXNodeData::RemoveState(ax::mojom::State state_enum) {
- DCHECK_GT(static_cast<int>(state_enum),
- static_cast<int>(ax::mojom::State::kNone));
- DCHECK_LE(static_cast<int>(state_enum),
- static_cast<int>(ax::mojom::State::kMaxValue));
+ BASE_DCHECK(static_cast<int>(state_enum) >
+ static_cast<int>(ax::mojom::State::kNone));
+ BASE_DCHECK(static_cast<int>(state_enum) <=
+ static_cast<int>(ax::mojom::State::kMaxValue));
state = ModifyFlag(state, static_cast<uint32_t>(state_enum), false);
}
void AXNodeData::AddAction(ax::mojom::Action action_enum) {
switch (action_enum) {
case ax::mojom::Action::kNone:
- NOTREACHED();
+ BASE_UNREACHABLE();
break;
// Note: all of the attributes are included here explicitly, rather than
@@ -684,7 +683,7 @@
ax::mojom::Action excluded_action =
(action_enum == ax::mojom::Action::kBlur) ? ax::mojom::Action::kFocus
: ax::mojom::Action::kBlur;
- DCHECK(!HasAction(excluded_action)) << excluded_action;
+ BASE_DCHECK(!HasAction(excluded_action));
break;
}
@@ -726,10 +725,10 @@
}
void AXNodeData::AddTextStyle(ax::mojom::TextStyle text_style_enum) {
- DCHECK_GE(static_cast<int>(text_style_enum),
- static_cast<int>(ax::mojom::TextStyle::kMinValue));
- DCHECK_LE(static_cast<int>(text_style_enum),
- static_cast<int>(ax::mojom::TextStyle::kMaxValue));
+ BASE_DCHECK(static_cast<int>(text_style_enum) >=
+ static_cast<int>(ax::mojom::TextStyle::kMinValue));
+ BASE_DCHECK(static_cast<int>(text_style_enum) <=
+ static_cast<int>(ax::mojom::TextStyle::kMaxValue));
int32_t style = GetIntAttribute(ax::mojom::IntAttribute::kTextStyle);
style = ModifyFlag(static_cast<uint32_t>(style),
static_cast<uint32_t>(text_style_enum), true);
@@ -738,10 +737,10 @@
}
void AXNodeData::AddDropeffect(ax::mojom::Dropeffect dropeffect_enum) {
- DCHECK_GE(static_cast<int>(dropeffect_enum),
- static_cast<int>(ax::mojom::Dropeffect::kMinValue));
- DCHECK_LE(static_cast<int>(dropeffect_enum),
- static_cast<int>(ax::mojom::Dropeffect::kMaxValue));
+ BASE_DCHECK(static_cast<int>(dropeffect_enum) >=
+ static_cast<int>(ax::mojom::Dropeffect::kMinValue));
+ BASE_DCHECK(static_cast<int>(dropeffect_enum) <=
+ static_cast<int>(ax::mojom::Dropeffect::kMaxValue));
int32_t dropeffect = GetIntAttribute(ax::mojom::IntAttribute::kDropeffect);
dropeffect = ModifyFlag(static_cast<uint32_t>(dropeffect),
static_cast<uint32_t>(dropeffect_enum), true);
@@ -959,8 +958,12 @@
role == ax::mojom::Role::kIgnored;
}
+bool AXNodeData::IsInvisible() const {
+ return HasState(ax::mojom::State::kInvisible);
+}
+
bool AXNodeData::IsInvisibleOrIgnored() const {
- return IsIgnored() || HasState(ax::mojom::State::kInvisible);
+ return IsIgnored() || IsInvisible();
}
bool AXNodeData::IsInvocable() const {
diff --git a/third_party/accessibility/ax/ax_node_data.h b/third_party/accessibility/ax/ax_node_data.h
index bc2484c..ef458c0 100644
--- a/third_party/accessibility/ax/ax_node_data.h
+++ b/third_party/accessibility/ax/ax_node_data.h
@@ -13,13 +13,10 @@
#include <utility>
#include <vector>
-#include "base/strings/string16.h"
-#include "base/strings/string_split.h"
-#include "ui/accessibility/ax_base_export.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_node_text_styles.h"
-#include "ui/accessibility/ax_relative_bounds.h"
-#include "ui/gfx/geometry/rect_f.h"
+#include "ax_base_export.h"
+#include "ax_enums.h"
+#include "ax_node_text_styles.h"
+#include "ax_relative_bounds.h"
namespace ui {
@@ -62,7 +59,7 @@
// need to distinguish between the default value and a missing attribute),
// and another that returns the default value for that type if the
// attribute is not present. In addition, strings can be returned as
- // either std::string or base::string16, for convenience.
+ // either std::string or std::u16string, for convenience.
bool HasBoolAttribute(ax::mojom::BoolAttribute attribute) const;
bool GetBoolAttribute(ax::mojom::BoolAttribute attribute) const;
@@ -84,8 +81,8 @@
std::string* value) const;
bool GetString16Attribute(ax::mojom::StringAttribute attribute,
- base::string16* value) const;
- base::string16 GetString16Attribute(
+ std::u16string* value) const;
+ std::u16string GetString16Attribute(
ax::mojom::StringAttribute attribute) const;
bool HasIntListAttribute(ax::mojom::IntListAttribute attribute) const;
@@ -99,16 +96,15 @@
ax::mojom::StringListAttribute attribute) const;
bool GetStringListAttribute(ax::mojom::StringListAttribute attribute,
std::vector<std::string>* value) const;
-
- bool GetHtmlAttribute(const char* attribute, base::string16* value) const;
+ bool GetHtmlAttribute(const char* attribute, std::u16string* value) const;
bool GetHtmlAttribute(const char* attribute, std::string* value) const;
//
// Setting accessibility attributes.
//
- // Replaces an attribute if present. This is safer than crashing via a DCHECK
- // or doing nothing, because most likely replacing is what the caller would
- // have wanted or what existing code already assumes.
+ // Replaces an attribute if present. This is safer than crashing via a
+ // BASE_DCHECK or doing nothing, because most likely replacing is what the
+ // caller would have wanted or what existing code already assumes.
//
void AddStringAttribute(ax::mojom::StringAttribute attribute,
@@ -144,18 +140,18 @@
// Adds the name attribute or replaces it if already present. Also sets the
// NameFrom attribute if not already set.
void SetName(const std::string& name);
- void SetName(const base::string16& name);
+ void SetName(const std::u16string& name);
// Allows nameless objects to pass accessibility checks.
void SetNameExplicitlyEmpty();
// Adds the description attribute or replaces it if already present.
void SetDescription(const std::string& description);
- void SetDescription(const base::string16& description);
+ void SetDescription(const std::u16string& description);
// Adds the value attribute or replaces it if already present.
void SetValue(const std::string& value);
- void SetValue(const base::string16& value);
+ void SetValue(const std::u16string& value);
// Returns true if the given enum bit is 1.
bool HasState(ax::mojom::State state) const;
@@ -220,6 +216,9 @@
// Helper to determine if the data has the ignored state or ignored role.
bool IsIgnored() const;
+ // Helper to determine if the data has the invisible state.
+ bool IsInvisible() const;
+
// Helper to determine if the data has the ignored state, the invisible state
// or the ignored role.
bool IsInvisibleOrIgnored() const;
@@ -289,7 +288,7 @@
std::vector<
std::pair<ax::mojom::StringListAttribute, std::vector<std::string>>>
stringlist_attributes;
- base::StringPairs html_attributes;
+ std::vector<std::pair<std::string, std::string>> html_attributes;
std::vector<int32_t> child_ids;
AXRelativeBounds relative_bounds;
diff --git a/third_party/accessibility/ax/ax_node_data_unittest.cc b/third_party/accessibility/ax/ax_node_data_unittest.cc
index 90a96af..ac04107 100644
--- a/third_party/accessibility/ax/ax_node_data_unittest.cc
+++ b/third_party/accessibility/ax/ax_node_data_unittest.cc
@@ -2,15 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_node_data.h"
+#include "ax_node_data.h"
#include <set>
+#include <unordered_set>
-#include "base/stl_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enum_util.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_role_properties.h"
+#include "gtest/gtest.h"
+
+#include "ax_enum_util.h"
+#include "ax_enums.h"
+#include "ax_role_properties.h"
+#include "base/container_utils.h"
namespace ui {
@@ -259,7 +261,7 @@
SCOPED_TRACE(testing::Message()
<< "ax::mojom::Role=" << ToString(button_with_popup.role)
- << ", hasPopup=" << button_with_popup.GetHasPopup()
+ << ", hasPopup=" << ToString(button_with_popup.GetHasPopup())
<< ", Actual: isMenuButton=" << is_menu_button
<< ", Expected: isMenuButton=" << !is_menu_button);
diff --git a/third_party/accessibility/ax/ax_node_position.cc b/third_party/accessibility/ax/ax_node_position.cc
index f00db5f..4130893 100644
--- a/third_party/accessibility/ax/ax_node_position.cc
+++ b/third_party/accessibility/ax/ax_node_position.cc
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_node_position.h"
+#include "ax_node_position.h"
-#include "base/strings/string_util.h"
-#include "build/build_config.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_tree_manager.h"
-#include "ui/accessibility/ax_tree_manager_map.h"
+#include "ax_build/build_config.h"
+#include "ax_enums.h"
+#include "ax_node_data.h"
+#include "ax_tree_manager.h"
+#include "ax_tree_manager_map.h"
+#include "base/string_utils.h"
namespace ui {
@@ -51,8 +51,8 @@
void AXNodePosition::AnchorChild(int child_index,
AXTreeID* tree_id,
AXNode::AXID* child_id) const {
- DCHECK(tree_id);
- DCHECK(child_id);
+ BASE_DCHECK(tree_id);
+ BASE_DCHECK(child_id);
if (!GetAnchor() || child_index < 0 || child_index >= AnchorChildCount()) {
*tree_id = AXTreeIDUnknown();
@@ -68,11 +68,11 @@
child = child_tree_manager->GetRootAsAXNode();
*tree_id = child_tree_manager->GetTreeID();
} else {
- child = GetAnchor()->children()[size_t{child_index}];
+ child = GetAnchor()->children()[static_cast<size_t>(child_index)];
*tree_id = this->tree_id();
}
- DCHECK(child);
+ BASE_DCHECK(child);
*child_id = child->id();
}
@@ -85,7 +85,7 @@
if (child_tree_manager)
return 1;
- return int{GetAnchor()->children().size()};
+ return static_cast<int>(GetAnchor()->children().size());
}
int AXNodePosition::AnchorUnignoredChildCount() const {
@@ -96,7 +96,8 @@
}
int AXNodePosition::AnchorIndexInParent() const {
- return GetAnchor() ? int{GetAnchor()->index_in_parent()} : INVALID_INDEX;
+ return GetAnchor() ? static_cast<int>(GetAnchor()->index_in_parent())
+ : INVALID_INDEX;
}
int AXNodePosition::AnchorSiblingCount() const {
@@ -107,8 +108,8 @@
return 0;
}
-base::stack<AXNode*> AXNodePosition::GetAncestorAnchors() const {
- base::stack<AXNode*> anchors;
+std::stack<AXNode*> AXNodePosition::GetAncestorAnchors() const {
+ std::stack<AXNode*> anchors;
AXNode* current_anchor = GetAnchor();
AXNode::AXID current_anchor_id = GetAnchor()->id();
@@ -138,8 +139,8 @@
void AXNodePosition::AnchorParent(AXTreeID* tree_id,
AXNode::AXID* parent_id) const {
- DCHECK(tree_id);
- DCHECK(parent_id);
+ BASE_DCHECK(tree_id);
+ BASE_DCHECK(parent_id);
*tree_id = AXTreeIDUnknown();
*parent_id = AXNode::kInvalidAXID;
@@ -165,7 +166,6 @@
AXTreeManager* manager = AXTreeManagerMap::GetInstance().GetManager(tree_id);
if (manager)
return manager->GetNodeFromTree(tree_id, node_id);
-
return nullptr;
}
@@ -177,18 +177,18 @@
return node->tree()->GetAXTreeID();
}
-base::string16 AXNodePosition::GetText() const {
+std::u16string AXNodePosition::GetText() const {
if (IsNullPosition())
return {};
- base::string16 text;
+ std::u16string text;
if (IsEmptyObjectReplacedByCharacter()) {
text += kEmbeddedCharacter;
return text;
}
const AXNode* anchor = GetAnchor();
- DCHECK(anchor);
+ BASE_DCHECK(anchor);
// TODO(nektar): Replace with PlatformChildCount when AXNodePosition and
// BrowserAccessibilityPosition are merged into one class.
if (!AnchorChildCount()) {
@@ -214,21 +214,21 @@
bool AXNodePosition::IsInLineBreak() const {
if (IsNullPosition())
return false;
- DCHECK(GetAnchor());
+ BASE_DCHECK(GetAnchor());
return GetAnchor()->IsLineBreak();
}
bool AXNodePosition::IsInTextObject() const {
if (IsNullPosition())
return false;
- DCHECK(GetAnchor());
+ BASE_DCHECK(GetAnchor());
return GetAnchor()->IsText();
}
bool AXNodePosition::IsInWhiteSpace() const {
if (IsNullPosition())
return false;
- DCHECK(GetAnchor());
+ BASE_DCHECK(GetAnchor());
return GetAnchor()->IsLineBreak() ||
base::ContainsOnlyChars(GetText(), base::kWhitespaceUTF16);
}
@@ -246,11 +246,11 @@
return 1;
const AXNode* anchor = GetAnchor();
- DCHECK(anchor);
+ BASE_DCHECK(anchor);
// TODO(nektar): Replace with PlatformChildCount when AXNodePosition and
// BrowserAccessibilityPosition will make one.
if (!AnchorChildCount()) {
- base::string16 value =
+ std::u16string value =
anchor->data().GetString16Attribute(ax::mojom::StringAttribute::kValue);
if (!value.empty())
return value.length();
@@ -285,7 +285,7 @@
bool AXNodePosition::IsInLineBreakingObject() const {
if (IsNullPosition())
return false;
- DCHECK(GetAnchor());
+ BASE_DCHECK(GetAnchor());
return GetAnchor()->data().GetBoolAttribute(
ax::mojom::BoolAttribute::kIsLineBreakingObject) &&
!GetAnchor()->IsInListMarker();
@@ -294,7 +294,7 @@
ax::mojom::Role AXNodePosition::GetAnchorRole() const {
if (IsNullPosition())
return ax::mojom::Role::kNone;
- DCHECK(GetAnchor());
+ BASE_DCHECK(GetAnchor());
return GetRole(GetAnchor());
}
@@ -318,7 +318,7 @@
std::vector<int32_t> AXNodePosition::GetWordStartOffsets() const {
if (IsNullPosition())
return std::vector<int32_t>();
- DCHECK(GetAnchor());
+ BASE_DCHECK(GetAnchor());
// Embedded object replacement characters are not represented in |kWordStarts|
// attribute.
@@ -332,7 +332,7 @@
std::vector<int32_t> AXNodePosition::GetWordEndOffsets() const {
if (IsNullPosition())
return std::vector<int32_t>();
- DCHECK(GetAnchor());
+ BASE_DCHECK(GetAnchor());
// Embedded object replacement characters are not represented in |kWordEnds|
// attribute. Since the whole text exposed inside of an embedded object is of
@@ -376,8 +376,8 @@
AXTreeID child_tree_id,
AXTreeID* parent_tree_id,
AXNode::AXID* parent_id) {
- DCHECK(parent_tree_id);
- DCHECK(parent_id);
+ BASE_DCHECK(parent_tree_id);
+ BASE_DCHECK(parent_id);
*parent_tree_id = AXTreeIDUnknown();
*parent_id = AXNode::kInvalidAXID;
diff --git a/third_party/accessibility/ax/ax_node_position.h b/third_party/accessibility/ax/ax_node_position.h
index e7d03f6..bba9ab7 100644
--- a/third_party/accessibility/ax/ax_node_position.h
+++ b/third_party/accessibility/ax/ax_node_position.h
@@ -9,13 +9,11 @@
#include <vector>
-#include "base/containers/stack.h"
-#include "base/strings/string16.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_position.h"
-#include "ui/accessibility/ax_tree_id.h"
+#include "ax_enums.h"
+#include "ax_export.h"
+#include "ax_node.h"
+#include "ax_position.h"
+#include "ax_tree_id.h"
namespace ui {
@@ -36,7 +34,7 @@
AXPositionInstance Clone() const override;
- base::string16 GetText() const override;
+ std::u16string GetText() const override;
bool IsInLineBreak() const override;
bool IsInTextObject() const override;
bool IsInWhiteSpace() const override;
@@ -50,7 +48,7 @@
int AnchorUnignoredChildCount() const override;
int AnchorIndexInParent() const override;
int AnchorSiblingCount() const override;
- base::stack<AXNode*> GetAncestorAnchors() const override;
+ std::stack<AXNode*> GetAncestorAnchors() const override;
AXNode* GetLowestUnignoredAncestor() const override;
void AnchorParent(AXTreeID* tree_id, AXNode::AXID* parent_id) const override;
AXNode* GetNodeInTree(AXTreeID tree_id, AXNode::AXID node_id) const override;
diff --git a/third_party/accessibility/ax/ax_node_position_perftest.cc b/third_party/accessibility/ax/ax_node_position_perftest.cc
deleted file mode 100644
index 9c94098..0000000
--- a/third_party/accessibility/ax/ax_node_position_perftest.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/strings/stringprintf.h"
-#include "base/timer/lap_timer.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/perf/perf_result_reporter.h"
-#include "ui/accessibility/ax_node_position.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/accessibility/ax_tree_update.h"
-#include "ui/accessibility/test_ax_tree_manager.h"
-
-namespace ui {
-
-using TestPositionType = std::unique_ptr<AXPosition<AXNodePosition, AXNode>>;
-
-namespace {
-
-constexpr int kLaps = 5000;
-constexpr int kWarmupLaps = 5;
-constexpr char kMetricCallsPerSecondRunsPerS[] = "calls_per_second";
-
-class AXPositionPerfTest : public testing::Test, public TestAXTreeManager {
- public:
- AXPositionPerfTest() = default;
- ~AXPositionPerfTest() override = default;
-
- protected:
- void SetUp() override;
-
- perf_test::PerfResultReporter SetUpReporter(const std::string& story) {
- perf_test::PerfResultReporter reporter("AXPositionPerfTest.", story);
- reporter.RegisterImportantMetric(kMetricCallsPerSecondRunsPerS, "runs/s");
- return reporter;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AXPositionPerfTest);
-};
-
-void AXPositionPerfTest::SetUp() {
- // Setup a root with 5 child kGenericContainer with 5 kStaticText each.
- // Each kStaticText contains 5 characters of text.
- //
- // +------------------------+--------------+
- // | Tree Hierarchy + Role | anchor_id(s) |
- // +------------------------+--------------+
- // | ++kRootWebArea | 1 |
- // | ++++kGenericContainer | 2 |
- // | ++++++kStaticText | 7 - 11 |
- // | ++++kGenericContainer | 3 |
- // | ++++++kStaticText | 12 - 16 |
- // | ++++kGenericContainer | 4 |
- // | ++++++kStaticText | 17 - 21 |
- // | ++++kGenericContainer | 5 |
- // | ++++++kStaticText | 22 - 26 |
- // | ++++kGenericContainer | 6 |
- // | ++++++kStaticText | 27 - 31 |
- // +------------------------+--------------+
-
- constexpr int kNumberOfGroups = 5;
- constexpr int kStaticTextNodesPerGroup = 5;
- constexpr int kNumberOfStaticTextNodes =
- kNumberOfGroups * kStaticTextNodesPerGroup;
-
- constexpr int kGroupNodesStartIndex = 1;
- constexpr int kStaticTextNodesStartIndex =
- kGroupNodesStartIndex + kNumberOfGroups;
-
- AXNode::AXID current_id = 0;
- std::vector<AXNodeData> nodes;
- nodes.resize(1 + kNumberOfGroups + kNumberOfStaticTextNodes);
-
- AXNodeData& root_data = nodes[0];
- root_data.id = ++current_id;
- root_data.role = ax::mojom::Role::kRootWebArea;
-
- for (int group_index = 0; group_index < kNumberOfGroups; ++group_index) {
- AXNodeData& group = nodes[kGroupNodesStartIndex + group_index];
- group.id = ++current_id;
- group.role = ax::mojom::Role::kGenericContainer;
- root_data.child_ids.push_back(group.id);
- }
-
- for (int text_index = 0; text_index < kNumberOfStaticTextNodes;
- ++text_index) {
- const int group_index = text_index / kStaticTextNodesPerGroup;
- AXNodeData& group = nodes[kGroupNodesStartIndex + group_index];
- AXNodeData& static_text = nodes[kStaticTextNodesStartIndex + text_index];
- static_text.id = ++current_id;
- static_text.role = ax::mojom::Role::kStaticText;
- static_text.SetName(base::StringPrintf("id_%02X", static_text.id));
- group.child_ids.push_back(static_text.id);
- }
-
- AXTreeUpdate initial_state;
- initial_state.root_id = nodes[0].id;
- initial_state.nodes = nodes;
- initial_state.has_tree_data = true;
- initial_state.tree_data.tree_id = AXTreeID::CreateNewAXTreeID();
- initial_state.tree_data.title = "Perftest title";
-
- SetTree(std::make_unique<AXTree>(initial_state));
-}
-
-} // namespace
-
-TEST_F(AXPositionPerfTest, AsTreePositionFromTextPosition) {
- TestPositionType text_position = AXNodePosition::CreateTextPosition(
- GetTreeID(), /*anchor_id=*/1, /*text_offset=*/103,
- ax::mojom::TextAffinity::kDownstream);
-
- // The time limit is unused. Use kLaps for the check interval so the time is
- // only measured once.
- base::LapTimer timer(kWarmupLaps, base::TimeDelta(), kLaps);
- for (int i = 0; i < kLaps + kWarmupLaps; ++i) {
- TestPositionType as_tree_position = text_position->AsTreePosition();
- timer.NextLap();
- }
-
- auto reporter = SetUpReporter("AsTreePositionFromTextPosition");
- reporter.AddResult(kMetricCallsPerSecondRunsPerS, timer.LapsPerSecond());
-}
-
-TEST_F(AXPositionPerfTest, AsLeafTextPositionFromTextPosition) {
- TestPositionType text_position = AXNodePosition::CreateTextPosition(
- GetTreeID(), /*anchor_id=*/1, /*text_offset=*/103,
- ax::mojom::TextAffinity::kDownstream);
-
- // The time limit is unused. Use kLaps for the check interval so the time is
- // only measured once.
- base::LapTimer timer(kWarmupLaps, base::TimeDelta(), kLaps);
- for (int i = 0; i < kLaps + kWarmupLaps; ++i) {
- TestPositionType as_tree_position = text_position->AsLeafTextPosition();
- timer.NextLap();
- }
-
- auto reporter = SetUpReporter("AsLeafTextPositionFromTextPosition");
- reporter.AddResult(kMetricCallsPerSecondRunsPerS, timer.LapsPerSecond());
-}
-
-TEST_F(AXPositionPerfTest, AsLeafTextPositionFromTreePosition) {
- TestPositionType tree_position = AXNodePosition::CreateTreePosition(
- GetTreeID(), /*anchor_id=*/1, /*child_index=*/4);
-
- base::LapTimer timer(kWarmupLaps, base::TimeDelta(), kLaps);
- for (int i = 0; i < kLaps + kWarmupLaps; ++i) {
- TestPositionType as_tree_position = tree_position->AsLeafTextPosition();
- timer.NextLap();
- }
-
- auto reporter = SetUpReporter("AsLeafTextPositionFromTreePosition");
- reporter.AddResult(kMetricCallsPerSecondRunsPerS, timer.LapsPerSecond());
-}
-
-TEST_F(AXPositionPerfTest, CompareTextPositions) {
- TestPositionType text_position_1 = AXNodePosition::CreateTextPosition(
- GetTreeID(), /*anchor_id=*/7, /*text_offset=*/1,
- ax::mojom::TextAffinity::kDownstream);
-
- TestPositionType text_position_2 = AXNodePosition::CreateTextPosition(
- GetTreeID(), /*anchor_id=*/27, /*text_offset=*/1,
- ax::mojom::TextAffinity::kDownstream);
-
- base::LapTimer timer(kWarmupLaps, base::TimeDelta(), kLaps);
- for (int i = 0; i < kLaps + kWarmupLaps; ++i) {
- text_position_1->CompareTo(*text_position_2);
- timer.NextLap();
- }
-
- auto reporter = SetUpReporter("CompareTextPositions");
- reporter.AddResult(kMetricCallsPerSecondRunsPerS, timer.LapsPerSecond());
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_node_position_unittest.cc b/third_party/accessibility/ax/ax_node_position_unittest.cc
index 4fa8a3c..159e8b7 100644
--- a/third_party/accessibility/ax/ax_node_position_unittest.cc
+++ b/third_party/accessibility/ax/ax_node_position_unittest.cc
@@ -10,21 +10,21 @@
#include <utility>
#include <vector>
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/strings/string16.h"
-#include "base/strings/utf_string_conversions.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_node_position.h"
-#include "ui/accessibility/ax_range.h"
-#include "ui/accessibility/ax_tree.h"
-#include "ui/accessibility/ax_tree_data.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/accessibility/ax_tree_update.h"
-#include "ui/accessibility/test_ax_tree_manager.h"
+// #include "base/bind.h"
+// #include "base/callback.h"
+// #include "base/strings/string16.h"
+// #include "base/strings/utf_string_conversions.h"
+#include "ax/ax_enums.h"
+#include "ax/ax_node.h"
+#include "ax/ax_node_data.h"
+#include "ax/ax_node_position.h"
+#include "ax/ax_range.h"
+#include "ax/ax_tree.h"
+#include "ax/ax_tree_data.h"
+#include "ax/ax_tree_id.h"
+#include "ax/ax_tree_update.h"
+#include "ax/test_ax_tree_manager.h"
+#include "gtest/gtest.h"
namespace ui {
@@ -33,6 +33,10 @@
namespace {
+std::u16string WideToUTF16(const std::wstring wide) {
+ return std::u16string(wide.begin(), wide.end());
+}
+
constexpr AXNode::AXID ROOT_ID = 1;
constexpr AXNode::AXID BUTTON_ID = 2;
constexpr AXNode::AXID CHECK_BOX_ID = 3;
@@ -106,7 +110,7 @@
AXNodeData inline_box2_;
private:
- DISALLOW_COPY_AND_ASSIGN(AXPositionTest);
+ BASE_DISALLOW_COPY_AND_ASSIGN(AXPositionTest);
};
// Used by AXPositionExpandToEnclosingTextBoundaryTestWithParam.
@@ -149,7 +153,7 @@
AXPositionExpandToEnclosingTextBoundaryTestWithParam() = default;
~AXPositionExpandToEnclosingTextBoundaryTestWithParam() override = default;
- DISALLOW_COPY_AND_ASSIGN(
+ BASE_DISALLOW_COPY_AND_ASSIGN(
AXPositionExpandToEnclosingTextBoundaryTestWithParam);
};
@@ -195,7 +199,8 @@
AXPositionCreatePositionAtTextBoundaryTestWithParam() = default;
~AXPositionCreatePositionAtTextBoundaryTestWithParam() override = default;
- DISALLOW_COPY_AND_ASSIGN(AXPositionCreatePositionAtTextBoundaryTestWithParam);
+ BASE_DISALLOW_COPY_AND_ASSIGN(
+ AXPositionCreatePositionAtTextBoundaryTestWithParam);
};
// Used by |AXPositionTextNavigationTestWithParam|.
@@ -215,7 +220,7 @@
// Stores the method that should be called repeatedly by the test to create
// the next position.
- base::RepeatingCallback<TestPositionType(const TestPositionType&)> TestMethod;
+ std::function<TestPositionType(const TestPositionType&)> TestMethod;
// The node at which the test should start.
AXNode::AXID start_node_id;
@@ -242,7 +247,7 @@
AXPositionTextNavigationTestWithParam() = default;
~AXPositionTextNavigationTestWithParam() override = default;
- DISALLOW_COPY_AND_ASSIGN(AXPositionTextNavigationTestWithParam);
+ BASE_DISALLOW_COPY_AND_ASSIGN(AXPositionTextNavigationTestWithParam);
};
const char* AXPositionTest::TEXT_VALUE = "Line 1\nLine 2";
@@ -416,31 +421,34 @@
EXPECT_NE(nullptr, text_offsets);
text_offsets->push_back(0);
- base::string16 english_text;
+ std::u16string english_text;
for (int i = 0; i < 3; ++i) {
- base::string16 grapheme = base::WideToUTF16(kGraphemeClusters[i]);
+ std::u16string grapheme = WideToUTF16(kGraphemeClusters[i]);
EXPECT_EQ(1u, grapheme.length())
<< "All English characters should be one UTF16 code unit in length.";
- text_offsets->push_back(text_offsets->back() + int{grapheme.length()});
+ text_offsets->push_back(text_offsets->back() +
+ static_cast<int>(grapheme.length()));
english_text.append(grapheme);
}
- base::string16 hindi_text;
+ std::u16string hindi_text;
for (int i = 3; i < 5; ++i) {
- base::string16 grapheme = base::WideToUTF16(kGraphemeClusters[i]);
+ std::u16string grapheme = WideToUTF16(kGraphemeClusters[i]);
EXPECT_LE(2u, grapheme.length()) << "All Hindi characters should be two "
"or more UTF16 code units in length.";
- text_offsets->push_back(text_offsets->back() + int{grapheme.length()});
+ text_offsets->push_back(text_offsets->back() +
+ static_cast<int>(grapheme.length()));
hindi_text.append(grapheme);
}
- base::string16 thai_text;
+ std::u16string thai_text;
for (int i = 5; i < 8; ++i) {
- base::string16 grapheme = base::WideToUTF16(kGraphemeClusters[i]);
+ std::u16string grapheme = WideToUTF16(kGraphemeClusters[i]);
EXPECT_LT(0u, grapheme.length())
<< "One of the Thai characters should be one UTF16 code unit, "
"whilst others should be two or more.";
- text_offsets->push_back(text_offsets->back() + int{grapheme.length()});
+ text_offsets->push_back(text_offsets->back() +
+ static_cast<int>(grapheme.length()));
thai_text.append(grapheme);
}
@@ -614,7 +622,7 @@
AXNodeData static_text_data_2;
static_text_data_2.id = 3;
static_text_data_2.role = ax::mojom::Role::kStaticText;
- static_text_data_2.SetName(base::WideToUTF16(L"\xfffc"));
+ static_text_data_2.SetName(WideToUTF16(L"\xfffc"));
AXNodeData static_text_data_3;
static_text_data_3.id = 4;
@@ -872,7 +880,7 @@
TestPositionType text_position = AXNodePosition::CreateNullPosition();
ASSERT_NE(nullptr, text_position);
ASSERT_TRUE(text_position->IsNullPosition());
- ASSERT_EQ(base::WideToUTF16(L""), text_position->GetText());
+ ASSERT_EQ(WideToUTF16(L""), text_position->GetText());
}
TEST_F(AXPositionTest, GetTextFromRoot) {
@@ -881,7 +889,7 @@
ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
ASSERT_TRUE(text_position->IsTextPosition());
- ASSERT_EQ(base::WideToUTF16(L"Line 1\nLine 2"), text_position->GetText());
+ ASSERT_EQ(WideToUTF16(L"Line 1\nLine 2"), text_position->GetText());
}
TEST_F(AXPositionTest, GetTextFromButton) {
@@ -890,7 +898,7 @@
ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
ASSERT_TRUE(text_position->IsTextPosition());
- ASSERT_EQ(base::WideToUTF16(L""), text_position->GetText());
+ ASSERT_EQ(WideToUTF16(L""), text_position->GetText());
}
TEST_F(AXPositionTest, GetTextFromCheckbox) {
@@ -899,7 +907,7 @@
ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
ASSERT_TRUE(text_position->IsTextPosition());
- ASSERT_EQ(base::WideToUTF16(L""), text_position->GetText());
+ ASSERT_EQ(WideToUTF16(L""), text_position->GetText());
}
TEST_F(AXPositionTest, GetTextFromTextField) {
@@ -908,7 +916,7 @@
ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
ASSERT_TRUE(text_position->IsTextPosition());
- ASSERT_EQ(base::WideToUTF16(L"Line 1\nLine 2"), text_position->GetText());
+ ASSERT_EQ(WideToUTF16(L"Line 1\nLine 2"), text_position->GetText());
}
TEST_F(AXPositionTest, GetTextFromStaticText) {
@@ -917,7 +925,7 @@
ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
ASSERT_TRUE(text_position->IsTextPosition());
- ASSERT_EQ(base::WideToUTF16(L"Line 1"), text_position->GetText());
+ ASSERT_EQ(WideToUTF16(L"Line 1"), text_position->GetText());
}
TEST_F(AXPositionTest, GetTextFromInlineTextBox) {
@@ -926,7 +934,7 @@
ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
ASSERT_TRUE(text_position->IsTextPosition());
- ASSERT_EQ(base::WideToUTF16(L"Line 1"), text_position->GetText());
+ ASSERT_EQ(WideToUTF16(L"Line 1"), text_position->GetText());
}
TEST_F(AXPositionTest, GetTextFromLineBreak) {
@@ -935,7 +943,7 @@
ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
ASSERT_TRUE(text_position->IsTextPosition());
- ASSERT_EQ(base::WideToUTF16(L"\n"), text_position->GetText());
+ ASSERT_EQ(WideToUTF16(L"\n"), text_position->GetText());
}
TEST_F(AXPositionTest, GetMaxTextOffsetFromNullPosition) {
@@ -1102,7 +1110,7 @@
ASSERT_NE(nullptr, text_position);
EXPECT_TRUE(text_position->IsTextPosition());
EXPECT_EQ(38, text_position->MaxTextOffset());
- EXPECT_EQ(base::WideToUTF16(L"Placeholder from generated content3.14"),
+ EXPECT_EQ(WideToUTF16(L"Placeholder from generated content3.14"),
text_position->GetText());
}
@@ -5566,6 +5574,8 @@
TEST_F(AXPositionTest,
AsLeafTextPositionBeforeAndAfterCharacterAtInvalidGraphemeBoundary) {
+ GTEST_SKIP()
+ << "Skipping, current accessibility library cannot handle grapheme";
std::vector<int> text_offsets;
SetTree(CreateMultilingualDocument(&text_offsets));
@@ -6393,6 +6403,8 @@
}
TEST_F(AXPositionTest, CreateNextCharacterPositionAtGraphemeBoundary) {
+ GTEST_SKIP()
+ << "Skipping, current accessibility library cannot handle grapheme";
std::vector<int> text_offsets;
SetTree(CreateMultilingualDocument(&text_offsets));
@@ -6467,6 +6479,8 @@
}
TEST_F(AXPositionTest, CreatePreviousCharacterPositionAtGraphemeBoundary) {
+ GTEST_SKIP()
+ << "Skipping, current accessibility library cannot handle grapheme";
std::vector<int> text_offsets;
SetTree(CreateMultilingualDocument(&text_offsets));
@@ -7692,7 +7706,7 @@
GetTreeID(), generic_container_5.id, 0 /* text_offset */,
ax::mojom::TextAffinity::kDownstream);
- base::string16 expected_text;
+ std::u16string expected_text;
expected_text += AXNodePosition::kEmbeddedCharacter;
ASSERT_EQ(expected_text, position->GetText());
@@ -7702,10 +7716,10 @@
GetTreeID(), root_1.id, 0 /* text_offset */,
ax::mojom::TextAffinity::kDownstream);
- expected_text =
- base::WideToUTF16(L"Hello ") + AXNodePosition::kEmbeddedCharacter +
- base::WideToUTF16(L" world3.14") + AXNodePosition::kEmbeddedCharacter +
- base::WideToUTF16(L"hey") + AXNodePosition::kEmbeddedCharacter;
+ expected_text = WideToUTF16(L"Hello ") + AXNodePosition::kEmbeddedCharacter +
+ WideToUTF16(L" world3.14") +
+ AXNodePosition::kEmbeddedCharacter + WideToUTF16(L"hey") +
+ AXNodePosition::kEmbeddedCharacter;
ASSERT_EQ(expected_text, position->GetText());
// MaxTextOffset() with an embedded object replacement character.
@@ -7966,7 +7980,7 @@
ax::mojom::TextAffinity::kDownstream);
ASSERT_TRUE(text_position->IsTextPosition());
for (const std::string& expectation : GetParam().expectations) {
- text_position = GetParam().TestMethod.Run(text_position);
+ text_position = GetParam().TestMethod(text_position);
EXPECT_NE(nullptr, text_position);
EXPECT_EQ(expectation, text_position->ToString());
}
@@ -7979,7 +7993,7 @@
ax::mojom::TextAffinity::kUpstream);
ASSERT_TRUE(text_position->IsTextPosition());
for (const std::string& expectation : GetParam().expectations) {
- text_position = GetParam().TestMethod.Run(text_position);
+ text_position = GetParam().TestMethod(text_position);
EXPECT_NE(nullptr, text_position);
EXPECT_EQ(expectation, text_position->ToString());
}
@@ -8340,10 +8354,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=5 "
@@ -8354,10 +8368,10 @@
"affinity=downstream annotated_text=Line 1\nLine <2>",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=5 "
@@ -8367,40 +8381,38 @@
"TextPosition anchor_id=4 text_offset=12 "
"affinity=downstream annotated_text=Line 1\nLine <2>",
"NullPosition"}},
- TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
- return position->CreateNextWordStartPosition(
- AXBoundaryBehavior::CrossBoundary);
- }),
- STATIC_TEXT1_ID,
- 1 /* text_offset */,
- {"TextPosition anchor_id=5 text_offset=5 "
- "affinity=downstream annotated_text=Line <1>",
- "TextPosition anchor_id=9 text_offset=0 "
- "affinity=downstream annotated_text=<L>ine 2",
- "TextPosition anchor_id=9 text_offset=5 "
- "affinity=downstream annotated_text=Line <2>",
- "NullPosition"}},
- TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
- return position->CreateNextWordStartPosition(
- AXBoundaryBehavior::CrossBoundary);
- }),
- INLINE_BOX2_ID,
- 4 /* text_offset */,
- {"TextPosition anchor_id=9 text_offset=5 "
- "affinity=downstream annotated_text=Line <2>",
- "NullPosition"}}));
+ TextNavigationTestParam{[](const TestPositionType& position) {
+ return position->CreateNextWordStartPosition(
+ AXBoundaryBehavior::CrossBoundary);
+ },
+ STATIC_TEXT1_ID,
+ 1 /* text_offset */,
+ {"TextPosition anchor_id=5 text_offset=5 "
+ "affinity=downstream annotated_text=Line <1>",
+ "TextPosition anchor_id=9 text_offset=0 "
+ "affinity=downstream annotated_text=<L>ine 2",
+ "TextPosition anchor_id=9 text_offset=5 "
+ "affinity=downstream annotated_text=Line <2>",
+ "NullPosition"}},
+ TextNavigationTestParam{[](const TestPositionType& position) {
+ return position->CreateNextWordStartPosition(
+ AXBoundaryBehavior::CrossBoundary);
+ },
+ INLINE_BOX2_ID,
+ 4 /* text_offset */,
+ {"TextPosition anchor_id=9 text_offset=5 "
+ "affinity=downstream annotated_text=Line <2>",
+ "NullPosition"}}));
INSTANTIATE_TEST_SUITE_P(
CreateNextWordStartPositionWithBoundaryBehaviorStopAtAnchorBoundary,
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=5 "
@@ -8412,10 +8424,10 @@
"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=5 "
@@ -8427,10 +8439,10 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=5 "
@@ -8438,10 +8450,10 @@
"TextPosition anchor_id=5 text_offset=6 "
"affinity=downstream annotated_text=Line 1<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=5 "
@@ -8454,10 +8466,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=0 "
@@ -8465,10 +8477,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=0 "
@@ -8476,10 +8488,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=5 "
@@ -8487,10 +8499,10 @@
"TextPosition anchor_id=5 text_offset=5 "
"affinity=downstream annotated_text=Line <1>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=5 "
@@ -8503,10 +8515,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=5 "
@@ -8520,10 +8532,10 @@
"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=5 "
@@ -8537,10 +8549,10 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=5 "
@@ -8554,10 +8566,10 @@
"TextPosition anchor_id=9 text_offset=6 "
"affinity=downstream annotated_text=Line 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=5 "
@@ -8572,10 +8584,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{"TextPosition anchor_id=1 text_offset=12 "
@@ -8588,10 +8600,10 @@
"affinity=downstream annotated_text=<L>ine 1\nLine 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=12 "
@@ -8604,20 +8616,20 @@
"affinity=downstream annotated_text=<L>ine 1\nLine 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -8633,10 +8645,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{"TextPosition anchor_id=1 text_offset=12 "
@@ -8650,10 +8662,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=12 "
@@ -8667,10 +8679,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=0 "
@@ -8678,10 +8690,10 @@
"TextPosition anchor_id=5 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -8694,10 +8706,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{"TextPosition anchor_id=1 text_offset=12 "
@@ -8705,10 +8717,10 @@
"TextPosition anchor_id=1 text_offset=12 "
"affinity=downstream annotated_text=Line 1\nLine <2>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=12 "
@@ -8716,19 +8728,19 @@
"TextPosition anchor_id=4 text_offset=12 "
"affinity=downstream annotated_text=Line 1\nLine <2>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=5 "
"affinity=downstream annotated_text=Line <1>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -8741,10 +8753,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=12 "
@@ -8758,10 +8770,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=12 "
@@ -8775,10 +8787,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=0 "
@@ -8786,10 +8798,10 @@
"TextPosition anchor_id=5 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -8806,10 +8818,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=4 "
@@ -8822,10 +8834,10 @@
"affinity=downstream annotated_text=Line 1\nLine 2<>",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=4 "
@@ -8837,42 +8849,40 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>",
"NullPosition"}},
- TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
- return position->CreateNextWordEndPosition(
- AXBoundaryBehavior::CrossBoundary);
- }),
- STATIC_TEXT1_ID,
- 1 /* text_offset */,
- {"TextPosition anchor_id=5 text_offset=4 "
- "affinity=downstream annotated_text=Line< >1",
- "TextPosition anchor_id=5 text_offset=6 "
- "affinity=downstream annotated_text=Line 1<>",
- "TextPosition anchor_id=9 text_offset=4 "
- "affinity=downstream annotated_text=Line< >2",
- "TextPosition anchor_id=9 text_offset=6 "
- "affinity=downstream annotated_text=Line 2<>",
- "NullPosition"}},
- TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
- return position->CreateNextWordEndPosition(
- AXBoundaryBehavior::CrossBoundary);
- }),
- INLINE_BOX2_ID,
- 4 /* text_offset */,
- {"TextPosition anchor_id=9 text_offset=6 "
- "affinity=downstream annotated_text=Line 2<>",
- "NullPosition"}}));
+ TextNavigationTestParam{[](const TestPositionType& position) {
+ return position->CreateNextWordEndPosition(
+ AXBoundaryBehavior::CrossBoundary);
+ },
+ STATIC_TEXT1_ID,
+ 1 /* text_offset */,
+ {"TextPosition anchor_id=5 text_offset=4 "
+ "affinity=downstream annotated_text=Line< >1",
+ "TextPosition anchor_id=5 text_offset=6 "
+ "affinity=downstream annotated_text=Line 1<>",
+ "TextPosition anchor_id=9 text_offset=4 "
+ "affinity=downstream annotated_text=Line< >2",
+ "TextPosition anchor_id=9 text_offset=6 "
+ "affinity=downstream annotated_text=Line 2<>",
+ "NullPosition"}},
+ TextNavigationTestParam{[](const TestPositionType& position) {
+ return position->CreateNextWordEndPosition(
+ AXBoundaryBehavior::CrossBoundary);
+ },
+ INLINE_BOX2_ID,
+ 4 /* text_offset */,
+ {"TextPosition anchor_id=9 text_offset=6 "
+ "affinity=downstream annotated_text=Line 2<>",
+ "NullPosition"}}));
INSTANTIATE_TEST_SUITE_P(
CreateNextWordEndPositionWithBoundaryBehaviorStopAtAnchorBoundary,
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=4 "
@@ -8886,10 +8896,10 @@
"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=4 "
@@ -8903,10 +8913,10 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=4 "
@@ -8916,10 +8926,10 @@
"TextPosition anchor_id=5 text_offset=6 "
"affinity=downstream annotated_text=Line 1<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -8932,10 +8942,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=4 "
@@ -8943,10 +8953,10 @@
"TextPosition anchor_id=1 text_offset=4 "
"affinity=downstream annotated_text=Line< >1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=4 "
@@ -8954,10 +8964,10 @@
"TextPosition anchor_id=4 text_offset=4 "
"affinity=downstream annotated_text=Line< >1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=4 "
@@ -8965,10 +8975,10 @@
"TextPosition anchor_id=5 text_offset=4 "
"affinity=downstream annotated_text=Line< >1"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=4 "
@@ -8979,10 +8989,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=4 "
@@ -8996,10 +9006,10 @@
"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=4 "
@@ -9013,10 +9023,10 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=4 "
@@ -9030,10 +9040,10 @@
"TextPosition anchor_id=9 text_offset=6 "
"affinity=downstream annotated_text=Line 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextWordEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -9046,10 +9056,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{"TextPosition anchor_id=1 text_offset=11 "
@@ -9060,10 +9070,10 @@
"affinity=downstream annotated_text=Line< >1\nLine 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=11 "
@@ -9074,20 +9084,20 @@
"affinity=downstream annotated_text=Line< >1\nLine 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=4 "
"affinity=downstream annotated_text=Line< >1",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=6 text_offset=6 "
@@ -9101,10 +9111,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{
@@ -9118,10 +9128,10 @@
"affinity=downstream annotated_text=<L>ine 1\nLine 2",
}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=11 "
@@ -9133,10 +9143,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=4 "
@@ -9144,10 +9154,10 @@
"TextPosition anchor_id=5 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -9158,28 +9168,28 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=4 "
@@ -9187,10 +9197,10 @@
"TextPosition anchor_id=5 text_offset=4 "
"affinity=downstream annotated_text=Line< >1"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=4 "
@@ -9201,10 +9211,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{"TextPosition anchor_id=1 text_offset=11 "
@@ -9218,10 +9228,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=11 "
@@ -9235,10 +9245,10 @@
"TextPosition anchor_id=2 text_offset=0 "
"affinity=downstream annotated_text=<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=4 "
@@ -9248,10 +9258,10 @@
"TextPosition anchor_id=2 text_offset=0 "
"affinity=downstream annotated_text=<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousWordEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=6 text_offset=6 "
@@ -9268,53 +9278,51 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=7 "
"affinity=downstream annotated_text=Line 1\n<L>ine 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=7 "
"affinity=downstream annotated_text=Line 1\n<L>ine 2",
"NullPosition"}},
- TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
- return position->CreateNextLineStartPosition(
- AXBoundaryBehavior::CrossBoundary);
- }),
- STATIC_TEXT1_ID,
- 1 /* text_offset */,
- {"TextPosition anchor_id=9 text_offset=0 "
- "affinity=downstream annotated_text=<L>ine 2",
- "NullPosition"}},
- TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
- return position->CreateNextLineStartPosition(
- AXBoundaryBehavior::CrossBoundary);
- }),
- INLINE_BOX2_ID,
- 4 /* text_offset */,
- {"NullPosition"}}));
+ TextNavigationTestParam{[](const TestPositionType& position) {
+ return position->CreateNextLineStartPosition(
+ AXBoundaryBehavior::CrossBoundary);
+ },
+ STATIC_TEXT1_ID,
+ 1 /* text_offset */,
+ {"TextPosition anchor_id=9 text_offset=0 "
+ "affinity=downstream annotated_text=<L>ine 2",
+ "NullPosition"}},
+ TextNavigationTestParam{[](const TestPositionType& position) {
+ return position->CreateNextLineStartPosition(
+ AXBoundaryBehavior::CrossBoundary);
+ },
+ INLINE_BOX2_ID,
+ 4 /* text_offset */,
+ {"NullPosition"}}));
INSTANTIATE_TEST_SUITE_P(
CreateNextLineStartPositionWithBoundaryBehaviorStopAtAnchorBoundary,
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -9322,10 +9330,10 @@
"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -9333,19 +9341,19 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=6 "
"affinity=downstream annotated_text=Line 1<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -9356,10 +9364,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=0 "
@@ -9367,10 +9375,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=0 "
@@ -9378,10 +9386,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -9389,10 +9397,10 @@
"TextPosition anchor_id=9 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"NullPosition"}}));
@@ -9402,10 +9410,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -9415,10 +9423,10 @@
"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -9428,10 +9436,10 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -9441,10 +9449,10 @@
"TextPosition anchor_id=9 text_offset=6 "
"affinity=downstream annotated_text=Line 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -9457,10 +9465,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at the end of root. */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -9469,10 +9477,10 @@
"affinity=downstream annotated_text=<L>ine 1\nLine 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -9481,20 +9489,20 @@
"affinity=downstream annotated_text=<L>ine 1\nLine 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -9508,10 +9516,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at the end of root. */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -9521,10 +9529,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -9534,10 +9542,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=0 "
@@ -9545,10 +9553,10 @@
"TextPosition anchor_id=5 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -9561,10 +9569,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at the end of root. */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -9572,10 +9580,10 @@
"TextPosition anchor_id=1 text_offset=7 "
"affinity=downstream annotated_text=Line 1\n<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -9583,10 +9591,10 @@
"TextPosition anchor_id=4 text_offset=7 "
"affinity=downstream annotated_text=Line 1\n<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=0 "
@@ -9594,10 +9602,10 @@
"TextPosition anchor_id=5 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -9610,10 +9618,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at the end of root. */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -9623,10 +9631,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -9636,10 +9644,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=0 "
@@ -9647,10 +9655,10 @@
"TextPosition anchor_id=5 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -9665,10 +9673,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=6 "
@@ -9677,10 +9685,10 @@
"affinity=downstream annotated_text=Line 1\nLine 2<>",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=6 "
@@ -9688,38 +9696,36 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>",
"NullPosition"}},
- TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
- return position->CreateNextLineEndPosition(
- AXBoundaryBehavior::CrossBoundary);
- }),
- STATIC_TEXT1_ID,
- 1 /* text_offset */,
- {"TextPosition anchor_id=5 text_offset=6 "
- "affinity=downstream annotated_text=Line 1<>",
- "TextPosition anchor_id=9 text_offset=6 "
- "affinity=downstream annotated_text=Line 2<>",
- "NullPosition"}},
- TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
- return position->CreateNextLineEndPosition(
- AXBoundaryBehavior::CrossBoundary);
- }),
- INLINE_BOX2_ID,
- 4 /* text_offset */,
- {"TextPosition anchor_id=9 text_offset=6 "
- "affinity=downstream annotated_text=Line 2<>",
- "NullPosition"}}));
+ TextNavigationTestParam{[](const TestPositionType& position) {
+ return position->CreateNextLineEndPosition(
+ AXBoundaryBehavior::CrossBoundary);
+ },
+ STATIC_TEXT1_ID,
+ 1 /* text_offset */,
+ {"TextPosition anchor_id=5 text_offset=6 "
+ "affinity=downstream annotated_text=Line 1<>",
+ "TextPosition anchor_id=9 text_offset=6 "
+ "affinity=downstream annotated_text=Line 2<>",
+ "NullPosition"}},
+ TextNavigationTestParam{[](const TestPositionType& position) {
+ return position->CreateNextLineEndPosition(
+ AXBoundaryBehavior::CrossBoundary);
+ },
+ INLINE_BOX2_ID,
+ 4 /* text_offset */,
+ {"TextPosition anchor_id=9 text_offset=6 "
+ "affinity=downstream annotated_text=Line 2<>",
+ "NullPosition"}}));
INSTANTIATE_TEST_SUITE_P(
CreateNextLineEndPositionWithBoundaryBehaviorStopAtAnchorBoundary,
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=6 "
@@ -9729,10 +9735,10 @@
"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=6 "
@@ -9742,10 +9748,10 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=6 "
@@ -9753,10 +9759,10 @@
"TextPosition anchor_id=5 text_offset=6 "
"affinity=downstream annotated_text=Line 1<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -9769,10 +9775,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=6 "
@@ -9780,10 +9786,10 @@
"TextPosition anchor_id=1 text_offset=6 "
"affinity=downstream annotated_text=Line 1<\n>Line 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=6 "
@@ -9791,10 +9797,10 @@
"TextPosition anchor_id=4 text_offset=6 "
"affinity=downstream annotated_text=Line 1<\n>Line 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=6 "
@@ -9802,10 +9808,10 @@
"TextPosition anchor_id=5 text_offset=6 "
"affinity=downstream annotated_text=Line 1<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -9818,10 +9824,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=6 "
@@ -9831,10 +9837,10 @@
"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=6 "
@@ -9844,10 +9850,10 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=6 "
@@ -9857,10 +9863,10 @@
"TextPosition anchor_id=9 text_offset=6 "
"affinity=downstream annotated_text=Line 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextLineEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -9873,56 +9879,56 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{"TextPosition anchor_id=1 text_offset=6 "
"affinity=downstream annotated_text=Line 1<\n>Line 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=6 "
"affinity=downstream annotated_text=Line 1<\n>Line 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
5 /* text_offset on the last character of "Line 1". */,
{"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
5 /* text_offset on the last character of "Line 1". */,
{"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=6 text_offset=6 "
"affinity=downstream annotated_text=Line 1<>",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
INLINE_BOX2_ID,
0 /* text_offset */,
{"TextPosition anchor_id=7 text_offset=0 "
@@ -9934,10 +9940,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{"TextPosition anchor_id=1 text_offset=6 "
@@ -9945,10 +9951,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=6 "
@@ -9956,10 +9962,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
5 /* text_offset on the last character of "Line 1". */,
{"TextPosition anchor_id=1 text_offset=0 "
@@ -9967,10 +9973,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
5 /* text_offset on the last character of "Line 1". */,
{"TextPosition anchor_id=4 text_offset=0 "
@@ -9978,10 +9984,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -9989,10 +9995,10 @@
"TextPosition anchor_id=9 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
0 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -10005,10 +10011,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
ROOT_ID,
12 /* text_offset one before the end of root. */,
{"TextPosition anchor_id=1 text_offset=6 "
@@ -10016,10 +10022,10 @@
"TextPosition anchor_id=1 text_offset=6 "
"affinity=downstream annotated_text=Line 1<\n>Line 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
TEXT_FIELD_ID,
12 /* text_offset one before the end of text field */,
{"TextPosition anchor_id=4 text_offset=6 "
@@ -10027,18 +10033,18 @@
"TextPosition anchor_id=4 text_offset=6 "
"affinity=downstream annotated_text=Line 1<\n>Line 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX1_ID,
2 /* text_offset */,
{"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=6 text_offset=6 "
@@ -10046,10 +10052,10 @@
"TextPosition anchor_id=6 text_offset=6 "
"affinity=downstream annotated_text=Line 1<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
0 /* text_offset */,
{"TextPosition anchor_id=6 text_offset=6 "
@@ -10062,10 +10068,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{"TextPosition anchor_id=1 text_offset=6 "
@@ -10075,10 +10081,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=6 "
@@ -10088,10 +10094,10 @@
"TextPosition anchor_id=2 text_offset=0 "
"affinity=downstream annotated_text=<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
5 /* text_offset on the last character of "Line 1". */,
{"TextPosition anchor_id=1 text_offset=0 "
@@ -10099,10 +10105,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
5 /* text_offset on the last character of "Line 1". */,
{"TextPosition anchor_id=2 text_offset=0 "
@@ -10110,10 +10116,10 @@
"TextPosition anchor_id=2 text_offset=0 "
"affinity=downstream annotated_text=<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=6 text_offset=6 "
@@ -10123,10 +10129,10 @@
"TextPosition anchor_id=2 text_offset=0 "
"affinity=downstream annotated_text=<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousLineEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
0 /* text_offset */,
{"TextPosition anchor_id=7 text_offset=0 "
@@ -10141,37 +10147,37 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=7 "
"affinity=downstream annotated_text=Line 1\n<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=7 "
"affinity=downstream annotated_text=Line 1\n<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"NullPosition"}}));
@@ -10181,10 +10187,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -10192,10 +10198,10 @@
"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10203,19 +10209,19 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=6 "
"affinity=downstream annotated_text=Line 1<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -10226,10 +10232,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=0 "
@@ -10237,10 +10243,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=0 "
@@ -10248,10 +10254,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -10259,10 +10265,10 @@
"TextPosition anchor_id=9 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"NullPosition"}}));
@@ -10272,10 +10278,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -10285,10 +10291,10 @@
"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10298,10 +10304,10 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -10311,10 +10317,10 @@
"TextPosition anchor_id=9 text_offset=6 "
"affinity=downstream annotated_text=Line 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -10327,10 +10333,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at the end of root. */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -10339,10 +10345,10 @@
"affinity=downstream annotated_text=<L>ine 1\nLine 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10351,20 +10357,20 @@
"affinity=downstream annotated_text=<L>ine 1\nLine 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -10378,10 +10384,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at the end of root. */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -10391,10 +10397,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10404,10 +10410,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=0 "
@@ -10415,10 +10421,10 @@
"TextPosition anchor_id=5 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -10431,10 +10437,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at the end of root. */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -10442,10 +10448,10 @@
"TextPosition anchor_id=1 text_offset=7 "
"affinity=downstream annotated_text=Line 1\n<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10453,10 +10459,10 @@
"TextPosition anchor_id=4 text_offset=7 "
"affinity=downstream annotated_text=Line 1\n<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=0 "
@@ -10464,10 +10470,10 @@
"TextPosition anchor_id=5 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -10480,10 +10486,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at the end of root. */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -10495,10 +10501,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10508,10 +10514,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
5 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=0 "
@@ -10519,10 +10525,10 @@
"TextPosition anchor_id=5 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphStartPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -10537,10 +10543,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -10549,10 +10555,10 @@
"affinity=downstream annotated_text=Line 1\nLine 2<>",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10561,10 +10567,10 @@
"affinity=downstream annotated_text=Line 1\nLine 2<>",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=7 text_offset=1 "
@@ -10573,10 +10579,10 @@
"affinity=downstream annotated_text=Line 2<>",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -10588,10 +10594,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -10603,10 +10609,10 @@
"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10618,10 +10624,10 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=5 text_offset=6 "
@@ -10629,10 +10635,10 @@
"TextPosition anchor_id=5 text_offset=6 "
"affinity=downstream annotated_text=Line 1<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -10645,10 +10651,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=0 "
@@ -10656,10 +10662,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10667,10 +10673,10 @@
"TextPosition anchor_id=4 text_offset=7 "
"affinity=upstream annotated_text=Line 1\n<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=7 text_offset=1 "
@@ -10678,10 +10684,10 @@
"TextPosition anchor_id=7 text_offset=1 "
"affinity=downstream annotated_text=\n<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -10689,10 +10695,10 @@
"TextPosition anchor_id=9 text_offset=6 "
"affinity=downstream annotated_text=Line 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
LINE_BREAK_ID,
0 /* text_offset */,
{"TextPosition anchor_id=7 text_offset=1 "
@@ -10700,10 +10706,10 @@
"TextPosition anchor_id=7 text_offset=1 "
"affinity=downstream annotated_text=\n<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
LINE_BREAK_ID,
1 /* text_offset */,
{"TextPosition anchor_id=7 text_offset=1 "
@@ -10716,10 +10722,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
0 /* text_offset */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -10729,10 +10735,10 @@
"TextPosition anchor_id=1 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
0 /* text_offset */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10742,10 +10748,10 @@
"TextPosition anchor_id=4 text_offset=13 "
"affinity=downstream annotated_text=Line 1\nLine 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
STATIC_TEXT1_ID,
1 /* text_offset */,
{"TextPosition anchor_id=7 text_offset=1 "
@@ -10755,10 +10761,10 @@
"TextPosition anchor_id=9 text_offset=6 "
"affinity=downstream annotated_text=Line 2<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreateNextParagraphEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=6 "
@@ -10771,10 +10777,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -10783,10 +10789,10 @@
"affinity=downstream annotated_text=<L>ine 1\nLine 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10795,30 +10801,30 @@
"affinity=downstream annotated_text=<>",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
ROOT_ID,
5 /* text_offset on the last character of "Line 1". */,
{"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
TEXT_FIELD_ID,
5 /* text_offset on the last character of "Line 1". */,
{"TextPosition anchor_id=3 text_offset=0 "
"affinity=downstream annotated_text=<>",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=7 text_offset=1 "
@@ -10827,10 +10833,10 @@
"affinity=downstream annotated_text=<>",
"NullPosition"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::CrossBoundary);
- }),
+ },
INLINE_BOX2_ID,
0 /* text_offset */,
{"TextPosition anchor_id=3 text_offset=0 "
@@ -10842,10 +10848,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -10855,10 +10861,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10868,10 +10874,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
ROOT_ID,
5 /* text_offset on the last character of "Line 1". */,
{"TextPosition anchor_id=1 text_offset=0 "
@@ -10879,10 +10885,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
5 /* text_offset on the last character of "Line 1". */,
{"TextPosition anchor_id=4 text_offset=0 "
@@ -10890,10 +10896,10 @@
"TextPosition anchor_id=4 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -10901,10 +10907,10 @@
"TextPosition anchor_id=9 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
0 /* text_offset */,
{"TextPosition anchor_id=9 text_offset=0 "
@@ -10917,10 +10923,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
ROOT_ID,
12 /* text_offset one before the end of root. */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -10928,10 +10934,10 @@
"TextPosition anchor_id=1 text_offset=7 "
"affinity=upstream annotated_text=Line 1\n<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
TEXT_FIELD_ID,
12 /* text_offset one before the end of text field */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -10939,10 +10945,10 @@
"TextPosition anchor_id=4 text_offset=7 "
"affinity=upstream annotated_text=Line 1\n<L>ine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX1_ID,
2 /* text_offset */,
{"TextPosition anchor_id=3 text_offset=0 "
@@ -10950,10 +10956,10 @@
"TextPosition anchor_id=3 text_offset=0 "
"affinity=downstream annotated_text=<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=7 text_offset=1 "
@@ -10961,10 +10967,10 @@
"TextPosition anchor_id=7 text_offset=1 "
"affinity=downstream annotated_text=\n<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
INLINE_BOX2_ID,
0 /* text_offset */,
{"TextPosition anchor_id=7 text_offset=1 "
@@ -10972,10 +10978,10 @@
"TextPosition anchor_id=7 text_offset=1 "
"affinity=downstream annotated_text=\n<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
LINE_BREAK_ID,
0 /* text_offset */,
{"TextPosition anchor_id=3 text_offset=0 "
@@ -10983,10 +10989,10 @@
"TextPosition anchor_id=3 text_offset=0 "
"affinity=downstream annotated_text=<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- }),
+ },
LINE_BREAK_ID,
1 /* text_offset */,
{"TextPosition anchor_id=7 text_offset=1 "
@@ -10999,10 +11005,10 @@
AXPositionTextNavigationTestWithParam,
testing::Values(
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
13 /* text_offset at end of root. */,
{"TextPosition anchor_id=1 text_offset=7 "
@@ -11012,10 +11018,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
13 /* text_offset at end of text field */,
{"TextPosition anchor_id=4 text_offset=7 "
@@ -11025,10 +11031,10 @@
"TextPosition anchor_id=3 text_offset=0 "
"affinity=downstream annotated_text=<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
ROOT_ID,
5 /* text_offset on the last character of "Line 1". */,
{"TextPosition anchor_id=1 text_offset=0 "
@@ -11036,10 +11042,10 @@
"TextPosition anchor_id=1 text_offset=0 "
"affinity=downstream annotated_text=<L>ine 1\nLine 2"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
TEXT_FIELD_ID,
5 /* text_offset on the last character of "Line 1". */,
{"TextPosition anchor_id=3 text_offset=0 "
@@ -11047,10 +11053,10 @@
"TextPosition anchor_id=3 text_offset=0 "
"affinity=downstream annotated_text=<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
4 /* text_offset */,
{"TextPosition anchor_id=7 text_offset=1 "
@@ -11060,10 +11066,10 @@
"TextPosition anchor_id=3 text_offset=0 "
"affinity=downstream annotated_text=<>"}},
TextNavigationTestParam{
- base::BindRepeating([](const TestPositionType& position) {
+ [](const TestPositionType& position) {
return position->CreatePreviousParagraphEndPosition(
AXBoundaryBehavior::StopAtLastAnchorBoundary);
- }),
+ },
INLINE_BOX2_ID,
0 /* text_offset */,
{"TextPosition anchor_id=3 text_offset=0 "
diff --git a/third_party/accessibility/ax/ax_node_text_styles.cc b/third_party/accessibility/ax/ax_node_text_styles.cc
index 516832c..cf46b1f 100644
--- a/third_party/accessibility/ax/ax_node_text_styles.cc
+++ b/third_party/accessibility/ax/ax_node_text_styles.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_node_text_styles.h"
+#include "ax_node_text_styles.h"
constexpr int kUnsetValue = -1;
diff --git a/third_party/accessibility/ax/ax_node_text_styles.h b/third_party/accessibility/ax/ax_node_text_styles.h
index 2dd98a9..d37b426 100644
--- a/third_party/accessibility/ax/ax_node_text_styles.h
+++ b/third_party/accessibility/ax/ax_node_text_styles.h
@@ -7,7 +7,7 @@
#include <string>
-#include "ui/accessibility/ax_base_export.h"
+#include "ax_base_export.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_param_traits.cc b/third_party/accessibility/ax/ax_param_traits.cc
deleted file mode 100644
index d7b19f7..0000000
--- a/third_party/accessibility/ax/ax_param_traits.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_param_traits.h"
-
-namespace IPC {
-
-void ParamTraits<ui::AXTreeID>::Write(base::Pickle* m, const param_type& p) {
- WriteParam(m, p.ToString());
-}
-
-bool ParamTraits<ui::AXTreeID>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- std::string value;
- if (!ReadParam(m, iter, &value))
- return false;
- *r = ui::AXTreeID::FromString(value);
- return true;
-}
-
-void ParamTraits<ui::AXTreeID>::Log(const param_type& p, std::string* l) {
- l->append("<ui::AXTreeID>");
-}
-
-} // namespace IPC
-
-// Generate param traits write methods.
-#include "ipc/param_traits_write_macros.h"
-namespace IPC {
-#undef UI_ACCESSIBILITY_AX_PARAM_TRAITS_MACROS_H_
-#include "ui/accessibility/ax_param_traits_macros.h"
-} // namespace IPC
-
-// Generate param traits read methods.
-#include "ipc/param_traits_read_macros.h"
-namespace IPC {
-#undef UI_ACCESSIBILITY_AX_PARAM_TRAITS_MACROS_H_
-#include "ui/accessibility/ax_param_traits_macros.h"
-} // namespace IPC
-
-// Generate param traits log methods.
-#include "ipc/param_traits_log_macros.h"
-namespace IPC {
-#undef UI_ACCESSIBILITY_AX_PARAM_TRAITS_MACROS_H_
-#include "ui/accessibility/ax_param_traits_macros.h"
-} // namespace IPC
diff --git a/third_party/accessibility/ax/ax_param_traits.h b/third_party/accessibility/ax/ax_param_traits.h
deleted file mode 100644
index 2b61486..0000000
--- a/third_party/accessibility/ax/ax_param_traits.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_PARAM_TRAITS_H_
-#define UI_ACCESSIBILITY_AX_PARAM_TRAITS_H_
-
-#include "ui/accessibility/ax_param_traits_macros.h"
-
-namespace IPC {
-
-template <>
-struct AX_EXPORT ParamTraits<ui::AXTreeID> {
- typedef ui::AXTreeID param_type;
- static void Write(base::Pickle* m, const param_type& p);
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-} // namespace IPC
-
-#endif // UI_ACCESSIBILITY_AX_PARAM_TRAITS_H_
diff --git a/third_party/accessibility/ax/ax_param_traits_macros.h b/third_party/accessibility/ax/ax_param_traits_macros.h
deleted file mode 100644
index 75e5b14..0000000
--- a/third_party/accessibility/ax/ax_param_traits_macros.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_PARAM_TRAITS_MACROS_H_
-#define UI_ACCESSIBILITY_AX_PARAM_TRAITS_MACROS_H_
-
-#include "build/build_config.h"
-#include "ipc/ipc_message_macros.h"
-#include "ui/accessibility/ax_enums.mojom-shared.h"
-#include "ui/accessibility/ax_event.h"
-#include "ui/accessibility/ax_event_intent.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/accessibility/ax_tree_update.h"
-#include "ui/gfx/ipc/geometry/gfx_param_traits.h"
-#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
-
-#undef IPC_MESSAGE_EXPORT
-#define IPC_MESSAGE_EXPORT AX_EXPORT
-
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::Event, ax::mojom::Event::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::Role, ax::mojom::Role::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::BoolAttribute,
- ax::mojom::BoolAttribute::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::FloatAttribute,
- ax::mojom::FloatAttribute::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::IntAttribute,
- ax::mojom::IntAttribute::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::IntListAttribute,
- ax::mojom::IntListAttribute::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::StringListAttribute,
- ax::mojom::StringListAttribute::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::StringAttribute,
- ax::mojom::StringAttribute::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::TextAffinity,
- ax::mojom::TextAffinity::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::EventFrom, ax::mojom::EventFrom::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::Command, ax::mojom::Command::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::TextBoundary,
- ax::mojom::TextBoundary::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(ax::mojom::MoveDirection,
- ax::mojom::MoveDirection::kMaxValue)
-
-IPC_STRUCT_TRAITS_BEGIN(ui::AXRelativeBounds)
-IPC_STRUCT_TRAITS_MEMBER(offset_container_id)
-IPC_STRUCT_TRAITS_MEMBER(bounds)
-IPC_STRUCT_TRAITS_MEMBER(transform)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(ui::AXEvent)
-IPC_STRUCT_TRAITS_MEMBER(event_type)
-IPC_STRUCT_TRAITS_MEMBER(id)
-IPC_STRUCT_TRAITS_MEMBER(event_from)
-IPC_STRUCT_TRAITS_MEMBER(event_intents)
-IPC_STRUCT_TRAITS_MEMBER(action_request_id)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(ui::AXEventIntent)
-IPC_STRUCT_TRAITS_MEMBER(command)
-IPC_STRUCT_TRAITS_MEMBER(text_boundary)
-IPC_STRUCT_TRAITS_MEMBER(move_direction)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(ui::AXNodeData)
-IPC_STRUCT_TRAITS_MEMBER(id)
-IPC_STRUCT_TRAITS_MEMBER(role)
-IPC_STRUCT_TRAITS_MEMBER(state)
-IPC_STRUCT_TRAITS_MEMBER(actions)
-IPC_STRUCT_TRAITS_MEMBER(string_attributes)
-IPC_STRUCT_TRAITS_MEMBER(int_attributes)
-IPC_STRUCT_TRAITS_MEMBER(float_attributes)
-IPC_STRUCT_TRAITS_MEMBER(bool_attributes)
-IPC_STRUCT_TRAITS_MEMBER(intlist_attributes)
-IPC_STRUCT_TRAITS_MEMBER(stringlist_attributes)
-IPC_STRUCT_TRAITS_MEMBER(html_attributes)
-IPC_STRUCT_TRAITS_MEMBER(child_ids)
-IPC_STRUCT_TRAITS_MEMBER(relative_bounds)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(ui::AXTreeData)
-IPC_STRUCT_TRAITS_MEMBER(tree_id)
-IPC_STRUCT_TRAITS_MEMBER(parent_tree_id)
-IPC_STRUCT_TRAITS_MEMBER(focused_tree_id)
-IPC_STRUCT_TRAITS_MEMBER(url)
-IPC_STRUCT_TRAITS_MEMBER(title)
-IPC_STRUCT_TRAITS_MEMBER(mimetype)
-IPC_STRUCT_TRAITS_MEMBER(doctype)
-IPC_STRUCT_TRAITS_MEMBER(loaded)
-IPC_STRUCT_TRAITS_MEMBER(loading_progress)
-IPC_STRUCT_TRAITS_MEMBER(focus_id)
-IPC_STRUCT_TRAITS_MEMBER(sel_is_backward)
-IPC_STRUCT_TRAITS_MEMBER(sel_anchor_object_id)
-IPC_STRUCT_TRAITS_MEMBER(sel_anchor_offset)
-IPC_STRUCT_TRAITS_MEMBER(sel_anchor_affinity)
-IPC_STRUCT_TRAITS_MEMBER(sel_focus_object_id)
-IPC_STRUCT_TRAITS_MEMBER(sel_focus_offset)
-IPC_STRUCT_TRAITS_MEMBER(sel_focus_affinity)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(ui::AXTreeUpdate)
-IPC_STRUCT_TRAITS_MEMBER(has_tree_data)
-IPC_STRUCT_TRAITS_MEMBER(tree_data)
-IPC_STRUCT_TRAITS_MEMBER(node_id_to_clear)
-IPC_STRUCT_TRAITS_MEMBER(root_id)
-IPC_STRUCT_TRAITS_MEMBER(nodes)
-IPC_STRUCT_TRAITS_MEMBER(event_from)
-IPC_STRUCT_TRAITS_MEMBER(event_intents)
-IPC_STRUCT_TRAITS_END()
-
-#undef IPC_MESSAGE_EXPORT
-#define IPC_MESSAGE_EXPORT
-
-#endif // UI_ACCESSIBILITY_AX_PARAM_TRAITS_MACROS_H_
diff --git a/third_party/accessibility/ax/ax_position.h b/third_party/accessibility/ax/ax_position.h
index b47a077..c38eec4 100644
--- a/third_party/accessibility/ax/ax_position.h
+++ b/third_party/accessibility/ax/ax_position.h
@@ -7,29 +7,24 @@
#include <math.h>
#include <stdint.h>
-
#include <functional>
#include <memory>
#include <ostream>
+#include <stack>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
-#include "base/containers/stack.h"
-#include "base/i18n/break_iterator.h"
-#include "base/optional.h"
-#include "base/stl_util.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_enum_util.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_node_text_styles.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/gfx/utf16_indexing.h"
+#include "ax_enum_util.h"
+#include "ax_enums.h"
+#include "ax_node.h"
+#include "ax_node_text_styles.h"
+#include "ax_role_properties.h"
+#include "ax_tree_id.h"
+#include "base/container_utils.h"
+#include "base/logging.h"
+#include "base/string_utils.h"
namespace ui {
@@ -159,11 +154,10 @@
using AXRangeType = AXRange<AXPosition<AXPositionType, AXNodeType>>;
- using BoundaryConditionPredicate =
- base::RepeatingCallback<bool(const AXPositionInstance&)>;
+ typedef bool BoundaryConditionPredicate(const AXPositionInstance&);
- using BoundaryTextOffsetsFunc =
- base::RepeatingCallback<std::vector<int32_t>(const AXPositionInstance&)>;
+ typedef std::vector<int32_t> BoundaryTextOffsetsFunc(
+ const AXPositionInstance&);
static const int BEFORE_TEXT = -1;
static const int INVALID_INDEX = -2;
@@ -174,7 +168,7 @@
//
// Duplicate of AXPlatformNodeBase::kEmbeddedCharacter because we don't want
// to include platform specific code in here.
- static constexpr base::char16 kEmbeddedCharacter = L'\xfffc';
+ static constexpr char16_t kEmbeddedCharacter = L'\xfffc';
static AXPositionInstance CreateNullPosition() {
AXPositionInstance new_position(new AXPositionType());
@@ -237,7 +231,7 @@
// A tree ID can be serialized as a 32-byte string.
std::string tree_id_string = tree_id_.ToString();
- DCHECK_LE(tree_id_string.size(), 32U);
+ BASE_DCHECK(tree_id_string.size() <= 32U);
strncpy(result.tree_id, tree_id_string.c_str(), 32);
result.tree_id[32] = 0;
@@ -294,19 +288,18 @@
if (!IsTextPosition() || text_offset_ > MaxTextOffset())
return str;
- base::string16 text = GetText();
- DCHECK_GE(text_offset_, 0);
+ std::u16string text = GetText();
+ BASE_DCHECK(text_offset_ >= 0);
int max_text_offset = MaxTextOffset();
- DCHECK_LE(text_offset_, max_text_offset);
- base::string16 annotated_text;
+ BASE_DCHECK(text_offset_ <= max_text_offset);
+ std::u16string annotated_text;
if (text_offset_ == max_text_offset) {
- annotated_text = text + base::WideToUTF16(L"<>");
+ annotated_text = text + u"<>";
} else {
- annotated_text = text.substr(0, text_offset_) + base::WideToUTF16(L"<") +
- text[text_offset_] + base::WideToUTF16(L">") +
+ annotated_text = text.substr(0, text_offset_) + u"<" +
+ text[text_offset_] + u">" +
text.substr(text_offset_ + 1);
}
-
return str + " annotated_text=" + base::UTF16ToUTF8(annotated_text);
}
@@ -328,7 +321,7 @@
if (IsNullPosition())
return false;
- DCHECK(GetAnchor());
+ BASE_DCHECK(GetAnchor());
// If this position is anchored to an ignored node, then consider this
// position to be ignored.
if (GetAnchor()->IsIgnored())
@@ -336,13 +329,14 @@
switch (kind_) {
case AXPositionKind::NULL_POSITION:
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
case AXPositionKind::TREE_POSITION: {
// If this is a "before text" or an "after text" tree position, it's
// pointing to the anchor itself, which we've determined to be
// unignored.
- DCHECK(!IsLeaf() || child_index_ == BEFORE_TEXT || child_index_ == 0)
+ BASE_DCHECK(!IsLeaf() || child_index_ == BEFORE_TEXT ||
+ child_index_ == 0)
<< "\"Before text\" and \"after text\" tree positions are only "
"valid on leaf nodes.";
if (child_index_ == BEFORE_TEXT || IsLeaf())
@@ -371,7 +365,7 @@
: child_index_ - 1;
AXPositionInstance child_position =
CreateChildPositionAt(adjusted_child_index);
- DCHECK(child_position && !child_position->IsNullPosition());
+ BASE_DCHECK(child_position && !child_position->IsNullPosition());
return child_position->GetAnchor()->IsIgnored();
}
case AXPositionKind::TEXT_POSITION:
@@ -473,7 +467,7 @@
case AXPositionKind::NULL_POSITION:
return false;
case AXPositionKind::TREE_POSITION:
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
case AXPositionKind::TEXT_POSITION: {
const std::vector<int32_t> word_starts =
@@ -490,7 +484,7 @@
case AXPositionKind::NULL_POSITION:
return false;
case AXPositionKind::TREE_POSITION:
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
case AXPositionKind::TEXT_POSITION: {
const std::vector<int32_t> word_ends =
@@ -506,7 +500,7 @@
case AXPositionKind::NULL_POSITION:
return false;
case AXPositionKind::TREE_POSITION:
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
case AXPositionKind::TEXT_POSITION:
// We treat a position after some white space that is not connected to
@@ -552,7 +546,7 @@
case AXPositionKind::NULL_POSITION:
return false;
case AXPositionKind::TREE_POSITION:
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
case AXPositionKind::TEXT_POSITION:
// Text positions on objects with no text should not be considered at
@@ -635,7 +629,7 @@
case AXPositionKind::NULL_POSITION:
return false;
case AXPositionKind::TREE_POSITION:
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
case AXPositionKind::TEXT_POSITION: {
// 1. The current leaf text position must be an unignored position at
@@ -662,9 +656,14 @@
// This will return a null position when an anchor movement would
// cross a paragraph boundary, or the start of document was reached.
bool crossed_line_breaking_object_token = false;
- const AbortMovePredicate abort_move_predicate =
- base::BindRepeating(&AbortMoveAtParagraphBoundary,
- std::ref(crossed_line_breaking_object_token));
+ auto abort_move_predicate =
+ [&crossed_line_breaking_object_token](
+ const AXPosition& move_from, const AXPosition& move_to,
+ const AXMoveType type, const AXMoveDirection direction) {
+ return AbortMoveAtParagraphBoundary(
+ crossed_line_breaking_object_token, move_from, move_to, type,
+ direction);
+ };
AXPositionInstance previous_text_position = text_position->Clone();
do {
@@ -709,7 +708,7 @@
case AXPositionKind::NULL_POSITION:
return false;
case AXPositionKind::TREE_POSITION:
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
case AXPositionKind::TEXT_POSITION: {
// 1. The current leaf text position must be an unignored position at
@@ -734,9 +733,14 @@
// There are some fringe cases related to whitespace collapse that
// cannot be handled easily with only |AbortMoveAtParagraphBoundary|.
bool crossed_line_breaking_object_token = false;
- const AbortMovePredicate abort_move_predicate =
- base::BindRepeating(&AbortMoveAtParagraphBoundary,
- std::ref(crossed_line_breaking_object_token));
+ auto abort_move_predicate =
+ [&crossed_line_breaking_object_token](
+ const AXPosition& move_from, const AXPosition& move_to,
+ const AXMoveType type, const AXMoveDirection direction) {
+ return AbortMoveAtParagraphBoundary(
+ crossed_line_breaking_object_token, move_from, move_to, type,
+ direction);
+ };
AXPositionInstance next_text_position = text_position->Clone();
do {
@@ -777,7 +781,7 @@
case AXPositionKind::NULL_POSITION:
return false;
case AXPositionKind::TREE_POSITION:
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
case AXPositionKind::TEXT_POSITION: {
if (!text_position->AtStartOfAnchor())
@@ -791,7 +795,7 @@
// cross a page boundary, or the start of document was reached.
AXPositionInstance previous_text_position =
text_position->CreatePreviousTextAnchorPosition(
- base::BindRepeating(&AbortMoveAtPageBoundary));
+ AbortMoveAtPageBoundary);
return previous_text_position->IsNullPosition();
}
}
@@ -803,7 +807,7 @@
case AXPositionKind::NULL_POSITION:
return false;
case AXPositionKind::TREE_POSITION:
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
case AXPositionKind::TEXT_POSITION: {
if (!text_position->AtEndOfAnchor())
@@ -817,7 +821,7 @@
// cross a page boundary, or the end of document was reached.
AXPositionInstance next_text_position =
text_position->CreateNextTextAnchorPosition(
- base::BindRepeating(&AbortMoveAtPageBoundary));
+ AbortMoveAtPageBoundary);
return next_text_position->IsNullPosition();
}
}
@@ -875,7 +879,7 @@
AXPositionInstance previous_position = Clone();
do {
previous_position = previous_position->CreatePreviousLeafTreePosition(
- base::BindRepeating(&AbortMoveAtFormatBoundary));
+ AbortMoveAtFormatBoundary);
} while (previous_position->IsIgnored());
if (previous_position->IsNullPosition())
@@ -907,8 +911,8 @@
// not on an ignored node.
AXPositionInstance next_position = Clone();
do {
- next_position = next_position->CreateNextLeafTreePosition(
- base::BindRepeating(&AbortMoveAtFormatBoundary));
+ next_position =
+ next_position->CreateNextLeafTreePosition(AbortMoveAtFormatBoundary);
} while (next_position->IsIgnored());
if (next_position->IsNullPosition())
@@ -927,7 +931,7 @@
case AXPositionKind::NULL_POSITION:
return false;
case AXPositionKind::TREE_POSITION:
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
case AXPositionKind::TEXT_POSITION: {
if (text_position->AtStartOfAnchor()) {
@@ -937,7 +941,7 @@
// Check that this position is not the start of the first anchor.
if (!previous_position->IsNullPosition()) {
previous_position = text_position->CreatePreviousLeafTreePosition(
- base::BindRepeating(&AbortMoveAtStartOfInlineBlock));
+ &AbortMoveAtStartOfInlineBlock);
// If we get a null position here it means we have crossed an inline
// block's start, thus this position is located at such start.
@@ -952,7 +956,7 @@
// Check that this position is not the end of the last anchor.
if (!next_position->IsNullPosition()) {
next_position = text_position->CreateNextLeafTreePosition(
- base::BindRepeating(&AbortMoveAtStartOfInlineBlock));
+ &AbortMoveAtStartOfInlineBlock);
// If we get a null position here it means we have crossed an inline
// block's start, thus this position is located at such start.
@@ -996,8 +1000,8 @@
if (GetAnchor() == second.GetAnchor())
return GetAnchor();
- base::stack<AXNodeType*> our_ancestors = GetAncestorAnchors();
- base::stack<AXNodeType*> other_ancestors = second.GetAncestorAnchors();
+ std::stack<AXNodeType*> our_ancestors = GetAncestorAnchors();
+ std::stack<AXNodeType*> other_ancestors = second.GetAncestorAnchors();
AXNodeType* common_anchor = nullptr;
while (!our_ancestors.empty() && !other_ancestors.empty() &&
@@ -1105,7 +1109,7 @@
break;
}
}
- DCHECK(position->IsValid());
+ BASE_DCHECK(position->IsValid());
return position;
}
@@ -1114,8 +1118,8 @@
return Clone();
AXPositionInstance copy = Clone();
- DCHECK(copy);
- DCHECK_GE(copy->text_offset_, 0);
+ BASE_DCHECK(copy);
+ BASE_DCHECK(copy->text_offset_ >= 0);
if (copy->IsLeaf()) {
const int max_text_offset = copy->MaxTextOffset();
copy->child_index_ =
@@ -1137,7 +1141,7 @@
int child_index = 0;
for (; child_index < copy->AnchorChildCount(); ++child_index) {
AXPositionInstance child = copy->CreateChildPositionAt(child_index);
- DCHECK(child);
+ BASE_DCHECK(child);
int child_length = child->MaxTextOffsetInParent();
// If the text offset falls on the boundary between two adjacent children,
// we look at the affinity to decide whether to place the tree position on
@@ -1204,10 +1208,10 @@
tree_position =
tree_position->CreateChildPositionAt(tree_position->child_index_);
}
- DCHECK(tree_position && !tree_position->IsNullPosition());
+ BASE_DCHECK(tree_position && !tree_position->IsNullPosition());
} while (!tree_position->IsLeaf());
- DCHECK(tree_position && tree_position->IsLeafTreePosition());
+ BASE_DCHECK(tree_position && tree_position->IsLeafTreePosition());
return tree_position;
}
@@ -1216,19 +1220,18 @@
return Clone();
AXPositionInstance copy = Clone();
- DCHECK(copy);
+ BASE_DCHECK(copy);
// Check if it is a "before text" position.
if (copy->child_index_ == BEFORE_TEXT) {
// "Before text" positions can only appear on leaf nodes.
- DCHECK(copy->IsLeaf());
+ BASE_DCHECK(copy->IsLeaf());
// If the current text offset is valid, we don't touch it to potentially
// allow converting from a text position to a tree position and back
// without losing information.
//
// We test for INVALID_OFFSET first, due to the possible performance
// implications of calling MaxTextOffset().
- DCHECK_GE(copy->text_offset_, INVALID_OFFSET)
- << "Unrecognized text offset.";
+ BASE_DCHECK(copy->text_offset_ >= INVALID_OFFSET);
if (copy->text_offset_ == INVALID_OFFSET ||
(copy->text_offset_ > 0 &&
copy->text_offset_ >= copy->MaxTextOffset())) {
@@ -1237,12 +1240,12 @@
} else if (copy->child_index_ == copy->AnchorChildCount()) {
copy->text_offset_ = copy->MaxTextOffset();
} else {
- DCHECK_GE(copy->child_index_, 0);
- DCHECK_LT(copy->child_index_, copy->AnchorChildCount());
+ BASE_DCHECK(copy->child_index_ >= 0);
+ BASE_DCHECK(copy->child_index_ < copy->AnchorChildCount());
int new_offset = 0;
for (int i = 0; i <= child_index_; ++i) {
AXPositionInstance child = copy->CreateChildPositionAt(i);
- DCHECK(child);
+ BASE_DCHECK(child);
// If the current text offset is valid, we don't touch it to
// potentially allow converting from a text position to a tree
// position and back without losing information. Otherwise, if the
@@ -1293,7 +1296,7 @@
do {
AXPositionInstance child_position =
text_position->CreateChildPositionAt(0);
- DCHECK(child_position);
+ BASE_DCHECK(child_position);
// If the text offset corresponds to multiple child positions because some
// of the children have empty text, the condition "adjusted_offset > 0"
@@ -1320,8 +1323,8 @@
text_position = std::move(child_position);
} while (!text_position->IsLeaf());
- DCHECK(text_position);
- DCHECK(text_position->IsLeafTextPosition());
+ BASE_DCHECK(text_position);
+ BASE_DCHECK(text_position->IsLeafTextPosition());
text_position->text_offset_ = adjusted_offset;
// A leaf Text position is always downstream since there is no ambiguity as
// to whether it refers to the end of the current or the start of the next
@@ -1372,7 +1375,7 @@
// Since the equivalent leaf tree position is unignored, search for the
// first unignored ancestor anchor and return that text position.
if (!unignored_position->GetAnchor()->IsIgnored()) {
- DCHECK(!unignored_position->IsIgnored());
+ BASE_DCHECK(!unignored_position->IsIgnored());
return unignored_position;
}
unignored_position = unignored_position->CreateParentPosition();
@@ -1607,21 +1610,27 @@
break;
case ax::mojom::TextBoundary::kSentenceEnd:
- NOTREACHED() << "Sentence boundaries are not yet supported.";
+ BASE_LOG() << "Sentence boundaries are not yet supported.";
+ BASE_UNREACHABLE();
return CreateNullPosition();
case ax::mojom::TextBoundary::kSentenceStart:
- NOTREACHED() << "Sentence boundaries are not yet supported.";
+ BASE_LOG() << "Sentence boundaries are not yet supported.";
+ BASE_UNREACHABLE();
return CreateNullPosition();
case ax::mojom::TextBoundary::kSentenceStartOrEnd:
- NOTREACHED() << "Sentence boundaries are not yet supported.";
+ BASE_LOG() << "Sentence boundaries are not yet supported.";
+ BASE_UNREACHABLE();
return CreateNullPosition();
case ax::mojom::TextBoundary::kWebPage:
- DCHECK_EQ(boundary_behavior, AXBoundaryBehavior::CrossBoundary)
- << "We can't reach the start of the document if we are disallowed "
- "from crossing boundaries.";
+ if (boundary_behavior != AXBoundaryBehavior::CrossBoundary) {
+ BASE_LOG() << "We can't reach the start of the document if we "
+ "are disallowed "
+ "from crossing boundaries.";
+ BASE_UNREACHABLE();
+ }
switch (direction) {
case ax::mojom::MoveDirection::kBackward:
resulting_position = CreatePositionAtStartOfDocument();
@@ -1717,7 +1726,7 @@
} while (!previous_position->AtStartOfAXTree());
// This method should not cross tree boundaries.
- DCHECK_EQ(previous_position->tree_id(), tree_id());
+ BASE_DCHECK(previous_position->tree_id() == tree_id());
if (IsTextPosition())
previous_position = previous_position->AsTextPosition();
@@ -1741,7 +1750,7 @@
} while (!next_position->AtEndOfAXTree());
// This method should not cross tree boundaries.
- DCHECK_EQ(next_position->tree_id(), tree_id());
+ BASE_DCHECK(next_position->tree_id() == tree_id());
if (IsTextPosition())
next_position = next_position->AsTextPosition();
@@ -1803,11 +1812,11 @@
AXTreeID tree_id = AXTreeIDUnknown();
AXNode::AXID child_id = AXNode::kInvalidAXID;
AnchorChild(child_index, &tree_id, &child_id);
- DCHECK_NE(tree_id, AXTreeIDUnknown());
- DCHECK_NE(child_id, AXNode::kInvalidAXID);
+ BASE_DCHECK(tree_id != AXTreeIDUnknown());
+ BASE_DCHECK(child_id != AXNode::kInvalidAXID);
switch (kind_) {
case AXPositionKind::NULL_POSITION:
- NOTREACHED();
+ BASE_UNREACHABLE();
return CreateNullPosition();
case AXPositionKind::TREE_POSITION: {
AXPositionInstance child_position =
@@ -1861,7 +1870,7 @@
switch (kind_) {
case AXPositionKind::NULL_POSITION:
- NOTREACHED();
+ BASE_UNREACHABLE();
return CreateNullPosition();
case AXPositionKind::TREE_POSITION:
return CreateTreePosition(tree_id, parent_id, AnchorIndexInParent());
@@ -1960,15 +1969,13 @@
// Creates a tree position using the next text-only node as its anchor.
// Assumes that text-only nodes are leaf nodes.
AXPositionInstance CreateNextLeafTreePosition() const {
- return CreateNextLeafTreePosition(
- base::BindRepeating(&DefaultAbortMovePredicate));
+ return CreateNextLeafTreePosition(&DefaultAbortMovePredicate);
}
// Creates a tree position using the previous text-only node as its anchor.
// Assumes that text-only nodes are leaf nodes.
AXPositionInstance CreatePreviousLeafTreePosition() const {
- return CreatePreviousLeafTreePosition(
- base::BindRepeating(&DefaultAbortMovePredicate));
+ return CreatePreviousLeafTreePosition(&DefaultAbortMovePredicate);
}
// Creates the next text position anchored at a leaf node of the AXTree.
@@ -1984,20 +1991,31 @@
// If this is an ancestor text position, resolve to its leaf text position.
if (IsTextPosition() && !IsLeaf())
return AsLeafTextPosition();
-
- AbortMovePredicate abort_move_predicate =
- crossed_line_breaking_object
- ? base::BindRepeating(&UpdateCrossedLineBreakingObjectToken,
- std::ref(*crossed_line_breaking_object))
- : base::BindRepeating(&DefaultAbortMovePredicate);
+ std::function<AbortMovePredicate> abort_move_predicate;
+ if (crossed_line_breaking_object) {
+ abort_move_predicate = [crossed_line_breaking_object](
+ const AXPosition& move_from,
+ const AXPosition& move_to,
+ const AXMoveType type,
+ const AXMoveDirection direction) {
+ return UpdateCrossedLineBreakingObjectToken(
+ *crossed_line_breaking_object, move_from, move_to, type, direction);
+ };
+ } else {
+ abort_move_predicate =
+ [](const AXPosition& move_from, const AXPosition& move_to,
+ const AXMoveType type, const AXMoveDirection direction) {
+ return AXPosition::DefaultAbortMovePredicate(move_from, move_to,
+ type, direction);
+ };
+ }
return CreateNextLeafTreePosition(abort_move_predicate)->AsTextPosition();
}
// Creates a text position using the previous text-only node as its anchor.
// Assumes that text-only nodes are leaf nodes.
AXPositionInstance CreatePreviousLeafTextPosition() const {
- return CreatePreviousTextAnchorPosition(
- base::BindRepeating(&DefaultAbortMovePredicate));
+ return CreatePreviousTextAnchorPosition(DefaultAbortMovePredicate);
}
// Returns a text position located right before the next character (from this
@@ -2036,27 +2054,13 @@
// position will always be "before character".
text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
text_position = text_position->AsLeafTextPosition();
- DCHECK(!text_position->IsNullPosition())
+ BASE_DCHECK(!text_position->IsNullPosition())
<< "Adjusting to a leaf position should never turn a non-null position "
"into a null one.";
-
if (!text_position->IsIgnored() && !text_position->AtEndOfAnchor()) {
- std::unique_ptr<base::i18n::BreakIterator> grapheme_iterator =
- text_position->GetGraphemeIterator();
- DCHECK_GE(text_position->text_offset_, 0);
- DCHECK_LE(text_position->text_offset_,
- int{text_position->name_.length()});
- while (
- !text_position->AtStartOfAnchor() &&
- (!gfx::IsValidCodePointIndex(text_position->name_,
- size_t{text_position->text_offset_}) ||
- (grapheme_iterator && !grapheme_iterator->IsGraphemeBoundary(
- size_t{text_position->text_offset_})))) {
- --text_position->text_offset_;
- }
+ BASE_DCHECK(text_position->text_offset_ >= 0);
return text_position;
}
-
text_position = text_position->CreateNextLeafTextPosition();
while (!text_position->IsNullPosition() &&
(text_position->IsIgnored() || !text_position->MaxTextOffset())) {
@@ -2083,39 +2087,23 @@
// position will always be "after character".
text_position->affinity_ = ax::mojom::TextAffinity::kUpstream;
text_position = text_position->AsLeafTextPosition();
- DCHECK(!text_position->IsNullPosition())
+ BASE_DCHECK(!text_position->IsNullPosition())
<< "Adjusting to a leaf position should never turn a non-null position "
"into a null one.";
-
if (!text_position->IsIgnored() && !text_position->AtStartOfAnchor()) {
- std::unique_ptr<base::i18n::BreakIterator> grapheme_iterator =
- text_position->GetGraphemeIterator();
// The following situation should not be possible but there are existing
// crashes in the field.
//
// TODO(nektar): Remove this workaround as soon as the source of the bug
// is identified.
- if (text_position->text_offset_ > int{text_position->name_.length()})
- return CreateNullPosition();
-
- DCHECK_GE(text_position->text_offset_, 0);
- DCHECK_LE(text_position->text_offset_,
- int{text_position->name_.length()});
- while (
- !text_position->AtEndOfAnchor() &&
- (!gfx::IsValidCodePointIndex(text_position->name_,
- size_t{text_position->text_offset_}) ||
- (grapheme_iterator && !grapheme_iterator->IsGraphemeBoundary(
- size_t{text_position->text_offset_})))) {
- ++text_position->text_offset_;
- }
+ BASE_DCHECK(text_position->text_offset_ >= 0);
+ // TODO(chunhtai): handles grapheme.
// Reset the affinity to downstream, because an upstream affinity doesn't
// make sense on a leaf anchor.
text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
return text_position;
}
-
text_position = text_position->CreatePreviousLeafTextPosition();
while (!text_position->IsNullPosition() &&
(text_position->IsIgnored() || !text_position->MaxTextOffset())) {
@@ -2154,18 +2142,11 @@
*text_position == *this) {
return Clone();
}
-
- DCHECK_LT(text_position->text_offset_, text_position->MaxTextOffset());
- std::unique_ptr<base::i18n::BreakIterator> grapheme_iterator =
- text_position->GetGraphemeIterator();
- do {
- ++text_position->text_offset_;
- } while (!text_position->AtEndOfAnchor() && grapheme_iterator &&
- !grapheme_iterator->IsGraphemeBoundary(
- size_t{text_position->text_offset_}));
- DCHECK_GT(text_position->text_offset_, 0);
- DCHECK_LE(text_position->text_offset_, text_position->MaxTextOffset());
-
+ BASE_DCHECK(text_position->text_offset_ < text_position->MaxTextOffset());
+ // TODO(chunhtai): Need to consider grapheme cluster.
+ ++text_position->text_offset_;
+ BASE_DCHECK(text_position->text_offset_ > 0);
+ BASE_DCHECK(text_position->text_offset_ <= text_position->MaxTextOffset());
// If the character boundary is in the same subtree, return a position
// rooted at this position's anchor. This is necessary because we don't want
// to return a position that might be in the shadow DOM when this position
@@ -2179,12 +2160,10 @@
// with StopAtAnchorBoundary, snap to the end of the current anchor.
return CreatePositionAtEndOfAnchor();
}
-
// Even if the resulting position is right on a soft line break, affinity is
// defaulted to downstream so that this method will always produce the same
// result regardless of the direction of motion or the input affinity.
text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
-
if (IsTreePosition())
return text_position->AsTreePosition();
return text_position;
@@ -2217,18 +2196,11 @@
*text_position == *this) {
return Clone();
}
-
- DCHECK_GT(text_position->text_offset_, 0);
- std::unique_ptr<base::i18n::BreakIterator> grapheme_iterator =
- text_position->GetGraphemeIterator();
- do {
- --text_position->text_offset_;
- } while (!text_position->AtStartOfAnchor() && grapheme_iterator &&
- !grapheme_iterator->IsGraphemeBoundary(
- size_t{text_position->text_offset_}));
- DCHECK_GE(text_position->text_offset_, 0);
- DCHECK_LT(text_position->text_offset_, text_position->MaxTextOffset());
-
+ BASE_DCHECK(text_position->text_offset_ > 0);
+ // TODO(chunhtai): Need to consider grapheme cluster.
+ --text_position->text_offset_;
+ BASE_DCHECK(text_position->text_offset_ >= 0);
+ BASE_DCHECK(text_position->text_offset_ < text_position->MaxTextOffset());
// The character boundary should be in the same subtree. Return a position
// rooted at this position's anchor. This is necessary because we don't want
// to return a position that might be in the shadow DOM when this position
@@ -2242,12 +2214,10 @@
// with StopAtAnchorBoundary, snap to the start of the current anchor.
return CreatePositionAtStartOfAnchor();
}
-
// Even if the resulting position is right on a soft line break, affinity is
// defaulted to downstream so that this method will always produce the same
// result regardless of the direction of motion or the input affinity.
text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
-
if (IsTreePosition())
return text_position->AsTreePosition();
return text_position;
@@ -2257,18 +2227,16 @@
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryStartPosition(
boundary_behavior, ax::mojom::MoveDirection::kForward,
- base::BindRepeating(&AtStartOfWordPredicate),
- base::BindRepeating(&AtEndOfWordPredicate),
- base::BindRepeating(&GetWordStartOffsetsFunc));
+ &AtStartOfWordPredicate, &AtEndOfWordPredicate,
+ &GetWordStartOffsetsFunc);
}
AXPositionInstance CreatePreviousWordStartPosition(
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryStartPosition(
boundary_behavior, ax::mojom::MoveDirection::kBackward,
- base::BindRepeating(&AtStartOfWordPredicate),
- base::BindRepeating(&AtEndOfWordPredicate),
- base::BindRepeating(&GetWordStartOffsetsFunc));
+ &AtStartOfWordPredicate, &AtEndOfWordPredicate,
+ &GetWordStartOffsetsFunc);
}
// Word end positions are one past the last character of the word.
@@ -2276,9 +2244,7 @@
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryEndPosition(
boundary_behavior, ax::mojom::MoveDirection::kForward,
- base::BindRepeating(&AtStartOfWordPredicate),
- base::BindRepeating(&AtEndOfWordPredicate),
- base::BindRepeating(&GetWordEndOffsetsFunc));
+ &AtStartOfWordPredicate, &AtEndOfWordPredicate, &GetWordEndOffsetsFunc);
}
// Word end positions are one past the last character of the word.
@@ -2286,25 +2252,21 @@
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryEndPosition(
boundary_behavior, ax::mojom::MoveDirection::kBackward,
- base::BindRepeating(&AtStartOfWordPredicate),
- base::BindRepeating(&AtEndOfWordPredicate),
- base::BindRepeating(&GetWordEndOffsetsFunc));
+ &AtStartOfWordPredicate, &AtEndOfWordPredicate, &GetWordEndOffsetsFunc);
}
AXPositionInstance CreateNextLineStartPosition(
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryStartPosition(
boundary_behavior, ax::mojom::MoveDirection::kForward,
- base::BindRepeating(&AtStartOfLinePredicate),
- base::BindRepeating(&AtEndOfLinePredicate));
+ &AtStartOfLinePredicate, &AtEndOfLinePredicate);
}
AXPositionInstance CreatePreviousLineStartPosition(
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryStartPosition(
boundary_behavior, ax::mojom::MoveDirection::kBackward,
- base::BindRepeating(&AtStartOfLinePredicate),
- base::BindRepeating(&AtEndOfLinePredicate));
+ &AtStartOfLinePredicate, &AtEndOfLinePredicate);
}
// Line end positions are one past the last character of the line, excluding
@@ -2313,8 +2275,7 @@
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryEndPosition(
boundary_behavior, ax::mojom::MoveDirection::kForward,
- base::BindRepeating(&AtStartOfLinePredicate),
- base::BindRepeating(&AtEndOfLinePredicate));
+ &AtStartOfLinePredicate, &AtEndOfLinePredicate);
}
// Line end positions are one past the last character of the line, excluding
@@ -2323,8 +2284,7 @@
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryEndPosition(
boundary_behavior, ax::mojom::MoveDirection::kBackward,
- base::BindRepeating(&AtStartOfLinePredicate),
- base::BindRepeating(&AtEndOfLinePredicate));
+ &AtStartOfLinePredicate, &AtEndOfLinePredicate);
}
AXPositionInstance CreatePreviousFormatStartPosition(
@@ -2461,32 +2421,28 @@
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryStartPosition(
boundary_behavior, ax::mojom::MoveDirection::kForward,
- base::BindRepeating(&AtStartOfParagraphPredicate),
- base::BindRepeating(&AtEndOfParagraphPredicate));
+ &AtStartOfParagraphPredicate, &AtEndOfParagraphPredicate);
}
AXPositionInstance CreatePreviousParagraphStartPosition(
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryStartPosition(
boundary_behavior, ax::mojom::MoveDirection::kBackward,
- base::BindRepeating(&AtStartOfParagraphPredicate),
- base::BindRepeating(&AtEndOfParagraphPredicate));
+ &AtStartOfParagraphPredicate, &AtEndOfParagraphPredicate);
}
AXPositionInstance CreateNextParagraphEndPosition(
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryEndPosition(
boundary_behavior, ax::mojom::MoveDirection::kForward,
- base::BindRepeating(&AtStartOfParagraphPredicate),
- base::BindRepeating(&AtEndOfParagraphPredicate));
+ &AtStartOfParagraphPredicate, &AtEndOfParagraphPredicate);
}
AXPositionInstance CreatePreviousParagraphEndPosition(
AXBoundaryBehavior boundary_behavior) const {
AXPositionInstance previous_position = CreateBoundaryEndPosition(
boundary_behavior, ax::mojom::MoveDirection::kBackward,
- base::BindRepeating(&AtStartOfParagraphPredicate),
- base::BindRepeating(&AtEndOfParagraphPredicate));
+ &AtStartOfParagraphPredicate, &AtEndOfParagraphPredicate);
if (boundary_behavior == AXBoundaryBehavior::CrossBoundary ||
boundary_behavior == AXBoundaryBehavior::StopAtLastAnchorBoundary) {
// This is asymmetric with CreateNextParagraphEndPosition due to
@@ -2537,8 +2493,7 @@
previous_position = previous_position->CreateBoundaryEndPosition(
boundary_behavior, ax::mojom::MoveDirection::kBackward,
- base::BindRepeating(&AtStartOfParagraphPredicate),
- base::BindRepeating(&AtEndOfParagraphPredicate));
+ &AtStartOfParagraphPredicate, &AtEndOfParagraphPredicate);
}
}
@@ -2549,32 +2504,28 @@
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryStartPosition(
boundary_behavior, ax::mojom::MoveDirection::kForward,
- base::BindRepeating(&AtStartOfPagePredicate),
- base::BindRepeating(&AtEndOfPagePredicate));
+ &AtStartOfPagePredicate, &AtEndOfPagePredicate);
}
AXPositionInstance CreatePreviousPageStartPosition(
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryStartPosition(
boundary_behavior, ax::mojom::MoveDirection::kBackward,
- base::BindRepeating(&AtStartOfPagePredicate),
- base::BindRepeating(&AtEndOfPagePredicate));
+ &AtStartOfPagePredicate, &AtEndOfPagePredicate);
}
AXPositionInstance CreateNextPageEndPosition(
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryEndPosition(
boundary_behavior, ax::mojom::MoveDirection::kForward,
- base::BindRepeating(&AtStartOfPagePredicate),
- base::BindRepeating(&AtEndOfPagePredicate));
+ &AtStartOfPagePredicate, &AtEndOfPagePredicate);
}
AXPositionInstance CreatePreviousPageEndPosition(
AXBoundaryBehavior boundary_behavior) const {
return CreateBoundaryEndPosition(
boundary_behavior, ax::mojom::MoveDirection::kBackward,
- base::BindRepeating(&AtStartOfPagePredicate),
- base::BindRepeating(&AtEndOfPagePredicate));
+ &AtStartOfPagePredicate, &AtEndOfPagePredicate);
}
AXPositionInstance CreateBoundaryStartPosition(
@@ -2582,8 +2533,7 @@
ax::mojom::MoveDirection move_direction,
BoundaryConditionPredicate at_start_condition,
BoundaryConditionPredicate at_end_condition,
- BoundaryTextOffsetsFunc get_start_offsets =
- BoundaryTextOffsetsFunc()) const {
+ BoundaryTextOffsetsFunc get_start_offsets = {}) const {
AXPositionInstance text_position = AsLeafTextPosition();
if (text_position->IsNullPosition())
return text_position;
@@ -2601,11 +2551,11 @@
}
}
- if (!at_start_condition.Run(text_position)) {
+ if (!at_start_condition(text_position)) {
text_position = text_position->CreatePositionAtNextOffsetBoundary(
move_direction, get_start_offsets);
- while (!at_start_condition.Run(text_position)) {
+ while (!at_start_condition(text_position)) {
AXPositionInstance next_position;
if (move_direction == ax::mojom::MoveDirection::kForward) {
next_position = text_position->CreateNextLeafTextPosition();
@@ -2614,7 +2564,7 @@
next_position = text_position->CreatePreviousLeafTextPosition();
} else {
text_position = text_position->CreatePositionAtStartOfAnchor();
- DCHECK(!text_position->IsNullPosition());
+ BASE_DCHECK(!text_position->IsNullPosition());
continue;
}
}
@@ -2703,8 +2653,7 @@
ax::mojom::MoveDirection move_direction,
BoundaryConditionPredicate at_start_condition,
BoundaryConditionPredicate at_end_condition,
- BoundaryTextOffsetsFunc get_end_offsets =
- BoundaryTextOffsetsFunc()) const {
+ BoundaryTextOffsetsFunc get_end_offsets = {}) const {
AXPositionInstance text_position = AsLeafTextPosition();
if (text_position->IsNullPosition())
return text_position;
@@ -2722,18 +2671,18 @@
}
}
- if (!at_end_condition.Run(text_position)) {
+ if (!at_end_condition(text_position)) {
text_position = text_position->CreatePositionAtNextOffsetBoundary(
move_direction, get_end_offsets);
- while (!at_end_condition.Run(text_position)) {
+ while (!at_end_condition(text_position)) {
AXPositionInstance next_position;
if (move_direction == ax::mojom::MoveDirection::kForward) {
if (text_position->AtEndOfAnchor()) {
next_position = text_position->CreateNextLeafTextPosition();
} else {
text_position = text_position->CreatePositionAtEndOfAnchor();
- DCHECK(!text_position->IsNullPosition());
+ BASE_DCHECK(!text_position->IsNullPosition());
continue;
}
} else {
@@ -2811,7 +2760,7 @@
downstream_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
if (downstream_position->AtStartOfAnchor() ||
downstream_position->AtEndOfAnchor() ||
- !at_start_condition.Run(downstream_position)) {
+ !at_start_condition(downstream_position)) {
text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
}
}
@@ -2839,14 +2788,12 @@
// Uses depth-first pre-order traversal.
AXPositionInstance CreateNextAnchorPosition() const {
- return CreateNextAnchorPosition(
- base::BindRepeating(&DefaultAbortMovePredicate));
+ return CreateNextAnchorPosition(&DefaultAbortMovePredicate);
}
// Uses depth-first pre-order traversal.
AXPositionInstance CreatePreviousAnchorPosition() const {
- return CreatePreviousAnchorPosition(
- base::BindRepeating(&DefaultAbortMovePredicate));
+ return CreatePreviousAnchorPosition(&DefaultAbortMovePredicate);
}
// Returns an optional integer indicating the logical order of this position
@@ -2859,11 +2806,11 @@
// 0: if this position is logically equivalent to the other position
// <0: if this position is logically less than the other position
// >0: if this position is logically greater than the other position
- base::Optional<int> CompareTo(const AXPosition& other) const {
+ std::optional<int> CompareTo(const AXPosition& other) const {
if (this->IsNullPosition() && other.IsNullPosition())
- return base::Optional<int>(0);
+ return std::optional<int>(0);
if (this->IsNullPosition() || other.IsNullPosition())
- return base::Optional<int>(base::nullopt);
+ return std::optional<int>(std::nullopt);
// If both positions share an anchor and are of the same type, we can do a
// straight compare of text offsets or child indices.
@@ -2906,15 +2853,15 @@
if (normalized_this_position->IsNullPosition()) {
if (normalized_other_position->IsNullPosition()) {
// Both positions normalized to a position past the end of the document.
- DCHECK_EQ(SlowCompareTo(other).value(), 0);
+ BASE_DCHECK(SlowCompareTo(other).value() == 0);
return 0;
}
// |this| normalized to a position past the end of the document.
- DCHECK_GT(SlowCompareTo(other).value(), 0);
+ BASE_DCHECK(SlowCompareTo(other).value() > 0);
return 1;
} else if (normalized_other_position->IsNullPosition()) {
// |other| normalized to a position past the end of the document.
- DCHECK_LT(SlowCompareTo(other).value(), 0);
+ BASE_DCHECK(SlowCompareTo(other).value() < 0);
return -1;
}
@@ -2922,9 +2869,9 @@
// rather than calling LowestCommonAnchor(). That way, we can discover the
// first uncommon ancestors.
const AXNodeType* common_anchor = nullptr;
- base::stack<AXNodeType*> our_ancestors =
+ std::stack<AXNodeType*> our_ancestors =
normalized_this_position->GetAncestorAnchors();
- base::stack<AXNodeType*> other_ancestors =
+ std::stack<AXNodeType*> other_ancestors =
normalized_other_position->GetAncestorAnchors();
while (!our_ancestors.empty() && !other_ancestors.empty() &&
our_ancestors.top() == other_ancestors.top()) {
@@ -2934,7 +2881,7 @@
}
if (!common_anchor)
- return base::Optional<int>(base::nullopt);
+ return std::optional<int>(std::nullopt);
// If each position has an uncommon ancestor node, we can compare those
// instead of needing to compute ancestor positions.
@@ -2949,9 +2896,8 @@
0 /*child_index*/);
int other_uncommon_ancestor_index =
other_uncommon_tree_position->AnchorIndexInParent();
- DCHECK_NE(this_uncommon_ancestor_index, other_uncommon_ancestor_index)
- << "Deepest uncommon ancestors should truly be uncommon, i.e. not "
- "the same.";
+ BASE_DCHECK(this_uncommon_ancestor_index !=
+ other_uncommon_ancestor_index);
int result = this_uncommon_ancestor_index - other_uncommon_ancestor_index;
// On platforms that support embedded objects, if a text position is
@@ -3004,12 +2950,12 @@
}
}
-#if DCHECK_IS_ON()
+#ifndef NDEBUG
// Validate the optimization.
int slow_result = SlowCompareTo(other).value();
- DCHECK((result == 0 && slow_result == 0) ||
- (result < 0 && slow_result < 0) ||
- (result > 0 && slow_result > 0));
+ BASE_DCHECK((result == 0 && slow_result == 0) ||
+ (result < 0 && slow_result < 0) ||
+ (result > 0 && slow_result > 0));
#endif
return result;
@@ -3018,7 +2964,7 @@
return SlowCompareTo(other);
}
- base::Optional<int> SlowCompareTo(const AXPosition& other) const {
+ std::optional<int> SlowCompareTo(const AXPosition& other) const {
// It is potentially costly to compute the parent position of a text
// position, whilst computing the parent position of a tree position is
// really inexpensive. In order to find the lowest common ancestor,
@@ -3033,7 +2979,7 @@
// or one is the ancestor of the other.
const AXNodeType* common_anchor = this->LowestCommonAnchor(other);
if (!common_anchor)
- return base::Optional<int>(base::nullopt);
+ return std::optional<int>(std::nullopt);
// Attempt to avoid recomputing the lowest common ancestor because we may
// already have its anchor in which case just find the text offset.
@@ -3043,8 +2989,8 @@
if (this->GetAnchor() == common_anchor) {
AXPositionInstance other_text_position =
other.CreateAncestorPosition(common_anchor);
- return base::Optional<int>(this->text_offset_ -
- other_text_position->text_offset_);
+ return std::optional<int>(this->text_offset_ -
+ other_text_position->text_offset_);
}
// The other text position's anchor is the common ancestor of this text
@@ -3052,8 +2998,8 @@
if (other.GetAnchor() == common_anchor) {
AXPositionInstance this_text_position =
this->CreateAncestorPosition(common_anchor);
- return base::Optional<int>(this_text_position->text_offset_ -
- other.text_offset_);
+ return std::optional<int>(this_text_position->text_offset_ -
+ other.text_offset_);
}
// All optimizations failed. Fall back to comparing text positions with
@@ -3062,10 +3008,10 @@
this->CreateAncestorPosition(common_anchor);
AXPositionInstance other_text_position_ancestor =
other.CreateAncestorPosition(common_anchor);
- DCHECK(this_text_position_ancestor->IsTextPosition());
- DCHECK(other_text_position_ancestor->IsTextPosition());
- DCHECK_EQ(common_anchor, this_text_position_ancestor->GetAnchor());
- DCHECK_EQ(common_anchor, other_text_position_ancestor->GetAnchor());
+ BASE_DCHECK(this_text_position_ancestor->IsTextPosition());
+ BASE_DCHECK(other_text_position_ancestor->IsTextPosition());
+ BASE_DCHECK(common_anchor == this_text_position_ancestor->GetAnchor());
+ BASE_DCHECK(common_anchor == other_text_position_ancestor->GetAnchor());
// TODO - This does not take into account |affinity_|, so we may return
// a false positive when comparing at the end of a line.
@@ -3088,8 +3034,8 @@
// TextPosition anchor_id=2 text_offset=7
// ... except anchor_id=5 creates a kUpstream position, while
// anchor_id=7 creates a kDownstream position.
- return base::Optional<int>(this_text_position_ancestor->text_offset_ -
- other_text_position_ancestor->text_offset_);
+ return std::optional<int>(this_text_position_ancestor->text_offset_ -
+ other_text_position_ancestor->text_offset_);
}
// All optimizations failed. Fall back to comparing child index with
@@ -3098,13 +3044,13 @@
this->AsTreePosition()->CreateAncestorPosition(common_anchor);
AXPositionInstance other_tree_position_ancestor =
other.AsTreePosition()->CreateAncestorPosition(common_anchor);
- DCHECK(this_tree_position_ancestor->IsTreePosition());
- DCHECK(other_tree_position_ancestor->IsTreePosition());
- DCHECK_EQ(common_anchor, this_tree_position_ancestor->GetAnchor());
- DCHECK_EQ(common_anchor, other_tree_position_ancestor->GetAnchor());
+ BASE_DCHECK(this_tree_position_ancestor->IsTreePosition());
+ BASE_DCHECK(other_tree_position_ancestor->IsTreePosition());
+ BASE_DCHECK(common_anchor == this_tree_position_ancestor->GetAnchor());
+ BASE_DCHECK(common_anchor == other_tree_position_ancestor->GetAnchor());
- return base::Optional<int>(this_tree_position_ancestor->child_index() -
- other_tree_position_ancestor->child_index());
+ return std::optional<int>(this_tree_position_ancestor->child_index() -
+ other_tree_position_ancestor->child_index());
}
// A valid position can become invalid if the underlying tree structure
@@ -3205,9 +3151,6 @@
std::swap(child_index_, other.child_index_);
std::swap(text_offset_, other.text_offset_);
std::swap(affinity_, other.affinity_);
- // We explicitly don't swap any cached members.
- name_ = base::string16();
- other.name_ = base::string16();
}
// Abstract methods.
@@ -3216,7 +3159,7 @@
// found in descendant text nodes, based on the platform's text
// representation. Some platforms use an embedded object replacement character
// that replaces the text coming from each child node.
- virtual base::string16 GetText() const = 0;
+ virtual std::u16string GetText() const = 0;
// Determines if the anchor containing this position is a <br> or a text
// object whose parent's anchor is an enclosing <br>.
@@ -3240,7 +3183,7 @@
virtual int MaxTextOffset() const {
if (IsNullPosition())
return INVALID_OFFSET;
- return int{GetText().length()};
+ return static_cast<int>(GetText().length());
}
protected:
@@ -3259,8 +3202,7 @@
anchor_id_(other.anchor_id_),
child_index_(other.child_index_),
text_offset_(other.text_offset_),
- affinity_(other.affinity_),
- name_() {}
+ affinity_(other.affinity_) {}
// Returns the character offset inside our anchor's parent at which our text
// starts.
@@ -3270,40 +3212,21 @@
// Calculate how much text there is to the left of this anchor.
AXPositionInstance tree_position = AsTreePosition();
- DCHECK(tree_position);
+ BASE_DCHECK(tree_position);
AXPositionInstance parent_position = tree_position->CreateParentPosition();
- DCHECK(parent_position);
+ BASE_DCHECK(parent_position);
if (parent_position->IsNullPosition())
return 0;
int offset_in_parent = 0;
for (int i = 0; i < parent_position->child_index(); ++i) {
AXPositionInstance child = parent_position->CreateChildPositionAt(i);
- DCHECK(child);
+ BASE_DCHECK(child);
offset_in_parent += child->MaxTextOffsetInParent();
}
return offset_in_parent;
}
- // In the case of a text position, lazily initializes or returns the existing
- // grapheme iterator for the position's text. The grapheme iterator breaks at
- // every grapheme cluster boundary.
- //
- // We only allow creating this iterator on leaf nodes. We currently don't need
- // to move by grapheme boundaries on non-leaf nodes and computing plus caching
- // the inner text for all nodes is costly.
- std::unique_ptr<base::i18n::BreakIterator> GetGraphemeIterator() const {
- if (!IsTextPosition() || !IsLeaf())
- return {};
-
- name_ = GetText();
- auto grapheme_iterator = std::make_unique<base::i18n::BreakIterator>(
- name_, base::i18n::BreakIterator::BREAK_CHARACTER);
- if (!grapheme_iterator->Init())
- return {};
- return grapheme_iterator;
- }
-
void Initialize(AXPositionKind kind,
AXTreeID tree_id,
int32_t anchor_id,
@@ -3344,7 +3267,7 @@
virtual int AnchorUnignoredChildCount() const = 0;
virtual int AnchorIndexInParent() const = 0;
virtual int AnchorSiblingCount() const = 0;
- virtual base::stack<AXNodeType*> GetAncestorAnchors() const = 0;
+ virtual std::stack<AXNodeType*> GetAncestorAnchors() const = 0;
virtual AXNodeType* GetLowestUnignoredAncestor() const = 0;
virtual void AnchorParent(AXTreeID* tree_id, int32_t* parent_id) const = 0;
virtual AXNodeType* GetNodeInTree(AXTreeID tree_id,
@@ -3393,11 +3316,10 @@
// Type of predicate function called during anchor navigation.
// When the predicate returns |true|, the navigation stops and returns a
// null position object.
- using AbortMovePredicate =
- base::RepeatingCallback<bool(const AXPosition& move_from,
- const AXPosition& move_to,
- const AXMoveType type,
- const AXMoveDirection direction)>;
+ typedef bool AbortMovePredicate(const AXPosition& move_from,
+ const AXPosition& move_to,
+ const AXMoveType type,
+ const AXMoveDirection direction);
// A text span is defined by a series of inline text boxes that make up a
// single static text object.
@@ -3417,12 +3339,12 @@
// Uses depth-first pre-order traversal.
AXPositionInstance CreateNextAnchorPosition(
- const AbortMovePredicate& abort_predicate) const {
+ std::function<AbortMovePredicate> abort_predicate) const {
if (IsNullPosition())
return Clone();
AXPositionInstance current_position = AsTreePosition();
- DCHECK(!current_position->IsNullPosition());
+ BASE_DCHECK(!current_position->IsNullPosition());
if (!IsLeaf()) {
const int child_index = current_position->child_index_;
@@ -3430,9 +3352,9 @@
AXPositionInstance child_position =
current_position->CreateChildPositionAt(child_index);
- if (abort_predicate.Run(*current_position, *child_position,
- AXMoveType::kDescendant,
- AXMoveDirection::kNextInTree)) {
+ if (abort_predicate(*current_position, *child_position,
+ AXMoveType::kDescendant,
+ AXMoveDirection::kNextInTree)) {
return CreateNullPosition();
}
return child_position;
@@ -3449,19 +3371,19 @@
if (index_in_parent + 1 < parent_position->AnchorChildCount()) {
AXPositionInstance next_sibling =
parent_position->CreateChildPositionAt(index_in_parent + 1);
- DCHECK(!next_sibling->IsNullPosition());
+ BASE_DCHECK(!next_sibling->IsNullPosition());
- if (abort_predicate.Run(*current_position, *next_sibling,
- AXMoveType::kSibling,
- AXMoveDirection::kNextInTree)) {
+ if (abort_predicate(*current_position, *next_sibling,
+ AXMoveType::kSibling,
+ AXMoveDirection::kNextInTree)) {
return CreateNullPosition();
}
return next_sibling;
}
- if (abort_predicate.Run(*current_position, *parent_position,
- AXMoveType::kAncestor,
- AXMoveDirection::kNextInTree)) {
+ if (abort_predicate(*current_position, *parent_position,
+ AXMoveType::kAncestor,
+ AXMoveDirection::kNextInTree)) {
return CreateNullPosition();
}
@@ -3473,12 +3395,12 @@
// Uses depth-first pre-order traversal.
AXPositionInstance CreatePreviousAnchorPosition(
- const AbortMovePredicate& abort_predicate) const {
+ std::function<AbortMovePredicate> abort_predicate) const {
if (IsNullPosition())
return Clone();
AXPositionInstance current_position = AsTreePosition();
- DCHECK(!current_position->IsNullPosition());
+ BASE_DCHECK(!current_position->IsNullPosition());
AXPositionInstance parent_position =
current_position->CreateParentPosition();
@@ -3488,9 +3410,9 @@
// If there is no previous sibling, move up to the parent.
const int index_in_parent = current_position->AnchorIndexInParent();
if (index_in_parent <= 0) {
- if (abort_predicate.Run(*current_position, *parent_position,
- AXMoveType::kAncestor,
- AXMoveDirection::kPreviousInTree)) {
+ if (abort_predicate(*current_position, *parent_position,
+ AXMoveType::kAncestor,
+ AXMoveDirection::kPreviousInTree)) {
return CreateNullPosition();
}
return parent_position;
@@ -3499,11 +3421,11 @@
// Get the previous sibling's deepest last child.
AXPositionInstance rightmost_leaf =
parent_position->CreateChildPositionAt(index_in_parent - 1);
- DCHECK(!rightmost_leaf->IsNullPosition());
+ BASE_DCHECK(!rightmost_leaf->IsNullPosition());
- if (abort_predicate.Run(*current_position, *rightmost_leaf,
- AXMoveType::kSibling,
- AXMoveDirection::kPreviousInTree)) {
+ if (abort_predicate(*current_position, *rightmost_leaf,
+ AXMoveType::kSibling,
+ AXMoveDirection::kPreviousInTree)) {
return CreateNullPosition();
}
@@ -3511,11 +3433,11 @@
parent_position = std::move(rightmost_leaf);
rightmost_leaf = parent_position->CreateChildPositionAt(
parent_position->AnchorChildCount() - 1);
- DCHECK(!rightmost_leaf->IsNullPosition());
+ BASE_DCHECK(!rightmost_leaf->IsNullPosition());
- if (abort_predicate.Run(*parent_position, *rightmost_leaf,
- AXMoveType::kDescendant,
- AXMoveDirection::kPreviousInTree)) {
+ if (abort_predicate(*parent_position, *rightmost_leaf,
+ AXMoveType::kDescendant,
+ AXMoveDirection::kPreviousInTree)) {
return CreateNullPosition();
}
}
@@ -3525,7 +3447,7 @@
// Creates a position using the next text-only node as its anchor.
// Assumes that text-only nodes are leaf nodes.
AXPositionInstance CreateNextTextAnchorPosition(
- const AbortMovePredicate& abort_predicate) const {
+ std::function<AbortMovePredicate> abort_predicate) const {
// If this is an ancestor text position, resolve to its leaf text position.
if (IsTextPosition() && !IsLeaf())
return AsLeafTextPosition();
@@ -3534,14 +3456,14 @@
while (!next_leaf->IsNullPosition() && !next_leaf->IsLeaf())
next_leaf = next_leaf->CreateNextAnchorPosition(abort_predicate);
- DCHECK(next_leaf);
+ BASE_DCHECK(next_leaf);
return next_leaf->AsLeafTextPosition();
}
// Creates a position using the previous text-only node as its anchor.
// Assumes that text-only nodes are leaf nodes.
AXPositionInstance CreatePreviousTextAnchorPosition(
- const AbortMovePredicate& abort_predicate) const {
+ std::function<AbortMovePredicate> abort_predicate) const {
// If this is an ancestor text position, resolve to its leaf text position.
if (IsTextPosition() && !IsLeaf())
return AsLeafTextPosition();
@@ -3553,27 +3475,27 @@
previous_leaf->CreatePreviousAnchorPosition(abort_predicate);
}
- DCHECK(previous_leaf);
+ BASE_DCHECK(previous_leaf);
return previous_leaf->AsLeafTextPosition();
}
// Creates a tree position using the next text-only node as its anchor.
// Assumes that text-only nodes are leaf nodes.
AXPositionInstance CreateNextLeafTreePosition(
- const AbortMovePredicate& abort_predicate) const {
+ std::function<AbortMovePredicate> abort_predicate) const {
AXPositionInstance next_leaf =
AsTreePosition()->CreateNextAnchorPosition(abort_predicate);
while (!next_leaf->IsNullPosition() && !next_leaf->IsLeaf())
next_leaf = next_leaf->CreateNextAnchorPosition(abort_predicate);
- DCHECK(next_leaf);
+ BASE_DCHECK(next_leaf);
return next_leaf;
}
// Creates a tree position using the previous text-only node as its anchor.
// Assumes that text-only nodes are leaf nodes.
AXPositionInstance CreatePreviousLeafTreePosition(
- const AbortMovePredicate& abort_predicate) const {
+ std::function<AbortMovePredicate> abort_predicate) const {
AXPositionInstance previous_leaf =
AsTreePosition()->CreatePreviousAnchorPosition(abort_predicate);
while (!previous_leaf->IsNullPosition() && !previous_leaf->IsLeaf()) {
@@ -3581,7 +3503,7 @@
previous_leaf->CreatePreviousAnchorPosition(abort_predicate);
}
- DCHECK(previous_leaf);
+ BASE_DCHECK(previous_leaf);
return previous_leaf;
}
@@ -3692,7 +3614,7 @@
// because that would mean exiting and/or entering a block.
return move_from_break || move_to_break;
}
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
}
@@ -3772,7 +3694,7 @@
// break, because that would mean exiting and/or entering a page break.
return move_from_break && move_to_break;
}
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
}
@@ -3803,7 +3725,7 @@
(move_type == AXMoveType::kAncestor ||
move_type == AXMoveType::kSibling);
}
- NOTREACHED();
+ BASE_UNREACHABLE();
return false;
}
@@ -3856,12 +3778,11 @@
AXPositionInstance CreatePositionAtNextOffsetBoundary(
ax::mojom::MoveDirection move_direction,
BoundaryTextOffsetsFunc get_offsets) const {
- if (IsNullPosition() || get_offsets.is_null())
+ if (IsNullPosition() || !get_offsets)
return Clone();
AXPositionInstance text_position = AsTextPosition();
- const std::vector<int32_t> boundary_offsets =
- get_offsets.Run(text_position);
+ const std::vector<int32_t> boundary_offsets = get_offsets(text_position);
if (boundary_offsets.empty())
return text_position;
@@ -3872,7 +3793,7 @@
int32_t{text_position->text_offset_});
// If there is no next offset, the current offset should be unchanged.
if (offsets_iterator < boundary_offsets.end()) {
- text_position->text_offset_ = int{*offsets_iterator};
+ text_position->text_offset_ = static_cast<int>(*offsets_iterator);
text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
}
break;
@@ -3888,7 +3809,7 @@
// can safely move the iterator one position back, even if it's
// currently at the vector's end.
--offsets_iterator;
- text_position->text_offset_ = int{*offsets_iterator};
+ text_position->text_offset_ = static_cast<int>(*offsets_iterator);
text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
}
break;
@@ -3908,18 +3829,17 @@
AXPositionInstance CreatePositionAtFirstOffsetBoundary(
ax::mojom::MoveDirection move_direction,
BoundaryTextOffsetsFunc get_offsets) const {
- if (IsNullPosition() || get_offsets.is_null())
+ if (IsNullPosition() || !get_offsets)
return Clone();
AXPositionInstance text_position = AsTextPosition();
- const std::vector<int32_t> boundary_offsets =
- get_offsets.Run(text_position);
+ const std::vector<int32_t> boundary_offsets = get_offsets(text_position);
switch (move_direction) {
case ax::mojom::MoveDirection::kForward:
if (boundary_offsets.empty()) {
return text_position->CreatePositionAtEndOfAnchor();
} else {
- text_position->text_offset_ = int{boundary_offsets[0]};
+ text_position->text_offset_ = static_cast<int>(boundary_offsets[0]);
return text_position;
}
break;
@@ -3928,7 +3848,7 @@
return text_position->CreatePositionAtStartOfAnchor();
} else {
text_position->text_offset_ =
- int{boundary_offsets[boundary_offsets.size() - 1]};
+ static_cast<int>(boundary_offsets[boundary_offsets.size() - 1]);
return text_position;
}
break;
@@ -3992,7 +3912,7 @@
break;
}
- DCHECK(text_position->IsValid());
+ BASE_DCHECK(text_position->IsValid());
return text_position;
}
@@ -4023,14 +3943,6 @@
// end of its anchor node, whilst a leaf text position after the soft line
// break would be pointing to the start of the next node.
ax::mojom::TextAffinity affinity_;
-
- //
- // Cached members that should be lazily created on first use.
- //
-
- // In the case of a leaf position, the name of its anchor used for
- // initializing a grapheme break iterator.
- mutable base::string16 name_;
};
template <class AXPositionType, class AXNodeType>
@@ -4043,42 +3955,42 @@
template <class AXPositionType, class AXNodeType>
bool operator==(const AXPosition<AXPositionType, AXNodeType>& first,
const AXPosition<AXPositionType, AXNodeType>& second) {
- const base::Optional<int> compare_to_optional = first.CompareTo(second);
+ const std::optional<int> compare_to_optional = first.CompareTo(second);
return compare_to_optional.has_value() && compare_to_optional.value() == 0;
}
template <class AXPositionType, class AXNodeType>
bool operator!=(const AXPosition<AXPositionType, AXNodeType>& first,
const AXPosition<AXPositionType, AXNodeType>& second) {
- const base::Optional<int> compare_to_optional = first.CompareTo(second);
+ const std::optional<int> compare_to_optional = first.CompareTo(second);
return compare_to_optional.has_value() && compare_to_optional.value() != 0;
}
template <class AXPositionType, class AXNodeType>
bool operator<(const AXPosition<AXPositionType, AXNodeType>& first,
const AXPosition<AXPositionType, AXNodeType>& second) {
- const base::Optional<int> compare_to_optional = first.CompareTo(second);
+ const std::optional<int> compare_to_optional = first.CompareTo(second);
return compare_to_optional.has_value() && compare_to_optional.value() < 0;
}
template <class AXPositionType, class AXNodeType>
bool operator<=(const AXPosition<AXPositionType, AXNodeType>& first,
const AXPosition<AXPositionType, AXNodeType>& second) {
- const base::Optional<int> compare_to_optional = first.CompareTo(second);
+ const std::optional<int> compare_to_optional = first.CompareTo(second);
return compare_to_optional.has_value() && compare_to_optional.value() <= 0;
}
template <class AXPositionType, class AXNodeType>
bool operator>(const AXPosition<AXPositionType, AXNodeType>& first,
const AXPosition<AXPositionType, AXNodeType>& second) {
- const base::Optional<int> compare_to_optional = first.CompareTo(second);
+ const std::optional<int> compare_to_optional = first.CompareTo(second);
return compare_to_optional.has_value() && compare_to_optional.value() > 0;
}
template <class AXPositionType, class AXNodeType>
bool operator>=(const AXPosition<AXPositionType, AXNodeType>& first,
const AXPosition<AXPositionType, AXNodeType>& second) {
- const base::Optional<int> compare_to_optional = first.CompareTo(second);
+ const std::optional<int> compare_to_optional = first.CompareTo(second);
return compare_to_optional.has_value() && compare_to_optional.value() >= 0;
}
diff --git a/third_party/accessibility/ax/ax_range.h b/third_party/accessibility/ax/ax_range.h
index 2d263e1..d7c9768 100644
--- a/third_party/accessibility/ax/ax_range.h
+++ b/third_party/accessibility/ax/ax_range.h
@@ -11,12 +11,11 @@
#include <utility>
#include <vector>
-#include "base/strings/string16.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_offscreen_result.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_tree_manager_map.h"
+#include "ax_enums.h"
+#include "ax_offscreen_result.h"
+#include "ax_role_properties.h"
+#include "ax_tree_manager_map.h"
+#include "base/string_utils.h"
namespace ui {
@@ -70,12 +69,12 @@
virtual ~AXRange() = default;
AXPositionType* anchor() const {
- DCHECK(anchor_);
+ BASE_DCHECK(anchor_);
return anchor_.get();
}
AXPositionType* focus() const {
- DCHECK(focus_);
+ BASE_DCHECK(focus_);
return focus_.get();
}
@@ -113,9 +112,9 @@
// <0 - If the first position would come BEFORE the second.
// >0 - If the first position would come AFTER the second.
// nullopt - If positions are not comparable (see AXPosition::CompareTo).
- static base::Optional<int> CompareEndpoints(const AXPositionType* first,
- const AXPositionType* second) {
- base::Optional<int> tree_position_comparison =
+ static std::optional<int> CompareEndpoints(const AXPositionType* first,
+ const AXPositionType* second) {
+ std::optional<int> tree_position_comparison =
first->AsTreePosition()->CompareTo(*second->AsTreePosition());
// When the tree comparison is nullopt, using value_or(1) forces a default
@@ -147,7 +146,7 @@
}
bool IsNull() const {
- DCHECK(anchor_ && focus_);
+ BASE_DCHECK(anchor_ && focus_);
return anchor_->IsNullPosition() || focus_->IsNullPosition();
}
@@ -225,27 +224,27 @@
// Only forward iteration is supported, so operator-- is not implemented.
Iterator& operator++() {
- DCHECK(!current_start_->IsNullPosition());
+ BASE_DCHECK(!current_start_->IsNullPosition());
if (current_start_->GetAnchor() == iterator_end_->GetAnchor()) {
current_start_ = AXPositionType::CreateNullPosition();
} else {
current_start_ = current_start_->CreateNextLeafTreePosition();
- DCHECK_LE(*current_start_, *iterator_end_);
+ BASE_DCHECK(*current_start_ <= *iterator_end_);
}
return *this;
}
AXRange operator*() const {
- DCHECK(!current_start_->IsNullPosition());
+ BASE_DCHECK(!current_start_->IsNullPosition());
AXPositionInstance current_end =
(current_start_->GetAnchor() != iterator_end_->GetAnchor())
? current_start_->CreatePositionAtEndOfAnchor()
: iterator_end_->Clone();
- DCHECK_LE(*current_end, *iterator_end_);
+ BASE_DCHECK(*current_end <= *iterator_end_);
AXRange current_leaf_text_range(current_start_->AsTextPosition(),
current_end->AsTextPosition());
- DCHECK(current_leaf_text_range.IsLeafTextRange());
+ BASE_DCHECK(current_leaf_text_range.IsLeafTextRange());
return std::move(current_leaf_text_range);
}
@@ -274,18 +273,18 @@
// Pass a |max_count| of -1 to retrieve all text in the AXRange.
// Note that if this AXRange has its anchor or focus located at an ignored
// position, we shrink the range to the closest unignored positions.
- base::string16 GetText(AXTextConcatenationBehavior concatenation_behavior =
+ std::u16string GetText(AXTextConcatenationBehavior concatenation_behavior =
AXTextConcatenationBehavior::kAsTextContent,
int max_count = -1,
bool include_ignored = false,
size_t* appended_newlines_count = nullptr) const {
if (max_count == 0 || IsNull())
- return base::string16();
+ return std::u16string();
- base::Optional<int> endpoint_comparison =
+ std::optional<int> endpoint_comparison =
CompareEndpoints(anchor(), focus());
if (!endpoint_comparison)
- return base::string16();
+ return std::u16string();
AXPositionInstance start = (endpoint_comparison.value() < 0)
? anchor_->AsLeafTextPosition()
@@ -294,7 +293,7 @@
? focus_->AsLeafTextPosition()
: anchor_->AsLeafTextPosition();
- base::string16 range_text;
+ std::u16string range_text;
size_t computed_newlines_count = 0;
bool is_first_non_whitespace_leaf = true;
bool crossed_paragraph_boundary = false;
@@ -302,8 +301,8 @@
bool found_trailing_newline = false;
while (!start->IsNullPosition()) {
- DCHECK(start->IsLeafTextPosition());
- DCHECK_GE(start->text_offset(), 0);
+ BASE_DCHECK(start->IsLeafTextPosition());
+ BASE_DCHECK(start->text_offset() >= 0);
if (include_ignored || !start->IsIgnored()) {
if (concatenation_behavior ==
@@ -336,7 +335,7 @@
if (current_end_offset > start->text_offset()) {
int characters_to_append =
(max_count > 0)
- ? std::min(max_count - int{range_text.length()},
+ ? std::min(max_count - static_cast<int>(range_text.length()),
current_end_offset - start->text_offset())
: current_end_offset - start->text_offset();
@@ -349,12 +348,13 @@
(found_trailing_newline && start->IsInWhiteSpace());
}
- DCHECK(max_count < 0 || int{range_text.length()} <= max_count);
+ BASE_DCHECK(max_count < 0 ||
+ static_cast<int>(range_text.length()) <= max_count);
is_first_unignored_leaf = false;
}
if (start->GetAnchor() == end->GetAnchor() ||
- int{range_text.length()} == max_count) {
+ static_cast<int>(range_text.length()) == max_count) {
break;
} else if (concatenation_behavior ==
AXTextConcatenationBehavior::kAsInnerText &&
@@ -377,7 +377,7 @@
std::vector<gfx::Rect> rects;
for (const AXRange& leaf_text_range : *this) {
- DCHECK(leaf_text_range.IsLeafTextRange());
+ BASE_DCHECK(leaf_text_range.IsLeafTextRange());
AXPositionType* current_line_start = leaf_text_range.anchor();
AXPositionType* current_line_end = leaf_text_range.focus();
diff --git a/third_party/accessibility/ax/ax_range_unittest.cc b/third_party/accessibility/ax/ax_range_unittest.cc
index b27df72..06cc8f8 100644
--- a/third_party/accessibility/ax/ax_range_unittest.cc
+++ b/third_party/accessibility/ax/ax_range_unittest.cc
@@ -2,23 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_range.h"
+#include "ax_range.h"
#include <memory>
#include <vector>
-#include "base/strings/string16.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_node_position.h"
-#include "ui/accessibility/ax_tree.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/accessibility/ax_tree_update.h"
-#include "ui/accessibility/test_ax_node_helper.h"
-#include "ui/accessibility/test_ax_tree_manager.h"
+#include "gtest/gtest.h"
+
+#include "ax_enums.h"
+#include "ax_node.h"
+#include "ax_node_data.h"
+#include "ax_node_position.h"
+#include "ax_tree.h"
+#include "ax_tree_id.h"
+#include "ax_tree_update.h"
+#include "test_ax_node_helper.h"
+#include "test_ax_tree_manager.h"
namespace ui {
@@ -28,6 +27,15 @@
namespace {
+bool ContainerEQ(std::vector<gfx::Rect> actual,
+ std::vector<gfx::Rect> expected) {
+ for (size_t i = 0; i < actual.size(); i++) {
+ if (actual[i] != expected[i])
+ return false;
+ }
+ return true;
+}
+
constexpr AXNode::AXID ROOT_ID = 1;
constexpr AXNode::AXID DIV1_ID = 2;
constexpr AXNode::AXID BUTTON_ID = 3;
@@ -98,15 +106,15 @@
class AXRangeTest : public testing::Test, public TestAXTreeManager {
public:
- const base::string16 EMPTY = base::ASCIIToUTF16("");
- const base::string16 NEWLINE = base::ASCIIToUTF16("\n");
- const base::string16 BUTTON = base::ASCIIToUTF16("Button");
- const base::string16 LINE_1 = base::ASCIIToUTF16("Line 1");
- const base::string16 LINE_2 = base::ASCIIToUTF16("Line 2");
- const base::string16 TEXT_FIELD =
+ const std::u16string EMPTY = base::ASCIIToUTF16("");
+ const std::u16string NEWLINE = base::ASCIIToUTF16("\n");
+ const std::u16string BUTTON = base::ASCIIToUTF16("Button");
+ const std::u16string LINE_1 = base::ASCIIToUTF16("Line 1");
+ const std::u16string LINE_2 = base::ASCIIToUTF16("Line 2");
+ const std::u16string TEXT_FIELD =
LINE_1.substr().append(NEWLINE).append(LINE_2).append(NEWLINE);
- const base::string16 AFTER_LINE = base::ASCIIToUTF16("After");
- const base::string16 ALL_TEXT =
+ const std::u16string AFTER_LINE = base::ASCIIToUTF16("After");
+ const std::u16string ALL_TEXT =
BUTTON.substr().append(TEXT_FIELD).append(AFTER_LINE);
AXRangeTest() = default;
@@ -133,7 +141,7 @@
AXNodeData paragraph_;
private:
- DISALLOW_COPY_AND_ASSIGN(AXRangeTest);
+ BASE_DISALLOW_COPY_AND_ASSIGN(AXRangeTest);
};
void AXRangeTest::SetUp() {
@@ -761,7 +769,7 @@
EXPECT_EQ(LINE_2, static_text2_range_backward.GetText());
// static_text1_ to static_text2_
- base::string16 text_between_text1_start_and_text2_end =
+ std::u16string text_between_text1_start_and_text2_end =
LINE_1.substr().append(NEWLINE).append(LINE_2);
start = AXNodePosition::CreateTextPosition(
GetTreeID(), static_text1_.id, 0 /* text_offset */,
@@ -780,7 +788,7 @@
static_text_range_backward.GetText());
// root_ to static_text2_'s end
- base::string16 text_up_to_text2_end =
+ std::u16string text_up_to_text2_end =
BUTTON.substr(0).append(LINE_1).append(NEWLINE).append(LINE_2);
start = AXNodePosition::CreateTreePosition(GetTreeID(), root_.id,
0 /* child_index */);
@@ -796,7 +804,7 @@
root_to_static2_text_range_backward.GetText());
// root_ to static_text2_'s start
- base::string16 text_up_to_text2_start =
+ std::u16string text_up_to_text2_start =
BUTTON.substr(0).append(LINE_1).append(NEWLINE);
start = AXNodePosition::CreateTreePosition(GetTreeID(), root_.id,
0 /* child_index */);
@@ -811,7 +819,7 @@
}
TEST_F(AXRangeTest, GetTextWithTextOffsets) {
- base::string16 most_text = BUTTON.substr(2).append(TEXT_FIELD.substr(0, 11));
+ std::u16string most_text = BUTTON.substr(2).append(TEXT_FIELD.substr(0, 11));
// Create a range starting from the button object and ending two characters
// before the end of the root.
TestPositionInstance start = AXNodePosition::CreateTextPosition(
@@ -828,7 +836,7 @@
EXPECT_EQ(most_text, backward_range.GetText());
// root_ to static_text2_'s start with offsets
- base::string16 text_up_to_text2_tree_start =
+ std::u16string text_up_to_text2_tree_start =
BUTTON.substr(0).append(TEXT_FIELD.substr(0, 10));
start = AXNodePosition::CreateTreePosition(GetTreeID(), root_.id,
0 /* child_index */);
@@ -932,7 +940,7 @@
auto TestGetTextForRange = [](TestPositionInstance range_start,
TestPositionInstance range_end,
- const base::string16& expected_text,
+ const std::u16string& expected_text,
const size_t expected_appended_newlines_count) {
TestPositionRange forward_test_range(range_start->Clone(),
range_end->Clone());
@@ -949,37 +957,37 @@
EXPECT_EQ(expected_appended_newlines_count, appended_newlines_count);
};
- base::string16 button_start_to_line1_end =
+ std::u16string button_start_to_line1_end =
BUTTON.substr().append(NEWLINE).append(LINE_1);
TestGetTextForRange(button_start->Clone(), line1_end->Clone(),
button_start_to_line1_end, 1);
- base::string16 button_start_to_line1_start = BUTTON.substr().append(NEWLINE);
+ std::u16string button_start_to_line1_start = BUTTON.substr().append(NEWLINE);
TestGetTextForRange(button_start->Clone(), line1_start->Clone(),
button_start_to_line1_start, 1);
- base::string16 button_end_to_line1_end = NEWLINE.substr().append(LINE_1);
+ std::u16string button_end_to_line1_end = NEWLINE.substr().append(LINE_1);
TestGetTextForRange(button_end->Clone(), line1_end->Clone(),
button_end_to_line1_end, 1);
- base::string16 button_end_to_line1_start = NEWLINE;
+ std::u16string button_end_to_line1_start = NEWLINE;
TestGetTextForRange(button_end->Clone(), line1_start->Clone(),
button_end_to_line1_start, 1);
- base::string16 line2_start_to_after_line_end =
+ std::u16string line2_start_to_after_line_end =
LINE_2.substr().append(NEWLINE).append(AFTER_LINE);
TestGetTextForRange(line2_start->Clone(), after_line_end->Clone(),
line2_start_to_after_line_end, 0);
- base::string16 line2_start_to_after_line_start =
+ std::u16string line2_start_to_after_line_start =
LINE_2.substr().append(NEWLINE);
TestGetTextForRange(line2_start->Clone(), after_line_start->Clone(),
line2_start_to_after_line_start, 0);
- base::string16 line2_end_to_after_line_end =
+ std::u16string line2_end_to_after_line_end =
NEWLINE.substr().append(AFTER_LINE);
TestGetTextForRange(line2_end->Clone(), after_line_end->Clone(),
line2_end_to_after_line_end, 0);
- base::string16 line2_end_to_after_line_start = NEWLINE;
+ std::u16string line2_end_to_after_line_start = NEWLINE;
TestGetTextForRange(line2_end->Clone(), after_line_start->Clone(),
line2_end_to_after_line_start, 0);
- base::string16 all_text =
+ std::u16string all_text =
BUTTON.substr().append(NEWLINE).append(TEXT_FIELD).append(AFTER_LINE);
TestPositionInstance start = AXNodePosition::CreateTextPosition(
GetTreeID(), root_.id, 0 /* text_offset */,
@@ -1012,11 +1020,11 @@
}
TEST_F(AXRangeTest, GetTextWithList) {
- const base::string16 kListMarker1 = base::ASCIIToUTF16("1. ");
- const base::string16 kListItemContent = base::ASCIIToUTF16("List item 1");
- const base::string16 kListMarker2 = base::ASCIIToUTF16("2. ");
- const base::string16 kAfterList = base::ASCIIToUTF16("After list");
- const base::string16 kAllText = kListMarker1.substr()
+ const std::u16string kListMarker1 = base::ASCIIToUTF16("1. ");
+ const std::u16string kListItemContent = base::ASCIIToUTF16("List item 1");
+ const std::u16string kListMarker2 = base::ASCIIToUTF16("2. ");
+ const std::u16string kAfterList = base::ASCIIToUTF16("After list");
+ const std::u16string kAllText = kListMarker1.substr()
.append(kListItemContent)
.append(NEWLINE)
.append(kListMarker2)
@@ -1206,15 +1214,15 @@
// empty anchor whose start and end positions are the same.
TestPositionRange button_range(button->Clone(), button->Clone());
std::vector<gfx::Rect> expected_screen_rects = {gfx::Rect(20, 20, 100, 30)};
- EXPECT_THAT(button_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(
+ ContainerEQ(button_range.GetRects(&delegate), expected_screen_rects));
// Since a check box is not visible to the text representation, it spans an
// empty anchor whose start and end positions are the same.
TestPositionRange check_box1_range(check_box1->Clone(), check_box1->Clone());
expected_screen_rects = {gfx::Rect(120, 20, 30, 30)};
- EXPECT_THAT(check_box1_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(
+ ContainerEQ(check_box1_range.GetRects(&delegate), expected_screen_rects));
// Retrieving bounding boxes of the button and both checkboxes.
TestPositionRange button_check_box2_range(button->Clone(),
@@ -1222,8 +1230,8 @@
expected_screen_rects = {gfx::Rect(20, 20, 100, 30),
gfx::Rect(120, 20, 30, 30),
gfx::Rect(150, 20, 30, 30)};
- EXPECT_THAT(button_check_box2_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(button_check_box2_range.GetRects(&delegate),
+ expected_screen_rects));
// Retrieving bounding box of text line 1, its whole range.
// 0 1 2 3 4 5
@@ -1231,8 +1239,8 @@
// |-----------|
TestPositionRange line1_whole_range(line1_start->Clone(), line1_end->Clone());
expected_screen_rects = {gfx::Rect(20, 50, 30, 30)};
- EXPECT_THAT(line1_whole_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(line1_whole_range.GetRects(&delegate),
+ expected_screen_rects));
// Retrieving bounding box of text line 1, its first half range.
// 0 1 2 3 4 5
@@ -1241,8 +1249,8 @@
TestPositionRange line1_first_half_range(line1_start->Clone(),
line1_middle->Clone());
expected_screen_rects = {gfx::Rect(20, 50, 15, 30)};
- EXPECT_THAT(line1_first_half_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(line1_first_half_range.GetRects(&delegate),
+ expected_screen_rects));
// Retrieving bounding box of text line 1, its second half range.
// 0 1 2 3 4 5
@@ -1251,8 +1259,8 @@
TestPositionRange line1_second_half_range(line1_middle->Clone(),
line1_end->Clone());
expected_screen_rects = {gfx::Rect(35, 50, 15, 30)};
- EXPECT_THAT(line1_second_half_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(line1_second_half_range.GetRects(&delegate),
+ expected_screen_rects));
// Retrieving bounding box of text line 1, its mid range.
// 0 1 2 3 4 5
@@ -1261,8 +1269,8 @@
TestPositionRange line1_mid_range(line1_second_char->Clone(),
line1_second_to_last_char->Clone());
expected_screen_rects = {gfx::Rect(25, 50, 20, 30)};
- EXPECT_THAT(line1_mid_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(
+ ContainerEQ(line1_mid_range.GetRects(&delegate), expected_screen_rects));
// Retrieving bounding box of text line 2, its whole range.
// 0 1 2 3 4 5
@@ -1270,8 +1278,8 @@
// |-----------|
TestPositionRange line2_whole_range(line2_start->Clone(), line2_end->Clone());
expected_screen_rects = {gfx::Rect(20, 80, 42, 30)};
- EXPECT_THAT(line2_whole_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(line2_whole_range.GetRects(&delegate),
+ expected_screen_rects));
// Retrieving bounding box of text line 2, its first half range.
// 0 1 2 3 4 5
@@ -1280,8 +1288,8 @@
TestPositionRange line2_first_half_range(line2_start->Clone(),
line2_middle->Clone());
expected_screen_rects = {gfx::Rect(20, 80, 21, 30)};
- EXPECT_THAT(line2_first_half_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(line2_first_half_range.GetRects(&delegate),
+ expected_screen_rects));
// Retrieving bounding box of text line 2, its second half range.
// 0 1 2 3 4 5
@@ -1290,8 +1298,8 @@
TestPositionRange line2_second_half_range(line2_middle->Clone(),
line2_end->Clone());
expected_screen_rects = {gfx::Rect(41, 80, 21, 30)};
- EXPECT_THAT(line2_second_half_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(line2_second_half_range.GetRects(&delegate),
+ expected_screen_rects));
// Retrieving bounding box of text line 2, its mid range.
// 0 1 2 3 4 5
@@ -1300,8 +1308,8 @@
TestPositionRange line2_mid_range(line2_second_char->Clone(),
line2_second_to_last_char->Clone());
expected_screen_rects = {gfx::Rect(27, 80, 28, 30)};
- EXPECT_THAT(line2_mid_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(
+ ContainerEQ(line2_mid_range.GetRects(&delegate), expected_screen_rects));
// Retrieving bounding boxes of text line 1 and line 2, the entire range.
// |L|i|n|e| |1|\n|L|i|n|e| |2|\n|
@@ -1310,8 +1318,8 @@
line2_end->Clone());
expected_screen_rects = {gfx::Rect(20, 50, 30, 30),
gfx::Rect(20, 80, 42, 30)};
- EXPECT_THAT(line1_line2_whole_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(line1_line2_whole_range.GetRects(&delegate),
+ expected_screen_rects));
// Retrieving bounding boxes of the range that spans from the middle of text
// line 1 to the middle of text line 2.
@@ -1321,8 +1329,8 @@
line2_middle->Clone());
expected_screen_rects = {gfx::Rect(35, 50, 15, 30),
gfx::Rect(20, 80, 21, 30)};
- EXPECT_THAT(line1_line2_mid_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(line1_line2_mid_range.GetRects(&delegate),
+ expected_screen_rects));
// Retrieving bounding boxes of the range that spans from the checkbox 2
// ("invisible" in the text representation) to the middle of text line 2.
@@ -1333,8 +1341,8 @@
expected_screen_rects = {gfx::Rect(150, 20, 30, 30),
gfx::Rect(20, 50, 30, 30),
gfx::Rect(20, 80, 21, 30)};
- EXPECT_THAT(check_box2_line2_mid_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(check_box2_line2_mid_range.GetRects(&delegate),
+ expected_screen_rects));
// Retrieving bounding boxes of the range spanning the entire document.
// |[Button][Checkbox 1][Checkbox 2]L|i|n|e| |1|\n|L|i|n|e| |2|\n|A|f|t|e|r|
@@ -1344,8 +1352,8 @@
gfx::Rect(20, 20, 100, 30), gfx::Rect(120, 20, 30, 30),
gfx::Rect(150, 20, 30, 30), gfx::Rect(20, 50, 30, 30),
gfx::Rect(20, 80, 42, 30), gfx::Rect(20, 110, 50, 30)};
- EXPECT_THAT(entire_test_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(entire_test_range.GetRects(&delegate),
+ expected_screen_rects));
}
TEST_F(AXRangeTest, GetRectsOffscreen) {
@@ -1384,8 +1392,8 @@
TestPositionRange entire_test_range(button->Clone(), after_line_end->Clone());
std::vector<gfx::Rect> expected_screen_rects = {gfx::Rect(20, 50, 30, 30),
gfx::Rect(20, 80, 42, 30)};
- EXPECT_THAT(entire_test_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(entire_test_range.GetRects(&delegate),
+ expected_screen_rects));
// Reset the root node bounds/viewport size back to {0, 0, 800x600}, and
// verify all elements should be onscreen.
@@ -1394,8 +1402,8 @@
gfx::Rect(20, 20, 100, 30), gfx::Rect(120, 20, 30, 30),
gfx::Rect(150, 20, 30, 30), gfx::Rect(20, 50, 30, 30),
gfx::Rect(20, 80, 42, 30), gfx::Rect(20, 110, 50, 30)};
- EXPECT_THAT(entire_test_range.GetRects(&delegate),
- testing::ContainerEq(expected_screen_rects));
+ EXPECT_TRUE(ContainerEQ(entire_test_range.GetRects(&delegate),
+ expected_screen_rects));
}
} // namespace ui
diff --git a/third_party/accessibility/ax/ax_relative_bounds.cc b/third_party/accessibility/ax/ax_relative_bounds.cc
index 871fb85..ef7eaa4 100644
--- a/third_party/accessibility/ax/ax_relative_bounds.cc
+++ b/third_party/accessibility/ax/ax_relative_bounds.cc
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_relative_bounds.h"
+#include "ax_relative_bounds.h"
-#include "base/strings/string_number_conversions.h"
-#include "ui/accessibility/ax_enum_util.h"
-#include "ui/gfx/transform.h"
+#include <math.h>
+
+#include "ax_enum_util.h"
+#include "base/string_utils.h"
using base::NumberToString;
@@ -53,13 +54,14 @@
std::string result;
if (offset_container_id != -1)
- result +=
- "offset_container_id=" + NumberToString(offset_container_id) + " ";
+ result += "offset_container_id=" +
+ NumberToString(static_cast<int>(round(offset_container_id))) +
+ " ";
- result += "(" + NumberToString(bounds.x()) + ", " +
- NumberToString(bounds.y()) + ")-(" +
- NumberToString(bounds.width()) + ", " +
- NumberToString(bounds.height()) + ")";
+ result += "(" + NumberToString(static_cast<int>(round(bounds.x()))) + ", " +
+ NumberToString(static_cast<int>(round(bounds.y()))) + ")-(" +
+ NumberToString(static_cast<int>(round(bounds.width()))) + ", " +
+ NumberToString(static_cast<int>(round(bounds.height()))) + ")";
if (transform && !transform->IsIdentity())
result += " transform=" + transform->ToString();
diff --git a/third_party/accessibility/ax/ax_relative_bounds.h b/third_party/accessibility/ax/ax_relative_bounds.h
index de780d5..317c1a1 100644
--- a/third_party/accessibility/ax/ax_relative_bounds.h
+++ b/third_party/accessibility/ax/ax_relative_bounds.h
@@ -10,10 +10,10 @@
#include <memory>
#include <ostream>
-#include "ui/accessibility/ax_base_export.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/transform.h"
+#include "ax_base_export.h"
+#include "ax_enums.h"
+#include "gfx/geometry/rect_f.h"
+#include "gfx/transform.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_role_properties.cc b/third_party/accessibility/ax/ax_role_properties.cc
index f776bb6..0e85813 100644
--- a/third_party/accessibility/ax/ax_role_properties.cc
+++ b/third_party/accessibility/ax/ax_role_properties.cc
@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_role_properties.h"
+#include "ax_role_properties.h"
-#include "build/build_config.h"
-#include "ui/accessibility/ax_enums.mojom.h"
+#include "ax_build/build_config.h"
+
+#include "ax_enums.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_role_properties.h b/third_party/accessibility/ax/ax_role_properties.h
index 724de52..a6519b0 100644
--- a/third_party/accessibility/ax/ax_role_properties.h
+++ b/third_party/accessibility/ax/ax_role_properties.h
@@ -5,8 +5,8 @@
#ifndef UI_ACCESSIBILITY_AX_ROLE_PROPERTIES_H_
#define UI_ACCESSIBILITY_AX_ROLE_PROPERTIES_H_
-#include "ui/accessibility/ax_base_export.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
+#include "ax_base_export.h"
+#include "ax_enums.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_role_properties_unittest.cc b/third_party/accessibility/ax/ax_role_properties_unittest.cc
index beb9a13..dee7e63 100644
--- a/third_party/accessibility/ax/ax_role_properties_unittest.cc
+++ b/third_party/accessibility/ax/ax_role_properties_unittest.cc
@@ -4,11 +4,11 @@
#include <unordered_set>
-#include "testing/gtest/include/gtest/gtest.h"
+#include "gtest/gtest.h"
-#include "ui/accessibility/ax_enum_util.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_role_properties.h"
+#include "ax_enum_util.h"
+#include "ax_enums.h"
+#include "ax_role_properties.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_serializable_tree.cc b/third_party/accessibility/ax/ax_serializable_tree.cc
deleted file mode 100644
index 959f41b..0000000
--- a/third_party/accessibility/ax/ax_serializable_tree.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_serializable_tree.h"
-
-#include <stdint.h>
-
-#include "ui/accessibility/ax_node.h"
-
-namespace ui {
-
-// This class is an implementation of the AXTreeSource interface with
-// AXNode as the node type, that just delegates to an AXTree. The purpose
-// of this is so that AXTreeSerializer only needs to work with the
-// AXTreeSource abstraction and doesn't need to actually know about
-// AXTree directly. Another AXTreeSource is used to abstract the Blink
-// accessibility tree.
-class AX_EXPORT AXTreeSourceAdapter
- : public AXTreeSource<const AXNode*, AXNodeData, AXTreeData> {
- public:
- AXTreeSourceAdapter(AXTree* tree) : tree_(tree) {}
- ~AXTreeSourceAdapter() override {}
-
- // AXTreeSource implementation.
- bool GetTreeData(AXTreeData* data) const override {
- *data = tree_->data();
- return true;
- }
-
- AXNode* GetRoot() const override { return tree_->root(); }
-
- AXNode* GetFromId(int32_t id) const override { return tree_->GetFromId(id); }
-
- int32_t GetId(const AXNode* node) const override { return node->id(); }
-
- void GetChildren(const AXNode* node,
- std::vector<const AXNode*>* out_children) const override {
- *out_children = std::vector<const AXNode*>(node->children().cbegin(),
- node->children().cend());
- }
-
- AXNode* GetParent(const AXNode* node) const override {
- return node->parent();
- }
-
- bool IsIgnored(const AXNode* node) const override {
- return node->IsIgnored();
- }
-
- bool IsValid(const AXNode* node) const override { return node != nullptr; }
-
- bool IsEqual(const AXNode* node1, const AXNode* node2) const override {
- return node1 == node2;
- }
-
- const AXNode* GetNull() const override { return nullptr; }
-
- void SerializeNode(const AXNode* node, AXNodeData* out_data) const override {
- *out_data = node->data();
- }
-
- private:
- AXTree* tree_;
-};
-
-AXSerializableTree::AXSerializableTree() : AXTree() {}
-
-AXSerializableTree::AXSerializableTree(const AXTreeUpdate& initial_state)
- : AXTree(initial_state) {}
-
-AXSerializableTree::~AXSerializableTree() {}
-
-AXTreeSource<const AXNode*, AXNodeData, AXTreeData>*
-AXSerializableTree::CreateTreeSource() {
- return new AXTreeSourceAdapter(this);
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_serializable_tree.h b/third_party/accessibility/ax/ax_serializable_tree.h
deleted file mode 100644
index e618da9..0000000
--- a/third_party/accessibility/ax/ax_serializable_tree.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_SERIALIZABLE_TREE_H_
-#define UI_ACCESSIBILITY_AX_SERIALIZABLE_TREE_H_
-
-#include "ui/accessibility/ax_tree.h"
-#include "ui/accessibility/ax_tree_source.h"
-
-namespace ui {
-
-class AX_EXPORT AXSerializableTree : public AXTree {
- public:
- AXSerializableTree();
- explicit AXSerializableTree(const AXTreeUpdate& initial_state);
- ~AXSerializableTree() override;
-
- // Create a TreeSource adapter for this tree. The client gets ownership
- // of the return value and should delete it when done.
- virtual AXTreeSource<const AXNode*, AXNodeData, AXTreeData>*
- CreateTreeSource();
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_TREE_H_
diff --git a/third_party/accessibility/ax/ax_table_fuzzer.cc b/third_party/accessibility/ax/ax_table_fuzzer.cc
deleted file mode 100644
index b3b4224..0000000
--- a/third_party/accessibility/ax/ax_table_fuzzer.cc
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/macros.h"
-#include "build/build_config.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_tree.h"
-
-// The purpose of this script is to fuzz code that parses
-// table-like structures. As a result, we want to generate
-// accessibility trees that contain lots of table-related
-// roles.
-//
-// We also bias towards cells and rows so that we end up
-// with more of those overall.
-ax::mojom::Role GetInterestingTableRole(unsigned char byte) {
- switch (byte % 16) {
- default:
- case 0:
- case 1:
- case 2:
- case 3:
- return ax::mojom::Role::kCell;
- case 4:
- case 5:
- return ax::mojom::Role::kRow;
- case 6:
- return ax::mojom::Role::kTable;
- case 7:
- return ax::mojom::Role::kGrid;
- case 8:
- return ax::mojom::Role::kColumnHeader;
- case 9:
- return ax::mojom::Role::kRowHeader;
- case 10:
- return ax::mojom::Role::kGenericContainer;
- case 11:
- return ax::mojom::Role::kIgnored;
- case 12:
- return ax::mojom::Role::kLayoutTable;
- case 13:
- return ax::mojom::Role::kLayoutTableCell;
- case 14:
- return ax::mojom::Role::kLayoutTableRow;
- case 15:
- return ax::mojom::Role::kMain;
- }
-}
-
-// We want some of the nodes in the accessibility tree to have
-// table-related attributes.
-ax::mojom::IntAttribute GetInterestingTableAttribute(unsigned char byte) {
- switch (byte % 10) {
- case 0:
- default:
- return ax::mojom::IntAttribute::kTableCellRowIndex;
- case 1:
- return ax::mojom::IntAttribute::kTableCellColumnIndex;
- case 2:
- return ax::mojom::IntAttribute::kTableRowCount;
- case 3:
- return ax::mojom::IntAttribute::kTableColumnCount;
- case 4:
- return ax::mojom::IntAttribute::kAriaRowCount;
- case 5:
- return ax::mojom::IntAttribute::kAriaColumnCount;
- case 6:
- return ax::mojom::IntAttribute::kTableCellRowSpan;
- case 7:
- return ax::mojom::IntAttribute::kTableCellColumnSpan;
- case 8:
- return ax::mojom::IntAttribute::kAriaCellRowIndex;
- case 9:
- return ax::mojom::IntAttribute::kAriaCellColumnIndex;
- }
-}
-
-// Call all of the table-related APIs on an accessibility node.
-// These will be no-ops if the node is not part of a complete
-// table. We don't care about any of the results, we just want
-// to make sure none of these crash or hang.
-void TestTableAPIs(const ui::AXNode* node) {
- ignore_result(node->IsTable());
- ignore_result(node->GetTableColCount());
- ignore_result(node->GetTableRowCount());
- ignore_result(node->GetTableAriaColCount());
- ignore_result(node->GetTableAriaRowCount());
- ignore_result(node->GetTableCellCount());
- ignore_result(node->GetTableCaption());
- for (int i = 0; i < 8; i++)
- ignore_result(node->GetTableCellFromIndex(i));
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- ignore_result(node->GetTableCellFromCoords(i, j));
- // Note: some of the APIs return IDs - we don't care what's
- // returned, we just want to make sure these APIs don't
- // crash. Normally |ids| is an out argument only, but
- // there's no reason we shouldn't be able to pass a vector
- // that was previously used by another call.
- std::vector<ui::AXNode::AXID> ids;
- for (int i = 0; i < 3; i++) {
- std::vector<ui::AXNode::AXID> col_header_node_ids =
- node->GetTableColHeaderNodeIds(i);
- ids.insert(ids.end(), col_header_node_ids.begin(),
- col_header_node_ids.end());
-
- std::vector<ui::AXNode::AXID> row_header_node_ids =
- node->GetTableRowHeaderNodeIds(i);
- ids.insert(ids.end(), row_header_node_ids.begin(),
- row_header_node_ids.end());
- }
- std::vector<ui::AXNode::AXID> unique_cell_ids = node->GetTableUniqueCellIds();
- ids.insert(ids.end(), unique_cell_ids.begin(), unique_cell_ids.end());
-
- ignore_result(node->IsTableRow());
- ignore_result(node->GetTableRowRowIndex());
-#if defined(OS_APPLE)
- ignore_result(node->IsTableColumn());
- ignore_result(node->GetTableColColIndex());
-#endif
- ignore_result(node->IsTableCellOrHeader());
- ignore_result(node->GetTableCellIndex());
- ignore_result(node->GetTableCellColIndex());
- ignore_result(node->GetTableCellRowIndex());
- ignore_result(node->GetTableCellColSpan());
- ignore_result(node->GetTableCellRowSpan());
- ignore_result(node->GetTableCellAriaColIndex());
- ignore_result(node->GetTableCellAriaRowIndex());
- std::vector<ui::AXNode::AXID> cell_col_header_node_ids =
- node->GetTableCellColHeaderNodeIds();
- ids.insert(ids.end(), cell_col_header_node_ids.begin(),
- cell_col_header_node_ids.end());
- std::vector<ui::AXNode::AXID> cell_row_header_node_ids =
- node->GetTableCellRowHeaderNodeIds();
- ids.insert(ids.end(), cell_row_header_node_ids.begin(),
- cell_row_header_node_ids.end());
- std::vector<ui::AXNode*> headers;
- node->GetTableCellColHeaders(&headers);
- node->GetTableCellRowHeaders(&headers);
-
- for (const auto* child : node->children())
- TestTableAPIs(child);
-}
-
-// Entry point for LibFuzzer.
-extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) {
- ui::AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- size_t i = 0;
-
- // The root of the accessibility tree.
- ui::AXNodeData root;
- root.id = 1;
- if (i < size)
- root.role = GetInterestingTableRole(data[i++]);
- root.child_ids.push_back(2);
- initial_state.nodes.push_back(root);
-
- // Force the next node of the accessibility tree to be a table,
- // and give it no attributes but a few children.
- ui::AXNodeData table;
- table.id = 2;
- table.role = ax::mojom::Role::kTable;
- if (i < size) {
- size_t child_count = data[i++] % 8;
- for (size_t j = 0; j < child_count && i < size; j++)
- table.child_ids.push_back(3 + data[i++] % 32);
- }
- initial_state.nodes.push_back(table);
-
- // Create more accessibility nodes that might result in a table.
- int next_id = 3;
- while (i < size) {
- ui::AXNodeData node;
- node.id = next_id++;
- if (i < size)
- node.role = GetInterestingTableRole(data[i++]);
- if (i < size) {
- int attr_count = data[i++] % 6;
- for (int j = 0; j < attr_count && i + 1 < size; j++) {
- unsigned char attr = data[i++];
- int32_t value = static_cast<int32_t>(data[i++]) - 2;
- node.AddIntAttribute(GetInterestingTableAttribute(attr), value);
- }
- }
- if (i < size) {
- size_t child_count = data[i++] % 8;
- for (size_t j = 0; j < child_count && i < size; j++)
- node.child_ids.push_back(4 + data[i++] % 32);
- }
- initial_state.nodes.push_back(node);
- }
-
- // Run with --v=1 to aid in debugging a specific crash.
- VLOG(1) << "Input accessibility tree:\n" << initial_state.ToString();
-
- ui::AXTree tree;
- if (tree.Unserialize(initial_state))
- TestTableAPIs(tree.root());
-
- return 0;
-}
diff --git a/third_party/accessibility/ax/ax_table_info.cc b/third_party/accessibility/ax/ax_table_info.cc
index a861036..fe0d437 100644
--- a/third_party/accessibility/ax/ax_table_info.cc
+++ b/third_party/accessibility/ax/ax_table_info.cc
@@ -2,16 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_table_info.h"
+#include "ax_table_info.h"
-#include "base/strings/string_util.h"
-#include "ui/accessibility/ax_constants.mojom.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_tree.h"
-#include "ui/accessibility/ax_tree_observer.h"
-#include "ui/gfx/geometry/rect_f.h"
+#include <stddef.h>
+
+#include "ax_constants.h"
+#include "ax_enums.h"
+#include "ax_node.h"
+#include "ax_role_properties.h"
+#include "ax_tree.h"
+#include "ax_tree_observer.h"
+#include "base/logging.h"
using ax::mojom::IntAttribute;
@@ -72,15 +73,15 @@
// static
AXTableInfo* AXTableInfo::Create(AXTree* tree, AXNode* table_node) {
- DCHECK(tree);
- DCHECK(table_node);
+ BASE_DCHECK(tree);
+ BASE_DCHECK(table_node);
-#if DCHECK_IS_ON()
+#ifndef NDEBUG
// Sanity check, make sure the node is in the tree.
AXNode* node = table_node;
while (node && node != tree->root())
node = node->parent();
- DCHECK(node == tree->root());
+ BASE_DCHECK(node == tree->root());
#endif
if (!IsTableLike(table_node->data().role))
@@ -88,7 +89,7 @@
AXTableInfo* info = new AXTableInfo(tree, table_node);
bool success = info->Update();
- DCHECK(success);
+ BASE_DCHECK(success);
return info;
}
@@ -103,7 +104,7 @@
caption_id = 0;
FindRowsAndThenCells(table_node_, &row_nodes, &cell_nodes_per_row,
caption_id);
- DCHECK_EQ(cell_nodes_per_row.size(), row_nodes.size());
+ BASE_DCHECK(cell_nodes_per_row.size() == row_nodes.size());
// Get the optional row and column count from the table. If we encounter
// a cell with an index or span larger than this, we'll update the
@@ -113,10 +114,10 @@
// Note - GetIntAttribute returns 0 if no value has been specified for the
// attribute.
- aria_row_count =
- int{table_node_->GetIntAttribute(IntAttribute::kAriaRowCount)};
- aria_col_count =
- int{table_node_->GetIntAttribute(IntAttribute::kAriaColumnCount)};
+ aria_row_count = static_cast<int>(
+ table_node_->GetIntAttribute(IntAttribute::kAriaRowCount));
+ aria_col_count = static_cast<int>(
+ table_node_->GetIntAttribute(IntAttribute::kAriaColumnCount));
// Iterate over the cells and build up an array of CellData
// entries, one for each cell. Compute the actual row and column
@@ -295,14 +296,14 @@
row_count = std::max(row_count, cell_data.row_index + cell_data.row_span);
col_count = std::max(col_count, cell_data.col_index + cell_data.col_span);
if (aria_row_count != ax::mojom::kUnknownAriaColumnOrRowCount) {
- aria_row_count =
- std::max((aria_row_count),
- int{current_aria_row_index + cell_data.row_span - 1});
+ aria_row_count = std::max(
+ (aria_row_count),
+ static_cast<int>(current_aria_row_index + cell_data.row_span - 1));
}
if (aria_col_count != ax::mojom::kUnknownAriaColumnOrRowCount) {
- aria_col_count =
- std::max((aria_col_count),
- int{current_aria_col_index + cell_data.col_span - 1});
+ aria_col_count = std::max(
+ (aria_col_count),
+ static_cast<int>(current_aria_col_index + cell_data.col_span - 1));
}
// Update |current_col_index| to reflect the next available index after
// this cell including its colspan. The next column index in this row
@@ -358,10 +359,10 @@
for (auto& cell_data : cell_data_vector) {
for (size_t r = cell_data.row_index;
r < cell_data.row_index + cell_data.row_span; r++) {
- DCHECK_LT(r, row_count);
+ BASE_DCHECK(r < row_count);
for (size_t c = cell_data.col_index;
c < cell_data.col_index + cell_data.col_span; c++) {
- DCHECK_LT(c, col_count);
+ BASE_DCHECK(c < col_count);
AXNode* cell = cell_data.cell;
if (cell->data().role == ax::mojom::Role::kColumnHeader) {
col_headers[c].push_back(cell->id());
@@ -434,8 +435,8 @@
changes.push_back(AXTreeObserver::Change(
table_node_, AXTreeObserver::ChangeType::NODE_CHANGED));
- for (AXTreeObserver& observer : tree_->observers()) {
- observer.OnAtomicUpdateFinished(tree_, false, changes);
+ for (AXTreeObserver* observer : tree_->observers()) {
+ observer->OnAtomicUpdateFinished(tree_, false, changes);
}
}
@@ -450,8 +451,8 @@
data.id = id;
data.role = ax::mojom::Role::kColumn;
node->SetData(data);
- for (AXTreeObserver& observer : tree_->observers())
- observer.OnNodeCreated(tree_, node);
+ for (AXTreeObserver* observer : tree_->observers())
+ observer->OnNodeCreated(tree_, node);
return node;
}
@@ -467,8 +468,8 @@
data.role = ax::mojom::Role::kTableHeaderContainer;
node->SetData(data);
- for (AXTreeObserver& observer : tree_->observers())
- observer.OnNodeCreated(tree_, node);
+ for (AXTreeObserver* observer : tree_->observers())
+ observer->OnNodeCreated(tree_, node);
return node;
}
@@ -478,7 +479,8 @@
data.int_attributes.clear();
// Update the column index.
- data.AddIntAttribute(IntAttribute::kTableColumnIndex, int32_t{col_index});
+ data.AddIntAttribute(IntAttribute::kTableColumnIndex,
+ static_cast<int32_t>(col_index));
// Update the column header.
if (!col_headers[col_index].empty()) {
@@ -503,12 +505,12 @@
void AXTableInfo::ClearExtraMacNodes() {
for (AXNode* extra_mac_node : extra_mac_nodes) {
- for (AXTreeObserver& observer : tree_->observers())
- observer.OnNodeWillBeDeleted(tree_, extra_mac_node);
+ for (AXTreeObserver* observer : tree_->observers())
+ observer->OnNodeWillBeDeleted(tree_, extra_mac_node);
AXNode::AXID deleted_id = extra_mac_node->id();
delete extra_mac_node;
- for (AXTreeObserver& observer : tree_->observers())
- observer.OnNodeDeleted(tree_, deleted_id);
+ for (AXTreeObserver* observer : tree_->observers())
+ observer->OnNodeDeleted(tree_, deleted_id);
}
extra_mac_nodes.clear();
}
@@ -545,8 +547,8 @@
AXTableInfo::~AXTableInfo() {
if (!extra_mac_nodes.empty()) {
ClearExtraMacNodes();
- for (AXTreeObserver& observer : tree_->observers()) {
- observer.OnAtomicUpdateFinished(
+ for (AXTreeObserver* observer : tree_->observers()) {
+ observer->OnAtomicUpdateFinished(
tree_, false,
{{table_node_, AXTreeObserver::ChangeType::NODE_CHANGED}});
}
diff --git a/third_party/accessibility/ax/ax_table_info.h b/third_party/accessibility/ax/ax_table_info.h
index 3bfb246..53086c4 100644
--- a/third_party/accessibility/ax/ax_table_info.h
+++ b/third_party/accessibility/ax/ax_table_info.h
@@ -10,8 +10,7 @@
#include <unordered_map>
#include <vector>
-#include "base/optional.h"
-#include "ui/accessibility/ax_export.h"
+#include "ax_export.h"
namespace ui {
@@ -122,4 +121,4 @@
} // namespace ui
-#endif // UI_ACCESSIBILITY_AX_TABLE_INFO
+#endif // UI_ACCESSIBILITY_TABLE_INFO
diff --git a/third_party/accessibility/ax/ax_table_info_unittest.cc b/third_party/accessibility/ax/ax_table_info_unittest.cc
index a3631a6..c87e5a8 100644
--- a/third_party/accessibility/ax/ax_table_info_unittest.cc
+++ b/third_party/accessibility/ax/ax_table_info_unittest.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_table_info.h"
+#include "ax_table_info.h"
-#include "base/stl_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_tree.h"
+#include "gtest/gtest.h"
+
+#include "ax_enums.h"
+#include "ax_node.h"
+#include "ax_tree.h"
namespace ui {
@@ -72,7 +72,7 @@
} // namespace
-// A macro for testing that a base::Optional has both a value and that its value
+// A macro for testing that a std::optional has both a value and that its value
// is set to a particular expectation.
#define EXPECT_OPTIONAL_EQ(expected, actual) \
EXPECT_TRUE(actual.has_value()); \
@@ -91,7 +91,7 @@
}
private:
- DISALLOW_COPY_AND_ASSIGN(AXTableInfoTest);
+ BASE_DISALLOW_COPY_AND_ASSIGN(AXTableInfoTest);
};
TEST_F(AXTableInfoTest, SimpleTable) {
diff --git a/third_party/accessibility/ax/ax_text_utils.cc b/third_party/accessibility/ax/ax_text_utils.cc
deleted file mode 100644
index bda3a61..0000000
--- a/third_party/accessibility/ax/ax_text_utils.cc
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_text_utils.h"
-
-#include <algorithm>
-
-#include "base/check_op.h"
-#include "base/i18n/break_iterator.h"
-#include "base/notreached.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/optional.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-
-namespace ui {
-
-namespace {
-
-base::i18n::BreakIterator::BreakType ICUBreakTypeForBoundaryType(
- ax::mojom::TextBoundary boundary) {
- switch (boundary) {
- case ax::mojom::TextBoundary::kCharacter:
- return base::i18n::BreakIterator::BREAK_CHARACTER;
- case ax::mojom::TextBoundary::kSentenceStart:
- return base::i18n::BreakIterator::BREAK_SENTENCE;
- case ax::mojom::TextBoundary::kWordStart:
- case ax::mojom::TextBoundary::kWordStartOrEnd:
- return base::i18n::BreakIterator::BREAK_WORD;
- // These are currently unused since line breaking is done via an array of
- // line break offsets, and object boundary by finding no boundary within the
- // current node.
- case ax::mojom::TextBoundary::kObject:
- case ax::mojom::TextBoundary::kLineStart:
- case ax::mojom::TextBoundary::kParagraphStart:
- return base::i18n::BreakIterator::BREAK_NEWLINE;
- default:
- NOTREACHED() << boundary;
- return base::i18n::BreakIterator::BREAK_NEWLINE;
- }
-}
-
-} // namespace
-
-// line_breaks is a Misnomer. Blink provides the start offsets of each line
-// not the line breaks.
-// TODO(nektar): Rename line_breaks a11y attribute and variable references.
-size_t FindAccessibleTextBoundary(const base::string16& text,
- const std::vector<int>& line_breaks,
- ax::mojom::TextBoundary boundary,
- size_t start_offset,
- ax::mojom::MoveDirection direction,
- ax::mojom::TextAffinity affinity) {
- size_t text_size = text.size();
- DCHECK_LE(start_offset, text_size);
-
- base::i18n::BreakIterator::BreakType break_type =
- ICUBreakTypeForBoundaryType(boundary);
- base::i18n::BreakIterator break_iter(text, break_type);
- if (boundary == ax::mojom::TextBoundary::kCharacter ||
- boundary == ax::mojom::TextBoundary::kSentenceStart ||
- boundary == ax::mojom::TextBoundary::kWordStart ||
- boundary == ax::mojom::TextBoundary::kWordStartOrEnd) {
- if (!break_iter.Init())
- return start_offset;
- }
-
- if (boundary == ax::mojom::TextBoundary::kLineStart) {
- if (direction == ax::mojom::MoveDirection::kForward) {
- for (int line_break : line_breaks) {
- size_t clamped_line_break = size_t{std::max(0, line_break)};
- if ((affinity == ax::mojom::TextAffinity::kDownstream &&
- clamped_line_break > start_offset) ||
- (affinity == ax::mojom::TextAffinity::kUpstream &&
- clamped_line_break >= start_offset)) {
- return clamped_line_break;
- }
- }
- return text_size;
- } else {
- for (size_t j = line_breaks.size(); j != 0; --j) {
- size_t line_break = line_breaks[j - 1] >= 0 ? line_breaks[j - 1] : 0;
- if ((affinity == ax::mojom::TextAffinity::kDownstream &&
- line_break <= start_offset) ||
- (affinity == ax::mojom::TextAffinity::kUpstream &&
- line_break < start_offset)) {
- return line_break;
- }
- }
- return 0;
- }
- }
-
- size_t result = start_offset;
- for (;;) {
- size_t pos;
- if (direction == ax::mojom::MoveDirection::kForward) {
- if (result >= text_size)
- return text_size;
- pos = result;
- } else {
- if (result == 0)
- return 0;
- pos = result - 1;
- }
-
- switch (boundary) {
- case ax::mojom::TextBoundary::kLineStart:
- NOTREACHED() << boundary; // This is handled above.
- return result;
- case ax::mojom::TextBoundary::kCharacter:
- if (break_iter.IsGraphemeBoundary(result)) {
- // If we are searching forward and we are still at the start offset,
- // we need to find the next character.
- if (direction == ax::mojom::MoveDirection::kBackward ||
- result != start_offset)
- return result;
- }
- break;
- case ax::mojom::TextBoundary::kWordStart:
- if (break_iter.IsStartOfWord(result)) {
- // If we are searching forward and we are still at the start offset,
- // we need to find the next word.
- if (direction == ax::mojom::MoveDirection::kBackward ||
- result != start_offset)
- return result;
- }
- break;
- case ax::mojom::TextBoundary::kWordStartOrEnd:
- if (break_iter.IsStartOfWord(result)) {
- // If we are searching forward and we are still at the start offset,
- // we need to find the next word.
- if (direction == ax::mojom::MoveDirection::kBackward ||
- result != start_offset)
- return result;
- } else if (break_iter.IsEndOfWord(result)) {
- // If we are searching backward and we are still at the end offset, we
- // need to find the previous word.
- if (direction == ax::mojom::MoveDirection::kForward ||
- result != start_offset)
- return result;
- }
- break;
- case ax::mojom::TextBoundary::kSentenceStart:
- if (break_iter.IsSentenceBoundary(result)) {
- // If we are searching forward and we are still at the start offset,
- // we need to find the next sentence.
- if (direction == ax::mojom::MoveDirection::kBackward ||
- result != start_offset) {
- // ICU sometimes returns sentence boundaries in the whitespace
- // between sentences. For the purposes of accessibility, we want to
- // include all whitespace at the end of a sentence. We move the
- // boundary past the last whitespace offset. This works the same for
- // backwards and forwards searches.
- while (result < text_size &&
- base::IsUnicodeWhitespace(text[result]))
- result++;
- return result;
- }
- }
- break;
- case ax::mojom::TextBoundary::kParagraphStart:
- if (text[pos] == '\n')
- return result;
- break;
- default:
- break;
- }
-
- if (direction == ax::mojom::MoveDirection::kForward) {
- result++;
- } else {
- result--;
- }
- }
-}
-
-std::vector<int> GetWordStartOffsets(const base::string16& text) {
- std::vector<int> word_starts;
- base::i18n::BreakIterator iter(text, base::i18n::BreakIterator::BREAK_WORD);
- if (!iter.Init())
- return word_starts;
- // iter.Advance() returns false if we've run past end of the text.
- while (iter.Advance()) {
- if (!iter.IsWord())
- continue;
- word_starts.push_back(
- base::checked_cast<int>(iter.prev()) /* start index */);
- }
- return word_starts;
-}
-
-std::vector<int> GetWordEndOffsets(const base::string16& text) {
- std::vector<int> word_ends;
- base::i18n::BreakIterator iter(text, base::i18n::BreakIterator::BREAK_WORD);
- if (!iter.Init())
- return word_ends;
- // iter.Advance() returns false if we've run past end of the text.
- while (iter.Advance()) {
- if (!iter.IsWord())
- continue;
- word_ends.push_back(base::checked_cast<int>(iter.pos()) /* end index */);
- }
- return word_ends;
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_text_utils.h b/third_party/accessibility/ax/ax_text_utils.h
deleted file mode 100644
index 7e4d0ea..0000000
--- a/third_party/accessibility/ax/ax_text_utils.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_TEXT_UTILS_H_
-#define UI_ACCESSIBILITY_AX_TEXT_UTILS_H_
-
-#include <stddef.h>
-
-#include <vector>
-
-#include "base/strings/string16.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-
-namespace ui {
-
-// Convenience method needed to implement platform-specific text
-// accessibility APIs like IAccessible2. Search forwards or backwards
-// (depending on |direction|) from the given |start_offset| until the
-// given boundary is found, and return the offset of that boundary,
-// using the vector of line break character offsets in |line_breaks|.
-AX_EXPORT size_t FindAccessibleTextBoundary(const base::string16& text,
- const std::vector<int>& line_breaks,
- ax::mojom::TextBoundary boundary,
- size_t start_offset,
- ax::mojom::MoveDirection direction,
- ax::mojom::TextAffinity affinity);
-
-// Returns a string ID that corresponds to the name of the given action.
-AX_EXPORT base::string16 ActionVerbToLocalizedString(
- const ax::mojom::DefaultActionVerb action_verb);
-
-// Returns the non-localized string representation of a supported action.
-// Some APIs on Linux and Windows need to return non-localized action names.
-AX_EXPORT base::string16 ActionVerbToUnlocalizedString(
- const ax::mojom::DefaultActionVerb action_verb);
-
-// Returns indices of all word starts in |text|.
-AX_EXPORT std::vector<int> GetWordStartOffsets(const base::string16& text);
-// Returns indices of all word ends in |text|.
-AX_EXPORT std::vector<int> GetWordEndOffsets(const base::string16& text);
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_TEXT_UTILS_H_
diff --git a/third_party/accessibility/ax/ax_text_utils_unittest.cc b/third_party/accessibility/ax/ax_text_utils_unittest.cc
deleted file mode 100644
index 39d3f2b..0000000
--- a/third_party/accessibility/ax/ax_text_utils_unittest.cc
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_text_utils.h"
-
-#include <stddef.h>
-#include <utility>
-
-#include "base/strings/utf_string_conversions.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-
-namespace ui {
-
-TEST(AXTextUtils, FindAccessibleTextBoundaryWord) {
- const base::string16 text =
- base::UTF8ToUTF16("Hello there.This/is\ntesting.");
- const size_t text_length = text.length();
- std::vector<int> line_start_offsets;
- line_start_offsets.push_back(19);
- size_t result;
-
- result = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kWordStart, 0,
- ax::mojom::MoveDirection::kForward, ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(6UL, result);
- result = FindAccessibleTextBoundary(text, line_start_offsets,
- ax::mojom::TextBoundary::kWordStart, 5,
- ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(0UL, result);
- result = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kWordStart, 6,
- ax::mojom::MoveDirection::kForward, ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(12UL, result);
- result = FindAccessibleTextBoundary(text, line_start_offsets,
- ax::mojom::TextBoundary::kWordStart, 11,
- ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(6UL, result);
- result = FindAccessibleTextBoundary(text, line_start_offsets,
- ax::mojom::TextBoundary::kWordStart, 12,
- ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(12UL, result);
- result = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kWordStart, 15,
- ax::mojom::MoveDirection::kForward, ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(17UL, result);
- result = FindAccessibleTextBoundary(text, line_start_offsets,
- ax::mojom::TextBoundary::kWordStart, 15,
- ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(12UL, result);
- result = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kWordStart, 16,
- ax::mojom::MoveDirection::kForward, ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(17UL, result);
- result = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kWordStart, 17,
- ax::mojom::MoveDirection::kForward, ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(20UL, result);
- result = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kWordStart, 20,
- ax::mojom::MoveDirection::kForward, ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(text_length, result);
- result = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kWordStart,
- text_length, ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(20UL, result);
-}
-
-TEST(AXTextUtils, FindAccessibleTextBoundaryLine) {
- const base::string16 text = base::UTF8ToUTF16("Line 1.\nLine 2\n\t");
- const size_t text_length = text.length();
- std::vector<int> line_start_offsets;
- line_start_offsets.push_back(8);
- line_start_offsets.push_back(15);
- size_t result;
-
- // Basic cases.
- result = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kLineStart, 5,
- ax::mojom::MoveDirection::kForward, ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(8UL, result);
- result = FindAccessibleTextBoundary(text, line_start_offsets,
- ax::mojom::TextBoundary::kLineStart, 9,
- ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(8UL, result);
- result = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kLineStart, 10,
- ax::mojom::MoveDirection::kForward, ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(15UL, result);
-
- // Edge cases.
- result = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kLineStart,
- text_length, ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(15UL, result);
-
- // When the start_offset is at the start of the next line and we are searching
- // backwards, it should not move.
- result = FindAccessibleTextBoundary(text, line_start_offsets,
- ax::mojom::TextBoundary::kLineStart, 15,
- ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(15UL, result);
-
- // When the start_offset is at a hard line break and we are searching
- // backwards, it should return the start of the previous line.
- result = FindAccessibleTextBoundary(text, line_start_offsets,
- ax::mojom::TextBoundary::kLineStart, 14,
- ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(8UL, result);
-
- // When the start_offset is at the start of a line and we are searching
- // forwards, it should return the start of the next line.
- result = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kLineStart, 8,
- ax::mojom::MoveDirection::kForward, ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(15UL, result);
-
- // When there is no previous line break and we are searching backwards,
- // it should return 0.
- result = FindAccessibleTextBoundary(text, line_start_offsets,
- ax::mojom::TextBoundary::kLineStart, 4,
- ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(0UL, result);
-
- // When we are at the start of the last line and we are searching forwards.
- // it should return the text length.
- result = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kLineStart, 15,
- ax::mojom::MoveDirection::kForward, ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(text_length, result);
-}
-
-TEST(AXTextUtils, FindAccessibleTextBoundarySentence) {
- auto find_sentence_boundaries_at_offset = [](const base::string16& text,
- int offset) {
- std::vector<int> line_start_offsets;
- size_t backwards = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kSentenceStart,
- offset, ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- size_t forwards = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kSentenceStart,
- offset, ax::mojom::MoveDirection::kForward,
- ax::mojom::TextAffinity::kDownstream);
- return std::make_pair(backwards, forwards);
- };
-
- const base::string16 text =
- base::UTF8ToUTF16("Sentence 1. Sentence 2...\n\tSentence 3! Sentence 4");
- std::pair<size_t, size_t> boundaries =
- find_sentence_boundaries_at_offset(text, 5);
- EXPECT_EQ(0UL, boundaries.first);
- EXPECT_EQ(12UL, boundaries.second);
-
- // When a sentence ends with multiple punctuation, we should look for the
- // first word character that follows.
- boundaries = find_sentence_boundaries_at_offset(text, 16);
- EXPECT_EQ(12UL, boundaries.first);
- EXPECT_EQ(27UL, boundaries.second);
-
- // This is also true if we start in the middle of that punctuation.
- boundaries = find_sentence_boundaries_at_offset(text, 23);
- EXPECT_EQ(12UL, boundaries.first);
- EXPECT_EQ(27UL, boundaries.second);
-
- // When the offset is in the whitespace between two sentences, the boundaries
- // should be those of the previous sentence to the beginning of the first
- // non-whitespace character of the next one.
- boundaries = find_sentence_boundaries_at_offset(text, 38);
- EXPECT_EQ(27UL, boundaries.first);
- EXPECT_EQ(39UL, boundaries.second);
-
- // The end of the string should be considered the end of the last sentence
- // regardless of whether or not there is punctuation.
- boundaries = find_sentence_boundaries_at_offset(text, 44);
- EXPECT_EQ(39UL, boundaries.first);
- EXPECT_EQ(49UL, boundaries.second);
-
- // The sentence should include whitespace all the way until the end of the
- // string.
- const base::string16 text2 = base::UTF8ToUTF16("A sentence . \n\n\t\t\n");
- boundaries = find_sentence_boundaries_at_offset(text2, 10);
- EXPECT_EQ(0UL, boundaries.first);
- EXPECT_EQ(18UL, boundaries.second);
-}
-
-TEST(AXTextUtils, FindAccessibleTextBoundaryCharacter) {
- static const wchar_t* kCharacters[] = {
- // An English word consisting of four ASCII characters.
- L"w",
- L"o",
- L"r",
- L"d",
- L" ",
- // A Hindi word (which means "Hindi") consisting of three Devanagari
- // characters.
- L"\x0939\x093F",
- L"\x0928\x094D",
- L"\x0926\x0940",
- L" ",
- // A Thai word (which means "feel") consisting of three Thai characters.
- L"\x0E23\x0E39\x0E49",
- L"\x0E2A\x0E36",
- L"\x0E01",
- L" ",
- };
-
- std::vector<base::string16> characters;
- base::string16 text;
- for (auto*& i : kCharacters) {
- characters.push_back(base::WideToUTF16(i));
- text.append(characters.back());
- }
-
- auto verify_boundaries_at_offset = [&text](int offset, size_t start,
- size_t end) {
- testing::Message message;
- message << "Testing character bounds at index " << offset;
- SCOPED_TRACE(message);
-
- std::vector<int> line_start_offsets;
- size_t backwards = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kCharacter, offset,
- ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(backwards, start);
-
- size_t forwards = FindAccessibleTextBoundary(
- text, line_start_offsets, ax::mojom::TextBoundary::kCharacter, offset,
- ax::mojom::MoveDirection::kForward,
- ax::mojom::TextAffinity::kDownstream);
- EXPECT_EQ(forwards, end);
- };
-
- verify_boundaries_at_offset(0, 0UL, 1UL);
- verify_boundaries_at_offset(1, 1UL, 2UL);
- verify_boundaries_at_offset(2, 2UL, 3UL);
- verify_boundaries_at_offset(3, 3UL, 4UL);
- verify_boundaries_at_offset(4, 4UL, 5UL);
- verify_boundaries_at_offset(5, 5UL, 7UL);
- verify_boundaries_at_offset(6, 5UL, 7UL);
- verify_boundaries_at_offset(7, 7UL, 11UL);
- verify_boundaries_at_offset(8, 7UL, 11UL);
- verify_boundaries_at_offset(9, 7UL, 11UL);
- verify_boundaries_at_offset(10, 7UL, 11UL);
- verify_boundaries_at_offset(11, 11L, 12UL);
- verify_boundaries_at_offset(12, 12L, 15UL);
- verify_boundaries_at_offset(13, 12L, 15UL);
- verify_boundaries_at_offset(14, 12L, 15UL);
- verify_boundaries_at_offset(15, 15L, 17UL);
- verify_boundaries_at_offset(16, 15L, 17UL);
- verify_boundaries_at_offset(17, 17L, 18UL);
- verify_boundaries_at_offset(18, 18L, 19UL);
-}
-
-TEST(AXTextUtils, GetWordOffsetsEmptyTest) {
- const base::string16 text = base::UTF8ToUTF16("");
- std::vector<int> word_starts = GetWordStartOffsets(text);
- std::vector<int> word_ends = GetWordEndOffsets(text);
- EXPECT_EQ(0UL, word_starts.size());
- EXPECT_EQ(0UL, word_ends.size());
-}
-
-TEST(AXTextUtils, GetWordStartOffsetsBasicTest) {
- const base::string16 text = base::UTF8ToUTF16("This is very simple input");
- EXPECT_THAT(GetWordStartOffsets(text), testing::ElementsAre(0, 5, 8, 13, 20));
-}
-
-TEST(AXTextUtils, GetWordEndOffsetsBasicTest) {
- const base::string16 text = base::UTF8ToUTF16("This is very simple input");
- EXPECT_THAT(GetWordEndOffsets(text), testing::ElementsAre(4, 7, 12, 19, 25));
-}
-
-TEST(AXTextUtils, GetWordStartOffsetsMalformedInputTest) {
- const base::string16 text =
- base::UTF8ToUTF16("..we *## should parse $#@$ through bad ,, input");
- EXPECT_THAT(GetWordStartOffsets(text),
- testing::ElementsAre(2, 9, 16, 27, 35, 43));
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_tree.cc b/third_party/accessibility/ax/ax_tree.cc
index 6842af0..0675232 100644
--- a/third_party/accessibility/ax/ax_tree.cc
+++ b/third_party/accessibility/ax/ax_tree.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_tree.h"
+#include "ax_tree.h"
#include <stddef.h>
@@ -10,23 +10,14 @@
#include <numeric>
#include <utility>
+#include "ax_enums.h"
+#include "ax_node.h"
+#include "ax_node_position.h"
+#include "ax_role_properties.h"
+#include "ax_table_info.h"
+#include "ax_tree_observer.h"
#include "base/auto_reset.h"
-#include "base/check_op.h"
-#include "base/command_line.h"
-#include "base/memory/ptr_util.h"
-#include "base/no_destructor.h"
-#include "base/notreached.h"
-#include "base/stl_util.h"
-#include "base/strings/stringprintf.h"
-#include "ui/accessibility/accessibility_switches.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_language_detection.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_node_position.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_table_info.h"
-#include "ui/accessibility/ax_tree_observer.h"
-#include "ui/gfx/transform.h"
+#include "base/string_utils.h"
namespace ui {
@@ -161,8 +152,8 @@
create_node_count(0),
node_exists(!!node),
parent_node_id((node && node->parent())
- ? base::Optional<AXNode::AXID>{node->parent()->id()}
- : base::nullopt),
+ ? std::optional<AXNode::AXID>{node->parent()->id()}
+ : std::nullopt),
last_known_data(node ? &node->data() : nullptr) {}
// Returns true if this node has any changes remaining.
@@ -231,7 +222,7 @@
// Keep track of the parent id for this node as of the last pending
// update that was processed.
- base::Optional<AXNode::AXID> parent_node_id;
+ std::optional<AXNode::AXID> parent_node_id;
// Keep track of the last known node data for this node.
// This will be null either when a node does not exist in the tree, or
@@ -278,9 +269,12 @@
// Returns whether this update reparents |node|.
bool IsReparentedNode(const AXNode* node) const {
- DCHECK_EQ(AXTreePendingStructureStatus::kComplete, pending_update_status)
- << "This method should not be called before pending changes have "
- "finished computing.";
+ if (AXTreePendingStructureStatus::kComplete != pending_update_status) {
+ BASE_LOG()
+ << "This method should not be called before pending changes have "
+ "finished computing.";
+ BASE_UNREACHABLE();
+ }
PendingStructureChanges* data = GetPendingStructureChanges(node->id());
if (!data)
return false;
@@ -297,37 +291,49 @@
// Returns true if the node should exist in the tree but doesn't have
// any node data yet.
bool DoesPendingNodeRequireInit(AXNode::AXID node_id) const {
- DCHECK_EQ(AXTreePendingStructureStatus::kComputing, pending_update_status)
- << "This method should only be called while computing pending changes, "
- "before updates are made to the tree.";
+ if (AXTreePendingStructureStatus::kComputing != pending_update_status) {
+ BASE_LOG() << "This method should only be called while computing "
+ "pending changes, "
+ "before updates are made to the tree.";
+ BASE_UNREACHABLE();
+ }
PendingStructureChanges* data = GetPendingStructureChanges(node_id);
return data && data->DoesNodeRequireInit();
}
// Returns the parent node id for the pending node.
- base::Optional<AXNode::AXID> GetParentIdForPendingNode(AXNode::AXID node_id) {
- DCHECK_EQ(AXTreePendingStructureStatus::kComputing, pending_update_status)
- << "This method should only be called while computing pending changes, "
- "before updates are made to the tree.";
+ std::optional<AXNode::AXID> GetParentIdForPendingNode(AXNode::AXID node_id) {
+ if (AXTreePendingStructureStatus::kComputing != pending_update_status) {
+ BASE_LOG() << "This method should only be called while computing "
+ "pending changes, "
+ "before updates are made to the tree.";
+ BASE_UNREACHABLE();
+ }
PendingStructureChanges* data = GetOrCreatePendingStructureChanges(node_id);
- DCHECK(!data->parent_node_id ||
- ShouldPendingNodeExistInTree(*data->parent_node_id));
+ BASE_DCHECK(!data->parent_node_id ||
+ ShouldPendingNodeExistInTree(*data->parent_node_id));
return data->parent_node_id;
}
// Returns true if this node should exist in the tree.
bool ShouldPendingNodeExistInTree(AXNode::AXID node_id) {
- DCHECK_EQ(AXTreePendingStructureStatus::kComputing, pending_update_status)
- << "This method should only be called while computing pending changes, "
- "before updates are made to the tree.";
+ if (AXTreePendingStructureStatus::kComputing != pending_update_status) {
+ BASE_LOG() << "This method should only be called while computing "
+ "pending changes, "
+ "before updates are made to the tree.";
+ BASE_UNREACHABLE();
+ }
return GetOrCreatePendingStructureChanges(node_id)->node_exists;
}
// Returns the last known node data for a pending node.
const AXNodeData& GetLastKnownPendingNodeData(AXNode::AXID node_id) const {
- DCHECK_EQ(AXTreePendingStructureStatus::kComputing, pending_update_status)
- << "This method should only be called while computing pending changes, "
- "before updates are made to the tree.";
+ if (AXTreePendingStructureStatus::kComputing != pending_update_status) {
+ BASE_LOG() << "This method should only be called while computing "
+ "pending changes, "
+ "before updates are made to the tree.";
+ BASE_UNREACHABLE();
+ }
static base::NoDestructor<ui::AXNodeData> empty_data;
PendingStructureChanges* data = GetPendingStructureChanges(node_id);
return (data && data->last_known_data) ? *data->last_known_data
@@ -336,17 +342,23 @@
// Clear the last known pending data for |node_id|.
void ClearLastKnownPendingNodeData(AXNode::AXID node_id) {
- DCHECK_EQ(AXTreePendingStructureStatus::kComputing, pending_update_status)
- << "This method should only be called while computing pending changes, "
- "before updates are made to the tree.";
+ if (AXTreePendingStructureStatus::kComputing != pending_update_status) {
+ BASE_LOG() << "This method should only be called while computing "
+ "pending changes, "
+ "before updates are made to the tree.";
+ BASE_UNREACHABLE();
+ }
GetOrCreatePendingStructureChanges(node_id)->last_known_data = nullptr;
}
// Update the last known pending node data for |node_data.id|.
void SetLastKnownPendingNodeData(const AXNodeData* node_data) {
- DCHECK_EQ(AXTreePendingStructureStatus::kComputing, pending_update_status)
- << "This method should only be called while computing pending changes, "
- "before updates are made to the tree.";
+ if (AXTreePendingStructureStatus::kComputing != pending_update_status) {
+ BASE_LOG() << "This method should only be called while computing "
+ "pending changes, "
+ "before updates are made to the tree.";
+ BASE_UNREACHABLE();
+ }
GetOrCreatePendingStructureChanges(node_data->id)->last_known_data =
node_data;
}
@@ -354,9 +366,12 @@
// Returns the number of times the update is expected to destroy a
// subtree rooted at |node_id|.
int32_t GetPendingDestroySubtreeCount(AXNode::AXID node_id) const {
- DCHECK_EQ(AXTreePendingStructureStatus::kComplete, pending_update_status)
- << "This method should not be called before pending changes have "
- "finished computing.";
+ if (AXTreePendingStructureStatus::kComplete != pending_update_status) {
+ BASE_LOG()
+ << "This method should not be called before pending changes have "
+ "finished computing.";
+ BASE_UNREACHABLE();
+ }
if (PendingStructureChanges* data = GetPendingStructureChanges(node_id))
return data->destroy_subtree_count;
return 0;
@@ -366,9 +381,12 @@
// destroy a subtree rooted at |node_id|.
// Returns true on success, false on failure when the node will not exist.
bool IncrementPendingDestroySubtreeCount(AXNode::AXID node_id) {
- DCHECK_EQ(AXTreePendingStructureStatus::kComputing, pending_update_status)
- << "This method should only be called while computing pending changes, "
- "before updates are made to the tree.";
+ if (AXTreePendingStructureStatus::kComputing != pending_update_status) {
+ BASE_LOG() << "This method should only be called while computing "
+ "pending changes, "
+ "before updates are made to the tree.";
+ BASE_UNREACHABLE();
+ }
PendingStructureChanges* data = GetOrCreatePendingStructureChanges(node_id);
if (!data->node_exists)
return false;
@@ -380,11 +398,14 @@
// Decrements the number of times the update is expected to
// destroy a subtree rooted at |node_id|.
void DecrementPendingDestroySubtreeCount(AXNode::AXID node_id) {
- DCHECK_EQ(AXTreePendingStructureStatus::kComplete, pending_update_status)
- << "This method should not be called before pending changes have "
- "finished computing.";
+ if (AXTreePendingStructureStatus::kComplete != pending_update_status) {
+ BASE_LOG()
+ << "This method should not be called before pending changes have "
+ "finished computing.";
+ BASE_UNREACHABLE();
+ }
if (PendingStructureChanges* data = GetPendingStructureChanges(node_id)) {
- DCHECK_GT(data->destroy_subtree_count, 0);
+ BASE_DCHECK(data->destroy_subtree_count > 0);
--data->destroy_subtree_count;
}
}
@@ -392,9 +413,12 @@
// Returns the number of times the update is expected to destroy
// a node with |node_id|.
int32_t GetPendingDestroyNodeCount(AXNode::AXID node_id) const {
- DCHECK_EQ(AXTreePendingStructureStatus::kComplete, pending_update_status)
- << "This method should not be called before pending changes have "
- "finished computing.";
+ if (AXTreePendingStructureStatus::kComplete != pending_update_status) {
+ BASE_LOG()
+ << "This method should not be called before pending changes have "
+ "finished computing.";
+ BASE_UNREACHABLE();
+ }
if (PendingStructureChanges* data = GetPendingStructureChanges(node_id))
return data->destroy_node_count;
return 0;
@@ -404,9 +428,12 @@
// destroy a node with |node_id|.
// Returns true on success, false on failure when the node will not exist.
bool IncrementPendingDestroyNodeCount(AXNode::AXID node_id) {
- DCHECK_EQ(AXTreePendingStructureStatus::kComputing, pending_update_status)
- << "This method should only be called while computing pending changes, "
- "before updates are made to the tree.";
+ if (AXTreePendingStructureStatus::kComputing != pending_update_status) {
+ BASE_LOG() << "This method should only be called while computing "
+ "pending changes, "
+ "before updates are made to the tree.";
+ BASE_UNREACHABLE();
+ }
PendingStructureChanges* data = GetOrCreatePendingStructureChanges(node_id);
if (!data->node_exists)
return false;
@@ -414,20 +441,23 @@
++data->destroy_node_count;
data->node_exists = false;
data->last_known_data = nullptr;
- data->parent_node_id = base::nullopt;
+ data->parent_node_id = std::nullopt;
if (pending_root_id == node_id)
- pending_root_id = base::nullopt;
+ pending_root_id = std::nullopt;
return true;
}
// Decrements the number of times the update is expected to
// destroy a node with |node_id|.
void DecrementPendingDestroyNodeCount(AXNode::AXID node_id) {
- DCHECK_EQ(AXTreePendingStructureStatus::kComplete, pending_update_status)
- << "This method should not be called before pending changes have "
- "finished computing.";
+ if (AXTreePendingStructureStatus::kComplete != pending_update_status) {
+ BASE_LOG()
+ << "This method should not be called before pending changes have "
+ "finished computing.";
+ BASE_UNREACHABLE();
+ }
if (PendingStructureChanges* data = GetPendingStructureChanges(node_id)) {
- DCHECK_GT(data->destroy_node_count, 0);
+ BASE_DCHECK(data->destroy_node_count > 0);
--data->destroy_node_count;
}
}
@@ -435,9 +465,12 @@
// Returns the number of times the update is expected to create
// a node with |node_id|.
int32_t GetPendingCreateNodeCount(AXNode::AXID node_id) const {
- DCHECK_EQ(AXTreePendingStructureStatus::kComplete, pending_update_status)
- << "This method should not be called before pending changes have "
- "finished computing.";
+ if (AXTreePendingStructureStatus::kComplete != pending_update_status) {
+ BASE_LOG()
+ << "This method should not be called before pending changes have "
+ "finished computing.";
+ BASE_UNREACHABLE();
+ }
if (PendingStructureChanges* data = GetPendingStructureChanges(node_id))
return data->create_node_count;
return 0;
@@ -448,10 +481,13 @@
// Returns true on success, false on failure when the node will already exist.
bool IncrementPendingCreateNodeCount(
AXNode::AXID node_id,
- base::Optional<AXNode::AXID> parent_node_id) {
- DCHECK_EQ(AXTreePendingStructureStatus::kComputing, pending_update_status)
- << "This method should only be called while computing pending changes, "
- "before updates are made to the tree.";
+ std::optional<AXNode::AXID> parent_node_id) {
+ if (AXTreePendingStructureStatus::kComputing != pending_update_status) {
+ BASE_LOG() << "This method should only be called while computing "
+ "pending changes, "
+ "before updates are made to the tree.";
+ BASE_UNREACHABLE();
+ }
PendingStructureChanges* data = GetOrCreatePendingStructureChanges(node_id);
if (data->node_exists)
return false;
@@ -465,11 +501,14 @@
// Decrements the number of times the update is expected to
// create a node with |node_id|.
void DecrementPendingCreateNodeCount(AXNode::AXID node_id) {
- DCHECK_EQ(AXTreePendingStructureStatus::kComplete, pending_update_status)
- << "This method should not be called before pending changes have "
- "finished computing.";
+ if (AXTreePendingStructureStatus::kComplete != pending_update_status) {
+ BASE_LOG()
+ << "This method should not be called before pending changes have "
+ "finished computing.";
+ BASE_UNREACHABLE();
+ }
if (PendingStructureChanges* data = GetPendingStructureChanges(node_id)) {
- DCHECK_GT(data->create_node_count, 0);
+ BASE_DCHECK(data->create_node_count > 0);
--data->create_node_count;
}
}
@@ -483,10 +522,13 @@
// Adds the parent of |node_id| to the list of nodes to invalidate unignored
// cached values.
void InvalidateParentNodeUnignoredCacheValues(AXNode::AXID node_id) {
- DCHECK_EQ(AXTreePendingStructureStatus::kComputing, pending_update_status)
- << "This method should only be called while computing pending changes, "
- "before updates are made to the tree.";
- base::Optional<AXNode::AXID> parent_node_id =
+ if (AXTreePendingStructureStatus::kComputing != pending_update_status) {
+ BASE_LOG() << "This method should only be called while computing "
+ "pending changes, "
+ "before updates are made to the tree.";
+ BASE_UNREACHABLE();
+ }
+ std::optional<AXNode::AXID> parent_node_id =
GetParentIdForPendingNode(node_id);
if (parent_node_id) {
invalidate_unignored_cached_values_ids.insert(*parent_node_id);
@@ -499,7 +541,7 @@
// Keeps track of the root node id when calculating what changes will occur
// during an update before the update applies changes.
- base::Optional<AXNode::AXID> pending_root_id;
+ std::optional<AXNode::AXID> pending_root_id;
// Keeps track of whether the root node will need to be created as a new node.
// This may occur either when the root node does not exist before applying
@@ -540,7 +582,7 @@
// Optional copy of the old tree data, only populated when the tree
// data has changed.
- base::Optional<AXTreeData> old_tree_data;
+ std::optional<AXTreeData> old_tree_data;
private:
PendingStructureChanges* GetPendingStructureChanges(
@@ -587,7 +629,7 @@
~OrderedSetItemsMap() = default;
// Check if a particular hierarchical level exists in this map.
- bool HierarchicalLevelExists(base::Optional<int> level) {
+ bool HierarchicalLevelExists(std::optional<int> level) {
if (items_map_.find(level) == items_map_.end())
return false;
return true;
@@ -595,7 +637,7 @@
// Add the OrderedSetContent to the corresponding hierarchical level in the
// map.
- void Add(base::Optional<int> level,
+ void Add(std::optional<int> level,
const OrderedSetContent& ordered_set_content) {
if (!HierarchicalLevelExists(level))
items_map_[level] = std::vector<OrderedSetContent>();
@@ -610,7 +652,7 @@
// of being populated.
// - All other OrderedSetContent other than the last one on a level
// represents a complete ordered set and should not be modified.
- void AddItemToBack(base::Optional<int> level, const AXNode* item) {
+ void AddItemToBack(std::optional<int> level, const AXNode* item) {
if (!HierarchicalLevelExists(level))
return;
@@ -637,7 +679,7 @@
void Clear() { items_map_.clear(); }
// Maps a hierarchical level to a list of OrderedSetContent.
- std::map<base::Optional<int32_t>, std::vector<OrderedSetContent>> items_map_;
+ std::map<std::optional<int32_t>, std::vector<OrderedSetContent>> items_map_;
};
AXTree::AXTree() {
@@ -647,20 +689,17 @@
AXTreeUpdate initial_state;
initial_state.root_id = AXNode::kInvalidAXID;
initial_state.nodes.push_back(root);
- CHECK(Unserialize(initial_state)) << error();
- // TODO(chrishall): should language_detection_manager be a member or pointer?
- // TODO(chrishall): do we want to initialize all the time, on demand, or only
- // when feature flag is set?
- DCHECK(!language_detection_manager);
- language_detection_manager =
- std::make_unique<AXLanguageDetectionManager>(this);
+ if (!Unserialize(initial_state)) {
+ BASE_LOG() << error();
+ BASE_UNREACHABLE();
+ }
}
AXTree::AXTree(const AXTreeUpdate& initial_state) {
- CHECK(Unserialize(initial_state)) << error();
- DCHECK(!language_detection_manager);
- language_detection_manager =
- std::make_unique<AXLanguageDetectionManager>(this);
+ if (!Unserialize(initial_state)) {
+ BASE_LOG() << error();
+ BASE_UNREACHABLE();
+ }
}
AXTree::~AXTree() {
@@ -668,15 +707,19 @@
}
void AXTree::AddObserver(AXTreeObserver* observer) {
- observers_.AddObserver(observer);
+ observers_.push_back(observer);
}
bool AXTree::HasObserver(AXTreeObserver* observer) {
- return observers_.HasObserver(observer);
+ return std::find(observers_.begin(), observers_.end(), observer) !=
+ observers_.end();
}
void AXTree::RemoveObserver(AXTreeObserver* observer) {
- observers_.RemoveObserver(observer);
+ const auto it = std::find(observers_.begin(), observers_.end(), observer);
+ if (it == observers_.end())
+ return;
+ observers_.erase(it);
}
AXTreeID AXTree::GetAXTreeID() const {
@@ -705,8 +748,8 @@
AXTreeData old_data = data_;
data_ = new_data;
- for (AXTreeObserver& observer : observers_)
- observer.OnTreeDataChanged(this, old_data, new_data);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnTreeDataChanged(this, old_data, new_data);
}
gfx::RectF AXTree::RelativeToTreeBoundsInternal(const AXNode* node,
@@ -879,7 +922,7 @@
std::set<int32_t> AXTree::GetReverseRelations(ax::mojom::IntAttribute attr,
int32_t dst_id) const {
- DCHECK(IsNodeIdIntAttribute(attr));
+ BASE_DCHECK(IsNodeIdIntAttribute(attr));
// Conceptually, this is the "const" version of:
// return int_reverse_relations_[attr][dst_id];
@@ -894,7 +937,7 @@
std::set<int32_t> AXTree::GetReverseRelations(ax::mojom::IntListAttribute attr,
int32_t dst_id) const {
- DCHECK(IsNodeIdIntListAttribute(attr));
+ BASE_DCHECK(IsNodeIdIntListAttribute(attr));
// Conceptually, this is the "const" version of:
// return intlist_reverse_relations_[attr][dst_id];
@@ -925,11 +968,6 @@
}
bool AXTree::Unserialize(const AXTreeUpdate& update) {
- event_intents_ = update.event_intents;
- base::ScopedClosureRunner clear_event_intents(base::BindOnce(
- [](std::vector<AXEventIntent>* event_intents) { event_intents->clear(); },
- &event_intents_));
-
AXTreeUpdateState update_state(*this);
const AXNode::AXID old_root_id = root_ ? root_->id() : AXNode::kInvalidAXID;
@@ -985,7 +1023,7 @@
bool root_updated = false;
if (update.node_id_to_clear != AXNode::kInvalidAXID) {
if (AXNode* cleared_node = GetFromId(update.node_id_to_clear)) {
- DCHECK(root_);
+ BASE_DCHECK(root_);
if (cleared_node == root_) {
// Only destroy the root if the root was replaced and not if it's simply
// updated. To figure out if the root was simply updated, we compare
@@ -1015,7 +1053,7 @@
}
}
- DCHECK_EQ(!GetFromId(update.root_id), update_state.root_will_be_created);
+ BASE_DCHECK(!GetFromId(update.root_id) == update_state.root_will_be_created);
// Update the tree data, do not call |UpdateData| since we want to defer
// the |OnTreeDataChanged| event until after the tree has finished updating.
@@ -1121,8 +1159,8 @@
// the tree data changed. We must do this after updating nodes in case the
// root has been replaced, so observers have the most up-to-date information.
if (update_state.old_tree_data) {
- for (AXTreeObserver& observer : observers_)
- observer.OnTreeDataChanged(this, *update_state.old_tree_data, data_);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnTreeDataChanged(this, *update_state.old_tree_data, data_);
}
// Now that the unignored cached values are up to date, update observers to
@@ -1141,7 +1179,7 @@
// node changes.
for (AXNode::AXID node_data_changed_id : update_state.node_data_changed_ids) {
AXNode* node = GetFromId(node_data_changed_id);
- DCHECK(node);
+ BASE_DCHECK(node);
// If the node exists and is in the old data map, then the node data
// may have changed unless this is a new root.
@@ -1156,18 +1194,18 @@
}
// |OnNodeChanged| should be fired for all nodes that have been updated.
- for (AXTreeObserver& observer : observers_)
- observer.OnNodeChanged(this, node);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnNodeChanged(this, node);
}
- for (AXTreeObserver& observer : observers_)
- observer.OnAtomicUpdateFinished(this, root_->id() != old_root_id, changes);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnAtomicUpdateFinished(this, root_->id() != old_root_id, changes);
return true;
}
AXTableInfo* AXTree::GetTableInfo(const AXNode* const_table_node) const {
- DCHECK(!GetTreeUpdateInProgressState());
+ BASE_DCHECK(!GetTreeUpdateInProgressState());
// Note: the const_casts are here because we want this function to be able
// to be called from a const virtual function on AXNode. AXTableInfo is
// computed on demand and cached, but that's an implementation detail
@@ -1175,7 +1213,7 @@
AXNode* table_node = const_cast<AXNode*>(const_table_node);
AXTree* tree = const_cast<AXTree*>(this);
- DCHECK(table_node);
+ BASE_DCHECK(table_node);
const auto& cached = table_info_map_.find(table_node->id());
if (cached != table_info_map_.end()) {
// Get existing table info, and update if invalid because the
@@ -1196,7 +1234,7 @@
if (!table_info)
return nullptr;
- table_info_map_[table_node->id()] = base::WrapUnique<AXTableInfo>(table_info);
+ table_info_map_[table_node->id()] = std::unique_ptr<AXTableInfo>(table_info);
return table_info;
}
@@ -1208,15 +1246,15 @@
AXNode::AXID id,
size_t index_in_parent,
AXTreeUpdateState* update_state) {
- DCHECK(GetTreeUpdateInProgressState());
+ BASE_DCHECK(GetTreeUpdateInProgressState());
// |update_state| must already contain information about all of the expected
// changes and invalidations to apply. If any of these are missing, observers
// may not be notified of changes.
- DCHECK(!GetFromId(id));
- DCHECK_GT(update_state->GetPendingCreateNodeCount(id), 0);
- DCHECK(update_state->InvalidatesUnignoredCachedValues(id));
- DCHECK(!parent ||
- update_state->InvalidatesUnignoredCachedValues(parent->id()));
+ BASE_DCHECK(!GetFromId(id));
+ BASE_DCHECK(update_state->GetPendingCreateNodeCount(id) > 0);
+ BASE_DCHECK(update_state->InvalidatesUnignoredCachedValues(id));
+ BASE_DCHECK(!parent ||
+ update_state->InvalidatesUnignoredCachedValues(parent->id()));
update_state->DecrementPendingCreateNodeCount(id);
update_state->new_node_ids.insert(id);
// If this node is the root, use the given index_in_parent as the unignored
@@ -1229,15 +1267,17 @@
bool AXTree::ComputePendingChanges(const AXTreeUpdate& update,
AXTreeUpdateState* update_state) {
- DCHECK_EQ(AXTreePendingStructureStatus::kNotStarted,
- update_state->pending_update_status)
- << "Pending changes have already started being computed.";
+ if (AXTreePendingStructureStatus::kNotStarted !=
+ update_state->pending_update_status) {
+ BASE_LOG() << "Pending changes have already started being computed.";
+ BASE_UNREACHABLE();
+ }
update_state->pending_update_status =
AXTreePendingStructureStatus::kComputing;
- base::AutoReset<base::Optional<AXNode::AXID>> pending_root_id_resetter(
+ base::AutoReset<std::optional<AXNode::AXID>> pending_root_id_resetter(
&update_state->pending_root_id,
- root_ ? base::Optional<AXNode::AXID>{root_->id()} : base::nullopt);
+ root_ ? std::optional<AXNode::AXID>{root_->id()} : std::nullopt);
// We distinguish between updating the root, e.g. changing its children or
// some of its attributes, or replacing the root completely. If the root is
@@ -1246,7 +1286,7 @@
// of the new root.
if (update.node_id_to_clear != AXNode::kInvalidAXID) {
if (AXNode* cleared_node = GetFromId(update.node_id_to_clear)) {
- DCHECK(root_);
+ BASE_DCHECK(root_);
if (cleared_node == root_ &&
update.root_id != update_state->pending_root_id) {
// Only destroy the root if the root was replaced and not if it's simply
@@ -1312,7 +1352,7 @@
// Creation is implicit for new root nodes. If |new_data.id| is already
// pending for creation, then it must be a duplicate entry in the tree.
if (!update_state->IncrementPendingCreateNodeCount(new_data.id,
- base::nullopt)) {
+ std::nullopt)) {
error_ = base::StringPrintf(
"Node %d is already pending for creation, cannot be the new root",
new_data.id);
@@ -1424,7 +1464,7 @@
bool AXTree::UpdateNode(const AXNodeData& src,
bool is_new_root,
AXTreeUpdateState* update_state) {
- DCHECK(GetTreeUpdateInProgressState());
+ BASE_DCHECK(GetTreeUpdateInProgressState());
// This method updates one node in the tree based on serialized data
// received in an AXTreeUpdate. See AXTreeUpdate for pre and post
// conditions.
@@ -1487,15 +1527,15 @@
void AXTree::NotifySubtreeWillBeReparentedOrDeleted(
AXNode* node,
const AXTreeUpdateState* update_state) {
- DCHECK(!GetTreeUpdateInProgressState());
+ BASE_DCHECK(!GetTreeUpdateInProgressState());
if (node->id() == AXNode::kInvalidAXID)
return;
- for (AXTreeObserver& observer : observers_) {
+ for (AXTreeObserver* observer : observers_) {
if (update_state->IsReparentedNode(node)) {
- observer.OnSubtreeWillBeReparented(this, node);
+ observer->OnSubtreeWillBeReparented(this, node);
} else {
- observer.OnSubtreeWillBeDeleted(this, node);
+ observer->OnSubtreeWillBeDeleted(this, node);
}
}
}
@@ -1503,7 +1543,7 @@
void AXTree::NotifyNodeWillBeReparentedOrDeleted(
AXNode* node,
const AXTreeUpdateState* update_state) {
- DCHECK(!GetTreeUpdateInProgressState());
+ BASE_DCHECK(!GetTreeUpdateInProgressState());
AXNode::AXID id = node->id();
if (id == AXNode::kInvalidAXID)
@@ -1511,78 +1551,80 @@
table_info_map_.erase(id);
- for (AXTreeObserver& observer : observers_) {
+ for (AXTreeObserver* observer : observers_) {
if (update_state->IsReparentedNode(node)) {
- observer.OnNodeWillBeReparented(this, node);
+ observer->OnNodeWillBeReparented(this, node);
} else {
- observer.OnNodeWillBeDeleted(this, node);
+ observer->OnNodeWillBeDeleted(this, node);
}
}
- DCHECK(table_info_map_.find(id) == table_info_map_.end())
- << "Table info should never be recreated during node deletion";
+ if (table_info_map_.find(id) != table_info_map_.end()) {
+ BASE_LOG() << "Table info should never be recreated during node deletion";
+ BASE_UNREACHABLE();
+ }
}
void AXTree::RecursivelyNotifyNodeDeletedForTreeTeardown(AXNode* node) {
- DCHECK(!GetTreeUpdateInProgressState());
+ BASE_DCHECK(!GetTreeUpdateInProgressState());
if (node->id() == AXNode::kInvalidAXID)
return;
- for (AXTreeObserver& observer : observers_)
- observer.OnNodeDeleted(this, node->id());
+ for (AXTreeObserver* observer : observers_)
+ observer->OnNodeDeleted(this, node->id());
for (auto* child : node->children())
RecursivelyNotifyNodeDeletedForTreeTeardown(child);
}
void AXTree::NotifyNodeHasBeenDeleted(AXNode::AXID node_id) {
- DCHECK(!GetTreeUpdateInProgressState());
+ BASE_DCHECK(!GetTreeUpdateInProgressState());
if (node_id == AXNode::kInvalidAXID)
return;
- for (AXTreeObserver& observer : observers_)
- observer.OnNodeDeleted(this, node_id);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnNodeDeleted(this, node_id);
}
void AXTree::NotifyNodeHasBeenReparentedOrCreated(
AXNode* node,
const AXTreeUpdateState* update_state) {
- DCHECK(!GetTreeUpdateInProgressState());
+ BASE_DCHECK(!GetTreeUpdateInProgressState());
if (node->id() == AXNode::kInvalidAXID)
return;
- for (AXTreeObserver& observer : observers_) {
+ for (AXTreeObserver* observer : observers_) {
if (update_state->IsReparentedNode(node)) {
- observer.OnNodeReparented(this, node);
+ observer->OnNodeReparented(this, node);
} else {
- observer.OnNodeCreated(this, node);
+ observer->OnNodeCreated(this, node);
}
}
}
void AXTree::NotifyNodeDataWillChange(const AXNodeData& old_data,
const AXNodeData& new_data) {
- DCHECK(!GetTreeUpdateInProgressState());
+ BASE_DCHECK(!GetTreeUpdateInProgressState());
if (new_data.id == AXNode::kInvalidAXID)
return;
- for (AXTreeObserver& observer : observers_)
- observer.OnNodeDataWillChange(this, old_data, new_data);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnNodeDataWillChange(this, old_data, new_data);
}
void AXTree::NotifyNodeDataHasBeenChanged(AXNode* node,
const AXNodeData& old_data,
const AXNodeData& new_data) {
- DCHECK(!GetTreeUpdateInProgressState());
+ BASE_DCHECK(!GetTreeUpdateInProgressState());
if (node->id() == AXNode::kInvalidAXID)
return;
- for (AXTreeObserver& observer : observers_)
- observer.OnNodeDataChanged(this, old_data, new_data);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnNodeDataChanged(this, old_data, new_data);
if (old_data.role != new_data.role) {
- for (AXTreeObserver& observer : observers_)
- observer.OnRoleChanged(this, node, old_data.role, new_data.role);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnRoleChanged(this, node, old_data.role, new_data.role);
}
if (old_data.state != new_data.state) {
@@ -1590,8 +1632,8 @@
i <= static_cast<int32_t>(ax::mojom::State::kMaxValue); ++i) {
ax::mojom::State state = static_cast<ax::mojom::State>(i);
if (old_data.HasState(state) != new_data.HasState(state)) {
- for (AXTreeObserver& observer : observers_)
- observer.OnStateChanged(this, node, state, new_data.HasState(state));
+ for (AXTreeObserver* observer : observers_)
+ observer->OnStateChanged(this, node, state, new_data.HasState(state));
}
}
}
@@ -1599,9 +1641,9 @@
auto string_callback = [this, node](ax::mojom::StringAttribute attr,
const std::string& old_string,
const std::string& new_string) {
- for (AXTreeObserver& observer : observers_) {
- observer.OnStringAttributeChanged(this, node, attr, old_string,
- new_string);
+ for (AXTreeObserver* observer : observers_) {
+ observer->OnStringAttributeChanged(this, node, attr, old_string,
+ new_string);
}
};
CallIfAttributeValuesChanged(old_data.string_attributes,
@@ -1611,8 +1653,8 @@
auto bool_callback = [this, node](ax::mojom::BoolAttribute attr,
const bool& old_bool,
const bool& new_bool) {
- for (AXTreeObserver& observer : observers_)
- observer.OnBoolAttributeChanged(this, node, attr, new_bool);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnBoolAttributeChanged(this, node, attr, new_bool);
};
CallIfAttributeValuesChanged(old_data.bool_attributes,
new_data.bool_attributes, false, bool_callback);
@@ -1620,16 +1662,16 @@
auto float_callback = [this, node](ax::mojom::FloatAttribute attr,
const float& old_float,
const float& new_float) {
- for (AXTreeObserver& observer : observers_)
- observer.OnFloatAttributeChanged(this, node, attr, old_float, new_float);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnFloatAttributeChanged(this, node, attr, old_float, new_float);
};
CallIfAttributeValuesChanged(old_data.float_attributes,
new_data.float_attributes, 0.0f, float_callback);
auto int_callback = [this, node](ax::mojom::IntAttribute attr,
const int& old_int, const int& new_int) {
- for (AXTreeObserver& observer : observers_)
- observer.OnIntAttributeChanged(this, node, attr, old_int, new_int);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnIntAttributeChanged(this, node, attr, old_int, new_int);
};
CallIfAttributeValuesChanged(old_data.int_attributes, new_data.int_attributes,
0, int_callback);
@@ -1638,9 +1680,9 @@
ax::mojom::IntListAttribute attr,
const std::vector<int32_t>& old_intlist,
const std::vector<int32_t>& new_intlist) {
- for (AXTreeObserver& observer : observers_)
- observer.OnIntListAttributeChanged(this, node, attr, old_intlist,
- new_intlist);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnIntListAttributeChanged(this, node, attr, old_intlist,
+ new_intlist);
};
CallIfAttributeValuesChanged(old_data.intlist_attributes,
new_data.intlist_attributes,
@@ -1650,9 +1692,9 @@
[this, node](ax::mojom::StringListAttribute attr,
const std::vector<std::string>& old_stringlist,
const std::vector<std::string>& new_stringlist) {
- for (AXTreeObserver& observer : observers_)
- observer.OnStringListAttributeChanged(this, node, attr,
- old_stringlist, new_stringlist);
+ for (AXTreeObserver* observer : observers_)
+ observer->OnStringListAttributeChanged(
+ this, node, attr, old_stringlist, new_stringlist);
};
CallIfAttributeValuesChanged(old_data.stringlist_attributes,
new_data.stringlist_attributes,
@@ -1660,7 +1702,7 @@
}
void AXTree::UpdateReverseRelations(AXNode* node, const AXNodeData& new_data) {
- DCHECK(GetTreeUpdateInProgressState());
+ BASE_DCHECK(GetTreeUpdateInProgressState());
const AXNodeData& old_data = node->data();
int id = new_data.id;
auto int_callback = [this, id](ax::mojom::IntAttribute attr,
@@ -1738,8 +1780,9 @@
const AXTreeUpdateState& update_state) {
if (!update_state.pending_nodes.empty()) {
error_ = "Nodes left pending by the update:";
- for (const AXNode::AXID pending_id : update_state.pending_nodes)
+ for (const AXNode::AXID pending_id : update_state.pending_nodes) {
error_ += base::StringPrintf(" %d", pending_id);
+ }
return false;
}
@@ -1763,11 +1806,12 @@
}
}
if (has_pending_changes) {
- error_ = base::StringPrintf(
- "Changes left pending by the update; "
- "destroy subtrees: %s, destroy nodes: %s, create nodes: %s",
- destroy_subtree_ids.c_str(), destroy_node_ids.c_str(),
- create_node_ids.c_str());
+ std::ostringstream stringStream;
+ stringStream << "Changes left pending by the update; destroy subtrees: "
+ << destroy_subtree_ids.c_str()
+ << ", destroy nodes: " << destroy_node_ids.c_str()
+ << ", create nodes: " << create_node_ids.c_str();
+ error_ = stringStream.str();
}
return !has_pending_changes;
}
@@ -1798,23 +1842,23 @@
}
void AXTree::DestroySubtree(AXNode* node, AXTreeUpdateState* update_state) {
- DCHECK(GetTreeUpdateInProgressState());
+ BASE_DCHECK(GetTreeUpdateInProgressState());
// |update_state| must already contain information about all of the expected
// changes and invalidations to apply. If any of these are missing, observers
// may not be notified of changes.
- DCHECK(update_state);
- DCHECK_GT(update_state->GetPendingDestroySubtreeCount(node->id()), 0);
- DCHECK(!node->parent() ||
- update_state->InvalidatesUnignoredCachedValues(node->parent()->id()));
+ BASE_DCHECK(update_state);
+ BASE_DCHECK(update_state->GetPendingDestroySubtreeCount(node->id()) > 0);
+ BASE_DCHECK(!node->parent() || update_state->InvalidatesUnignoredCachedValues(
+ node->parent()->id()));
update_state->DecrementPendingDestroySubtreeCount(node->id());
DestroyNodeAndSubtree(node, update_state);
}
void AXTree::DestroyNodeAndSubtree(AXNode* node,
AXTreeUpdateState* update_state) {
- DCHECK(GetTreeUpdateInProgressState());
- DCHECK(!update_state ||
- update_state->GetPendingDestroyNodeCount(node->id()) > 0);
+ BASE_DCHECK(GetTreeUpdateInProgressState());
+ BASE_DCHECK(!update_state ||
+ update_state->GetPendingDestroyNodeCount(node->id()) > 0);
// Clear out any reverse relations.
AXNodeData empty_data;
@@ -1841,7 +1885,7 @@
void AXTree::DeleteOldChildren(AXNode* node,
const std::vector<int32_t>& new_child_ids,
AXTreeUpdateState* update_state) {
- DCHECK(GetTreeUpdateInProgressState());
+ BASE_DCHECK(GetTreeUpdateInProgressState());
// Create a set of child ids in |src| for fast lookup, we know the set does
// not contain duplicate entries already, because that was handled when
// populating |update_state| with information about all of the expected
@@ -1860,7 +1904,7 @@
const std::vector<int32_t>& new_child_ids,
std::vector<AXNode*>* new_children,
AXTreeUpdateState* update_state) {
- DCHECK(GetTreeUpdateInProgressState());
+ BASE_DCHECK(GetTreeUpdateInProgressState());
bool success = true;
for (size_t i = 0; i < new_child_ids.size(); ++i) {
int32_t child_id = new_child_ids[i];
@@ -1891,12 +1935,13 @@
if (enable_extra_mac_nodes_ == enabled)
return; // No change.
if (enable_extra_mac_nodes_ && !enabled) {
- NOTREACHED()
+ BASE_LOG()
<< "We don't support disabling the extra Mac nodes once enabled.";
+ BASE_UNREACHABLE();
return;
}
- DCHECK_EQ(0U, table_info_map_.size());
+ BASE_DCHECK(0U == table_info_map_.size());
enable_extra_mac_nodes_ = enabled;
}
@@ -1922,13 +1967,13 @@
// this, the set container (e.g. <tree>) will take on the min of the levels
// of its direct children(e.g. <treeitem>), if the children's levels are
// defined.
- base::Optional<int> ordered_set_min_level =
+ std::optional<int> ordered_set_min_level =
ordered_set->GetHierarchicalLevel();
for (AXNode::UnignoredChildIterator child =
ordered_set->UnignoredChildrenBegin();
child != ordered_set->UnignoredChildrenEnd(); ++child) {
- base::Optional<int> child_level = child->GetHierarchicalLevel();
+ std::optional<int> child_level = child->GetHierarchicalLevel();
if (child_level) {
ordered_set_min_level = ordered_set_min_level
? std::min(child_level, ordered_set_min_level)
@@ -1937,7 +1982,7 @@
}
RecursivelyPopulateOrderedSetItemsMap(original_node, ordered_set, ordered_set,
- ordered_set_min_level, base::nullopt,
+ ordered_set_min_level, std::nullopt,
items_map_to_be_populated);
// If after RecursivelyPopulateOrderedSetItemsMap() call, the corresponding
@@ -1959,8 +2004,8 @@
const AXNode& original_node,
const AXNode* ordered_set,
const AXNode* local_parent,
- base::Optional<int> ordered_set_min_level,
- base::Optional<int> prev_level,
+ std::optional<int> ordered_set_min_level,
+ std::optional<int> prev_level,
OrderedSetItemsMap* items_map_to_be_populated) const {
// For optimization purpose, we want to only populate set items that are
// direct descendants of |ordered_set|, since we will only be calculating
@@ -1995,7 +2040,7 @@
continue;
}
- base::Optional<int> curr_level = child->GetHierarchicalLevel();
+ std::optional<int> curr_level = child->GetHierarchicalLevel();
// Add child to |items_map_to_be_populated| if role matches with the role of
// |ordered_set|. If role of node is kRadioButton, don't add items of other
@@ -2072,7 +2117,7 @@
// Ordered_set should never be nullptr.
void AXTree::ComputeSetSizePosInSetAndCache(const AXNode& node,
const AXNode* ordered_set) {
- DCHECK(ordered_set);
+ BASE_DCHECK(ordered_set);
// Set items role::kComment and role::kRadioButton are special cases and do
// not necessarily need to be contained in an ordered set.
@@ -2175,7 +2220,7 @@
ordered_set->GetIntAttribute(ax::mojom::IntAttribute::kSetSize));
// Cache |ordered_set|'s hierarchical level.
- base::Optional<int> ordered_set_level = ordered_set->GetHierarchicalLevel();
+ std::optional<int> ordered_set_level = ordered_set->GetHierarchicalLevel();
if (node_set_size_pos_in_set_info_map_.find(ordered_set->id()) ==
node_set_size_pos_in_set_info_map_.end()) {
node_set_size_pos_in_set_info_map_[ordered_set->id()] =
@@ -2205,7 +2250,7 @@
} // End of iterating over each item in |ordered_set_content|.
}
-base::Optional<int> AXTree::GetPosInSet(const AXNode& node) {
+std::optional<int> AXTree::GetPosInSet(const AXNode& node) {
if (node.data().role == ax::mojom::Role::kPopUpButton &&
node.GetUnignoredChildCount() == 0 &&
node.HasIntAttribute(ax::mojom::IntAttribute::kPosInSet)) {
@@ -2219,28 +2264,28 @@
}
if (GetTreeUpdateInProgressState())
- return base::nullopt;
+ return std::nullopt;
// Only allow this to be called on nodes that can hold PosInSet values,
// which are defined in the ARIA spec.
if (!node.IsOrderedSetItem() || node.IsIgnored())
- return base::nullopt;
+ return std::nullopt;
const AXNode* ordered_set = node.GetOrderedSet();
if (!ordered_set)
- return base::nullopt;
+ return std::nullopt;
// Compute, cache, then return.
ComputeSetSizePosInSetAndCache(node, ordered_set);
- base::Optional<int> pos_in_set =
+ std::optional<int> pos_in_set =
node_set_size_pos_in_set_info_map_[node.id()].pos_in_set;
if (pos_in_set.has_value() && pos_in_set.value() < 1)
- return base::nullopt;
+ return std::nullopt;
return pos_in_set;
}
-base::Optional<int> AXTree::GetSetSize(const AXNode& node) {
+std::optional<int> AXTree::GetSetSize(const AXNode& node) {
if (node.data().role == ax::mojom::Role::kPopUpButton &&
node.GetUnignoredChildCount() == 0 &&
node.HasIntAttribute(ax::mojom::IntAttribute::kSetSize)) {
@@ -2254,14 +2299,14 @@
}
if (GetTreeUpdateInProgressState())
- return base::nullopt;
+ return std::nullopt;
// Only allow this to be called on nodes that can hold SetSize values, which
// are defined in the ARIA spec. However, we allow set-like items to receive
// SetSize values for internal purposes.
if ((!node.IsOrderedSetItem() && !node.IsOrderedSet()) || node.IsIgnored() ||
node.IsEmbeddedGroup()) {
- return base::nullopt;
+ return std::nullopt;
}
// If |node| is item-like, find its outerlying ordered set. Otherwise,
@@ -2270,7 +2315,7 @@
if (IsItemLike(node.data().role))
ordered_set = node.GetOrderedSet();
if (!ordered_set)
- return base::nullopt;
+ return std::nullopt;
// For popup buttons that control a single element, inherit the controlled
// item's SetSize. Skip this block if the popup button controls itself.
@@ -2281,8 +2326,7 @@
controls_ids[0] != node.id()) {
const AXNode& controlled_item = *GetFromId(controls_ids[0]);
- base::Optional<int> controlled_item_set_size =
- GetSetSize(controlled_item);
+ std::optional<int> controlled_item_set_size = GetSetSize(controlled_item);
node_set_size_pos_in_set_info_map_[node.id()].set_size =
controlled_item_set_size;
return controlled_item_set_size;
@@ -2291,10 +2335,10 @@
// Compute, cache, then return.
ComputeSetSizePosInSetAndCache(node, ordered_set);
- base::Optional<int> set_size =
+ std::optional<int> set_size =
node_set_size_pos_in_set_info_map_[node.id()].set_size;
if (set_size.has_value() && set_size.value() < 0)
- return base::nullopt;
+ return std::nullopt;
return set_size;
}
diff --git a/third_party/accessibility/ax/ax_tree.h b/third_party/accessibility/ax/ax_tree.h
index c47d1c2..3dbd3fd 100644
--- a/third_party/accessibility/ax/ax_tree.h
+++ b/third_party/accessibility/ax/ax_tree.h
@@ -14,20 +14,19 @@
#include <unordered_map>
#include <vector>
-#include "base/observer_list.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_tree_data.h"
-#include "ui/accessibility/ax_tree_update.h"
+#include "ax_enums.h"
+#include "ax_export.h"
+#include "ax_node.h"
+#include "ax_node_data.h"
+#include "ax_tree_data.h"
+#include "ax_tree_update.h"
+#include "gfx/geometry/rect.h"
namespace ui {
class AXTableInfo;
class AXTreeObserver;
struct AXTreeUpdateState;
-class AXLanguageDetectionManager;
// AXTree is a live, managed tree of AXNode objects that can receive
// updates from another AXTreeSource via AXTreeUpdates, and it can be
@@ -54,7 +53,7 @@
bool HasObserver(AXTreeObserver* observer);
void RemoveObserver(AXTreeObserver* observer);
- base::ObserverList<AXTreeObserver>& observers() { return observers_; }
+ std::vector<AXTreeObserver*>& observers() { return observers_; }
AXNode* root() const { return root_; }
@@ -150,11 +149,11 @@
// Returns the PosInSet of |node|. Looks in node_set_size_pos_in_set_info_map_
// for cached value. Calls |ComputeSetSizePosInSetAndCache|if no value is
// present in the cache.
- base::Optional<int> GetPosInSet(const AXNode& node) override;
+ std::optional<int> GetPosInSet(const AXNode& node) override;
// Returns the SetSize of |node|. Looks in node_set_size_pos_in_set_info_map_
// for cached value. Calls |ComputeSetSizePosInSetAndCache|if no value is
// present in the cache.
- base::Optional<int> GetSetSize(const AXNode& node) override;
+ std::optional<int> GetSetSize(const AXNode& node) override;
Selection GetUnignoredSelection() const override;
@@ -165,11 +164,6 @@
// Returns true if the tree represents a paginated document
bool HasPaginationSupport() const override;
- // Language detection manager, entry point to language detection features.
- // TODO(chrishall): Should this be stored by pointer or value?
- // When should we initialize this?
- std::unique_ptr<AXLanguageDetectionManager> language_detection_manager;
-
// A list of intents active during a tree update/unserialization.
const std::vector<AXEventIntent>& event_intents() const {
return event_intents_;
@@ -299,7 +293,7 @@
bool clip_bounds,
bool allow_recursion) const;
- base::ObserverList<AXTreeObserver> observers_;
+ std::vector<AXTreeObserver*> observers_;
AXNode* root_ = nullptr;
std::unordered_map<int32_t, AXNode*> id_map_;
std::string error_;
@@ -333,9 +327,9 @@
NodeSetSizePosInSetInfo();
~NodeSetSizePosInSetInfo();
- base::Optional<int> pos_in_set;
- base::Optional<int> set_size;
- base::Optional<int> lowest_hierarchical_level;
+ std::optional<int> pos_in_set;
+ std::optional<int> set_size;
+ std::optional<int> lowest_hierarchical_level;
};
// Represents the content of an ordered set which includes the ordered set
@@ -362,8 +356,8 @@
const AXNode& original_node,
const AXNode* ordered_set,
const AXNode* local_parent,
- base::Optional<int> ordered_set_min_level,
- base::Optional<int> prev_level,
+ std::optional<int> ordered_set_min_level,
+ std::optional<int> prev_level,
OrderedSetItemsMap* items_map_to_be_populated) const;
// Computes the pos_in_set and set_size values of all items in ordered_set and
diff --git a/third_party/accessibility/ax/ax_tree_combiner.cc b/third_party/accessibility/ax/ax_tree_combiner.cc
deleted file mode 100644
index 642ac2b..0000000
--- a/third_party/accessibility/ax/ax_tree_combiner.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_tree_combiner.h"
-
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_tree.h"
-#include "ui/gfx/geometry/rect_f.h"
-
-namespace ui {
-
-AXTreeCombiner::AXTreeCombiner() {}
-
-AXTreeCombiner::~AXTreeCombiner() {}
-
-void AXTreeCombiner::AddTree(const AXTreeUpdate& tree, bool is_root) {
- if (tree.tree_data.tree_id == AXTreeIDUnknown()) {
- LOG(WARNING) << "Skipping AXTreeID because its tree ID is unknown";
- return;
- }
-
- trees_.push_back(tree);
- if (is_root) {
- DCHECK_EQ(root_tree_id_, AXTreeIDUnknown());
- root_tree_id_ = tree.tree_data.tree_id;
- }
-}
-
-bool AXTreeCombiner::Combine() {
- // First create a map from tree ID to tree update.
- for (const auto& tree : trees_) {
- AXTreeID tree_id = tree.tree_data.tree_id;
- if (tree_id_map_.find(tree_id) != tree_id_map_.end())
- return false;
- tree_id_map_[tree.tree_data.tree_id] = &tree;
- }
-
- // Make sure the root tree ID is in the map, otherwise fail.
- if (tree_id_map_.find(root_tree_id_) == tree_id_map_.end())
- return false;
-
- // Process the nodes recursively, starting with the root tree.
- const AXTreeUpdate* root = tree_id_map_.find(root_tree_id_)->second;
- ProcessTree(root);
-
- // Set the root id.
- combined_.root_id = combined_.nodes.size() > 0 ? combined_.nodes[0].id : 0;
-
- // Finally, handle the tree ID, taking into account which subtree might
- // have focus and mapping IDs from the tree data appropriately.
- combined_.has_tree_data = true;
- combined_.tree_data = root->tree_data;
- AXTreeID focused_tree_id = root->tree_data.focused_tree_id;
- const AXTreeUpdate* focused_tree = root;
- if (tree_id_map_.find(focused_tree_id) != tree_id_map_.end())
- focused_tree = tree_id_map_[focused_tree_id];
- combined_.tree_data.focus_id =
- MapId(focused_tree_id, focused_tree->tree_data.focus_id);
- combined_.tree_data.sel_is_backward =
- MapId(focused_tree_id, focused_tree->tree_data.sel_is_backward);
- combined_.tree_data.sel_anchor_object_id =
- MapId(focused_tree_id, focused_tree->tree_data.sel_anchor_object_id);
- combined_.tree_data.sel_focus_object_id =
- MapId(focused_tree_id, focused_tree->tree_data.sel_focus_object_id);
- combined_.tree_data.sel_anchor_offset =
- focused_tree->tree_data.sel_anchor_offset;
- combined_.tree_data.sel_focus_offset =
- focused_tree->tree_data.sel_focus_offset;
-
- // Debug-mode check that the resulting combined tree is valid.
- AXTree tree;
- DCHECK(tree.Unserialize(combined_)) << combined_.ToString() << "\n"
- << tree.error();
-
- return true;
-}
-
-int32_t AXTreeCombiner::MapId(AXTreeID tree_id, int32_t node_id) {
- auto tree_id_node_id = std::make_pair(tree_id, node_id);
- if (tree_id_node_id_map_[tree_id_node_id] == 0)
- tree_id_node_id_map_[tree_id_node_id] = next_id_++;
- return tree_id_node_id_map_[tree_id_node_id];
-}
-
-void AXTreeCombiner::ProcessTree(const AXTreeUpdate* tree) {
- AXTreeID tree_id = tree->tree_data.tree_id;
- for (size_t i = 0; i < tree->nodes.size(); ++i) {
- AXNodeData node = tree->nodes[i];
- AXTreeID child_tree_id = AXTreeID::FromString(
- node.GetStringAttribute(ax::mojom::StringAttribute::kChildTreeId));
-
- // Map the node's ID.
- node.id = MapId(tree_id, node.id);
-
- // Map the node's child IDs.
- for (size_t j = 0; j < node.child_ids.size(); ++j)
- node.child_ids[j] = MapId(tree_id, node.child_ids[j]);
-
- // Map the container id.
- if (node.relative_bounds.offset_container_id > 0)
- node.relative_bounds.offset_container_id =
- MapId(tree_id, node.relative_bounds.offset_container_id);
-
- // Map other int attributes that refer to node IDs.
- for (size_t j = 0; j < node.int_attributes.size(); ++j) {
- auto& attr = node.int_attributes[j];
- if (IsNodeIdIntAttribute(attr.first))
- attr.second = MapId(tree_id, attr.second);
- }
-
- // Map other int list attributes that refer to node IDs.
- for (size_t j = 0; j < node.intlist_attributes.size(); ++j) {
- auto& attr = node.intlist_attributes[j];
- if (IsNodeIdIntListAttribute(attr.first)) {
- for (size_t k = 0; k < attr.second.size(); k++)
- attr.second[k] = MapId(tree_id, attr.second[k]);
- }
- }
-
- // Remove the ax::mojom::StringAttribute::kChildTreeId attribute.
- for (size_t j = 0; j < node.string_attributes.size(); ++j) {
- auto& attr = node.string_attributes[j];
- if (attr.first == ax::mojom::StringAttribute::kChildTreeId) {
- attr.first = ax::mojom::StringAttribute::kNone;
- attr.second = "";
- }
- }
-
- // See if this node has a child tree. As a sanity check make sure the
- // child tree lists this tree as its parent tree id.
- const AXTreeUpdate* child_tree = nullptr;
- if (tree_id_map_.find(child_tree_id) != tree_id_map_.end()) {
- child_tree = tree_id_map_.find(child_tree_id)->second;
- if (child_tree->tree_data.parent_tree_id != tree_id)
- child_tree = nullptr;
- if (child_tree && child_tree->nodes.empty())
- child_tree = nullptr;
- if (child_tree) {
- node.child_ids.push_back(MapId(child_tree_id, child_tree->nodes[0].id));
- }
- }
-
- // Put the rewritten AXNodeData into the output data structure.
- combined_.nodes.push_back(node);
-
- // Recurse into the child tree now, if any.
- if (child_tree)
- ProcessTree(child_tree);
- }
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_tree_combiner.h b/third_party/accessibility/ax/ax_tree_combiner.h
deleted file mode 100644
index 59626af..0000000
--- a/third_party/accessibility/ax/ax_tree_combiner.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_TREE_COMBINER_H_
-#define UI_ACCESSIBILITY_AX_TREE_COMBINER_H_
-
-#include <vector>
-
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_tree_id_registry.h"
-#include "ui/accessibility/ax_tree_update.h"
-
-namespace ui {
-
-// This helper class takes multiple accessibility trees that reference each
-// other via tree IDs, and combines them into a single accessibility tree
-// that spans all of them.
-//
-// Since node IDs are relative to each ID, it has to renumber all of the IDs
-// and update all of the attributes that reference IDs of other nodes to
-// ensure they point to the right node.
-//
-// It also makes sure the final combined tree points to the correct focused
-// node across all of the trees based on the focused tree ID of the root tree.
-class AX_EXPORT AXTreeCombiner {
- public:
- AXTreeCombiner();
- ~AXTreeCombiner();
-
- void AddTree(const AXTreeUpdate& tree, bool is_root);
- bool Combine();
-
- const AXTreeUpdate& combined() { return combined_; }
-
- private:
- int32_t MapId(AXTreeID tree_id, int32_t node_id);
-
- void ProcessTree(const AXTreeUpdate* tree);
-
- std::vector<ui::AXTreeUpdate> trees_;
- AXTreeID root_tree_id_;
- int32_t next_id_ = 1;
- std::map<AXTreeID, const AXTreeUpdate*> tree_id_map_;
- std::map<std::pair<AXTreeID, int32_t>, int32_t> tree_id_node_id_map_;
- AXTreeUpdate combined_;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_TREE_COMBINER_H_
diff --git a/third_party/accessibility/ax/ax_tree_combiner_unittest.cc b/third_party/accessibility/ax/ax_tree_combiner_unittest.cc
deleted file mode 100644
index f0d530d..0000000
--- a/third_party/accessibility/ax/ax_tree_combiner_unittest.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_tree_combiner.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-
-namespace ui {
-
-TEST(CombineAXTreesTest, RenumberOneTree) {
- AXTreeID tree_id_1 = AXTreeID::CreateNewAXTreeID();
-
- AXTreeUpdate tree;
- tree.has_tree_data = true;
- tree.tree_data.tree_id = tree_id_1;
- tree.root_id = 2;
- tree.nodes.resize(3);
- tree.nodes[0].id = 2;
- tree.nodes[0].child_ids.push_back(4);
- tree.nodes[0].child_ids.push_back(6);
- tree.nodes[1].id = 4;
- tree.nodes[2].id = 6;
-
- AXTreeCombiner combiner;
- combiner.AddTree(tree, true);
- combiner.Combine();
-
- const AXTreeUpdate& combined = combiner.combined();
-
- EXPECT_EQ(1, combined.root_id);
- ASSERT_EQ(3U, combined.nodes.size());
- EXPECT_EQ(1, combined.nodes[0].id);
- ASSERT_EQ(2U, combined.nodes[0].child_ids.size());
- EXPECT_EQ(2, combined.nodes[0].child_ids[0]);
- EXPECT_EQ(3, combined.nodes[0].child_ids[1]);
- EXPECT_EQ(2, combined.nodes[1].id);
- EXPECT_EQ(3, combined.nodes[2].id);
-}
-
-TEST(CombineAXTreesTest, EmbedChildTree) {
- AXTreeID tree_id_1 = AXTreeID::CreateNewAXTreeID();
- AXTreeID tree_id_2 = AXTreeID::CreateNewAXTreeID();
-
- AXTreeUpdate parent_tree;
- parent_tree.root_id = 1;
- parent_tree.has_tree_data = true;
- parent_tree.tree_data.tree_id = tree_id_1;
- parent_tree.nodes.resize(3);
- parent_tree.nodes[0].id = 1;
- parent_tree.nodes[0].child_ids.push_back(2);
- parent_tree.nodes[0].child_ids.push_back(3);
- parent_tree.nodes[1].id = 2;
- parent_tree.nodes[1].role = ax::mojom::Role::kButton;
- parent_tree.nodes[2].id = 3;
- parent_tree.nodes[2].role = ax::mojom::Role::kIframe;
- parent_tree.nodes[2].AddStringAttribute(
- ax::mojom::StringAttribute::kChildTreeId, tree_id_2.ToString());
-
- AXTreeUpdate child_tree;
- child_tree.root_id = 1;
- child_tree.has_tree_data = true;
- child_tree.tree_data.parent_tree_id = tree_id_1;
- child_tree.tree_data.tree_id = tree_id_2;
- child_tree.nodes.resize(3);
- child_tree.nodes[0].id = 1;
- child_tree.nodes[0].child_ids.push_back(2);
- child_tree.nodes[0].child_ids.push_back(3);
- child_tree.nodes[1].id = 2;
- child_tree.nodes[1].role = ax::mojom::Role::kCheckBox;
- child_tree.nodes[2].id = 3;
- child_tree.nodes[2].role = ax::mojom::Role::kRadioButton;
-
- AXTreeCombiner combiner;
- combiner.AddTree(parent_tree, true);
- combiner.AddTree(child_tree, false);
- combiner.Combine();
-
- const AXTreeUpdate& combined = combiner.combined();
-
- EXPECT_EQ(1, combined.root_id);
- ASSERT_EQ(6U, combined.nodes.size());
- EXPECT_EQ(1, combined.nodes[0].id);
- ASSERT_EQ(2U, combined.nodes[0].child_ids.size());
- EXPECT_EQ(2, combined.nodes[0].child_ids[0]);
- EXPECT_EQ(3, combined.nodes[0].child_ids[1]);
- EXPECT_EQ(2, combined.nodes[1].id);
- EXPECT_EQ(ax::mojom::Role::kButton, combined.nodes[1].role);
- EXPECT_EQ(3, combined.nodes[2].id);
- EXPECT_EQ(ax::mojom::Role::kIframe, combined.nodes[2].role);
- EXPECT_EQ(1U, combined.nodes[2].child_ids.size());
- EXPECT_EQ(4, combined.nodes[2].child_ids[0]);
- EXPECT_EQ(4, combined.nodes[3].id);
- EXPECT_EQ(5, combined.nodes[4].id);
- EXPECT_EQ(ax::mojom::Role::kCheckBox, combined.nodes[4].role);
- EXPECT_EQ(6, combined.nodes[5].id);
- EXPECT_EQ(ax::mojom::Role::kRadioButton, combined.nodes[5].role);
-}
-
-TEST(CombineAXTreesTest, MapAllIdAttributes) {
- AXTreeID tree_id_1 = AXTreeID::CreateNewAXTreeID();
-
- // This is a nonsensical accessibility tree, the goal is to make sure
- // that all attributes that reference IDs of other nodes are remapped.
-
- AXTreeUpdate tree;
- tree.has_tree_data = true;
- tree.tree_data.tree_id = tree_id_1;
- tree.root_id = 11;
- tree.nodes.resize(2);
- tree.nodes[0].id = 11;
- tree.nodes[0].child_ids.push_back(22);
- tree.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kTableHeaderId, 22);
- tree.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kTableRowHeaderId, 22);
- tree.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kTableColumnHeaderId,
- 22);
- tree.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
- 22);
- std::vector<int32_t> ids{22};
- tree.nodes[0].AddIntListAttribute(
- ax::mojom::IntListAttribute::kIndirectChildIds, ids);
- tree.nodes[0].AddIntListAttribute(ax::mojom::IntListAttribute::kControlsIds,
- ids);
- tree.nodes[0].AddIntListAttribute(
- ax::mojom::IntListAttribute::kDescribedbyIds, ids);
- tree.nodes[0].AddIntListAttribute(ax::mojom::IntListAttribute::kFlowtoIds,
- ids);
- tree.nodes[0].AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
- ids);
- tree.nodes[1].id = 22;
-
- AXTreeCombiner combiner;
- combiner.AddTree(tree, true);
- combiner.Combine();
-
- const AXTreeUpdate& combined = combiner.combined();
-
- EXPECT_EQ(1, combined.root_id);
- ASSERT_EQ(2U, combined.nodes.size());
- EXPECT_EQ(1, combined.nodes[0].id);
- ASSERT_EQ(1U, combined.nodes[0].child_ids.size());
- EXPECT_EQ(2, combined.nodes[0].child_ids[0]);
- EXPECT_EQ(2, combined.nodes[1].id);
-
- EXPECT_EQ(2, combined.nodes[0].GetIntAttribute(
- ax::mojom::IntAttribute::kTableHeaderId));
- EXPECT_EQ(2, combined.nodes[0].GetIntAttribute(
- ax::mojom::IntAttribute::kTableRowHeaderId));
- EXPECT_EQ(2, combined.nodes[0].GetIntAttribute(
- ax::mojom::IntAttribute::kTableColumnHeaderId));
- EXPECT_EQ(2, combined.nodes[0].GetIntAttribute(
- ax::mojom::IntAttribute::kActivedescendantId));
- EXPECT_EQ(2, combined.nodes[0].GetIntListAttribute(
- ax::mojom::IntListAttribute::kIndirectChildIds)[0]);
- EXPECT_EQ(2, combined.nodes[0].GetIntListAttribute(
- ax::mojom::IntListAttribute::kControlsIds)[0]);
- EXPECT_EQ(2, combined.nodes[0].GetIntListAttribute(
- ax::mojom::IntListAttribute::kDescribedbyIds)[0]);
- EXPECT_EQ(2, combined.nodes[0].GetIntListAttribute(
- ax::mojom::IntListAttribute::kFlowtoIds)[0]);
- EXPECT_EQ(2, combined.nodes[0].GetIntListAttribute(
- ax::mojom::IntListAttribute::kLabelledbyIds)[0]);
-}
-
-TEST(CombineAXTreesTest, FocusedTree) {
- AXTreeID tree_id_1 = AXTreeID::CreateNewAXTreeID();
- AXTreeID tree_id_2 = AXTreeID::CreateNewAXTreeID();
-
- AXTreeUpdate parent_tree;
- parent_tree.has_tree_data = true;
- parent_tree.tree_data.tree_id = tree_id_1;
- parent_tree.tree_data.focused_tree_id = tree_id_2;
- parent_tree.tree_data.focus_id = 2;
- parent_tree.root_id = 1;
- parent_tree.nodes.resize(3);
- parent_tree.nodes[0].id = 1;
- parent_tree.nodes[0].child_ids.push_back(2);
- parent_tree.nodes[0].child_ids.push_back(3);
- parent_tree.nodes[1].id = 2;
- parent_tree.nodes[1].role = ax::mojom::Role::kButton;
- parent_tree.nodes[2].id = 3;
- parent_tree.nodes[2].role = ax::mojom::Role::kIframe;
- parent_tree.nodes[2].AddStringAttribute(
- ax::mojom::StringAttribute::kChildTreeId, tree_id_2.ToString());
-
- AXTreeUpdate child_tree;
- child_tree.has_tree_data = true;
- child_tree.tree_data.parent_tree_id = tree_id_1;
- child_tree.tree_data.tree_id = tree_id_2;
- child_tree.tree_data.focus_id = 3;
- child_tree.root_id = 1;
- child_tree.nodes.resize(3);
- child_tree.nodes[0].id = 1;
- child_tree.nodes[0].child_ids.push_back(2);
- child_tree.nodes[0].child_ids.push_back(3);
- child_tree.nodes[1].id = 2;
- child_tree.nodes[1].role = ax::mojom::Role::kCheckBox;
- child_tree.nodes[2].id = 3;
- child_tree.nodes[2].role = ax::mojom::Role::kRadioButton;
-
- AXTreeCombiner combiner;
- combiner.AddTree(parent_tree, true);
- combiner.AddTree(child_tree, false);
- combiner.Combine();
-
- const AXTreeUpdate& combined = combiner.combined();
-
- ASSERT_EQ(6U, combined.nodes.size());
- EXPECT_EQ(6, combined.tree_data.focus_id);
-}
-
-TEST(CombineAXTreesTest, EmptyTree) {
- AXTreeUpdate tree;
-
- AXTreeCombiner combiner;
- combiner.AddTree(tree, true);
- combiner.Combine();
-
- const AXTreeUpdate& combined = combiner.combined();
- ASSERT_EQ(0U, combined.nodes.size());
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_tree_data.cc b/third_party/accessibility/ax/ax_tree_data.cc
index 43ba38f..a573700 100644
--- a/third_party/accessibility/ax/ax_tree_data.cc
+++ b/third_party/accessibility/ax/ax_tree_data.cc
@@ -2,16 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_tree_data.h"
+#include "ax_tree_data.h"
#include <set>
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_enum_util.h"
-#include "ui/accessibility/ax_enums.mojom.h"
+#include "ax_enum_util.h"
+#include "ax_enums.h"
+#include "base/string_utils.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_tree_data.h b/third_party/accessibility/ax/ax_tree_data.h
index 4f94423..be1c6fb 100644
--- a/third_party/accessibility/ax/ax_tree_data.h
+++ b/third_party/accessibility/ax/ax_tree_data.h
@@ -11,14 +11,10 @@
#include <string>
#include <vector>
-#include "base/optional.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_split.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_tree_id_registry.h"
-#include "ui/gfx/geometry/rect.h"
+#include "ax_enums.h"
+#include "ax_export.h"
+#include "ax_node.h"
+#include "ax_tree_id_registry.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_tree_fuzzer.cc b/third_party/accessibility/ax/ax_tree_fuzzer.cc
deleted file mode 100644
index 9a5b7f9..0000000
--- a/third_party/accessibility/ax/ax_tree_fuzzer.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_tree.h"
-#include "ui/accessibility/ax_tree_observer.h"
-
-class EmptyAXTreeObserver : public ui::AXTreeObserver {
- public:
- EmptyAXTreeObserver() {}
- ~EmptyAXTreeObserver() override {}
-};
-
-// Entry point for LibFuzzer.
-extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) {
- ui::AXTreeUpdate initial_state;
- size_t i = 0;
- while (i < size) {
- ui::AXNodeData node;
- node.id = data[i++];
- if (i < size) {
- size_t child_count = data[i++];
- for (size_t j = 0; j < child_count && i < size; j++)
- node.child_ids.push_back(data[i++]);
- }
- initial_state.nodes.push_back(node);
- }
-
- // Don't test absurdly large trees, it might time out.
-#if defined(NDEBUG)
- constexpr size_t kMaxNodes = 500000;
-#else
- constexpr size_t kMaxNodes = 50000;
-#endif
- if (initial_state.nodes.size() > kMaxNodes) {
- LOG(WARNING) << "Skipping input because it's too large";
- return 0;
- }
-
- // Run with --v=1 to aid in debugging a specific crash.
- VLOG(1) << "Input accessibility tree:\n" << initial_state.ToString();
-
- EmptyAXTreeObserver observer;
- ui::AXTree tree;
- tree.AddObserver(&observer);
- tree.Unserialize(initial_state);
- tree.RemoveObserver(&observer);
-
- return 0;
-}
diff --git a/third_party/accessibility/ax/ax_tree_id.cc b/third_party/accessibility/ax/ax_tree_id.cc
index d829f43..4ee545b 100644
--- a/third_party/accessibility/ax/ax_tree_id.cc
+++ b/third_party/accessibility/ax/ax_tree_id.cc
@@ -2,17 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_tree_id.h"
+#include "ax_tree_id.h"
#include <algorithm>
#include <iostream>
-#include "base/check.h"
+#include "ax_enums.h"
+#include "base/logging.h"
#include "base/no_destructor.h"
-#include "base/notreached.h"
-#include "base/util/values/values_util.h"
-#include "base/values.h"
-#include "ui/accessibility/ax_enums.mojom.h"
namespace ui {
@@ -22,7 +19,7 @@
AXTreeID::AXTreeID(ax::mojom::AXTreeIDType type) : type_(type) {
if (type_ == ax::mojom::AXTreeIDType::kToken)
- token_ = base::UnguessableToken::Create();
+ token_ = base::SimpleToken::Create();
}
AXTreeID::AXTreeID(const std::string& string) {
@@ -30,9 +27,8 @@
type_ = ax::mojom::AXTreeIDType::kUnknown;
} else {
type_ = ax::mojom::AXTreeIDType::kToken;
- base::Optional<base::UnguessableToken> token =
- util::ValueToUnguessableToken(base::Value(string));
- CHECK(token);
+ std::optional<base::SimpleToken> token = base::ValueToSimpleToken(string);
+ BASE_DCHECK(token);
token_ = *token;
}
}
@@ -43,7 +39,7 @@
}
// static
-AXTreeID AXTreeID::FromToken(const base::UnguessableToken& token) {
+AXTreeID AXTreeID::FromToken(const base::SimpleToken& token) {
return AXTreeID(token.ToString());
}
@@ -59,10 +55,10 @@
case ax::mojom::AXTreeIDType::kUnknown:
return "";
case ax::mojom::AXTreeIDType::kToken:
- return util::UnguessableTokenToValue(*token_).GetString();
+ return base::SimpleTokenToValue(*token_);
}
- NOTREACHED();
+ BASE_UNREACHABLE();
return std::string();
}
@@ -96,8 +92,8 @@
}
size_t AXTreeIDHash::operator()(const ui::AXTreeID& tree_id) const {
- DCHECK(tree_id.type() == ax::mojom::AXTreeIDType::kToken);
- return base::UnguessableTokenHash()(tree_id.token().value());
+ BASE_DCHECK(tree_id.type() == ax::mojom::AXTreeIDType::kToken);
+ return base::SimpleTokenHash(tree_id.token().value());
}
std::ostream& operator<<(std::ostream& stream, const AXTreeID& value) {
diff --git a/third_party/accessibility/ax/ax_tree_id.h b/third_party/accessibility/ax/ax_tree_id.h
index 354ef7c..11e201a 100644
--- a/third_party/accessibility/ax/ax_tree_id.h
+++ b/third_party/accessibility/ax/ax_tree_id.h
@@ -7,21 +7,10 @@
#include <string>
+#include "ax_base_export.h"
+#include "ax_enums.h"
#include "base/no_destructor.h"
-#include "base/unguessable_token.h"
-#include "ui/accessibility/ax_base_export.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-
-namespace mojo {
-template <typename DataViewType, typename T>
-struct UnionTraits;
-}
-
-namespace ax {
-namespace mojom {
-class AXTreeIDDataView;
-}
-} // namespace ax
+#include "base/simple_token.h"
namespace ui {
@@ -43,15 +32,15 @@
// automation API.
static AXTreeID FromString(const std::string& string);
- // Convenience method to unserialize an AXTreeID from an UnguessableToken.
- static AXTreeID FromToken(const base::UnguessableToken& token);
+ // Convenience method to unserialize an AXTreeID from an SimpleToken.
+ static AXTreeID FromToken(const base::SimpleToken& token);
AXTreeID& operator=(const AXTreeID& other);
std::string ToString() const;
ax::mojom::AXTreeIDType type() const { return type_; }
- const base::Optional<base::UnguessableToken>& token() const { return token_; }
+ const std::optional<base::SimpleToken>& token() const { return token_; }
bool operator==(const AXTreeID& rhs) const;
bool operator!=(const AXTreeID& rhs) const;
@@ -64,12 +53,11 @@
explicit AXTreeID(ax::mojom::AXTreeIDType type);
explicit AXTreeID(const std::string& string);
- friend struct mojo::UnionTraits<ax::mojom::AXTreeIDDataView, ui::AXTreeID>;
friend class base::NoDestructor<AXTreeID>;
friend void swap(AXTreeID& first, AXTreeID& second);
ax::mojom::AXTreeIDType type_;
- base::Optional<base::UnguessableToken> token_ = base::nullopt;
+ std::optional<base::SimpleToken> token_ = std::nullopt;
};
// For use in std::unordered_map.
diff --git a/third_party/accessibility/ax/ax_tree_id_registry.cc b/third_party/accessibility/ax/ax_tree_id_registry.cc
index 129bc6b..939a8b5 100644
--- a/third_party/accessibility/ax/ax_tree_id_registry.cc
+++ b/third_party/accessibility/ax/ax_tree_id_registry.cc
@@ -2,24 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_tree_id_registry.h"
+#include "ax_tree_id_registry.h"
-#include "base/memory/singleton.h"
-#include "base/strings/string_number_conversions.h"
-#include "ui/accessibility/ax_action_handler_base.h"
+#include "ax_action_handler_base.h"
+#include "base/logging.h"
namespace ui {
// static
-AXTreeIDRegistry* AXTreeIDRegistry::GetInstance() {
- return base::Singleton<AXTreeIDRegistry>::get();
+AXTreeIDRegistry& AXTreeIDRegistry::GetInstance() {
+ static AXTreeIDRegistry INSTANCE;
+ return INSTANCE;
}
void AXTreeIDRegistry::SetFrameIDForAXTreeID(const FrameID& frame_id,
const AXTreeID& ax_tree_id) {
auto it = frame_to_ax_tree_id_map_.find(frame_id);
if (it != frame_to_ax_tree_id_map_.end()) {
- NOTREACHED();
+ BASE_UNREACHABLE();
return;
}
@@ -63,7 +63,7 @@
void AXTreeIDRegistry::SetAXTreeID(const ui::AXTreeID& id,
AXActionHandlerBase* action_handler) {
- DCHECK(id_to_action_handler_.find(id) == id_to_action_handler_.end());
+ BASE_DCHECK(id_to_action_handler_.find(id) == id_to_action_handler_.end());
id_to_action_handler_[id] = action_handler;
}
diff --git a/third_party/accessibility/ax/ax_tree_id_registry.h b/third_party/accessibility/ax/ax_tree_id_registry.h
index 8ccbfee..6bce1ef 100644
--- a/third_party/accessibility/ax/ax_tree_id_registry.h
+++ b/third_party/accessibility/ax/ax_tree_id_registry.h
@@ -9,10 +9,10 @@
#include <string>
#include <utility>
+#include "ax_action_handler.h"
+#include "ax_export.h"
+#include "ax_tree_id.h"
#include "base/macros.h"
-#include "ui/accessibility/ax_action_handler.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_tree_id.h"
namespace base {
template <typename T>
@@ -36,7 +36,7 @@
using FrameID = std::pair<int, int>;
// Get the single instance of this class.
- static AXTreeIDRegistry* GetInstance();
+ static AXTreeIDRegistry& GetInstance();
// Gets the frame id based on an ax tree id.
FrameID GetFrameID(const AXTreeID& ax_tree_id);
@@ -79,7 +79,7 @@
// Maps an id to its handler.
std::map<AXTreeID, AXActionHandlerBase*> id_to_action_handler_;
- DISALLOW_COPY_AND_ASSIGN(AXTreeIDRegistry);
+ BASE_DISALLOW_COPY_AND_ASSIGN(AXTreeIDRegistry);
};
} // namespace ui
diff --git a/third_party/accessibility/ax/ax_tree_manager.h b/third_party/accessibility/ax/ax_tree_manager.h
index 45388a8..7a3c3bb 100644
--- a/third_party/accessibility/ax/ax_tree_manager.h
+++ b/third_party/accessibility/ax/ax_tree_manager.h
@@ -5,9 +5,9 @@
#ifndef UI_ACCESSIBILITY_AX_TREE_MANAGER_H_
#define UI_ACCESSIBILITY_AX_TREE_MANAGER_H_
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_tree_id.h"
+#include "ax_export.h"
+#include "ax_node.h"
+#include "ax_tree_id.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_tree_manager_map.cc b/third_party/accessibility/ax/ax_tree_manager_map.cc
index 56083ca..bb80805 100644
--- a/third_party/accessibility/ax/ax_tree_manager_map.cc
+++ b/third_party/accessibility/ax/ax_tree_manager_map.cc
@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_tree_manager_map.h"
+#include "ax_tree_manager_map.h"
-#include "base/stl_util.h"
-#include "ui/accessibility/ax_enums.mojom.h"
+#include "ax_enums.h"
+#include "base/container_utils.h"
+#include "base/logging.h"
namespace ui {
@@ -54,8 +55,8 @@
if (!child_tree_manager)
return nullptr;
- DCHECK(child_tree_manager->GetParentNodeFromParentTreeAsAXNode()->id() ==
- parent_node.id());
+ BASE_DCHECK(child_tree_manager->GetParentNodeFromParentTreeAsAXNode()->id() ==
+ parent_node.id());
return child_tree_manager;
}
diff --git a/third_party/accessibility/ax/ax_tree_manager_map.h b/third_party/accessibility/ax/ax_tree_manager_map.h
index 7cd92ff..9a7b251 100644
--- a/third_party/accessibility/ax/ax_tree_manager_map.h
+++ b/third_party/accessibility/ax/ax_tree_manager_map.h
@@ -7,10 +7,9 @@
#include <unordered_map>
-#include "base/macros.h"
+#include "ax_tree_id.h"
+#include "ax_tree_manager.h"
#include "base/no_destructor.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/accessibility/ax_tree_manager.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_tree_observer.cc b/third_party/accessibility/ax/ax_tree_observer.cc
index 9080e81..1f89cd8 100644
--- a/third_party/accessibility/ax/ax_tree_observer.cc
+++ b/third_party/accessibility/ax/ax_tree_observer.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_tree_observer.h"
+#include "ax_tree_observer.h"
namespace ui {
diff --git a/third_party/accessibility/ax/ax_tree_observer.h b/third_party/accessibility/ax/ax_tree_observer.h
index c9517c6..7257168 100644
--- a/third_party/accessibility/ax/ax_tree_observer.h
+++ b/third_party/accessibility/ax/ax_tree_observer.h
@@ -5,9 +5,12 @@
#ifndef UI_ACCESSIBILITY_AX_TREE_OBSERVER_H_
#define UI_ACCESSIBILITY_AX_TREE_OBSERVER_H_
-#include "base/observer_list_types.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include "ax_enums.h"
+#include "ax_export.h"
namespace ui {
@@ -21,10 +24,10 @@
// |OnAtomicUpdateFinished| is notified at the end of an atomic update.
// It provides a vector of nodes that were added or changed, for final
// postprocessing.
-class AX_EXPORT AXTreeObserver : public base::CheckedObserver {
+class AX_EXPORT AXTreeObserver {
public:
AXTreeObserver();
- ~AXTreeObserver() override;
+ virtual ~AXTreeObserver();
// Called before any tree modifications have occurred, notifying that a single
// node will change its data. Its id and data will be valid, but its links to
diff --git a/third_party/accessibility/ax/ax_tree_serializer.cc b/third_party/accessibility/ax/ax_tree_serializer.cc
deleted file mode 100644
index d4eee28..0000000
--- a/third_party/accessibility/ax/ax_tree_serializer.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_tree_serializer.h"
-
-namespace ui {
-
-ClientTreeNode::ClientTreeNode() {}
-
-ClientTreeNode::~ClientTreeNode() {}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_tree_serializer.h b/third_party/accessibility/ax/ax_tree_serializer.h
deleted file mode 100644
index 737ad7c..0000000
--- a/third_party/accessibility/ax/ax_tree_serializer.h
+++ /dev/null
@@ -1,695 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_
-#define UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-#include "base/logging.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_tree_source.h"
-#include "ui/accessibility/ax_tree_update.h"
-
-namespace ui {
-
-struct ClientTreeNode;
-
-// AXTreeSerializer is a helper class that serializes incremental
-// updates to an AXTreeSource as a AXTreeUpdate struct.
-// These structs can be unserialized by a client object such as an
-// AXTree. An AXTreeSerializer keeps track of the tree of node ids that its
-// client is aware of so that it will never generate an AXTreeUpdate that
-// results in an invalid tree.
-//
-// Every node in the source tree must have an id that's a unique positive
-// integer, the same node must not appear twice.
-//
-// Usage:
-//
-// You must call SerializeChanges() every time a node in the tree changes,
-// and send the generated AXTreeUpdate to the client. Changes to the
-// AXTreeData, if any, are also automatically included in the AXTreeUpdate.
-//
-// If a node is added, call SerializeChanges on its parent.
-// If a node is removed, call SerializeChanges on its parent.
-// If a whole new subtree is added, just call SerializeChanges on its root.
-// If the root of the tree changes, call SerializeChanges on the new root.
-//
-// AXTreeSerializer will avoid re-serializing nodes that do not change.
-// For example, if node 1 has children 2, 3, 4, 5 and then child 2 is
-// removed and a new child 6 is added, the AXTreeSerializer will only
-// update nodes 1 and 6 (and any children of node 6 recursively). It will
-// assume that nodes 3, 4, and 5 are not modified unless you explicitly
-// call SerializeChanges() on them.
-//
-// As long as the source tree has unique ids for every node and no loops,
-// and as long as every update is applied to the client tree, AXTreeSerializer
-// will continue to work. If the source tree makes a change but fails to
-// call SerializeChanges properly, the trees may get out of sync - but
-// because AXTreeSerializer always keeps track of what updates it's sent,
-// it will never send an invalid update and the client tree will not break,
-// it just may not contain all of the changes.
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-class AXTreeSerializer {
- public:
- explicit AXTreeSerializer(
- AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree);
- ~AXTreeSerializer();
-
- // Throw out the internal state that keeps track of the nodes the client
- // knows about. This has the effect that the next update will send the
- // entire tree over because it assumes the client knows nothing.
- void Reset();
-
- // Sets the maximum number of nodes that will be serialized, or zero
- // for no maximum. This is not a hard maximum - once it hits or
- // exceeds this maximum it stops walking the children of nodes, but
- // it may exceed this value a bit in order to create a consistent
- // tree.
- void set_max_node_count(size_t max_node_count) {
- max_node_count_ = max_node_count;
- }
-
- // Serialize all changes to |node| and append them to |out_update|.
- // Returns true on success. On failure, returns false and calls Reset();
- // this only happens when the source tree has a problem like duplicate
- // ids or changing during serialization.
- bool SerializeChanges(AXSourceNode node,
- AXTreeUpdateBase<AXNodeData, AXTreeData>* out_update);
-
- // Invalidate the subtree rooted at this node, ensuring that the whole
- // subtree is re-serialized the next time any of those nodes end up
- // being serialized.
- void InvalidateSubtree(AXSourceNode node);
-
- // Return whether or not this node is in the client tree. If you call
- // this immediately after serializing, this indicates whether a given
- // node is in the set of nodes that the client (the recipient of
- // the AXTreeUpdates) is aware of.
- //
- // For example, you could use this to determine if a given node is
- // reachable. If one of its ancestors is hidden and it was pruned
- // from the accessibility tree, this would return false.
- bool IsInClientTree(AXSourceNode node);
-
- // Only for unit testing. Normally this class relies on getting a call
- // to SerializeChanges() every time the source tree changes. For unit
- // testing, it's convenient to create a static AXTree for the initial
- // state and then call ChangeTreeSourceForTesting and then SerializeChanges
- // to simulate the changes you'd get if a tree changed from the initial
- // state to the second tree's state.
- void ChangeTreeSourceForTesting(
- AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* new_tree);
-
- // Returns the number of nodes in the client tree. After a serialization
- // operation this should be an accurate representation of the tree source
- // as explored by the serializer.
- size_t ClientTreeNodeCount() const;
-
- private:
- // Return the least common ancestor of a node in the source tree
- // and a node in the client tree, or nullptr if there is no such node.
- // The least common ancestor is the closest ancestor to |node| (which
- // may be |node| itself) that's in both the source tree and client tree,
- // and for which both the source and client tree agree on their ancestor
- // chain up to the root.
- //
- // Example 1:
- //
- // Client Tree Source tree |
- // 1 1 |
- // / \ / \ |
- // 2 3 2 4 |
- //
- // LCA(source node 2, client node 2) is node 2.
- // LCA(source node 3, client node 4) is node 1.
- //
- // Example 2:
- //
- // Client Tree Source tree |
- // 1 1 |
- // / \ / \ |
- // 2 3 2 3 |
- // / \ / / |
- // 4 7 8 4 |
- // / \ / \ |
- // 5 6 5 6 |
- //
- // LCA(source node 8, client node 7) is node 2.
- // LCA(source node 5, client node 5) is node 1.
- // It's not node 5, because the two trees disagree on the parent of
- // node 4, so the LCA is the first ancestor both trees agree on.
- AXSourceNode LeastCommonAncestor(AXSourceNode node,
- ClientTreeNode* client_node);
-
- // Return the least common ancestor of |node| that's in the client tree.
- // This just walks up the ancestors of |node| until it finds a node that's
- // also in the client tree and not inside an invalid subtree, and then calls
- // LeastCommonAncestor on the source node and client node.
- AXSourceNode LeastCommonAncestor(AXSourceNode node);
-
- // Walk the subtree rooted at |node| and return true if any nodes that
- // would be updated are being reparented. If so, update |out_lca| to point
- // to the least common ancestor of the previous LCA and the previous
- // parent of the node being reparented.
- bool AnyDescendantWasReparented(AXSourceNode node, AXSourceNode* out_lca);
-
- ClientTreeNode* ClientTreeNodeById(int32_t id);
-
- // Invalidate the subtree rooted at this node.
- void InvalidateClientSubtree(ClientTreeNode* client_node);
-
- // Delete all descendants of this node.
- void DeleteDescendants(ClientTreeNode* client_node);
-
- // Delete the client subtree rooted at this node.
- void DeleteClientSubtree(ClientTreeNode* client_node);
-
- // Helper function, called recursively with each new node to serialize.
- bool SerializeChangedNodes(
- AXSourceNode node,
- AXTreeUpdateBase<AXNodeData, AXTreeData>* out_update);
-
- // Delete the entire client subtree but don't set the did_reset_ flag
- // like when Reset() is called.
- void InternalReset();
-
- ClientTreeNode* GetClientTreeNodeParent(ClientTreeNode* obj);
-
- // The tree source.
- AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree_;
-
- // The tree data most recently sent to the client.
- AXTreeData client_tree_data_;
-
- // Our representation of the client tree.
- ClientTreeNode* client_root_ = nullptr;
-
- // A map from IDs to nodes in the client tree.
- std::unordered_map<int32_t, ClientTreeNode*> client_id_map_;
-
- // The maximum number of nodes to serialize in a given call to
- // SerializeChanges, or 0 if there's no maximum.
- size_t max_node_count_ = 0;
-
- // Keeps track of if Reset() was called. If so, we need to always
- // explicitly set node_id_to_clear to ensure that the next serialized
- // tree is treated as a completely new tree and not a partial update.
- bool did_reset_ = false;
-};
-
-// In order to keep track of what nodes the client knows about, we keep a
-// representation of the client tree - just IDs and parent/child
-// relationships, and a marker indicating whether it's been invalidated.
-struct AX_EXPORT ClientTreeNode {
- ClientTreeNode();
- virtual ~ClientTreeNode();
- int32_t id;
- ClientTreeNode* parent;
- std::vector<ClientTreeNode*> children;
- bool ignored;
- bool invalid;
-};
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::AXTreeSerializer(
- AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree)
- : tree_(tree) {}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::~AXTreeSerializer() {
- // Clear |tree_| to prevent any additional calls to the tree source
- // during teardown.
- tree_ = nullptr;
- Reset();
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::Reset() {
- InternalReset();
- did_reset_ = true;
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::InternalReset() {
- client_tree_data_ = AXTreeData();
-
- // Normally we use DeleteClientSubtree to remove nodes from the tree,
- // but Reset() needs to work even if the tree is in a broken state.
- // Instead, iterate over |client_id_map_| to ensure we clear all nodes and
- // start from scratch.
- for (auto&& item : client_id_map_) {
- if (tree_)
- tree_->SerializerClearedNode(item.first);
- delete item.second;
- }
- client_id_map_.clear();
- client_root_ = nullptr;
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
- ChangeTreeSourceForTesting(
- AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* new_tree) {
- tree_ = new_tree;
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-size_t
-AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::ClientTreeNodeCount()
- const {
- return client_id_map_.size();
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-AXSourceNode
-AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::LeastCommonAncestor(
- AXSourceNode node,
- ClientTreeNode* client_node) {
- if (!tree_->IsValid(node) || client_node == nullptr)
- return tree_->GetNull();
-
- std::vector<AXSourceNode> ancestors;
- while (tree_->IsValid(node)) {
- ancestors.push_back(node);
- node = tree_->GetParent(node);
- }
-
- std::vector<ClientTreeNode*> client_ancestors;
- while (client_node) {
- client_ancestors.push_back(client_node);
- client_node = GetClientTreeNodeParent(client_node);
- }
-
- // Start at the root. Keep going until the source ancestor chain and
- // client ancestor chain disagree. The last node before they disagree
- // is the LCA.
- AXSourceNode lca = tree_->GetNull();
- int source_index = static_cast<int>(ancestors.size() - 1);
- int client_index = static_cast<int>(client_ancestors.size() - 1);
- while (source_index >= 0 && client_index >= 0) {
- if (tree_->GetId(ancestors[source_index]) !=
- client_ancestors[client_index]->id) {
- return lca;
- }
- lca = ancestors[source_index];
- source_index--;
- client_index--;
- }
- return lca;
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-AXSourceNode
-AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::LeastCommonAncestor(
- AXSourceNode node) {
- // Walk up the tree until the source node's id also exists in the
- // client tree, whose parent is not invalid, then call LeastCommonAncestor
- // on those two nodes.
- //
- // Note that it's okay if |client_node| is invalid - the LCA can be the
- // root of an invalid subtree, since we're going to serialize the
- // LCA. But it's not okay if |client_node->parent| is invalid - that means
- // that we're inside of an invalid subtree that all needs to be
- // re-serialized, so the LCA should be higher.
- ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node));
- while (tree_->IsValid(node)) {
- if (client_node) {
- ClientTreeNode* parent = GetClientTreeNodeParent(client_node);
- if (!parent || !parent->invalid)
- break;
- }
- node = tree_->GetParent(node);
- if (tree_->IsValid(node))
- client_node = ClientTreeNodeById(tree_->GetId(node));
- }
- return LeastCommonAncestor(node, client_node);
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
- AnyDescendantWasReparented(AXSourceNode node, AXSourceNode* out_lca) {
- bool result = false;
- int id = tree_->GetId(node);
- std::vector<AXSourceNode> children;
- tree_->GetChildren(node, &children);
- for (size_t i = 0; i < children.size(); ++i) {
- AXSourceNode& child = children[i];
- int child_id = tree_->GetId(child);
- ClientTreeNode* client_child = ClientTreeNodeById(child_id);
- if (client_child) {
- ClientTreeNode* parent = client_child->parent;
- if (!parent) {
- // If the client child has no parent, it must have been the
- // previous root node, so there is no LCA and we can exit early.
- *out_lca = tree_->GetNull();
- return true;
- } else if (parent->id != id) {
- // If the client child's parent is not this node, update the LCA
- // and return true (reparenting was found).
- *out_lca = LeastCommonAncestor(*out_lca, client_child);
- result = true;
- continue;
- } else if (!client_child->invalid) {
- // This child is already in the client tree and valid, we won't
- // recursively serialize it so we don't need to check this
- // subtree recursively for reparenting.
- // However, if the child is ignored, the children may now be
- // considered as reparented, so continue recursion in that case.
- if (!client_child->ignored)
- continue;
- }
- }
-
- // This is a new child or reparented child, check it recursively.
- if (AnyDescendantWasReparented(child, out_lca))
- result = true;
- }
- return result;
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-ClientTreeNode*
-AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::ClientTreeNodeById(
- int32_t id) {
- std::unordered_map<int32_t, ClientTreeNode*>::iterator iter =
- client_id_map_.find(id);
- if (iter != client_id_map_.end())
- return iter->second;
- return nullptr;
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-ClientTreeNode*
-AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::GetClientTreeNodeParent(
- ClientTreeNode* obj) {
- ClientTreeNode* parent = obj->parent;
-#if DCHECK_IS_ON()
- if (!parent)
- return nullptr;
- DCHECK(ClientTreeNodeById(parent->id)) << "Parent not in id map.";
-#endif // DCHECK_IS_ON()
- return parent;
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::SerializeChanges(
- AXSourceNode node,
- AXTreeUpdateBase<AXNodeData, AXTreeData>* out_update) {
- // Send the tree data if it's changed since the last update, or if
- // out_update->has_tree_data is already set to true.
- AXTreeData new_tree_data;
- if (tree_->GetTreeData(&new_tree_data) &&
- (out_update->has_tree_data || new_tree_data != client_tree_data_)) {
- out_update->has_tree_data = true;
- out_update->tree_data = new_tree_data;
- client_tree_data_ = new_tree_data;
- }
-
- // If the node isn't in the client tree, we need to serialize starting
- // with the LCA.
- AXSourceNode lca = LeastCommonAncestor(node);
-
- // This loop computes the least common ancestor that includes the old
- // and new parents of any nodes that have been reparented, and clears the
- // whole client subtree of that LCA if necessary. If we do end up clearing
- // any client nodes, keep looping because we have to search for more
- // nodes that may have been reparented from this new LCA.
- bool need_delete;
- do {
- need_delete = false;
- if (client_root_) {
- if (tree_->IsValid(lca)) {
- // Check for any reparenting within this subtree - if there is
- // any, we need to delete and reserialize the whole subtree
- // that contains the old and new parents of the reparented node.
- if (AnyDescendantWasReparented(lca, &lca))
- need_delete = true;
- }
-
- if (!tree_->IsValid(lca)) {
- // If there's no LCA, just tell the client to destroy the whole
- // tree and then we'll serialize everything from the new root.
- out_update->node_id_to_clear = client_root_->id;
- InternalReset();
- } else if (need_delete) {
- // Otherwise, if we need to reserialize a subtree, first we need
- // to delete those nodes in our client tree so that
- // SerializeChangedNodes() will be sure to send them again.
- out_update->node_id_to_clear = tree_->GetId(lca);
- ClientTreeNode* client_lca = ClientTreeNodeById(tree_->GetId(lca));
- CHECK(client_lca);
- DeleteDescendants(client_lca);
- }
- }
- } while (need_delete);
-
- // Serialize from the LCA, or from the root if there isn't one.
- if (!tree_->IsValid(lca))
- lca = tree_->GetRoot();
-
- if (!SerializeChangedNodes(lca, out_update))
- return false;
-
- // If we had a reset, ensure that the old tree is cleared before the client
- // unserializes this update. If we didn't do this, there's a chance that
- // treating this update as an incremental update could result in some
- // reparenting.
- if (did_reset_) {
- out_update->node_id_to_clear = tree_->GetId(lca);
- did_reset_ = false;
- }
-
- return true;
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::InvalidateSubtree(
- AXSourceNode node) {
- ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node));
- if (client_node)
- InvalidateClientSubtree(client_node);
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::IsInClientTree(
- AXSourceNode node) {
- ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node));
- return client_node ? !client_node->invalid : false;
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
- InvalidateClientSubtree(ClientTreeNode* client_node) {
- client_node->invalid = true;
- for (size_t i = 0; i < client_node->children.size(); ++i)
- InvalidateClientSubtree(client_node->children[i]);
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
- DeleteClientSubtree(ClientTreeNode* client_node) {
- if (client_node == client_root_) {
- Reset(); // Do not try to reuse a bad root later.
- } else {
- DeleteDescendants(client_node);
- tree_->SerializerClearedNode(client_node->id);
- client_id_map_.erase(client_node->id);
- delete client_node;
- }
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::DeleteDescendants(
- ClientTreeNode* client_node) {
- for (size_t i = 0; i < client_node->children.size(); ++i)
- DeleteClientSubtree(client_node->children[i]);
- client_node->children.clear();
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
- SerializeChangedNodes(
- AXSourceNode node,
- AXTreeUpdateBase<AXNodeData, AXTreeData>* out_update) {
- // This method has three responsibilities:
- // 1. Serialize |node| into an AXNodeData, and append it to
- // the AXTreeUpdate to be sent to the client.
- // 2. Determine if |node| has any new children that the client doesn't
- // know about yet, and call SerializeChangedNodes recursively on those.
- // 3. Update our internal data structure that keeps track of what nodes
- // the client knows about.
-
- // First, find the ClientTreeNode for this id in our data structure where
- // we keep track of what accessibility objects the client already knows
- // about. If we don't find it, then this must be the new root of the
- // accessibility tree.
- int id = tree_->GetId(node);
- ClientTreeNode* client_node = ClientTreeNodeById(id);
- if (!client_node) {
- if (client_root_)
- Reset();
- client_root_ = new ClientTreeNode();
- client_node = client_root_;
- client_node->id = id;
- client_node->parent = nullptr;
- client_id_map_[client_node->id] = client_node;
- }
-
- // We're about to serialize it, so mark it as valid.
- client_node->invalid = false;
- client_node->ignored = tree_->IsIgnored(node);
-
- // Iterate over the ids of the children of |node|.
- // Create a set of the child ids so we can quickly look
- // up which children are new and which ones were there before.
- // If we've hit the maximum number of serialized nodes, pretend
- // this node has no children but keep going so that we get
- // consistent results.
- std::unordered_set<int32_t> new_ignored_ids;
- std::unordered_set<int32_t> new_child_ids;
- std::vector<AXSourceNode> children;
- if (max_node_count_ == 0 || out_update->nodes.size() < max_node_count_) {
- tree_->GetChildren(node, &children);
- } else if (max_node_count_ > 0) {
- static bool logged_once = false;
- if (!logged_once) {
- LOG(WARNING) << "Warning: not serializing AX nodes after a max of "
- << max_node_count_;
- logged_once = true;
- }
- }
- for (size_t i = 0; i < children.size(); ++i) {
- AXSourceNode& child = children[i];
- int new_child_id = tree_->GetId(child);
- new_child_ids.insert(new_child_id);
- if (tree_->IsIgnored(child))
- new_ignored_ids.insert(new_child_id);
-
- // There shouldn't be any reparenting because we've already handled it
- // above. If this happens, reset and return an error.
-
- ClientTreeNode* client_child = ClientTreeNodeById(new_child_id);
- if (client_child && GetClientTreeNodeParent(client_child) != client_node) {
- DVLOG(1) << "Illegal reparenting detected";
-#if defined(ADDRESS_SANITIZER)
- // Wrapping this in ADDRESS_SANITIZER will cause it to run on
- // clusterfuzz, which should help us narrow down the issue.
- // TODO(accessibility) Remove all cases where this occurs and re-add
- // NOTREACHED(). This condition leads to performance problems. It will
- // also reset virtual buffers, causing users to lose their place.
- NOTREACHED() << "Illegal reparenting detected: "
- << "\nPassed-in parent: "
- << tree_->GetDebugString(tree_->GetFromId(client_node->id))
- << "\nChild: " << tree_->GetDebugString(child)
- << "\nChild's parent: "
- << tree_->GetDebugString(
- tree_->GetFromId(client_child->parent->id))
- << "\n-----------------------------------------\n\n\n";
-#endif
- Reset();
- return false;
- }
- }
-
- // Go through the old children and delete subtrees for child
- // ids that are no longer present, and create a map from
- // id to ClientTreeNode for the rest. It's important to delete
- // first in a separate pass so that nodes that are reparented
- // don't end up children of two different parents in the middle
- // of an update, which can lead to a double-free.
- std::unordered_map<int32_t, ClientTreeNode*> client_child_id_map;
- std::vector<ClientTreeNode*> old_children;
- old_children.swap(client_node->children);
- for (size_t i = 0; i < old_children.size(); ++i) {
- ClientTreeNode* old_child = old_children[i];
- int old_child_id = old_child->id;
- if (new_child_ids.find(old_child_id) == new_child_ids.end()) {
- DeleteClientSubtree(old_child);
- } else {
- client_child_id_map[old_child_id] = old_child;
- }
- }
-
- // Serialize this node. This fills in all of the fields in
- // AXNodeData except child_ids, which we handle below.
- size_t serialized_node_index = out_update->nodes.size();
- out_update->nodes.push_back(AXNodeData());
- {
- // Take the address of an element in a vector only within a limited
- // scope because otherwise the pointer can become invalid if the
- // vector is resized.
- AXNodeData* serialized_node = &out_update->nodes[serialized_node_index];
-
- tree_->SerializeNode(node, serialized_node);
- if (serialized_node->id == client_root_->id)
- out_update->root_id = serialized_node->id;
- }
-
- // Iterate over the children, serialize them, and update the ClientTreeNode
- // data structure to reflect the new tree.
- std::vector<int32_t> actual_serialized_node_child_ids;
- client_node->children.reserve(children.size());
- for (size_t i = 0; i < children.size(); ++i) {
- AXSourceNode& child = children[i];
- int child_id = tree_->GetId(child);
-
- // Skip if the child isn't valid.
- if (!tree_->IsValid(child))
- continue;
-
- // Skip if the same child is included more than once.
- if (new_child_ids.find(child_id) == new_child_ids.end())
- continue;
-
- new_child_ids.erase(child_id);
- actual_serialized_node_child_ids.push_back(child_id);
- ClientTreeNode* reused_child = nullptr;
- if (client_child_id_map.find(child_id) != client_child_id_map.end())
- reused_child = ClientTreeNodeById(child_id);
- if (reused_child) {
- client_node->children.push_back(reused_child);
- const bool ignored_state_changed =
- reused_child->ignored !=
- (new_ignored_ids.find(reused_child->id) != new_ignored_ids.end());
- // Re-serialize it if the child is marked as invalid, otherwise
- // we don't have to because the client already has it.
- if (reused_child->invalid || ignored_state_changed) {
- if (!SerializeChangedNodes(child, out_update))
- return false;
- }
- } else {
- ClientTreeNode* new_child = new ClientTreeNode();
- new_child->id = child_id;
- new_child->parent = client_node;
- new_child->ignored = tree_->IsIgnored(child);
- new_child->invalid = false;
- client_node->children.push_back(new_child);
- DCHECK(!ClientTreeNodeById(child_id))
- << "Child id " << child_id << " already exists in map."
- << "\nChild is " << tree_->GetDebugString(tree_->GetFromId(child_id))
- << " of parent " << tree_->GetDebugString(node);
- client_id_map_[child_id] = new_child;
- if (!SerializeChangedNodes(child, out_update))
- return false;
- }
- }
-
- // Finally, update the child ids of this node to reflect the actual child
- // ids that were valid during serialization.
- out_update->nodes[serialized_node_index].child_ids.swap(
- actual_serialized_node_child_ids);
-
- return true;
-}
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_
diff --git a/third_party/accessibility/ax/ax_tree_serializer_unittest.cc b/third_party/accessibility/ax/ax_tree_serializer_unittest.cc
deleted file mode 100644
index 5f1721a..0000000
--- a/third_party/accessibility/ax/ax_tree_serializer_unittest.cc
+++ /dev/null
@@ -1,628 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_tree_serializer.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/strings/string_number_conversions.h"
-#include "testing/gmock/include/gmock/gmock-matchers.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_serializable_tree.h"
-#include "ui/accessibility/ax_tree.h"
-
-using testing::UnorderedElementsAre;
-
-namespace ui {
-
-using BasicAXTreeSerializer =
- AXTreeSerializer<const AXNode*, AXNodeData, AXTreeData>;
-
-// The framework for these tests is that each test sets up |treedata0_|
-// and |treedata1_| and then calls GetTreeSerializer, which creates a
-// serializer for a tree that's initially in state |treedata0_|, but then
-// changes to state |treedata1_|. This allows each test to check the
-// updates created by AXTreeSerializer or unit-test its private
-// member functions.
-class AXTreeSerializerTest : public testing::Test {
- public:
- AXTreeSerializerTest() {}
- ~AXTreeSerializerTest() override {}
-
- protected:
- void CreateTreeSerializer();
-
- AXTreeUpdate treedata0_;
- AXTreeUpdate treedata1_;
- std::unique_ptr<AXSerializableTree> tree0_;
- std::unique_ptr<AXSerializableTree> tree1_;
- std::unique_ptr<AXTreeSource<const AXNode*, AXNodeData, AXTreeData>>
- tree0_source_;
- std::unique_ptr<AXTreeSource<const AXNode*, AXNodeData, AXTreeData>>
- tree1_source_;
- std::unique_ptr<BasicAXTreeSerializer> serializer_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AXTreeSerializerTest);
-};
-
-void AXTreeSerializerTest::CreateTreeSerializer() {
- if (serializer_)
- return;
-
- tree0_ = std::make_unique<AXSerializableTree>(treedata0_);
- tree1_ = std::make_unique<AXSerializableTree>(treedata1_);
-
- // Serialize tree0 so that AXTreeSerializer thinks that its client
- // is totally in sync.
- tree0_source_.reset(tree0_->CreateTreeSource());
- serializer_ = std::make_unique<BasicAXTreeSerializer>(tree0_source_.get());
- AXTreeUpdate unused_update;
- ASSERT_TRUE(serializer_->SerializeChanges(tree0_->root(), &unused_update));
-
- // Pretend that tree0_ turned into tree1_. The next call to
- // AXTreeSerializer will force it to consider these changes to
- // the tree and send them as part of the next update.
- tree1_source_.reset(tree1_->CreateTreeSource());
- serializer_->ChangeTreeSourceForTesting(tree1_source_.get());
-}
-
-// In this test, one child is added to the root. Only the root and
-// new child should be added.
-TEST_F(AXTreeSerializerTest, UpdateContainsOnlyChangedNodes) {
- // (1 (2 3))
- treedata0_.root_id = 1;
- treedata0_.nodes.resize(3);
- treedata0_.nodes[0].id = 1;
- treedata0_.nodes[0].child_ids.push_back(2);
- treedata0_.nodes[0].child_ids.push_back(3);
- treedata0_.nodes[1].id = 2;
- treedata0_.nodes[2].id = 3;
-
- // (1 (4 2 3))
- treedata1_.root_id = 1;
- treedata1_.nodes.resize(4);
- treedata1_.nodes[0].id = 1;
- treedata1_.nodes[0].child_ids.push_back(4);
- treedata1_.nodes[0].child_ids.push_back(2);
- treedata1_.nodes[0].child_ids.push_back(3);
- treedata1_.nodes[1].id = 2;
- treedata1_.nodes[2].id = 3;
- treedata1_.nodes[3].id = 4;
-
- CreateTreeSerializer();
- AXTreeUpdate update;
- ASSERT_TRUE(serializer_->SerializeChanges(tree1_->GetFromId(1), &update));
-
- // The update should only touch nodes 1 and 4 - nodes 2 and 3 are unchanged
- // and shouldn't be affected.
- EXPECT_EQ(0, update.node_id_to_clear);
- ASSERT_EQ(2u, update.nodes.size());
- EXPECT_EQ(1, update.nodes[0].id);
- EXPECT_EQ(4, update.nodes[1].id);
-}
-
-// When the root changes, the whole tree is updated, even if some of it
-// is unaffected.
-TEST_F(AXTreeSerializerTest, NewRootUpdatesEntireTree) {
- // (1 (2 (3 (4))))
- treedata0_.root_id = 1;
- treedata0_.nodes.resize(4);
- treedata0_.nodes[0].id = 1;
- treedata0_.nodes[0].child_ids.push_back(2);
- treedata0_.nodes[1].id = 2;
- treedata0_.nodes[1].child_ids.push_back(3);
- treedata0_.nodes[2].id = 3;
- treedata0_.nodes[2].child_ids.push_back(4);
- treedata0_.nodes[3].id = 4;
-
- // (5 (2 (3 (4))))
- treedata1_.root_id = 5;
- treedata1_.nodes.resize(4);
- treedata1_.nodes[0].id = 5;
- treedata1_.nodes[0].child_ids.push_back(2);
- treedata1_.nodes[1].id = 2;
- treedata1_.nodes[1].child_ids.push_back(3);
- treedata1_.nodes[2].id = 3;
- treedata1_.nodes[2].child_ids.push_back(4);
- treedata1_.nodes[3].id = 4;
-
- CreateTreeSerializer();
- AXTreeUpdate update;
- ASSERT_TRUE(serializer_->SerializeChanges(tree1_->GetFromId(4), &update));
-
- // The update should delete the subtree rooted at node id=1, and
- // then include all four nodes in the update, even though the
- // subtree rooted at id=2 didn't actually change.
- EXPECT_EQ(1, update.node_id_to_clear);
- ASSERT_EQ(4u, update.nodes.size());
- EXPECT_EQ(5, update.nodes[0].id);
- EXPECT_EQ(2, update.nodes[1].id);
- EXPECT_EQ(3, update.nodes[2].id);
- EXPECT_EQ(4, update.nodes[3].id);
-}
-
-// When a node is reparented, the subtree including both the old parent
-// and new parent of the reparented node must be deleted and recreated.
-TEST_F(AXTreeSerializerTest, ReparentingUpdatesSubtree) {
- // (1 (2 (3 (4) 5)))
- treedata0_.root_id = 1;
- treedata0_.nodes.resize(5);
- treedata0_.nodes[0].id = 1;
- treedata0_.nodes[0].child_ids.push_back(2);
- treedata0_.nodes[1].id = 2;
- treedata0_.nodes[1].child_ids.push_back(3);
- treedata0_.nodes[1].child_ids.push_back(5);
- treedata0_.nodes[2].id = 3;
- treedata0_.nodes[2].child_ids.push_back(4);
- treedata0_.nodes[3].id = 4;
- treedata0_.nodes[4].id = 5;
-
- // Node 5 has been reparented from being a child of node 2,
- // to a child of node 4.
- // (1 (2 (3 (4 (5)))))
- treedata1_.root_id = 1;
- treedata1_.nodes.resize(5);
- treedata1_.nodes[0].id = 1;
- treedata1_.nodes[0].child_ids.push_back(2);
- treedata1_.nodes[1].id = 2;
- treedata1_.nodes[1].child_ids.push_back(3);
- treedata1_.nodes[2].id = 3;
- treedata1_.nodes[2].child_ids.push_back(4);
- treedata1_.nodes[3].id = 4;
- treedata1_.nodes[3].child_ids.push_back(5);
- treedata1_.nodes[4].id = 5;
-
- CreateTreeSerializer();
- AXTreeUpdate update;
- ASSERT_TRUE(serializer_->SerializeChanges(tree1_->GetFromId(4), &update));
-
- // The update should unserialize without errors.
- AXTree dst_tree(treedata0_);
- EXPECT_TRUE(dst_tree.Unserialize(update)) << dst_tree.error();
-
- // The update should delete the subtree rooted at node id=2, and
- // then include nodes 2...5.
- EXPECT_EQ(2, update.node_id_to_clear);
- ASSERT_EQ(4u, update.nodes.size());
- EXPECT_EQ(2, update.nodes[0].id);
- EXPECT_EQ(3, update.nodes[1].id);
- EXPECT_EQ(4, update.nodes[2].id);
- EXPECT_EQ(5, update.nodes[3].id);
-}
-
-// Similar to ReparentingUpdatesSubtree, except that InvalidateSubtree is
-// called on id=1 - we need to make sure that the reparenting is still
-// detected.
-TEST_F(AXTreeSerializerTest, ReparentingWithInvalidationUpdatesSubtree) {
- // (1 (2 (3 (4 (5)))))
- treedata0_.root_id = 1;
- treedata0_.nodes.resize(5);
- treedata0_.nodes[0].id = 1;
- treedata0_.nodes[0].child_ids.push_back(2);
- treedata0_.nodes[1].id = 2;
- treedata0_.nodes[1].child_ids.push_back(3);
- treedata0_.nodes[2].id = 3;
- treedata0_.nodes[2].child_ids.push_back(4);
- treedata0_.nodes[3].id = 4;
- treedata0_.nodes[3].child_ids.push_back(5);
- treedata0_.nodes[4].id = 5;
-
- // Node 5 has been reparented from being a child of node 4,
- // to a child of node 2.
- // (1 (2 (3 (4) 5)))
- treedata1_.root_id = 1;
- treedata1_.nodes.resize(5);
- treedata1_.nodes[0].id = 1;
- treedata1_.nodes[0].child_ids.push_back(2);
- treedata1_.nodes[1].id = 2;
- treedata1_.nodes[1].child_ids.push_back(3);
- treedata1_.nodes[1].child_ids.push_back(5);
- treedata1_.nodes[2].id = 3;
- treedata1_.nodes[2].child_ids.push_back(4);
- treedata1_.nodes[3].id = 4;
- treedata1_.nodes[4].id = 5;
-
- CreateTreeSerializer();
- AXTreeUpdate update;
- serializer_->InvalidateSubtree(tree1_->GetFromId(1));
- ASSERT_TRUE(serializer_->SerializeChanges(tree1_->GetFromId(4), &update));
-
- // The update should unserialize without errors.
- AXTree dst_tree(treedata0_);
- EXPECT_TRUE(dst_tree.Unserialize(update)) << dst_tree.error();
-}
-
-// A variant of AXTreeSource that returns true for IsValid() for one
-// particular id.
-class AXTreeSourceWithInvalidId
- : public AXTreeSource<const AXNode*, AXNodeData, AXTreeData> {
- public:
- AXTreeSourceWithInvalidId(AXTree* tree, int invalid_id)
- : tree_(tree), invalid_id_(invalid_id) {}
- ~AXTreeSourceWithInvalidId() override {}
-
- // AXTreeSource implementation.
- bool GetTreeData(AXTreeData* data) const override {
- *data = AXTreeData();
- return true;
- }
- AXNode* GetRoot() const override { return tree_->root(); }
- AXNode* GetFromId(int32_t id) const override { return tree_->GetFromId(id); }
- int32_t GetId(const AXNode* node) const override { return node->id(); }
- void GetChildren(const AXNode* node,
- std::vector<const AXNode*>* out_children) const override {
- *out_children = std::vector<const AXNode*>(node->children().cbegin(),
- node->children().cend());
- }
- AXNode* GetParent(const AXNode* node) const override {
- return node->parent();
- }
- bool IsIgnored(const AXNode* node) const override {
- return node->IsIgnored();
- }
- bool IsValid(const AXNode* node) const override {
- return node != nullptr && node->id() != invalid_id_;
- }
- bool IsEqual(const AXNode* node1, const AXNode* node2) const override {
- return node1 == node2;
- }
- const AXNode* GetNull() const override { return nullptr; }
- void SerializeNode(const AXNode* node, AXNodeData* out_data) const override {
- *out_data = node->data();
- if (node->id() == invalid_id_)
- out_data->id = -1;
- }
-
- private:
- AXTree* tree_;
- int invalid_id_;
-
- DISALLOW_COPY_AND_ASSIGN(AXTreeSourceWithInvalidId);
-};
-
-// Test that the serializer skips invalid children.
-TEST(AXTreeSerializerInvalidTest, InvalidChild) {
- // (1 (2 3))
- AXTreeUpdate treedata;
- treedata.root_id = 1;
- treedata.nodes.resize(3);
- treedata.nodes[0].id = 1;
- treedata.nodes[0].child_ids.push_back(2);
- treedata.nodes[0].child_ids.push_back(3);
- treedata.nodes[1].id = 2;
- treedata.nodes[2].id = 3;
-
- AXTree tree(treedata);
- AXTreeSourceWithInvalidId source(&tree, 3);
-
- BasicAXTreeSerializer serializer(&source);
- AXTreeUpdate update;
- ASSERT_TRUE(serializer.SerializeChanges(tree.root(), &update));
-
- ASSERT_EQ(2U, update.nodes.size());
- EXPECT_EQ(1, update.nodes[0].id);
- EXPECT_EQ(2, update.nodes[1].id);
-}
-
-// Test that we can set a maximum number of nodes to serialize.
-TEST_F(AXTreeSerializerTest, MaximumSerializedNodeCount) {
- // (1 (2 (3 4) 5 (6 7)))
- treedata0_.root_id = 1;
- treedata0_.nodes.resize(7);
- treedata0_.nodes[0].id = 1;
- treedata0_.nodes[0].child_ids.push_back(2);
- treedata0_.nodes[0].child_ids.push_back(5);
- treedata0_.nodes[1].id = 2;
- treedata0_.nodes[1].child_ids.push_back(3);
- treedata0_.nodes[1].child_ids.push_back(4);
- treedata0_.nodes[2].id = 3;
- treedata0_.nodes[3].id = 4;
- treedata0_.nodes[4].id = 5;
- treedata0_.nodes[4].child_ids.push_back(6);
- treedata0_.nodes[4].child_ids.push_back(7);
- treedata0_.nodes[5].id = 6;
- treedata0_.nodes[6].id = 7;
-
- tree0_ = std::make_unique<AXSerializableTree>(treedata0_);
- tree0_source_.reset(tree0_->CreateTreeSource());
- serializer_ = std::make_unique<BasicAXTreeSerializer>(tree0_source_.get());
- serializer_->set_max_node_count(4);
- AXTreeUpdate update;
- ASSERT_TRUE(serializer_->SerializeChanges(tree0_->root(), &update));
- // It actually serializes 5 nodes, not 4 - to be consistent.
- // It skips the children of node 5.
- ASSERT_EQ(5u, update.nodes.size());
-}
-
-#if !defined(ADDRESS_SANITIZER)
-// If duplicate ids are encountered, it returns an error and the next
-// update will re-send the entire tree.
-// Test does not work with address sanitizer -- if EXPECT_DEATH is used to
-// catch the "Illegal parenting" NOTREACHED(), an ASAN crash is still generated.
-TEST_F(AXTreeSerializerTest, DuplicateIdsReturnsErrorAndFlushes) {
- // (1 (2 (3 (4) 5)))
- treedata0_.root_id = 1;
- treedata0_.nodes.resize(5);
- treedata0_.nodes[0].id = 1;
- treedata0_.nodes[0].child_ids.push_back(2);
- treedata0_.nodes[1].id = 2;
- treedata0_.nodes[1].child_ids.push_back(3);
- treedata0_.nodes[1].child_ids.push_back(5);
- treedata0_.nodes[2].id = 3;
- treedata0_.nodes[2].child_ids.push_back(4);
- treedata0_.nodes[3].id = 4;
- treedata0_.nodes[4].id = 5;
-
- // (1 (2 (6 (7) 5)))
- treedata1_.root_id = 1;
- treedata1_.nodes.resize(5);
- treedata1_.nodes[0].id = 1;
- treedata1_.nodes[0].child_ids.push_back(2);
- treedata1_.nodes[1].id = 2;
- treedata1_.nodes[1].child_ids.push_back(6);
- treedata1_.nodes[1].child_ids.push_back(5);
- treedata1_.nodes[2].id = 6;
- treedata1_.nodes[2].child_ids.push_back(7);
- treedata1_.nodes[3].id = 7;
- treedata1_.nodes[4].id = 5;
-
- CreateTreeSerializer();
-
- // Do some open-heart surgery on tree1, giving it a duplicate node.
- // This could not happen with an AXTree, but could happen with
- // another AXTreeSource if the structure it wraps is buggy. We want to
- // fail but not crash when that happens.
- std::vector<AXNode*> node2_children;
- node2_children.push_back(tree1_->GetFromId(7));
- node2_children.push_back(tree1_->GetFromId(6));
- tree1_->GetFromId(2)->SwapChildren(&node2_children);
-
- AXTreeUpdate update;
- ASSERT_FALSE(serializer_->SerializeChanges(tree1_->GetFromId(7), &update));
-
- // Swap it back, fixing the tree.
- tree1_->GetFromId(2)->SwapChildren(&node2_children);
-
- // Now try to serialize again. We should get the whole tree because the
- // previous failed call to SerializeChanges reset it.
- update = AXTreeUpdate();
- serializer_->SerializeChanges(tree1_->GetFromId(7), &update);
- ASSERT_EQ(5u, update.nodes.size());
-}
-#endif
-
-// If a tree serializer is reset, that means it doesn't know about
-// the state of the client tree anymore. The safest thing to do in
-// that circumstance is to force the client to clear everything.
-TEST_F(AXTreeSerializerTest, ResetUpdatesNodeIdToClear) {
- // (1 (2 (3 (4 (5)))))
- treedata0_.root_id = 1;
- treedata0_.nodes.resize(5);
- treedata0_.nodes[0].id = 1;
- treedata0_.nodes[0].child_ids.push_back(2);
- treedata0_.nodes[1].id = 2;
- treedata0_.nodes[1].child_ids.push_back(3);
- treedata0_.nodes[2].id = 3;
- treedata0_.nodes[2].child_ids.push_back(4);
- treedata0_.nodes[3].id = 4;
- treedata0_.nodes[3].child_ids.push_back(5);
- treedata0_.nodes[4].id = 5;
-
- // Node 5 has been reparented from being a child of node 4,
- // to a child of node 2.
- // (1 (2 (3 (4) 5)))
- treedata1_.root_id = 1;
- treedata1_.nodes.resize(5);
- treedata1_.nodes[0].id = 1;
- treedata1_.nodes[0].child_ids.push_back(2);
- treedata1_.nodes[1].id = 2;
- treedata1_.nodes[1].child_ids.push_back(3);
- treedata1_.nodes[1].child_ids.push_back(5);
- treedata1_.nodes[2].id = 3;
- treedata1_.nodes[2].child_ids.push_back(4);
- treedata1_.nodes[3].id = 4;
- treedata1_.nodes[4].id = 5;
-
- CreateTreeSerializer();
-
- serializer_->Reset();
-
- AXTreeUpdate update;
- ASSERT_TRUE(serializer_->SerializeChanges(tree1_->GetFromId(4), &update));
-
- // The update should unserialize without errors.
- AXTree dst_tree(treedata0_);
- EXPECT_TRUE(dst_tree.Unserialize(update)) << dst_tree.error();
-}
-
-// Ensure that calling Reset doesn't cause any problems if
-// the root changes.
-TEST_F(AXTreeSerializerTest, ResetWorksWithNewRootId) {
- // (1 (2))
- treedata0_.root_id = 1;
- treedata0_.nodes.resize(2);
- treedata0_.nodes[0].id = 1;
- treedata0_.nodes[0].child_ids.push_back(2);
- treedata0_.nodes[1].id = 2;
-
- // (3 (4))
- treedata1_.root_id = 3;
- treedata1_.nodes.resize(2);
- treedata1_.nodes[0].id = 3;
- treedata1_.nodes[0].child_ids.push_back(4);
- treedata1_.nodes[1].id = 4;
-
- CreateTreeSerializer();
- serializer_->Reset();
-
- AXTreeUpdate update;
- ASSERT_TRUE(serializer_->SerializeChanges(tree1_->GetFromId(4), &update));
-
- // The update should unserialize without errors.
- AXTree dst_tree(treedata0_);
- EXPECT_TRUE(dst_tree.Unserialize(update)) << dst_tree.error();
-}
-
-// Wraps an AXTreeSource and provides access to the results of the
-// SerializerClearedNode callback.
-class AXTreeSourceTestWrapper
- : public AXTreeSource<const AXNode*, AXNodeData, AXTreeData> {
- public:
- explicit AXTreeSourceTestWrapper(
- AXTreeSource<const AXNode*, AXNodeData, AXTreeData>* tree_source)
- : tree_source_(tree_source) {}
- ~AXTreeSourceTestWrapper() override = default;
-
- // Override SerializerClearedNode and provide a way to access it.
- void SerializerClearedNode(int32_t node_id) override {
- cleared_node_ids_.insert(node_id);
- }
-
- void ClearClearedNodeIds() { cleared_node_ids_.clear(); }
- std::set<int32_t>& cleared_node_ids() { return cleared_node_ids_; }
-
- // The rest of the AXTreeSource implementation just calls through to
- // tree_source_.
- bool GetTreeData(AXTreeData* data) const override {
- return tree_source_->GetTreeData(data);
- }
- const AXNode* GetRoot() const override { return tree_source_->GetRoot(); }
- const AXNode* GetFromId(int32_t id) const override {
- return tree_source_->GetFromId(id);
- }
- int32_t GetId(const AXNode* node) const override {
- return tree_source_->GetId(node);
- }
- void GetChildren(const AXNode* node,
- std::vector<const AXNode*>* out_children) const override {
- return tree_source_->GetChildren(node, out_children);
- }
- const AXNode* GetParent(const AXNode* node) const override {
- return tree_source_->GetParent(node);
- }
- bool IsIgnored(const AXNode* node) const override {
- return tree_source_->IsIgnored(node);
- }
- bool IsValid(const AXNode* node) const override {
- return tree_source_->IsValid(node);
- }
- bool IsEqual(const AXNode* node1, const AXNode* node2) const override {
- return tree_source_->IsEqual(node1, node2);
- }
- const AXNode* GetNull() const override { return tree_source_->GetNull(); }
- void SerializeNode(const AXNode* node, AXNodeData* out_data) const override {
- tree_source_->SerializeNode(node, out_data);
- }
-
- private:
- AXTreeSource<const AXNode*, AXNodeData, AXTreeData>* tree_source_;
- std::set<int32_t> cleared_node_ids_;
-};
-
-TEST_F(AXTreeSerializerTest, TestClearedNodesWhenUpdatingRoot) {
- // (1 (2 (3 (4))))
- treedata0_.root_id = 1;
- treedata0_.nodes.resize(4);
- treedata0_.nodes[0].id = 1;
- treedata0_.nodes[0].child_ids.push_back(2);
- treedata0_.nodes[1].id = 2;
- treedata0_.nodes[1].child_ids.push_back(3);
- treedata0_.nodes[2].id = 3;
- treedata0_.nodes[2].child_ids.push_back(4);
- treedata0_.nodes[3].id = 4;
-
- // (5 (2 (3 (4))))
- treedata1_.root_id = 5;
- treedata1_.nodes.resize(4);
- treedata1_.nodes[0].id = 5;
- treedata1_.nodes[0].child_ids.push_back(2);
- treedata1_.nodes[1].id = 2;
- treedata1_.nodes[1].child_ids.push_back(3);
- treedata1_.nodes[2].id = 3;
- treedata1_.nodes[2].child_ids.push_back(4);
- treedata1_.nodes[3].id = 4;
-
- // Similar sequence to CreateTreeSerializer, but using
- // AXTreeSourceTestWrapper instead.
- tree0_ = std::make_unique<AXSerializableTree>(treedata0_);
- tree1_ = std::make_unique<AXSerializableTree>(treedata1_);
- tree0_source_.reset(tree0_->CreateTreeSource());
- AXTreeSourceTestWrapper tree0_source_wrapper(tree0_source_.get());
- serializer_ = std::make_unique<BasicAXTreeSerializer>(&tree0_source_wrapper);
- AXTreeUpdate unused_update;
- ASSERT_TRUE(serializer_->SerializeChanges(tree0_->root(), &unused_update));
- tree1_source_.reset(tree1_->CreateTreeSource());
- AXTreeSourceTestWrapper tree1_source_wrapper(tree1_source_.get());
- serializer_->ChangeTreeSourceForTesting(&tree1_source_wrapper);
- ASSERT_EQ(4U, serializer_->ClientTreeNodeCount());
-
- // If we swap out the root, all of the node IDs should have
- // SerializerClearedNode called on them.
- tree1_source_wrapper.ClearClearedNodeIds();
- ASSERT_TRUE(serializer_->SerializeChanges(tree1_->root(), &unused_update));
- EXPECT_THAT(tree1_source_wrapper.cleared_node_ids(),
- UnorderedElementsAre(1, 2, 3, 4));
-
- // Destroy the serializer first so that the AXTreeSources it points to
- // don't go out of scope first.
- serializer_.reset();
-}
-
-TEST_F(AXTreeSerializerTest, TestClearedNodesWhenUpdatingBranch) {
- // (1 (2 (3 (4))))
- treedata0_.root_id = 1;
- treedata0_.nodes.resize(4);
- treedata0_.nodes[0].id = 1;
- treedata0_.nodes[0].child_ids.push_back(2);
- treedata0_.nodes[1].id = 2;
- treedata0_.nodes[1].child_ids.push_back(3);
- treedata0_.nodes[2].id = 3;
- treedata0_.nodes[2].child_ids.push_back(4);
- treedata0_.nodes[3].id = 4;
-
- // (1 (2 (5 (6))))
- treedata1_.root_id = 1;
- treedata1_.nodes.resize(4);
- treedata1_.nodes[0].id = 1;
- treedata1_.nodes[0].child_ids.push_back(2);
- treedata1_.nodes[1].id = 2;
- treedata1_.nodes[1].child_ids.push_back(5);
- treedata1_.nodes[2].id = 5;
- treedata1_.nodes[2].child_ids.push_back(6);
- treedata1_.nodes[3].id = 6;
-
- // Similar sequence to CreateTreeSerializer, but using
- // AXTreeSourceTestWrapper instead.
- tree0_ = std::make_unique<AXSerializableTree>(treedata0_);
- tree1_ = std::make_unique<AXSerializableTree>(treedata1_);
- tree0_source_.reset(tree0_->CreateTreeSource());
- AXTreeSourceTestWrapper tree0_source_wrapper(tree0_source_.get());
- serializer_ = std::make_unique<BasicAXTreeSerializer>(&tree0_source_wrapper);
- AXTreeUpdate unused_update;
- ASSERT_TRUE(serializer_->SerializeChanges(tree0_->root(), &unused_update));
- tree1_source_.reset(tree1_->CreateTreeSource());
- AXTreeSourceTestWrapper tree1_source_wrapper(tree1_source_.get());
- serializer_->ChangeTreeSourceForTesting(&tree1_source_wrapper);
- ASSERT_EQ(4U, serializer_->ClientTreeNodeCount());
-
- // If we replace one branch with another, we should get calls to
- // SerializerClearedNode with all of the node IDs no longer in the tree.
- tree1_source_wrapper.ClearClearedNodeIds();
- ASSERT_TRUE(
- serializer_->SerializeChanges(tree1_->GetFromId(2), &unused_update));
- EXPECT_THAT(tree1_source_wrapper.cleared_node_ids(),
- UnorderedElementsAre(3, 4));
-
- // Destroy the serializer first so that the AXTreeSources it points to
- // don't go out of scope first.
- serializer_.reset();
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_tree_source.h b/third_party/accessibility/ax/ax_tree_source.h
deleted file mode 100644
index 0078571..0000000
--- a/third_party/accessibility/ax/ax_tree_source.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_TREE_SOURCE_H_
-#define UI_ACCESSIBILITY_AX_TREE_SOURCE_H_
-
-#include <stdint.h>
-
-#include <vector>
-
-namespace ui {
-
-// An AXTreeSource is an abstract interface for a serializable
-// accessibility tree. The tree may be in some other format or
-// may be computed dynamically, but maintains the properties that
-// it's a strict tree, it has a unique id for each node, and all
-// of the accessibility information about a node can be serialized
-// as an AXNodeData. This is the primary interface to use when
-// an accessibility tree will be sent over an IPC before being
-// consumed.
-template <typename AXNodeSource, typename AXNodeData, typename AXTreeData>
-class AXTreeSource {
- public:
- virtual ~AXTreeSource() {}
-
- // Get the tree data and returns true if there is any data to copy.
- virtual bool GetTreeData(AXTreeData* data) const = 0;
-
- // Get the root of the tree.
- virtual AXNodeSource GetRoot() const = 0;
-
- // Get a node by its id. If no node by that id exists in the tree, return a
- // null node, i.e. one that will return false if you call IsValid on it.
- virtual AXNodeSource GetFromId(int32_t id) const = 0;
-
- // Return the id of a node. All ids must be positive integers.
- virtual int32_t GetId(AXNodeSource node) const = 0;
-
- // Append all children of |node| to |out_children|.
- virtual void GetChildren(AXNodeSource node,
- std::vector<AXNodeSource>* out_children) const = 0;
-
- // Get the parent of |node|.
- virtual AXNodeSource GetParent(AXNodeSource node) const = 0;
-
- // Returns true if |node| is valid, and false if it's a null pointer or a
- // node object representing the null pointer.
- virtual bool IsValid(AXNodeSource node) const = 0;
-
- // Returns true if |node| is an ignored node
- virtual bool IsIgnored(AXNodeSource node) const = 0;
-
- // Returns true if two nodes are equal.
- virtual bool IsEqual(AXNodeSource node1, AXNodeSource node2) const = 0;
-
- // Return a AXNodeSource representing null.
- virtual AXNodeSource GetNull() const = 0;
-
- // Serialize one node in the tree.
- virtual void SerializeNode(AXNodeSource node, AXNodeData* out_data) const = 0;
-
- // Return a string useful for debugging a node.
- virtual std::string GetDebugString(AXNodeSource node) const {
- AXNodeData node_data;
- SerializeNode(node, &node_data);
- return node_data.ToString();
- }
-
- // This is called by AXTreeSerializer when it serializes a tree and
- // discovers that a node previously in the tree is no longer part of
- // the tree. It can be used to allow an AXTreeSource to keep a cache
- // indexed by node ID and delete nodes when they're no longer needed.
- virtual void SerializerClearedNode(int32_t node_id) {}
-
- protected:
- AXTreeSource() {}
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_TREE_SOURCE_H_
diff --git a/third_party/accessibility/ax/ax_tree_source_checker.h b/third_party/accessibility/ax/ax_tree_source_checker.h
deleted file mode 100644
index 748b334..0000000
--- a/third_party/accessibility/ax/ax_tree_source_checker.h
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_TREE_SOURCE_CHECKER_H_
-#define UI_ACCESSIBILITY_AX_TREE_SOURCE_CHECKER_H_
-
-#include <map>
-
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "ui/accessibility/ax_tree_source.h"
-
-namespace ui {
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-class AXTreeSourceChecker {
- public:
- explicit AXTreeSourceChecker(
- AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree);
- ~AXTreeSourceChecker();
-
- // Returns true if everything reachable from the root of the tree is
- // consistent in its parent/child connections, and returns the error
- // as a string.
- bool CheckAndGetErrorString(std::string* error_string);
-
- private:
- bool Check(AXSourceNode node, std::string indent, std::string* output);
- std::string NodeToString(AXSourceNode node);
-
- AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree_;
-
- std::map<int32_t, int32_t> node_id_to_parent_id_map_;
-
- DISALLOW_COPY_AND_ASSIGN(AXTreeSourceChecker);
-};
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-AXTreeSourceChecker<AXSourceNode, AXNodeData, AXTreeData>::AXTreeSourceChecker(
- AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree)
- : tree_(tree) {}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-AXTreeSourceChecker<AXSourceNode, AXNodeData, AXTreeData>::
- ~AXTreeSourceChecker() = default;
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-bool AXTreeSourceChecker<AXSourceNode, AXNodeData, AXTreeData>::
- CheckAndGetErrorString(std::string* error_string) {
- node_id_to_parent_id_map_.clear();
-
- AXSourceNode root = tree_->GetRoot();
- if (!tree_->IsValid(root)) {
- *error_string = "Root is not valid.";
- return false;
- }
-
- int32_t root_id = tree_->GetId(root);
- node_id_to_parent_id_map_[root_id] = -1;
-
- return Check(root, "", error_string);
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-std::string
-AXTreeSourceChecker<AXSourceNode, AXNodeData, AXTreeData>::NodeToString(
- AXSourceNode node) {
- AXNodeData node_data;
- tree_->SerializeNode(node, &node_data);
-
- std::vector<AXSourceNode> children;
- tree_->GetChildren(node, &children);
- std::string children_str;
- if (children.size() == 0) {
- children_str = "(no children)";
- } else {
- for (size_t i = 0; i < children.size(); i++) {
- auto& child = children[i];
- int32_t child_id = tree_->IsValid(child) ? tree_->GetId(child) : -1;
- if (i == 0)
- children_str += "child_ids=" + base::NumberToString(child_id);
- else
- children_str += "," + base::NumberToString(child_id);
- }
- }
-
- int32_t parent_id = tree_->IsValid(tree_->GetParent(node))
- ? tree_->GetId(tree_->GetParent(node))
- : -1;
-
- return base::StringPrintf("%s %s parent_id=%d", node_data.ToString().c_str(),
- children_str.c_str(), parent_id);
-}
-
-template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
-bool AXTreeSourceChecker<AXSourceNode, AXNodeData, AXTreeData>::Check(
- AXSourceNode node,
- std::string indent,
- std::string* output) {
- *output += indent + NodeToString(node);
-
- int32_t node_id = tree_->GetId(node);
- if (node_id <= 0) {
- std::string msg = base::StringPrintf(
- "Got a node with id %d, but all node IDs should be >= 1:\n%s\n",
- node_id, NodeToString(node).c_str());
- *output = msg + *output;
- return false;
- }
-
- // Check parent.
- int32_t expected_parent_id = node_id_to_parent_id_map_[node_id];
- AXSourceNode parent = tree_->GetParent(node);
- if (expected_parent_id == -1) {
- if (tree_->IsValid(parent)) {
- std::string msg = base::StringPrintf(
- "Node %d is the root, so its parent should be invalid, but we "
- "got a node with id %d.\n"
- "Node: %s\n"
- "Parent: %s\n",
- node_id, tree_->GetId(parent), NodeToString(node).c_str(),
- NodeToString(parent).c_str());
- *output = msg + *output;
- return false;
- }
- } else {
- if (!tree_->IsValid(parent)) {
- std::string msg = base::StringPrintf(
- "Node %d is not the root, but its parent was invalid:\n%s\n", node_id,
- NodeToString(node).c_str());
- *output = msg + *output;
- return false;
- }
- int32_t parent_id = tree_->GetId(parent);
- if (parent_id != expected_parent_id) {
- AXSourceNode expected_parent = tree_->GetFromId(expected_parent_id);
- std::string msg = base::StringPrintf(
- "Expected node %d to have a parent of %d, but found a parent of %d.\n"
- "Node: %s\n"
- "Parent: %s\n"
- "Expected parent: %s\n",
- node_id, expected_parent_id, parent_id, NodeToString(node).c_str(),
- NodeToString(parent).c_str(), NodeToString(expected_parent).c_str());
- *output = msg + *output;
- return false;
- }
- }
-
- // Check children.
- std::vector<AXSourceNode> children;
- tree_->GetChildren(node, &children);
-
- for (size_t i = 0; i < children.size(); i++) {
- auto& child = children[i];
- if (!tree_->IsValid(child)) {
- std::string msg =
- base::StringPrintf("Node %d has an invalid child (index %d): %s\n",
- node_id, int{i}, NodeToString(node).c_str());
- *output = msg + *output;
- return false;
- }
-
- int32_t child_id = tree_->GetId(child);
- if (node_id_to_parent_id_map_.find(child_id) !=
- node_id_to_parent_id_map_.end()) {
- *output += "\n" + indent + " ";
- AXNodeData child_data;
- tree_->SerializeNode(child, &child_data);
- *output += child_data.ToString() + "\n";
-
- std::string msg = base::StringPrintf(
- "Node %d has a child with ID %d, but we've previously seen a node "
- "with that ID, with a parent of %d.\n"
- "Node: %s",
- node_id, child_id, node_id_to_parent_id_map_[child_id],
- NodeToString(node).c_str());
- *output = msg + *output;
- return false;
- }
-
- node_id_to_parent_id_map_[child_id] = node_id;
- }
-
- *output += "\n";
-
- for (auto& child : children) {
- if (!Check(child, indent + " ", output))
- return false;
- }
-
- return true;
-}
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_TREE_SOURCE_CHECKER_H_
diff --git a/third_party/accessibility/ax/ax_tree_source_checker_unittest.cc b/third_party/accessibility/ax/ax_tree_source_checker_unittest.cc
deleted file mode 100644
index 85e3150..0000000
--- a/third_party/accessibility/ax/ax_tree_source_checker_unittest.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/ax_tree_source_checker.h"
-
-#include "base/strings/string_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_tree_source.h"
-
-namespace ui {
-namespace {
-
-struct FakeAXTreeData {};
-
-struct FakeAXNode {
- int32_t id;
- ax::mojom::Role role;
- std::vector<int32_t> child_ids;
- int32_t parent_id;
-};
-
-// It's distracting to see an empty bounding box from every node, so do a
-// search-and-replace to get rid of those strings.
-void CleanAXNodeDataString(std::string* error_str) {
- base::ReplaceSubstringsAfterOffset(error_str, 0, " (0, 0)-(0, 0)", "");
-}
-
-// A simple implementation of AXTreeSource initialized from a simple static
-// vector of node data, where both the child and parent connections are
-// explicit. This allows us to test that AXTreeSourceChecker properly warns
-// about errors in accessibility trees that have inconsistent parent/child
-// links.
-class FakeAXTreeSource
- : public AXTreeSource<const FakeAXNode*, ui::AXNodeData, FakeAXTreeData> {
- public:
- FakeAXTreeSource(std::vector<FakeAXNode> nodes, int32_t root_id)
- : nodes_(nodes), root_id_(root_id) {
- for (size_t i = 0; i < nodes_.size(); ++i)
- id_to_node_[nodes_[i].id] = &nodes_[i];
- }
-
- // AXTreeSource overrides.
- bool GetTreeData(FakeAXTreeData* data) const override { return true; }
-
- const FakeAXNode* GetRoot() const override { return GetFromId(root_id_); }
-
- const FakeAXNode* GetFromId(int32_t id) const override {
- const auto& iter = id_to_node_.find(id);
- if (iter != id_to_node_.end())
- return iter->second;
- return nullptr;
- }
-
- int32_t GetId(const FakeAXNode* node) const override { return node->id; }
-
- void GetChildren(
- const FakeAXNode* node,
- std::vector<const FakeAXNode*>* out_children) const override {
- for (size_t i = 0; i < node->child_ids.size(); ++i)
- out_children->push_back(GetFromId(node->child_ids[i]));
- }
-
- const FakeAXNode* GetParent(const FakeAXNode* node) const override {
- return GetFromId(node->parent_id);
- }
-
- bool IsIgnored(const FakeAXNode* node) const override { return false; }
-
- bool IsValid(const FakeAXNode* node) const override {
- return node != nullptr;
- }
-
- bool IsEqual(const FakeAXNode* node1,
- const FakeAXNode* node2) const override {
- return node1 == node2;
- }
-
- const FakeAXNode* GetNull() const override { return nullptr; }
-
- void SerializeNode(const FakeAXNode* node,
- AXNodeData* out_data) const override {
- out_data->id = node->id;
- out_data->role = node->role;
- }
-
- private:
- std::vector<FakeAXNode> nodes_;
- std::map<int32_t, FakeAXNode*> id_to_node_;
- int32_t root_id_;
-};
-
-} // namespace
-
-using FakeAXTreeSourceChecker =
- AXTreeSourceChecker<const FakeAXNode*, ui::AXNodeData, FakeAXTreeData>;
-
-TEST(AXTreeSourceCheckerTest, SimpleValidTree) {
- std::vector<FakeAXNode> nodes = {
- {1, ax::mojom::Role::kRootWebArea, {2}, -1},
- {2, ax::mojom::Role::kRootWebArea, {}, 1},
- };
- FakeAXTreeSource node_source(nodes, 1);
- FakeAXTreeSourceChecker checker(&node_source);
- std::string error_string;
- EXPECT_TRUE(checker.CheckAndGetErrorString(&error_string));
-}
-
-TEST(AXTreeSourceCheckerTest, BadRoot) {
- std::vector<FakeAXNode> nodes = {
- {1, ax::mojom::Role::kRootWebArea, {2}, -1},
- {2, ax::mojom::Role::kRootWebArea, {}, 1},
- };
- FakeAXTreeSource node_source(nodes, 3);
- FakeAXTreeSourceChecker checker(&node_source);
- std::string error_string;
- EXPECT_FALSE(checker.CheckAndGetErrorString(&error_string));
- CleanAXNodeDataString(&error_string);
- EXPECT_EQ("Root is not valid.", error_string);
-}
-
-TEST(AXTreeSourceCheckerTest, BadNodeIdOfRoot) {
- std::vector<FakeAXNode> nodes = {
- {0, ax::mojom::Role::kRootWebArea, {2}, -1},
- {2, ax::mojom::Role::kRootWebArea, {}, 0},
- };
- FakeAXTreeSource node_source(nodes, 0);
- FakeAXTreeSourceChecker checker(&node_source);
- std::string error_string;
- EXPECT_FALSE(checker.CheckAndGetErrorString(&error_string));
- CleanAXNodeDataString(&error_string);
- EXPECT_EQ(
- "Got a node with id 0, but all node IDs should be >= 1:\n"
- "id=0 rootWebArea child_ids=2 parent_id=-1\n"
- "id=0 rootWebArea child_ids=2 parent_id=-1",
- error_string);
-}
-
-TEST(AXTreeSourceCheckerTest, BadNodeIdOfChild) {
- std::vector<FakeAXNode> nodes = {
- {1, ax::mojom::Role::kRootWebArea, {-5}, -1},
- {-5, ax::mojom::Role::kRootWebArea, {}, 1},
- };
- FakeAXTreeSource node_source(nodes, -5);
- FakeAXTreeSourceChecker checker(&node_source);
- std::string error_string;
- EXPECT_FALSE(checker.CheckAndGetErrorString(&error_string));
- CleanAXNodeDataString(&error_string);
- EXPECT_EQ(
- "Got a node with id -5, but all node IDs should be >= 1:\n"
- "id=-5 rootWebArea (no children) parent_id=1\n"
- "id=-5 rootWebArea (no children) parent_id=1",
- error_string);
-}
-
-TEST(AXTreeSourceCheckerTest, RootShouldNotBeNodeWithParent) {
- std::vector<FakeAXNode> nodes = {
- {1, ax::mojom::Role::kRootWebArea, {2}, -1},
- {2, ax::mojom::Role::kRootWebArea, {}, 1},
- };
- FakeAXTreeSource node_source(nodes, 2);
- FakeAXTreeSourceChecker checker(&node_source);
- std::string error_string;
- EXPECT_FALSE(checker.CheckAndGetErrorString(&error_string));
- CleanAXNodeDataString(&error_string);
- EXPECT_EQ(
- "Node 2 is the root, so its parent should be invalid, "
- "but we got a node with id 1.\n"
- "Node: id=2 rootWebArea (no children) parent_id=1\n"
- "Parent: id=1 rootWebArea child_ids=2 parent_id=-1\n"
- "id=2 rootWebArea (no children) parent_id=1",
- error_string);
-}
-
-TEST(AXTreeSourceCheckerTest, MissingParent) {
- std::vector<FakeAXNode> nodes = {
- {1, ax::mojom::Role::kRootWebArea, {2}, -1},
- {2, ax::mojom::Role::kRootWebArea, {}, -1},
- };
- FakeAXTreeSource node_source(nodes, 1);
- FakeAXTreeSourceChecker checker(&node_source);
- std::string error_string;
- EXPECT_FALSE(checker.CheckAndGetErrorString(&error_string));
- CleanAXNodeDataString(&error_string);
- EXPECT_EQ(
- "Node 2 is not the root, but its parent was invalid:\n"
- "id=2 rootWebArea (no children) parent_id=-1\n"
- "id=1 rootWebArea child_ids=2 parent_id=-1\n"
- " id=2 rootWebArea (no children) parent_id=-1",
- error_string);
-}
-
-TEST(AXTreeSourceCheckerTest, InvalidParent) {
- std::vector<FakeAXNode> nodes = {
- {1, ax::mojom::Role::kRootWebArea, {2, 3}, -1},
- {2, ax::mojom::Role::kButton, {}, 1},
- {3, ax::mojom::Role::kParagraph, {}, 2},
- };
- FakeAXTreeSource node_source(nodes, 1);
- FakeAXTreeSourceChecker checker(&node_source);
- std::string error_string;
- EXPECT_FALSE(checker.CheckAndGetErrorString(&error_string));
- CleanAXNodeDataString(&error_string);
- EXPECT_EQ(
- "Expected node 3 to have a parent of 1, but found a parent of 2.\n"
- "Node: id=3 paragraph (no children) parent_id=2\n"
- "Parent: id=2 button (no children) parent_id=1\n"
- "Expected parent: id=1 rootWebArea child_ids=2,3 parent_id=-1\n"
- "id=1 rootWebArea child_ids=2,3 parent_id=-1\n"
- " id=2 button (no children) parent_id=1\n"
- " id=3 paragraph (no children) parent_id=2",
- error_string);
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/ax_tree_unittest.cc b/third_party/accessibility/ax/ax_tree_unittest.cc
index 0adce65..1ade84e 100644
--- a/third_party/accessibility/ax/ax_tree_unittest.cc
+++ b/third_party/accessibility/ax/ax_tree_unittest.cc
@@ -2,27 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/ax_tree.h"
+#include "ax_tree.h"
#include <stddef.h>
#include <stdint.h>
#include <memory>
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enum_util.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_node_position.h"
-#include "ui/accessibility/ax_serializable_tree.h"
-#include "ui/accessibility/ax_tree_data.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/accessibility/ax_tree_observer.h"
-#include "ui/accessibility/ax_tree_serializer.h"
-#include "ui/accessibility/test_ax_tree_manager.h"
-#include "ui/gfx/transform.h"
+#include "gtest/gtest.h"
+
+#include "ax_enum_util.h"
+#include "ax_node.h"
+#include "ax_node_position.h"
+#include "ax_tree_data.h"
+#include "ax_tree_id.h"
+#include "ax_tree_observer.h"
+#include "base/string_utils.h"
+#include "test_ax_tree_manager.h"
// Helper macro for testing selection values and maintain
// correct stack tracing and failure causality.
@@ -82,7 +78,7 @@
: tree_(tree), tree_data_changed_(false), root_changed_(false) {
tree_->AddObserver(this);
}
- ~TestAXTreeObserver() final { tree_->RemoveObserver(this); }
+ ~TestAXTreeObserver() { tree_->RemoveObserver(this); }
void OnNodeDataWillChange(AXTree* tree,
const AXNodeData& old_node_data,
@@ -96,7 +92,7 @@
tree_data_changed_ = true;
}
- base::Optional<AXNode::AXID> unignored_parent_id_before_node_deleted;
+ std::optional<AXNode::AXID> unignored_parent_id_before_node_deleted;
void OnNodeWillBeDeleted(AXTree* tree, AXNode* node) override {
// When this observer function is called in an update, the actual node
// deletion has not happened yet. Verify that node still exists in the tree.
@@ -208,10 +204,8 @@
ax::mojom::FloatAttribute attr,
float old_value,
float new_value) override {
- attribute_change_log_.push_back(
- base::StringPrintf("%s changed from %s to %s", ToString(attr),
- base::NumberToString(old_value).c_str(),
- base::NumberToString(new_value).c_str()));
+ attribute_change_log_.push_back(base::StringPrintf(
+ "%s changed from %.1f to %.1f", ToString(attr), old_value, new_value));
}
void OnBoolAttributeChanged(AXTree* tree,
@@ -294,7 +288,7 @@
} // namespace
-// A macro for testing that a base::Optional has both a value and that its value
+// A macro for testing that a std::optional has both a value and that its value
// is set to a particular expectation.
#define EXPECT_OPTIONAL_EQ(expected, actual) \
EXPECT_TRUE(actual.has_value()); \
@@ -302,67 +296,6 @@
EXPECT_EQ(expected, actual.value()); \
}
-TEST(AXTreeTest, SerializeSimpleAXTree) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kDialog;
- root.AddState(ax::mojom::State::kFocusable);
- root.relative_bounds.bounds = gfx::RectF(0, 0, 800, 600);
- root.child_ids.push_back(2);
- root.child_ids.push_back(3);
-
- AXNodeData button;
- button.id = 2;
- button.role = ax::mojom::Role::kButton;
- button.relative_bounds.bounds = gfx::RectF(20, 20, 200, 30);
-
- AXNodeData checkbox;
- checkbox.id = 3;
- checkbox.role = ax::mojom::Role::kCheckBox;
- checkbox.relative_bounds.bounds = gfx::RectF(20, 50, 200, 30);
-
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.push_back(root);
- initial_state.nodes.push_back(button);
- initial_state.nodes.push_back(checkbox);
- initial_state.has_tree_data = true;
- initial_state.tree_data.title = "Title";
- AXSerializableTree src_tree(initial_state);
-
- std::unique_ptr<AXTreeSource<const AXNode*, AXNodeData, AXTreeData>>
- tree_source(src_tree.CreateTreeSource());
- AXTreeSerializer<const AXNode*, AXNodeData, AXTreeData> serializer(
- tree_source.get());
- AXTreeUpdate update;
- serializer.SerializeChanges(src_tree.root(), &update);
-
- AXTree dst_tree;
- ASSERT_TRUE(dst_tree.Unserialize(update));
-
- const AXNode* root_node = dst_tree.root();
- ASSERT_TRUE(root_node != nullptr);
- EXPECT_EQ(root.id, root_node->id());
- EXPECT_EQ(root.role, root_node->data().role);
-
- ASSERT_EQ(2u, root_node->children().size());
-
- const AXNode* button_node = root_node->children()[0];
- EXPECT_EQ(button.id, button_node->id());
- EXPECT_EQ(button.role, button_node->data().role);
-
- const AXNode* checkbox_node = root_node->children()[1];
- EXPECT_EQ(checkbox.id, checkbox_node->id());
- EXPECT_EQ(checkbox.role, checkbox_node->data().role);
-
- EXPECT_EQ(
- "AXTree title=Title\n"
- "id=1 dialog FOCUSABLE (0, 0)-(800, 600) child_ids=2,3\n"
- " id=2 button (20, 20)-(200, 30)\n"
- " id=3 checkBox (20, 50)-(200, 30)\n",
- dst_tree.ToString());
-}
-
TEST(AXTreeTest, SerializeAXTreeUpdate) {
AXNodeData list;
list.id = 3;
@@ -1246,9 +1179,9 @@
EXPECT_EQ("description changed from D1 to D2", change_log[1]);
EXPECT_EQ("liveAtomic changed to false", change_log[2]);
EXPECT_EQ("busy changed to true", change_log[3]);
- EXPECT_EQ("minValueForRange changed from 1 to 2", change_log[4]);
- EXPECT_EQ("maxValueForRange changed from 10 to 9", change_log[5]);
- EXPECT_EQ("stepValueForRange changed from 3 to 0.5", change_log[6]);
+ EXPECT_EQ("minValueForRange changed from 1.0 to 2.0", change_log[4]);
+ EXPECT_EQ("maxValueForRange changed from 10.0 to 9.0", change_log[5]);
+ EXPECT_EQ("stepValueForRange changed from 3.0 to 0.5", change_log[6]);
EXPECT_EQ("scrollX changed from 5 to 6", change_log[7]);
EXPECT_EQ("scrollXMin changed from 1 to 2", change_log[8]);
@@ -1279,9 +1212,9 @@
EXPECT_EQ("value changed from to V3", change_log2[2]);
EXPECT_EQ("busy changed to false", change_log2[3]);
EXPECT_EQ("modal changed to true", change_log2[4]);
- EXPECT_EQ("minValueForRange changed from 2 to 0", change_log2[5]);
- EXPECT_EQ("stepValueForRange changed from 3 to 0.5", change_log[6]);
- EXPECT_EQ("valueForRange changed from 0 to 5", change_log2[7]);
+ EXPECT_EQ("minValueForRange changed from 2.0 to 0.0", change_log2[5]);
+ EXPECT_EQ("stepValueForRange changed from 3.0 to 0.5", change_log[6]);
+ EXPECT_EQ("valueForRange changed from 0.0 to 5.0", change_log2[7]);
EXPECT_EQ("scrollXMin changed from 2 to 0", change_log2[8]);
EXPECT_EQ("scrollX changed from 6 to 7", change_log2[9]);
EXPECT_EQ("scrollXMax changed from 0 to 10", change_log2[10]);
@@ -2557,8 +2490,8 @@
}
TEST(AXTreeTest, GetSiblingsNoIgnored) {
- // Since this tree contains no ignored nodes, PreviousSibling and NextSibling
- // are equivalent to their unignored counterparts.
+ // Since this tree base::contains no ignored nodes, PreviousSibling and
+ // NextSibling are equivalent to their unignored counterparts.
//
// 1
// ├── 2
@@ -3085,58 +3018,6 @@
EXPECT_EQ(nullptr, tree.GetFromId(5)->GetNextSibling());
}
-TEST(AXTreeTest, ChildTreeIds) {
- ui::AXTreeID tree_id_1 = ui::AXTreeID::CreateNewAXTreeID();
- ui::AXTreeID tree_id_2 = ui::AXTreeID::CreateNewAXTreeID();
- ui::AXTreeID tree_id_3 = ui::AXTreeID::CreateNewAXTreeID();
-
- AXTreeUpdate initial_state;
- initial_state.root_id = 1;
- initial_state.nodes.resize(4);
- initial_state.nodes[0].id = 1;
- initial_state.nodes[0].child_ids.push_back(2);
- initial_state.nodes[0].child_ids.push_back(3);
- initial_state.nodes[0].child_ids.push_back(4);
- initial_state.nodes[1].id = 2;
- initial_state.nodes[1].AddStringAttribute(
- ax::mojom::StringAttribute::kChildTreeId, tree_id_2.ToString());
- initial_state.nodes[2].id = 3;
- initial_state.nodes[2].AddStringAttribute(
- ax::mojom::StringAttribute::kChildTreeId, tree_id_3.ToString());
- initial_state.nodes[3].id = 4;
- initial_state.nodes[3].AddStringAttribute(
- ax::mojom::StringAttribute::kChildTreeId, tree_id_3.ToString());
- AXTree tree(initial_state);
-
- auto child_tree_1_nodes = tree.GetNodeIdsForChildTreeId(tree_id_1);
- EXPECT_EQ(0U, child_tree_1_nodes.size());
-
- auto child_tree_2_nodes = tree.GetNodeIdsForChildTreeId(tree_id_2);
- EXPECT_EQ(1U, child_tree_2_nodes.size());
- EXPECT_TRUE(base::Contains(child_tree_2_nodes, 2));
-
- auto child_tree_3_nodes = tree.GetNodeIdsForChildTreeId(tree_id_3);
- EXPECT_EQ(2U, child_tree_3_nodes.size());
- EXPECT_TRUE(base::Contains(child_tree_3_nodes, 3));
- EXPECT_TRUE(base::Contains(child_tree_3_nodes, 4));
-
- AXTreeUpdate update = initial_state;
- update.nodes[2].string_attributes.clear();
- update.nodes[2].AddStringAttribute(ax::mojom::StringAttribute::kChildTreeId,
- tree_id_2.ToString());
- update.nodes[3].string_attributes.clear();
-
- EXPECT_TRUE(tree.Unserialize(update));
-
- child_tree_2_nodes = tree.GetNodeIdsForChildTreeId(tree_id_2);
- EXPECT_EQ(2U, child_tree_2_nodes.size());
- EXPECT_TRUE(base::Contains(child_tree_2_nodes, 2));
- EXPECT_TRUE(base::Contains(child_tree_2_nodes, 3));
-
- child_tree_3_nodes = tree.GetNodeIdsForChildTreeId(tree_id_3);
- EXPECT_EQ(0U, child_tree_3_nodes.size());
-}
-
// Tests GetPosInSet and GetSetSize return the assigned int attribute values.
TEST(AXTreeTest, SetSizePosInSetAssigned) {
AXTreeUpdate tree_update;
@@ -3639,8 +3520,8 @@
tree_update.nodes[7].role = ax::mojom::Role::kList; // SetSize = 0
tree_update.nodes[8].id = 9;
tree_update.nodes[8].role =
- ax::mojom::Role::kList; // SetSize = 1 because only 1 item whose role
- // matches
+ ax::mojom::Role::kList; // SetSize = 1 because only 1
+ // item whose role matches
tree_update.nodes[8].child_ids = {10, 11};
tree_update.nodes[9].id = 10;
tree_update.nodes[9].role = ax::mojom::Role::kArticle;
@@ -3844,7 +3725,8 @@
tree_update.nodes.resize(6);
tree_update.nodes[0].id = 1;
tree_update.nodes[0].role =
- ax::mojom::Role::kList; // SetSize = 2, since only contains 2 ListItems
+ ax::mojom::Role::kList; // SetSize = 2, since only base::contains 2
+ // ListItems
tree_update.nodes[0].child_ids = {2, 3, 4, 5, 6};
tree_update.nodes[1].id = 2;
diff --git a/third_party/accessibility/ax/ax_tree_update.h b/third_party/accessibility/ax/ax_tree_update.h
index 99bd91b..780553f 100644
--- a/third_party/accessibility/ax/ax_tree_update.h
+++ b/third_party/accessibility/ax/ax_tree_update.h
@@ -12,12 +12,12 @@
#include <unordered_map>
#include <vector>
-#include "base/strings/string_number_conversions.h"
-#include "ui/accessibility/ax_enum_util.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_event_intent.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_tree_data.h"
+#include "ax_enum_util.h"
+#include "ax_enums.h"
+#include "ax_event_intent.h"
+#include "ax_node_data.h"
+#include "ax_tree_data.h"
+#include "base/string_utils.h"
namespace ui {
@@ -60,11 +60,11 @@
AXTreeData tree_data;
// The id of a node to clear, before applying any updates,
- // or 0 if no nodes should be cleared. Clearing a node means deleting
- // all of its children and their descendants, but leaving that node in
- // the tree. It's an error to clear a node but not subsequently update it
- // as part of the tree update.
- int node_id_to_clear = 0;
+ // or AXNode::kInvalidAXID if no nodes should be cleared. Clearing a node
+ // means deleting all of its children and their descendants, but leaving that
+ // node in the tree. It's an error to clear a node but not subsequently update
+ // it as part of the tree update.
+ int node_id_to_clear = AXNode::kInvalidAXID;
// The id of the root of the tree, if the root is changing. This is
// required to be set if the root of the tree is changing or Unserialize
@@ -97,12 +97,12 @@
result += "AXTreeUpdate tree data:" + tree_data.ToString() + "\n";
}
- if (node_id_to_clear != 0) {
+ if (node_id_to_clear != AXNode::kInvalidAXID) {
result += "AXTreeUpdate: clear node " +
base::NumberToString(node_id_to_clear) + "\n";
}
- if (root_id != 0) {
+ if (root_id != AXNode::kInvalidAXID) {
result += "AXTreeUpdate: root id " + base::NumberToString(root_id) + "\n";
}
@@ -141,7 +141,7 @@
bool TreeUpdatesCanBeMerged(
const AXTreeUpdateBase<AXNodeData, AXTreeData>& u1,
const AXTreeUpdateBase<AXNodeData, AXTreeData>& u2) {
- if (u2.node_id_to_clear)
+ if (u2.node_id_to_clear != AXNode::kInvalidAXID)
return false;
if (u2.has_tree_data && u2.tree_data != u1.tree_data)
diff --git a/third_party/accessibility/ax/ax_tree_update_forward.h b/third_party/accessibility/ax/ax_tree_update_forward.h
deleted file mode 100644
index c59dfaa..0000000
--- a/third_party/accessibility/ax/ax_tree_update_forward.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_AX_TREE_UPDATE_FORWARD_H_
-#define UI_ACCESSIBILITY_AX_TREE_UPDATE_FORWARD_H_
-
-namespace ui {
-
-struct AXNodeData;
-struct AXTreeData;
-template <typename A, typename B>
-struct AXTreeUpdateBase;
-using AXTreeUpdate = AXTreeUpdateBase<AXNodeData, AXTreeData>;
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_AX_TREE_UPDATE_FORWARD_H_
diff --git a/third_party/accessibility/ax/mojom/BUILD.gn b/third_party/accessibility/ax/mojom/BUILD.gn
deleted file mode 100644
index 654241c..0000000
--- a/third_party/accessibility/ax/mojom/BUILD.gn
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright 2018 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//mojo/public/tools/bindings/mojom.gni")
-
-mojom("mojom") {
- sources = [
- "ax_action_data.mojom",
- "ax_assistant_structure.mojom",
- "ax_event.mojom",
- "ax_event_intent.mojom",
- "ax_node_data.mojom",
- "ax_relative_bounds.mojom",
- "ax_tree_data.mojom",
- "ax_tree_id.mojom",
- "ax_tree_update.mojom",
- ]
-
- public_deps = [
- "//mojo/public/mojom/base",
- "//ui/accessibility:ax_constants_mojo",
- "//ui/accessibility:ax_enums_mojo",
- "//ui/gfx/geometry/mojom",
- "//ui/gfx/mojom",
- "//ui/gfx/range/mojom",
- "//url/mojom:url_mojom_gurl",
- ]
-
- cpp_typemaps = [
- {
- types = [
- {
- mojom = "ax.mojom.AXActionData"
- cpp = "::ui::AXActionData"
- },
- ]
- traits_sources = [ "ax_action_data_mojom_traits.cc" ]
- traits_headers = [ "ax_action_data_mojom_traits.h" ]
- traits_public_deps = [ "//ui/accessibility" ]
- },
- {
- types = [
- {
- mojom = "ax.mojom.AssistantTree"
- cpp = "::std::unique_ptr<::ui::AssistantTree>"
- move_only = true
- nullable_is_same_type = true
- },
- {
- mojom = "ax.mojom.AssistantNode"
- cpp = "::std::unique_ptr<::ui::AssistantNode>"
- move_only = true
- },
- ]
- traits_sources = [ "ax_assistant_structure_mojom_traits.cc" ]
- traits_headers = [ "ax_assistant_structure_mojom_traits.h" ]
- traits_public_deps = [
- "//ui/accessibility:ax_assistant",
- "//ui/gfx",
- "//ui/gfx/geometry/mojom",
- "//ui/gfx/geometry/mojom:mojom_traits",
- "//ui/gfx/range/mojom",
- ]
- },
- {
- types = [
- {
- mojom = "ax.mojom.AXEventIntent"
- cpp = "::ui::AXEventIntent"
- },
- ]
- traits_sources = [ "ax_event_intent_mojom_traits.cc" ]
- traits_headers = [ "ax_event_intent_mojom_traits.h" ]
- traits_public_deps = [ "//ui/accessibility" ]
- },
- {
- types = [
- {
- mojom = "ax.mojom.AXEvent"
- cpp = "::ui::AXEvent"
- },
- ]
- traits_sources = [ "ax_event_mojom_traits.cc" ]
- traits_headers = [ "ax_event_mojom_traits.h" ]
- traits_public_deps = [ "//ui/accessibility" ]
- },
- {
- types = [
- {
- mojom = "ax.mojom.AXNodeData"
- cpp = "::ui::AXNodeData"
- },
- ]
- traits_sources = [ "ax_node_data_mojom_traits.cc" ]
- traits_headers = [ "ax_node_data_mojom_traits.h" ]
- traits_public_deps = [ "//ui/accessibility" ]
- },
- {
- types = [
- {
- mojom = "ax.mojom.AXRelativeBounds"
- cpp = "::ui::AXRelativeBounds"
- },
- ]
- traits_sources = [ "ax_relative_bounds_mojom_traits.cc" ]
- traits_headers = [ "ax_relative_bounds_mojom_traits.h" ]
- traits_public_deps = [
- "//ui/gfx",
- "//ui/gfx/geometry/mojom",
- "//ui/gfx/geometry/mojom:mojom_traits",
- "//ui/gfx/mojom",
- ]
- },
- {
- types = [
- {
- mojom = "ax.mojom.AXTreeData"
- cpp = "::ui::AXTreeData"
- },
- ]
- traits_sources = [ "ax_tree_data_mojom_traits.cc" ]
- traits_headers = [ "ax_tree_data_mojom_traits.h" ]
- traits_public_deps = [ "//ui/accessibility" ]
- },
- {
- types = [
- {
- mojom = "ax.mojom.AXTreeID"
- cpp = "::ui::AXTreeID"
- },
- ]
- traits_sources = [ "ax_tree_id_mojom_traits.cc" ]
- traits_headers = [ "ax_tree_id_mojom_traits.h" ]
- traits_public_deps = [ "//ui/accessibility" ]
- },
- {
- types = [
- {
- mojom = "ax.mojom.AXTreeUpdate"
- cpp = "::ui::AXTreeUpdate"
- },
- ]
- traits_sources = [ "ax_tree_update_mojom_traits.cc" ]
- traits_headers = [ "ax_tree_update_mojom_traits.h" ]
- traits_public_deps = [ "//ui/accessibility" ]
- },
- ]
-}
diff --git a/third_party/accessibility/ax/mojom/OWNERS b/third_party/accessibility/ax/mojom/OWNERS
deleted file mode 100644
index ae29a36..0000000
--- a/third_party/accessibility/ax/mojom/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
-per-file *_mojom_traits*.*=set noparent
-per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
-per-file *.typemap=set noparent
-per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/third_party/accessibility/ax/mojom/ax_action_data.mojom b/third_party/accessibility/ax/mojom/ax_action_data.mojom
deleted file mode 100644
index d802f4a..0000000
--- a/third_party/accessibility/ax/mojom/ax_action_data.mojom
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module ax.mojom;
-
-import "ui/accessibility/ax_enums.mojom";
-import "ui/accessibility/mojom/ax_tree_id.mojom";
-import "ui/gfx/geometry/mojom/geometry.mojom";
-
-// A compact representation of an accessibility action and the arguments
-// associated with that action. See ui::AXActionData for full documentation.
-struct AXActionData {
- Action action;
- ax.mojom.AXTreeID target_tree_id;
- string source_extension_id;
- int32 target_node_id;
- int32 request_id;
- int32 flags;
- int32 anchor_node_id;
- int32 anchor_offset;
- int32 focus_node_id;
- int32 focus_offset;
- int32 custom_action_id;
- gfx.mojom.Rect target_rect;
- gfx.mojom.Point target_point;
- string value;
- Event hit_test_event_to_fire;
- ScrollAlignment horizontal_scroll_alignment;
- ScrollAlignment vertical_scroll_alignment;
- ScrollBehavior scroll_behavior;
-};
diff --git a/third_party/accessibility/ax/mojom/ax_action_data_mojom_traits.cc b/third_party/accessibility/ax/mojom/ax_action_data_mojom_traits.cc
deleted file mode 100644
index c9fac9b..0000000
--- a/third_party/accessibility/ax/mojom/ax_action_data_mojom_traits.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_action_data_mojom_traits.h"
-
-namespace mojo {
-
-// static
-bool StructTraits<ax::mojom::AXActionDataDataView, ui::AXActionData>::Read(
- ax::mojom::AXActionDataDataView data,
- ui::AXActionData* out) {
- if (!data.ReadAction(&out->action))
- return false;
- if (!data.ReadTargetTreeId(&out->target_tree_id))
- return false;
- if (!data.ReadSourceExtensionId(&out->source_extension_id))
- return false;
- out->target_node_id = data.target_node_id();
- out->request_id = data.request_id();
- out->flags = data.flags();
- out->anchor_node_id = data.anchor_node_id();
- out->anchor_offset = data.anchor_offset();
- out->focus_node_id = data.focus_node_id();
- out->focus_offset = data.focus_offset();
- out->custom_action_id = data.custom_action_id();
- out->horizontal_scroll_alignment = data.horizontal_scroll_alignment();
- out->vertical_scroll_alignment = data.vertical_scroll_alignment();
- out->scroll_behavior = data.scroll_behavior();
- return data.ReadTargetRect(&out->target_rect) &&
- data.ReadTargetPoint(&out->target_point) &&
- data.ReadValue(&out->value) &&
- data.ReadHitTestEventToFire(&out->hit_test_event_to_fire);
-}
-
-} // namespace mojo
diff --git a/third_party/accessibility/ax/mojom/ax_action_data_mojom_traits.h b/third_party/accessibility/ax/mojom/ax_action_data_mojom_traits.h
deleted file mode 100644
index 1988dcd..0000000
--- a/third_party/accessibility/ax/mojom/ax_action_data_mojom_traits.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_MOJOM_AX_ACTION_DATA_MOJOM_TRAITS_H_
-#define UI_ACCESSIBILITY_MOJOM_AX_ACTION_DATA_MOJOM_TRAITS_H_
-
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/mojom/ax_action_data.mojom-shared.h"
-#include "ui/accessibility/mojom/ax_tree_id_mojom_traits.h"
-#include "ui/gfx/geometry/mojom/geometry_mojom_traits.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<ax::mojom::AXActionDataDataView, ui::AXActionData> {
- static ax::mojom::Action action(const ui::AXActionData& a) {
- return a.action;
- }
- static const ui::AXTreeID& target_tree_id(const ui::AXActionData& a) {
- return a.target_tree_id;
- }
- static const std::string& source_extension_id(const ui::AXActionData& a) {
- return a.source_extension_id;
- }
- static int32_t target_node_id(const ui::AXActionData& a) {
- return a.target_node_id;
- }
- static int32_t request_id(const ui::AXActionData& a) { return a.request_id; }
- static int32_t flags(const ui::AXActionData& a) { return a.flags; }
- static int32_t anchor_node_id(const ui::AXActionData& a) {
- return a.anchor_node_id;
- }
- static int32_t anchor_offset(const ui::AXActionData& a) {
- return a.anchor_offset;
- }
- static int32_t focus_node_id(const ui::AXActionData& a) {
- return a.focus_node_id;
- }
- static int32_t focus_offset(const ui::AXActionData& a) {
- return a.focus_offset;
- }
- static int32_t custom_action_id(const ui::AXActionData& a) {
- return a.custom_action_id;
- }
- static const gfx::Rect& target_rect(const ui::AXActionData& a) {
- return a.target_rect;
- }
- static const gfx::Point& target_point(const ui::AXActionData& a) {
- return a.target_point;
- }
- static const std::string& value(const ui::AXActionData& a) { return a.value; }
- static ax::mojom::Event hit_test_event_to_fire(const ui::AXActionData& a) {
- return a.hit_test_event_to_fire;
- }
- static ax::mojom::ScrollAlignment horizontal_scroll_alignment(
- const ui::AXActionData& a) {
- return a.horizontal_scroll_alignment;
- }
- static ax::mojom::ScrollAlignment vertical_scroll_alignment(
- const ui::AXActionData& a) {
- return a.vertical_scroll_alignment;
- }
- static ax::mojom::ScrollBehavior scroll_behavior(const ui::AXActionData& a) {
- return a.scroll_behavior;
- }
-
- static bool Read(ax::mojom::AXActionDataDataView data, ui::AXActionData* out);
-};
-
-} // namespace mojo
-
-#endif // UI_ACCESSIBILITY_MOJOM_AX_ACTION_DATA_MOJOM_TRAITS_H_
diff --git a/third_party/accessibility/ax/mojom/ax_action_data_mojom_traits_unittest.cc b/third_party/accessibility/ax/mojom/ax_action_data_mojom_traits_unittest.cc
deleted file mode 100644
index e8f9364..0000000
--- a/third_party/accessibility/ax/mojom/ax_action_data_mojom_traits_unittest.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_action_data_mojom_traits.h"
-
-#include "base/strings/utf_string_conversions.h"
-#include "mojo/public/cpp/test_support/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/mojom/ax_action_data.mojom.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/rect.h"
-
-using mojo::test::SerializeAndDeserialize;
-
-TEST(AXActionDataMojomTraitsTest, RoundTrip) {
- ui::AXActionData input;
- input.action = ax::mojom::Action::kBlur;
- input.target_tree_id = ui::AXTreeID::CreateNewAXTreeID();
- EXPECT_EQ(32U, input.target_tree_id.ToString().size());
- input.source_extension_id = "extension_id";
- input.target_node_id = 2;
- input.request_id = 3;
- input.flags = 4;
- input.anchor_node_id = 5;
- input.anchor_offset = 6;
- input.focus_node_id = 7;
- input.focus_offset = 8;
- input.custom_action_id = 9;
- input.target_rect = gfx::Rect(10, 11, 12, 13);
- input.target_point = gfx::Point(14, 15);
- input.value = "value";
- input.hit_test_event_to_fire = ax::mojom::Event::kFocus;
-
- ui::AXActionData output;
- EXPECT_TRUE(
- SerializeAndDeserialize<ax::mojom::AXActionData>(&input, &output));
-
- EXPECT_EQ(output.action, ax::mojom::Action::kBlur);
- EXPECT_EQ(output.target_tree_id, input.target_tree_id);
- EXPECT_EQ(output.target_tree_id.ToString(), input.target_tree_id.ToString());
- EXPECT_EQ(output.source_extension_id, "extension_id");
- EXPECT_EQ(output.target_node_id, 2);
- EXPECT_EQ(output.request_id, 3);
- EXPECT_EQ(output.flags, 4);
- EXPECT_EQ(output.anchor_node_id, 5);
- EXPECT_EQ(output.anchor_offset, 6);
- EXPECT_EQ(output.focus_node_id, 7);
- EXPECT_EQ(output.focus_offset, 8);
- EXPECT_EQ(output.custom_action_id, 9);
- EXPECT_EQ(output.target_rect, gfx::Rect(10, 11, 12, 13));
- EXPECT_EQ(output.target_point, gfx::Point(14, 15));
- EXPECT_EQ(output.value, "value");
- EXPECT_EQ(output.hit_test_event_to_fire, ax::mojom::Event::kFocus);
-}
diff --git a/third_party/accessibility/ax/mojom/ax_assistant_structure.mojom b/third_party/accessibility/ax/mojom/ax_assistant_structure.mojom
deleted file mode 100644
index e2fa372..0000000
--- a/third_party/accessibility/ax/mojom/ax_assistant_structure.mojom
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module ax.mojom;
-
-import "mojo/public/mojom/base/string16.mojom";
-import "ui/gfx/geometry/mojom/geometry.mojom";
-import "ui/gfx/range/mojom/range.mojom";
-import "url/mojom/url.mojom";
-
-// Tree structure for assistant. The tree is represented as a flat array of
-// nodes, each containing a children_indices vector that points to its child
-// nodes. The purpose is to work around max depth restriction of recursive
-// data structure in mojo.
-struct AssistantTree {
- array<AssistantNode> nodes;
-};
-
-// Represents view structure to be passed to assistant. The view structure is
-// synthesized from the AXNode.
-struct AssistantNode {
- array<int32> children_indices;
-
- // Geometry of the view in pixels
- gfx.mojom.Rect rect;
-
- // Text of the view.
- mojo_base.mojom.String16 text;
-
- // Text properties
- float text_size;
- uint32 color;
- uint32 bgcolor;
- bool bold;
- bool italic;
- bool underline;
- bool line_through;
-
- // Selected portion of the text.
- gfx.mojom.Range? selection;
-
- // Fake Android view class name of the element. Each node is assigned
- // a closest approximation of Android's views to keep the server happy.
- string class_name;
-
- // Accessibility functionality of the node inferred from DOM or based on HTML
- // role attribute.
- string? role;
-};
-
-// Additional information to current context.
-struct AssistantExtra {
- url.mojom.Url url;
- gfx.mojom.Rect bounds_pixel;
- mojo_base.mojom.String16 title;
-};
-
-// Assistant structure, including Assistant tree and extra.
-struct AssistantStructure {
- AssistantTree? assistant_tree;
- AssistantExtra? assistant_extra;
-};
diff --git a/third_party/accessibility/ax/mojom/ax_assistant_structure_mojom_traits.cc b/third_party/accessibility/ax/mojom/ax_assistant_structure_mojom_traits.cc
deleted file mode 100644
index 5d4334c..0000000
--- a/third_party/accessibility/ax/mojom/ax_assistant_structure_mojom_traits.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_assistant_structure_mojom_traits.h"
-
-#include "mojo/public/cpp/base/string16_mojom_traits.h"
-#include "ui/gfx/geometry/mojom/geometry_mojom_traits.h"
-#include "ui/gfx/range/mojom/range_mojom_traits.h"
-
-namespace mojo {
-
-// static
-bool StructTraits<ax::mojom::AssistantTreeDataView,
- std::unique_ptr<ui::AssistantTree>>::
- Read(ax::mojom::AssistantTreeDataView data,
- std::unique_ptr<ui::AssistantTree>* out) {
- DCHECK(!*out);
- *out = std::make_unique<ui::AssistantTree>();
- if (!data.ReadNodes(&(*out)->nodes))
- return false;
- for (size_t i = 0; i < (*out)->nodes.size(); i++) {
- // Each child's index should be greater than its parent and within the array
- // bounds. This implies that there is no circle in the tree.
- for (size_t child_index : (*out)->nodes[i]->children_indices) {
- if (child_index <= i || child_index >= (*out)->nodes.size())
- return false;
- }
- }
- return true;
-}
-
-// static
-bool StructTraits<ax::mojom::AssistantNodeDataView,
- std::unique_ptr<ui::AssistantNode>>::
- Read(ax::mojom::AssistantNodeDataView data,
- std::unique_ptr<ui::AssistantNode>* out) {
- DCHECK(!out->get());
- *out = std::make_unique<ui::AssistantNode>();
- (*out)->bgcolor = data.bgcolor();
- (*out)->bold = data.bold();
-
- (*out)->color = data.color();
- (*out)->italic = data.italic();
- (*out)->line_through = data.line_through();
- (*out)->underline = data.underline();
-
- if (!data.ReadRect(&(*out)->rect) || !data.ReadText(&(*out)->text) ||
- !data.ReadRole(&(*out)->role) ||
- !data.ReadSelection(&(*out)->selection) ||
- !data.ReadChildrenIndices(&(*out)->children_indices) ||
- !data.ReadClassName(&(*out)->class_name)) {
- return false;
- }
-
- return true;
-}
-
-} // namespace mojo
diff --git a/third_party/accessibility/ax/mojom/ax_assistant_structure_mojom_traits.h b/third_party/accessibility/ax/mojom/ax_assistant_structure_mojom_traits.h
deleted file mode 100644
index 16d8d00..0000000
--- a/third_party/accessibility/ax/mojom/ax_assistant_structure_mojom_traits.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_MOJOM_AX_ASSISTANT_STRUCTURE_MOJOM_TRAITS_H_
-#define UI_ACCESSIBILITY_MOJOM_AX_ASSISTANT_STRUCTURE_MOJOM_TRAITS_H_
-
-#include <memory>
-
-#include "ui/accessibility/ax_assistant_structure.h"
-#include "ui/accessibility/mojom/ax_assistant_structure.mojom-shared.h"
-#include "ui/accessibility/mojom/ax_assistant_structure.mojom.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<ax::mojom::AssistantTreeDataView,
- std::unique_ptr<ui::AssistantTree>> {
- static bool IsNull(const std::unique_ptr<ui::AssistantTree>& ptr) {
- return !ptr;
- }
-
- static void SetToNull(std::unique_ptr<ui::AssistantTree>* output) {
- output->reset();
- }
-
- static const std::vector<std::unique_ptr<ui::AssistantNode>>& nodes(
- const std::unique_ptr<ui::AssistantTree>& tree) {
- return tree->nodes;
- }
- static bool Read(ax::mojom::AssistantTreeDataView data,
- std::unique_ptr<ui::AssistantTree>* out);
-};
-
-template <>
-struct StructTraits<ax::mojom::AssistantNodeDataView,
- std::unique_ptr<ui::AssistantNode>> {
- static const std::vector<int32_t>& children_indices(
- const std::unique_ptr<ui::AssistantNode>& node) {
- return node->children_indices;
- }
- static gfx::Rect rect(const std::unique_ptr<ui::AssistantNode>& node) {
- return node->rect;
- }
- static base::string16 text(const std::unique_ptr<ui::AssistantNode>& node) {
- return node->text;
- }
- static float text_size(const std::unique_ptr<ui::AssistantNode>& node) {
- return node->text_size;
- }
- static uint32_t color(const std::unique_ptr<ui::AssistantNode>& node) {
- return node->color;
- }
- static uint32_t bgcolor(const std::unique_ptr<ui::AssistantNode>& node) {
- return node->bgcolor;
- }
- static bool bold(const std::unique_ptr<ui::AssistantNode>& node) {
- return node->bold;
- }
- static bool italic(const std::unique_ptr<ui::AssistantNode>& node) {
- return node->italic;
- }
- static bool underline(const std::unique_ptr<ui::AssistantNode>& node) {
- return node->underline;
- }
- static bool line_through(const std::unique_ptr<ui::AssistantNode>& node) {
- return node->line_through;
- }
- static base::Optional<gfx::Range> selection(
- const std::unique_ptr<ui::AssistantNode>& node) {
- return node->selection;
- }
- static std::string class_name(
- const std::unique_ptr<ui::AssistantNode>& node) {
- return node->class_name;
- }
- static base::Optional<std::string> role(
- const std::unique_ptr<ui::AssistantNode>& node) {
- return node->role;
- }
- static bool Read(ax::mojom::AssistantNodeDataView data,
- std::unique_ptr<ui::AssistantNode>* out);
-};
-
-} // namespace mojo
-
-#endif // UI_ACCESSIBILITY_MOJOM_AX_ASSISTANT_STRUCTURE_MOJOM_TRAITS_H_
diff --git a/third_party/accessibility/ax/mojom/ax_event.mojom b/third_party/accessibility/ax/mojom/ax_event.mojom
deleted file mode 100644
index 857af93..0000000
--- a/third_party/accessibility/ax/mojom/ax_event.mojom
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module ax.mojom;
-
-import "ui/accessibility/ax_enums.mojom";
-import "ui/accessibility/mojom/ax_event_intent.mojom";
-
-// See ui::AXEvent for documentation.
-struct AXEvent {
- Event event_type;
- int32 id;
- EventFrom event_from;
- array<EventIntent> event_intents;
- int32 action_request_id;
-};
diff --git a/third_party/accessibility/ax/mojom/ax_event_intent.mojom b/third_party/accessibility/ax/mojom/ax_event_intent.mojom
deleted file mode 100644
index 789c910..0000000
--- a/third_party/accessibility/ax/mojom/ax_event_intent.mojom
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module ax.mojom;
-
-import "ui/accessibility/ax_enums.mojom";
-
-// See ui::AXEventIntent for documentation.
-struct EventIntent {
- Command command;
- TextBoundary text_boundary;
- MoveDirection move_direction;
-};
diff --git a/third_party/accessibility/ax/mojom/ax_event_intent_mojom_traits.cc b/third_party/accessibility/ax/mojom/ax_event_intent_mojom_traits.cc
deleted file mode 100644
index 9556a68..0000000
--- a/third_party/accessibility/ax/mojom/ax_event_intent_mojom_traits.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_event_intent_mojom_traits.h"
-
-namespace mojo {
-
-// static
-bool StructTraits<ax::mojom::EventIntentDataView, ui::AXEventIntent>::Read(
- ax::mojom::EventIntentDataView data,
- ui::AXEventIntent* out) {
- out->command = data.command();
- out->text_boundary = data.text_boundary();
- out->move_direction = data.move_direction();
- return true;
-}
-
-} // namespace mojo
diff --git a/third_party/accessibility/ax/mojom/ax_event_intent_mojom_traits.h b/third_party/accessibility/ax/mojom/ax_event_intent_mojom_traits.h
deleted file mode 100644
index 614c044..0000000
--- a/third_party/accessibility/ax/mojom/ax_event_intent_mojom_traits.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_MOJOM_AX_EVENT_INTENT_MOJOM_TRAITS_H_
-#define UI_ACCESSIBILITY_MOJOM_AX_EVENT_INTENT_MOJOM_TRAITS_H_
-
-#include "ui/accessibility/ax_event_intent.h"
-#include "ui/accessibility/mojom/ax_event_intent.mojom.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<ax::mojom::EventIntentDataView, ui::AXEventIntent> {
- static ax::mojom::Command command(const ui::AXEventIntent& p) {
- return p.command;
- }
- static ax::mojom::TextBoundary text_boundary(const ui::AXEventIntent& p) {
- return p.text_boundary;
- }
- static ax::mojom::MoveDirection move_direction(const ui::AXEventIntent& p) {
- return p.move_direction;
- }
- static bool Read(ax::mojom::EventIntentDataView data, ui::AXEventIntent* out);
-};
-
-} // namespace mojo
-
-#endif // UI_ACCESSIBILITY_MOJOM_AX_EVENT_INTENT_MOJOM_TRAITS_H_
diff --git a/third_party/accessibility/ax/mojom/ax_event_intent_mojom_traits_unittest.cc b/third_party/accessibility/ax/mojom/ax_event_intent_mojom_traits_unittest.cc
deleted file mode 100644
index 6c8d62b..0000000
--- a/third_party/accessibility/ax/mojom/ax_event_intent_mojom_traits_unittest.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_event_intent_mojom_traits.h"
-
-#include "mojo/public/cpp/test_support/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_event_intent.h"
-#include "ui/accessibility/mojom/ax_event_intent.mojom.h"
-
-using mojo::test::SerializeAndDeserialize;
-
-TEST(AXEventIntentMojomTraitsTest, RoundTrip) {
- ui::AXEventIntent input;
- input.command = ax::mojom::Command::kCut;
- input.text_boundary = ax::mojom::TextBoundary::kWordEnd;
- input.move_direction = ax::mojom::MoveDirection::kForward;
-
- ui::AXEventIntent output;
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::EventIntent>(&input, &output));
- EXPECT_EQ(ax::mojom::Command::kCut, output.command);
- EXPECT_EQ(ax::mojom::TextBoundary::kWordEnd, output.text_boundary);
- EXPECT_EQ(ax::mojom::MoveDirection::kForward, output.move_direction);
-}
diff --git a/third_party/accessibility/ax/mojom/ax_event_mojom_traits.cc b/third_party/accessibility/ax/mojom/ax_event_mojom_traits.cc
deleted file mode 100644
index 1b927ea..0000000
--- a/third_party/accessibility/ax/mojom/ax_event_mojom_traits.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_event_mojom_traits.h"
-
-namespace mojo {
-
-// static
-bool StructTraits<ax::mojom::AXEventDataView, ui::AXEvent>::Read(
- ax::mojom::AXEventDataView data,
- ui::AXEvent* out) {
- out->event_type = data.event_type();
- out->id = data.id();
- out->event_from = data.event_from();
- out->action_request_id = data.action_request_id();
- return data.ReadEventIntents(&out->event_intents);
-}
-
-} // namespace mojo
diff --git a/third_party/accessibility/ax/mojom/ax_event_mojom_traits.h b/third_party/accessibility/ax/mojom/ax_event_mojom_traits.h
deleted file mode 100644
index c192234..0000000
--- a/third_party/accessibility/ax/mojom/ax_event_mojom_traits.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_MOJOM_AX_EVENT_MOJOM_TRAITS_H_
-#define UI_ACCESSIBILITY_MOJOM_AX_EVENT_MOJOM_TRAITS_H_
-
-#include <vector>
-
-#include "ui/accessibility/ax_event.h"
-#include "ui/accessibility/ax_event_intent.h"
-#include "ui/accessibility/mojom/ax_event.mojom.h"
-#include "ui/accessibility/mojom/ax_event_intent.mojom.h"
-#include "ui/accessibility/mojom/ax_event_intent_mojom_traits.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<ax::mojom::AXEventDataView, ui::AXEvent> {
- static ax::mojom::Event event_type(const ui::AXEvent& p) {
- return p.event_type;
- }
- static int32_t id(const ui::AXEvent& p) { return p.id; }
- static ax::mojom::EventFrom event_from(const ui::AXEvent& p) {
- return p.event_from;
- }
- static std::vector<ui::AXEventIntent> event_intents(const ui::AXEvent& p) {
- return p.event_intents;
- }
- static int32_t action_request_id(const ui::AXEvent& p) {
- return p.action_request_id;
- }
- static bool Read(ax::mojom::AXEventDataView data, ui::AXEvent* out);
-};
-
-} // namespace mojo
-
-#endif // UI_ACCESSIBILITY_MOJOM_AX_EVENT_MOJOM_TRAITS_H_
diff --git a/third_party/accessibility/ax/mojom/ax_event_mojom_traits_unittest.cc b/third_party/accessibility/ax/mojom/ax_event_mojom_traits_unittest.cc
deleted file mode 100644
index ba5657c..0000000
--- a/third_party/accessibility/ax/mojom/ax_event_mojom_traits_unittest.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_event_mojom_traits.h"
-
-#include <vector>
-
-#include "mojo/public/cpp/test_support/test_utils.h"
-#include "testing/gmock/include/gmock/gmock-matchers.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_event.h"
-#include "ui/accessibility/ax_event_intent.h"
-#include "ui/accessibility/mojom/ax_event.mojom.h"
-#include "ui/accessibility/mojom/ax_event_intent.mojom.h"
-
-using mojo::test::SerializeAndDeserialize;
-
-TEST(AXEventMojomTraitsTest, RoundTrip) {
- ui::AXEvent input;
- input.event_type = ax::mojom::Event::kTextChanged;
- input.id = 111;
- input.event_from = ax::mojom::EventFrom::kUser;
- ui::AXEventIntent cut_intent;
- cut_intent.command = ax::mojom::Command::kCut;
- cut_intent.text_boundary = ax::mojom::TextBoundary::kWordEnd;
- cut_intent.move_direction = ax::mojom::MoveDirection::kForward;
- const std::vector<ui::AXEventIntent> event_intents{cut_intent};
- input.event_intents = event_intents;
- input.action_request_id = 222;
-
- ui::AXEvent output;
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXEvent>(&input, &output));
- EXPECT_EQ(ax::mojom::Event::kTextChanged, output.event_type);
- EXPECT_EQ(111, output.id);
- EXPECT_EQ(ax::mojom::EventFrom::kUser, output.event_from);
- EXPECT_THAT(output.event_intents, testing::ContainerEq(event_intents));
- EXPECT_EQ(222, output.action_request_id);
-}
diff --git a/third_party/accessibility/ax/mojom/ax_node_data.mojom b/third_party/accessibility/ax/mojom/ax_node_data.mojom
deleted file mode 100644
index b11ce2a..0000000
--- a/third_party/accessibility/ax/mojom/ax_node_data.mojom
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module ax.mojom;
-
-import "ui/accessibility/ax_enums.mojom";
-import "ui/accessibility/mojom/ax_relative_bounds.mojom";
-
-// See ui::AXNodeData for comments / explanations of these fields.
-struct AXNodeData {
- int32 id;
- ax.mojom.Role role;
- uint32 state;
- uint64 actions;
- map<ax.mojom.StringAttribute, string> string_attributes;
- map<ax.mojom.IntAttribute, int32> int_attributes;
- map<ax.mojom.FloatAttribute, float> float_attributes;
- map<ax.mojom.BoolAttribute, bool> bool_attributes;
- map<ax.mojom.IntListAttribute, array<int32>>
- intlist_attributes;
- map<ax.mojom.StringListAttribute, array<string>>
- stringlist_attributes;
- map<string, string> html_attributes;
- array<int32> child_ids;
- ax.mojom.AXRelativeBounds relative_bounds;
-};
diff --git a/third_party/accessibility/ax/mojom/ax_node_data_mojom_traits.cc b/third_party/accessibility/ax/mojom/ax_node_data_mojom_traits.cc
deleted file mode 100644
index f8c84a9..0000000
--- a/third_party/accessibility/ax/mojom/ax_node_data_mojom_traits.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_node_data_mojom_traits.h"
-#include "ui/accessibility/mojom/ax_relative_bounds.mojom-shared.h"
-#include "ui/accessibility/mojom/ax_relative_bounds_mojom_traits.h"
-
-namespace mojo {
-
-// static
-std::unordered_map<ax::mojom::StringAttribute, std::string>
-StructTraits<ax::mojom::AXNodeDataDataView, ui::AXNodeData>::string_attributes(
- const ui::AXNodeData& p) {
- std::unordered_map<ax::mojom::StringAttribute, std::string> result;
- for (const auto& iter : p.string_attributes)
- result[iter.first] = iter.second;
- return result;
-}
-
-// static
-std::unordered_map<ax::mojom::IntAttribute, int32_t>
-StructTraits<ax::mojom::AXNodeDataDataView, ui::AXNodeData>::int_attributes(
- const ui::AXNodeData& p) {
- std::unordered_map<ax::mojom::IntAttribute, int32_t> result;
- for (const auto& iter : p.int_attributes)
- result[iter.first] = iter.second;
- return result;
-}
-
-// static
-std::unordered_map<ax::mojom::FloatAttribute, float>
-StructTraits<ax::mojom::AXNodeDataDataView, ui::AXNodeData>::float_attributes(
- const ui::AXNodeData& p) {
- std::unordered_map<ax::mojom::FloatAttribute, float> result;
- for (const auto& iter : p.float_attributes)
- result[iter.first] = iter.second;
- return result;
-}
-
-// static
-std::unordered_map<ax::mojom::BoolAttribute, bool>
-StructTraits<ax::mojom::AXNodeDataDataView, ui::AXNodeData>::bool_attributes(
- const ui::AXNodeData& p) {
- std::unordered_map<ax::mojom::BoolAttribute, bool> result;
- for (const auto& iter : p.bool_attributes)
- result[iter.first] = iter.second;
- return result;
-}
-
-// static
-std::unordered_map<ax::mojom::IntListAttribute, std::vector<int32_t>>
-StructTraits<ax::mojom::AXNodeDataDataView, ui::AXNodeData>::intlist_attributes(
- const ui::AXNodeData& p) {
- std::unordered_map<ax::mojom::IntListAttribute, std::vector<int32_t>> result;
- for (const auto& iter : p.intlist_attributes)
- result[iter.first] = iter.second;
- return result;
-}
-
-// static
-std::unordered_map<ax::mojom::StringListAttribute, std::vector<std::string>>
-StructTraits<ax::mojom::AXNodeDataDataView,
- ui::AXNodeData>::stringlist_attributes(const ui::AXNodeData& p) {
- std::unordered_map<ax::mojom::StringListAttribute, std::vector<std::string>>
- result;
- for (const auto& iter : p.stringlist_attributes)
- result[iter.first] = iter.second;
- return result;
-}
-
-// static
-std::unordered_map<std::string, std::string>
-StructTraits<ax::mojom::AXNodeDataDataView, ui::AXNodeData>::html_attributes(
- const ui::AXNodeData& p) {
- std::unordered_map<std::string, std::string> result;
- for (const auto& iter : p.html_attributes)
- result[iter.first] = iter.second;
- return result;
-}
-
-// static
-bool StructTraits<ax::mojom::AXNodeDataDataView, ui::AXNodeData>::Read(
- ax::mojom::AXNodeDataDataView data,
- ui::AXNodeData* out) {
- out->id = data.id();
- out->role = data.role();
- out->state = data.state();
- out->actions = data.actions();
-
- std::unordered_map<ax::mojom::StringAttribute, std::string> string_attributes;
- if (!data.ReadStringAttributes(&string_attributes))
- return false;
- for (const auto& iter : string_attributes)
- out->AddStringAttribute(iter.first, iter.second);
-
- std::unordered_map<ax::mojom::IntAttribute, int32_t> int_attributes;
- if (!data.ReadIntAttributes(&int_attributes))
- return false;
- for (const auto& iter : int_attributes)
- out->AddIntAttribute(iter.first, iter.second);
-
- std::unordered_map<ax::mojom::FloatAttribute, float> float_attributes;
- if (!data.ReadFloatAttributes(&float_attributes))
- return false;
- for (const auto& iter : float_attributes)
- out->AddFloatAttribute(iter.first, iter.second);
-
- std::unordered_map<ax::mojom::BoolAttribute, bool> bool_attributes;
- if (!data.ReadBoolAttributes(&bool_attributes))
- return false;
- for (const auto& iter : bool_attributes)
- out->AddBoolAttribute(iter.first, iter.second);
-
- std::unordered_map<ax::mojom::IntListAttribute, std::vector<int32_t>>
- intlist_attributes;
- if (!data.ReadIntlistAttributes(&intlist_attributes))
- return false;
- for (const auto& iter : intlist_attributes)
- out->AddIntListAttribute(iter.first, iter.second);
-
- std::unordered_map<ax::mojom::StringListAttribute, std::vector<std::string>>
- stringlist_attributes;
- if (!data.ReadStringlistAttributes(&stringlist_attributes))
- return false;
- for (const auto& iter : stringlist_attributes)
- out->AddStringListAttribute(iter.first, iter.second);
-
- std::unordered_map<std::string, std::string> html_attributes;
- if (!data.ReadHtmlAttributes(&html_attributes))
- return false;
- for (const auto& iter : html_attributes)
- out->html_attributes.push_back(std::make_pair(iter.first, iter.second));
-
- if (!data.ReadChildIds(&out->child_ids))
- return false;
-
- if (!data.ReadRelativeBounds(&out->relative_bounds))
- return false;
-
- return true;
-}
-
-} // namespace mojo
diff --git a/third_party/accessibility/ax/mojom/ax_node_data_mojom_traits.h b/third_party/accessibility/ax/mojom/ax_node_data_mojom_traits.h
deleted file mode 100644
index 1149d61..0000000
--- a/third_party/accessibility/ax/mojom/ax_node_data_mojom_traits.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_MOJOM_AX_NODE_DATA_MOJOM_TRAITS_H_
-#define UI_ACCESSIBILITY_MOJOM_AX_NODE_DATA_MOJOM_TRAITS_H_
-
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_relative_bounds.h"
-#include "ui/accessibility/mojom/ax_node_data.mojom-shared.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<ax::mojom::AXNodeDataDataView, ui::AXNodeData> {
- static int32_t id(const ui::AXNodeData& p) { return p.id; }
- static ax::mojom::Role role(const ui::AXNodeData& p) { return p.role; }
- static uint32_t state(const ui::AXNodeData& p) { return p.state; }
- static uint64_t actions(const ui::AXNodeData& p) { return p.actions; }
- static std::unordered_map<ax::mojom::StringAttribute, std::string>
- string_attributes(const ui::AXNodeData& p);
- static std::unordered_map<ax::mojom::IntAttribute, int32_t> int_attributes(
- const ui::AXNodeData& p);
- static std::unordered_map<ax::mojom::FloatAttribute, float> float_attributes(
- const ui::AXNodeData& p);
- static std::unordered_map<ax::mojom::BoolAttribute, bool> bool_attributes(
- const ui::AXNodeData& p);
- static std::unordered_map<ax::mojom::IntListAttribute, std::vector<int32_t>>
- intlist_attributes(const ui::AXNodeData& p);
- static std::unordered_map<ax::mojom::StringListAttribute,
- std::vector<std::string>>
- stringlist_attributes(const ui::AXNodeData& p);
- static std::unordered_map<std::string, std::string> html_attributes(
- const ui::AXNodeData& p);
- static std::vector<int32_t> child_ids(const ui::AXNodeData& p) {
- return p.child_ids;
- }
- static ui::AXRelativeBounds relative_bounds(const ui::AXNodeData& p) {
- return p.relative_bounds;
- }
- static bool Read(ax::mojom::AXNodeDataDataView data, ui::AXNodeData* out);
-};
-
-} // namespace mojo
-
-#endif // UI_ACCESSIBILITY_MOJOM_AX_NODE_DATA_MOJOM_TRAITS_H_
diff --git a/third_party/accessibility/ax/mojom/ax_node_data_mojom_traits_unittest.cc b/third_party/accessibility/ax/mojom/ax_node_data_mojom_traits_unittest.cc
deleted file mode 100644
index 5b11af9..0000000
--- a/third_party/accessibility/ax/mojom/ax_node_data_mojom_traits_unittest.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_node_data_mojom_traits.h"
-#include "mojo/public/cpp/test_support/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/mojom/ax_node_data.mojom.h"
-#include "ui/accessibility/mojom/ax_relative_bounds_mojom_traits.h"
-
-using mojo::test::SerializeAndDeserialize;
-
-TEST(AXNodeDataMojomTraitsTest, ID) {
- ui::AXNodeData input, output;
- input.id = 42;
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_EQ(42, output.id);
-}
-
-TEST(AXNodeDataMojomTraitsTest, Role) {
- ui::AXNodeData input, output;
- input.role = ax::mojom::Role::kButton;
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_EQ(ax::mojom::Role::kButton, output.role);
-}
-
-TEST(AXNodeDataMojomTraitsTest, State) {
- ui::AXNodeData input, output;
- input.state = 0;
- input.AddState(ax::mojom::State::kCollapsed);
- input.AddState(ax::mojom::State::kHorizontal);
- input.AddState(ax::mojom::State::kMaxValue);
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_TRUE(output.HasState(ax::mojom::State::kCollapsed));
- EXPECT_TRUE(output.HasState(ax::mojom::State::kHorizontal));
- EXPECT_TRUE(output.HasState(ax::mojom::State::kMaxValue));
- EXPECT_FALSE(output.HasState(ax::mojom::State::kFocusable));
- EXPECT_FALSE(output.HasState(ax::mojom::State::kMultiline));
-}
-
-TEST(AXNodeDataMojomTraitsTest, Actions) {
- ui::AXNodeData input, output;
- input.actions = 0;
- input.AddAction(ax::mojom::Action::kDoDefault);
- input.AddAction(ax::mojom::Action::kDecrement);
- input.AddAction(ax::mojom::Action::kMaxValue);
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_TRUE(output.HasAction(ax::mojom::Action::kDoDefault));
- EXPECT_TRUE(output.HasAction(ax::mojom::Action::kDecrement));
- EXPECT_TRUE(output.HasAction(ax::mojom::Action::kMaxValue));
- EXPECT_FALSE(output.HasAction(ax::mojom::Action::kFocus));
- EXPECT_FALSE(output.HasAction(ax::mojom::Action::kBlur));
-}
-
-TEST(AXNodeDataMojomTraitsTest, StringAttributes) {
- ui::AXNodeData input, output;
- input.AddStringAttribute(ax::mojom::StringAttribute::kName, "Mojo");
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_EQ("Mojo",
- output.GetStringAttribute(ax::mojom::StringAttribute::kName));
-}
-
-TEST(AXNodeDataMojomTraitsTest, IntAttributes) {
- ui::AXNodeData input, output;
- input.AddIntAttribute(ax::mojom::IntAttribute::kScrollX, 42);
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_EQ(42, output.GetIntAttribute(ax::mojom::IntAttribute::kScrollX));
-}
-
-TEST(AXNodeDataMojomTraitsTest, FloatAttributes) {
- ui::AXNodeData input, output;
- input.AddFloatAttribute(ax::mojom::FloatAttribute::kFontSize, 42);
- input.AddFloatAttribute(ax::mojom::FloatAttribute::kFontWeight, 100);
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_EQ(42, output.GetFloatAttribute(ax::mojom::FloatAttribute::kFontSize));
- EXPECT_EQ(100,
- output.GetFloatAttribute(ax::mojom::FloatAttribute::kFontWeight));
-}
-
-TEST(AXNodeDataMojomTraitsTest, BoolAttributes) {
- ui::AXNodeData input, output;
- input.AddBoolAttribute(ax::mojom::BoolAttribute::kBusy, true);
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_TRUE(output.GetBoolAttribute(ax::mojom::BoolAttribute::kBusy));
-}
-
-TEST(AXNodeDataMojomTraitsTest, IntListAttributes) {
- ui::AXNodeData input, output;
- input.AddIntListAttribute(ax::mojom::IntListAttribute::kControlsIds, {1, 2});
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_EQ(
- std::vector<int32_t>({1, 2}),
- output.GetIntListAttribute(ax::mojom::IntListAttribute::kControlsIds));
-}
-
-TEST(AXNodeDataMojomTraitsTest, StringListAttributes) {
- ui::AXNodeData input, output;
- input.AddStringListAttribute(
- ax::mojom::StringListAttribute::kCustomActionDescriptions,
- {"foo", "bar"});
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_EQ(std::vector<std::string>({"foo", "bar"}),
- output.GetStringListAttribute(
- ax::mojom::StringListAttribute::kCustomActionDescriptions));
-}
-
-TEST(AXNodeDataMojomTraitsTest, ChildIds) {
- ui::AXNodeData input, output;
- input.child_ids = {3, 4};
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_EQ(std::vector<int32_t>({3, 4}), output.child_ids);
-}
-
-TEST(AXNodeDataMojomTraitsTest, OffsetContainerID) {
- ui::AXNodeData input, output;
- input.relative_bounds.offset_container_id = 10;
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_EQ(10, output.relative_bounds.offset_container_id);
-}
-
-TEST(AXNodeDataMojomTraitsTest, RelativeBounds) {
- ui::AXNodeData input, output;
- input.relative_bounds.bounds = gfx::RectF(1, 2, 3, 4);
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_EQ(1, output.relative_bounds.bounds.x());
- EXPECT_EQ(2, output.relative_bounds.bounds.y());
- EXPECT_EQ(3, output.relative_bounds.bounds.width());
- EXPECT_EQ(4, output.relative_bounds.bounds.height());
-}
-
-TEST(AXNodeDataMojomTraitsTest, Transform) {
- ui::AXNodeData input, output;
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_FALSE(output.relative_bounds.transform);
-
- input.relative_bounds.transform = std::make_unique<gfx::Transform>();
- input.relative_bounds.transform->Scale(2.0, 2.0);
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXNodeData>(&input, &output));
- EXPECT_TRUE(output.relative_bounds.transform);
- EXPECT_FALSE(output.relative_bounds.transform->IsIdentity());
-}
diff --git a/third_party/accessibility/ax/mojom/ax_relative_bounds.mojom b/third_party/accessibility/ax/mojom/ax_relative_bounds.mojom
deleted file mode 100644
index 50e737c..0000000
--- a/third_party/accessibility/ax/mojom/ax_relative_bounds.mojom
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module ax.mojom;
-
-import "ui/gfx/geometry/mojom/geometry.mojom";
-import "ui/gfx/mojom/transform.mojom";
-
-// See ui::RelativeBounds for documentation.
-struct AXRelativeBounds {
- int32 offset_container_id;
- gfx.mojom.RectF bounds;
- gfx.mojom.Transform transform;
-};
diff --git a/third_party/accessibility/ax/mojom/ax_relative_bounds_mojom_traits.cc b/third_party/accessibility/ax/mojom/ax_relative_bounds_mojom_traits.cc
deleted file mode 100644
index 6e1fa3b..0000000
--- a/third_party/accessibility/ax/mojom/ax_relative_bounds_mojom_traits.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "ui/accessibility/mojom/ax_relative_bounds_mojom_traits.h"
-
-namespace mojo {
-
-// static
-gfx::Transform
-StructTraits<ax::mojom::AXRelativeBoundsDataView,
- ui::AXRelativeBounds>::transform(const ui::AXRelativeBounds& p) {
- if (p.transform)
- return *p.transform;
- else
- return gfx::Transform();
-}
-
-// static
-bool StructTraits<ax::mojom::AXRelativeBoundsDataView, ui::AXRelativeBounds>::
- Read(ax::mojom::AXRelativeBoundsDataView data, ui::AXRelativeBounds* out) {
- out->offset_container_id = data.offset_container_id();
-
- gfx::Transform transform;
- if (!data.ReadTransform(&transform))
- return false;
- if (!transform.IsIdentity())
- out->transform = std::make_unique<gfx::Transform>(transform);
-
- if (!data.ReadBounds(&out->bounds))
- return false;
-
- return true;
-}
-
-} // namespace mojo
diff --git a/third_party/accessibility/ax/mojom/ax_relative_bounds_mojom_traits.h b/third_party/accessibility/ax/mojom/ax_relative_bounds_mojom_traits.h
deleted file mode 100644
index 8cb45aa..0000000
--- a/third_party/accessibility/ax/mojom/ax_relative_bounds_mojom_traits.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_MOJOM_AX_RELATIVE_BOUNDS_MOJOM_TRAITS_H_
-#define UI_ACCESSIBILITY_MOJOM_AX_RELATIVE_BOUNDS_MOJOM_TRAITS_H_
-
-#include "ui/accessibility/ax_relative_bounds.h"
-#include "ui/accessibility/mojom/ax_relative_bounds.mojom-shared.h"
-#include "ui/gfx/geometry/mojom/geometry_mojom_traits.h"
-#include "ui/gfx/mojom/transform.mojom.h"
-#include "ui/gfx/mojom/transform_mojom_traits.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<ax::mojom::AXRelativeBoundsDataView, ui::AXRelativeBounds> {
- static int32_t offset_container_id(const ui::AXRelativeBounds& p) {
- return p.offset_container_id;
- }
-
- static gfx::RectF bounds(const ui::AXRelativeBounds& p) { return p.bounds; }
-
- static gfx::Transform transform(const ui::AXRelativeBounds& p);
-
- static bool Read(ax::mojom::AXRelativeBoundsDataView data,
- ui::AXRelativeBounds* out);
-};
-
-} // namespace mojo
-
-#endif // UI_ACCESSIBILITY_MOJOM_AX_RELATIVE_BOUNDS_MOJOM_TRAITS_H_
diff --git a/third_party/accessibility/ax/mojom/ax_relative_bounds_mojom_traits_unittest.cc b/third_party/accessibility/ax/mojom/ax_relative_bounds_mojom_traits_unittest.cc
deleted file mode 100644
index 761c643..0000000
--- a/third_party/accessibility/ax/mojom/ax_relative_bounds_mojom_traits_unittest.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_relative_bounds_mojom_traits.h"
-
-#include "mojo/public/cpp/test_support/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_relative_bounds.h"
-#include "ui/accessibility/mojom/ax_relative_bounds.mojom.h"
-
-using mojo::test::SerializeAndDeserialize;
-
-TEST(AXRelativeBoundsMojomTraitsTest, RoundTrip) {
- ui::AXRelativeBounds input;
- input.offset_container_id = 111;
- input.bounds = gfx::RectF(1, 2, 3, 4);
- input.transform = std::make_unique<gfx::Transform>();
- input.transform->Scale(1.0, 2.0);
-
- ui::AXRelativeBounds output;
- EXPECT_TRUE(
- SerializeAndDeserialize<ax::mojom::AXRelativeBounds>(&input, &output));
- EXPECT_EQ(111, output.offset_container_id);
- EXPECT_EQ(1, output.bounds.x());
- EXPECT_EQ(2, output.bounds.y());
- EXPECT_EQ(3, output.bounds.width());
- EXPECT_EQ(4, output.bounds.height());
- EXPECT_FALSE(output.transform->IsIdentity());
-}
diff --git a/third_party/accessibility/ax/mojom/ax_tree_data.mojom b/third_party/accessibility/ax/mojom/ax_tree_data.mojom
deleted file mode 100644
index 5c04729..0000000
--- a/third_party/accessibility/ax/mojom/ax_tree_data.mojom
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module ax.mojom;
-
-import "ui/accessibility/ax_enums.mojom";
-import "ui/accessibility/mojom/ax_tree_id.mojom";
-
-// See ui::AXTreeData for comments / explanations of these fields.
-struct AXTreeData {
- ax.mojom.AXTreeID tree_id;
- ax.mojom.AXTreeID parent_tree_id;
- ax.mojom.AXTreeID focused_tree_id;
- string doctype;
- bool loaded;
- float loading_progress;
- string mimetype;
- string title;
- string url;
- int32 focus_id;
- bool sel_is_backward;
- int32 sel_anchor_object_id;
- int32 sel_anchor_offset;
- ax.mojom.TextAffinity sel_anchor_affinity;
- int32 sel_focus_object_id;
- int32 sel_focus_offset;
- ax.mojom.TextAffinity sel_focus_affinity;
- int32 root_scroller_id;
-};
diff --git a/third_party/accessibility/ax/mojom/ax_tree_data_mojom_traits.cc b/third_party/accessibility/ax/mojom/ax_tree_data_mojom_traits.cc
deleted file mode 100644
index a28da66..0000000
--- a/third_party/accessibility/ax/mojom/ax_tree_data_mojom_traits.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_tree_data_mojom_traits.h"
-
-namespace mojo {
-
-// static
-bool StructTraits<ax::mojom::AXTreeDataDataView, ui::AXTreeData>::Read(
- ax::mojom::AXTreeDataDataView data,
- ui::AXTreeData* out) {
- if (!data.ReadTreeId(&out->tree_id))
- return false;
- if (!data.ReadParentTreeId(&out->parent_tree_id))
- return false;
- if (!data.ReadFocusedTreeId(&out->focused_tree_id))
- return false;
- if (!data.ReadDoctype(&out->doctype))
- return false;
- out->loaded = data.loaded();
- out->loading_progress = data.loading_progress();
- if (!data.ReadMimetype(&out->mimetype))
- return false;
- if (!data.ReadTitle(&out->title))
- return false;
- if (!data.ReadUrl(&out->url))
- return false;
- out->focus_id = data.focus_id();
- out->sel_is_backward = data.sel_is_backward();
- out->sel_anchor_object_id = data.sel_anchor_object_id();
- out->sel_anchor_offset = data.sel_anchor_offset();
- out->sel_anchor_affinity = data.sel_anchor_affinity();
- out->sel_focus_object_id = data.sel_focus_object_id();
- out->sel_focus_offset = data.sel_focus_offset();
- out->sel_focus_affinity = data.sel_focus_affinity();
- out->root_scroller_id = data.root_scroller_id();
- return true;
-}
-
-} // namespace mojo
diff --git a/third_party/accessibility/ax/mojom/ax_tree_data_mojom_traits.h b/third_party/accessibility/ax/mojom/ax_tree_data_mojom_traits.h
deleted file mode 100644
index 043bb74..0000000
--- a/third_party/accessibility/ax/mojom/ax_tree_data_mojom_traits.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_MOJOM_AX_TREE_DATA_MOJOM_TRAITS_H_
-#define UI_ACCESSIBILITY_MOJOM_AX_TREE_DATA_MOJOM_TRAITS_H_
-
-#include "ui/accessibility/ax_tree_data.h"
-#include "ui/accessibility/mojom/ax_tree_data.mojom-shared.h"
-#include "ui/accessibility/mojom/ax_tree_id_mojom_traits.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<ax::mojom::AXTreeDataDataView, ui::AXTreeData> {
- static const ui::AXTreeID& tree_id(const ui::AXTreeData& p) {
- return p.tree_id;
- }
- static const ui::AXTreeID& parent_tree_id(const ui::AXTreeData& p) {
- return p.parent_tree_id;
- }
- static const ui::AXTreeID& focused_tree_id(const ui::AXTreeData& p) {
- return p.focused_tree_id;
- }
- static const std::string& doctype(const ui::AXTreeData& p) {
- return p.doctype;
- }
- static bool loaded(const ui::AXTreeData& p) { return p.loaded; }
- static float loading_progress(const ui::AXTreeData& p) {
- return p.loading_progress;
- }
- static const std::string& mimetype(const ui::AXTreeData& p) {
- return p.mimetype;
- }
- static const std::string& title(const ui::AXTreeData& p) { return p.title; }
- static const std::string& url(const ui::AXTreeData& p) { return p.url; }
- static int32_t focus_id(const ui::AXTreeData& p) { return p.focus_id; }
- static bool sel_is_backward(const ui::AXTreeData& p) {
- return p.sel_is_backward;
- }
- static int32_t sel_anchor_object_id(const ui::AXTreeData& p) {
- return p.sel_anchor_object_id;
- }
- static int32_t sel_anchor_offset(const ui::AXTreeData& p) {
- return p.sel_anchor_offset;
- }
- static ax::mojom::TextAffinity sel_anchor_affinity(const ui::AXTreeData& p) {
- return p.sel_anchor_affinity;
- }
- static int32_t sel_focus_object_id(const ui::AXTreeData& p) {
- return p.sel_focus_object_id;
- }
- static int32_t sel_focus_offset(const ui::AXTreeData& p) {
- return p.sel_focus_offset;
- }
- static ax::mojom::TextAffinity sel_focus_affinity(const ui::AXTreeData& p) {
- return p.sel_focus_affinity;
- }
- static int32_t root_scroller_id(const ui::AXTreeData& p) {
- return p.root_scroller_id;
- }
-
- static bool Read(ax::mojom::AXTreeDataDataView data, ui::AXTreeData* out);
-};
-
-} // namespace mojo
-
-#endif // UI_ACCESSIBILITY_MOJOM_AX_TREE_DATA_MOJOM_TRAITS_H_
diff --git a/third_party/accessibility/ax/mojom/ax_tree_data_mojom_traits_unittest.cc b/third_party/accessibility/ax/mojom/ax_tree_data_mojom_traits_unittest.cc
deleted file mode 100644
index e36061e..0000000
--- a/third_party/accessibility/ax/mojom/ax_tree_data_mojom_traits_unittest.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_tree_data_mojom_traits.h"
-#include "mojo/public/cpp/test_support/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_tree_data.h"
-#include "ui/accessibility/mojom/ax_tree_data.mojom.h"
-
-using mojo::test::SerializeAndDeserialize;
-
-TEST(AXTreeDataMojomTraitsTest, TestSerializeAndDeserializeAXTreeData) {
- ui::AXTreeID tree_id_1 = ui::AXTreeID::CreateNewAXTreeID();
- ui::AXTreeID tree_id_2 = ui::AXTreeID::CreateNewAXTreeID();
- ui::AXTreeID tree_id_3 = ui::AXTreeID::CreateNewAXTreeID();
-
- ui::AXTreeData input, output;
- input.tree_id = tree_id_1;
- input.parent_tree_id = tree_id_2;
- input.focused_tree_id = tree_id_3;
- input.doctype = "4";
- input.loaded = true;
- input.loading_progress = 5;
- input.mimetype = "6";
- input.title = "7";
- input.url = "8";
- input.focus_id = 9;
- input.sel_is_backward = true; // Set to true only for testing purposes.
- input.sel_anchor_object_id = 10;
- input.sel_anchor_offset = 11;
- input.sel_anchor_affinity = ax::mojom::TextAffinity::kUpstream;
- input.sel_focus_object_id = 12;
- input.sel_focus_offset = 13;
- input.sel_focus_affinity = ax::mojom::TextAffinity::kDownstream;
- input.root_scroller_id = 14;
-
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXTreeData>(&input, &output));
-
- EXPECT_EQ(tree_id_1, output.tree_id);
- EXPECT_EQ(tree_id_2, output.parent_tree_id);
- EXPECT_EQ(tree_id_3, output.focused_tree_id);
- EXPECT_EQ("4", output.doctype);
- EXPECT_EQ(true, output.loaded);
- EXPECT_EQ(5, output.loading_progress);
- EXPECT_EQ("6", output.mimetype);
- EXPECT_EQ("7", output.title);
- EXPECT_EQ("8", output.url);
- EXPECT_EQ(9, output.focus_id);
- EXPECT_TRUE(output.sel_is_backward);
- EXPECT_EQ(10, output.sel_anchor_object_id);
- EXPECT_EQ(11, output.sel_anchor_offset);
- EXPECT_EQ(ax::mojom::TextAffinity::kUpstream, output.sel_anchor_affinity);
- EXPECT_EQ(12, output.sel_focus_object_id);
- EXPECT_EQ(13, output.sel_focus_offset);
- EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, output.sel_focus_affinity);
- EXPECT_EQ(14, output.root_scroller_id);
-}
diff --git a/third_party/accessibility/ax/mojom/ax_tree_id.mojom b/third_party/accessibility/ax/mojom/ax_tree_id.mojom
deleted file mode 100644
index 0f3c794..0000000
--- a/third_party/accessibility/ax/mojom/ax_tree_id.mojom
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module ax.mojom;
-
-import "ui/accessibility/ax_enums.mojom";
-import "mojo/public/mojom/base/unguessable_token.mojom";
-
-union AXTreeID {
- // Placeholder for an unknown AXTreeID. The value of this field is not used.
- uint8 unknown;
-
- // Any AXTreeID that's not unknown must be an UnguessableToken.
- mojo_base.mojom.UnguessableToken token;
-};
diff --git a/third_party/accessibility/ax/mojom/ax_tree_id_mojom_traits.cc b/third_party/accessibility/ax/mojom/ax_tree_id_mojom_traits.cc
deleted file mode 100644
index d801177..0000000
--- a/third_party/accessibility/ax/mojom/ax_tree_id_mojom_traits.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_tree_id_mojom_traits.h"
-
-namespace mojo {
-
-// static
-bool UnionTraits<ax::mojom::AXTreeIDDataView, ui::AXTreeID>::Read(
- ax::mojom::AXTreeIDDataView data,
- ui::AXTreeID* out) {
- switch (data.tag()) {
- case ax::mojom::AXTreeIDDataView::Tag::UNKNOWN:
- out->type_ = ax::mojom::AXTreeIDType::kUnknown;
- return true;
- case ax::mojom::AXTreeIDDataView::Tag::TOKEN:
- out->type_ = ax::mojom::AXTreeIDType::kToken;
- if (!data.ReadToken(&out->token_))
- return false;
- return true;
- }
-
- NOTREACHED();
- return false;
-}
-
-} // namespace mojo
diff --git a/third_party/accessibility/ax/mojom/ax_tree_id_mojom_traits.h b/third_party/accessibility/ax/mojom/ax_tree_id_mojom_traits.h
deleted file mode 100644
index 13fc696..0000000
--- a/third_party/accessibility/ax/mojom/ax_tree_id_mojom_traits.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_MOJOM_AX_TREE_ID_MOJOM_TRAITS_H_
-#define UI_ACCESSIBILITY_MOJOM_AX_TREE_ID_MOJOM_TRAITS_H_
-
-#include "mojo/public/cpp/base/unguessable_token_mojom_traits.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/accessibility/mojom/ax_tree_id.mojom-shared.h"
-
-namespace mojo {
-
-template <>
-struct UnionTraits<ax::mojom::AXTreeIDDataView, ui::AXTreeID> {
- static ax::mojom::AXTreeIDDataView::Tag GetTag(const ui::AXTreeID& p) {
- switch (p.type()) {
- case ax::mojom::AXTreeIDType::kUnknown:
- return ax::mojom::AXTreeIDDataView::Tag::UNKNOWN;
- case ax::mojom::AXTreeIDType::kToken:
- return ax::mojom::AXTreeIDDataView::Tag::TOKEN;
- }
- }
- static uint8_t unknown(const ui::AXTreeID& p) { return 0; }
- static const base::UnguessableToken token(const ui::AXTreeID& p) {
- DCHECK_EQ(p.type(), ax::mojom::AXTreeIDType::kToken);
- return *p.token();
- }
-
- static bool Read(ax::mojom::AXTreeIDDataView data, ui::AXTreeID* out);
-};
-
-} // namespace mojo
-
-#endif // UI_ACCESSIBILITY_MOJOM_AX_TREE_ID_MOJOM_TRAITS_H_
diff --git a/third_party/accessibility/ax/mojom/ax_tree_id_mojom_traits_unittest.cc b/third_party/accessibility/ax/mojom/ax_tree_id_mojom_traits_unittest.cc
deleted file mode 100644
index fadf6cc..0000000
--- a/third_party/accessibility/ax/mojom/ax_tree_id_mojom_traits_unittest.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_tree_id_mojom_traits.h"
-#include "mojo/public/cpp/test_support/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/accessibility/mojom/ax_tree_id.mojom.h"
-
-using mojo::test::SerializeAndDeserialize;
-
-TEST(AXTreeIDMojomTraitsTest, TestSerializeAndDeserializeAXTreeID) {
- ui::AXTreeID empty_input = ui::AXTreeID();
- ui::AXTreeID empty_output;
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXTreeID>(&empty_input,
- &empty_output));
- EXPECT_EQ(empty_input, empty_output);
- EXPECT_EQ("", empty_output.ToString());
-
- ui::AXTreeID unknown_input = ui::AXTreeIDUnknown();
- ui::AXTreeID unknown_output;
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXTreeID>(&unknown_input,
- &unknown_output));
- EXPECT_EQ(unknown_input, unknown_output);
- EXPECT_EQ("", unknown_output.ToString());
-
- ui::AXTreeID token_input = ui::AXTreeID::CreateNewAXTreeID();
- ui::AXTreeID token_output;
- EXPECT_TRUE(SerializeAndDeserialize<ax::mojom::AXTreeID>(&token_input,
- &token_output));
- EXPECT_EQ(token_input, token_output);
- // It should be a 32-char hex string.
- EXPECT_EQ(32U, token_output.ToString().size());
-}
diff --git a/third_party/accessibility/ax/mojom/ax_tree_update.mojom b/third_party/accessibility/ax/mojom/ax_tree_update.mojom
deleted file mode 100644
index 957edd5..0000000
--- a/third_party/accessibility/ax/mojom/ax_tree_update.mojom
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module ax.mojom;
-
-import "ui/accessibility/ax_enums.mojom";
-import "ui/accessibility/mojom/ax_event_intent.mojom";
-import "ui/accessibility/mojom/ax_node_data.mojom";
-import "ui/accessibility/mojom/ax_tree_data.mojom";
-
-// See ui::AXTreeUpdate for comments / explanations of these fields.
-struct AXTreeUpdate {
- bool has_tree_data;
- AXTreeData tree_data;
- int32 node_id_to_clear;
- int32 root_id;
- array<AXNodeData> nodes;
- ax.mojom.EventFrom event_from;
- array<EventIntent> event_intents;
-};
diff --git a/third_party/accessibility/ax/mojom/ax_tree_update_mojom_traits.cc b/third_party/accessibility/ax/mojom/ax_tree_update_mojom_traits.cc
deleted file mode 100644
index e429ce9..0000000
--- a/third_party/accessibility/ax/mojom/ax_tree_update_mojom_traits.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_tree_update_mojom_traits.h"
-
-namespace mojo {
-
-// static
-bool StructTraits<ax::mojom::AXTreeUpdateDataView, ui::AXTreeUpdate>::Read(
- ax::mojom::AXTreeUpdateDataView data,
- ui::AXTreeUpdate* out) {
- out->has_tree_data = data.has_tree_data();
- if (!data.ReadTreeData(&out->tree_data))
- return false;
- out->node_id_to_clear = data.node_id_to_clear();
- out->root_id = data.root_id();
- if (!data.ReadNodes(&out->nodes))
- return false;
- out->event_from = data.event_from();
- return data.ReadEventIntents(&out->event_intents);
-}
-
-} // namespace mojo
diff --git a/third_party/accessibility/ax/mojom/ax_tree_update_mojom_traits.h b/third_party/accessibility/ax/mojom/ax_tree_update_mojom_traits.h
deleted file mode 100644
index 480c07a..0000000
--- a/third_party/accessibility/ax/mojom/ax_tree_update_mojom_traits.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_MOJOM_AX_TREE_UPDATE_MOJOM_TRAITS_H_
-#define UI_ACCESSIBILITY_MOJOM_AX_TREE_UPDATE_MOJOM_TRAITS_H_
-
-#include "ui/accessibility/ax_event_intent.h"
-#include "ui/accessibility/ax_tree_update.h"
-#include "ui/accessibility/mojom/ax_event_intent.mojom.h"
-#include "ui/accessibility/mojom/ax_event_intent_mojom_traits.h"
-#include "ui/accessibility/mojom/ax_node_data_mojom_traits.h"
-#include "ui/accessibility/mojom/ax_tree_data_mojom_traits.h"
-#include "ui/accessibility/mojom/ax_tree_update.mojom-shared.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<ax::mojom::AXTreeUpdateDataView, ui::AXTreeUpdate> {
- static bool has_tree_data(const ui::AXTreeUpdate& p) {
- return p.has_tree_data;
- }
- static const ui::AXTreeData& tree_data(const ui::AXTreeUpdate& p) {
- return p.tree_data;
- }
- static int32_t node_id_to_clear(const ui::AXTreeUpdate& p) {
- return p.node_id_to_clear;
- }
- static int32_t root_id(const ui::AXTreeUpdate& p) { return p.root_id; }
- static const std::vector<ui::AXNodeData>& nodes(const ui::AXTreeUpdate& p) {
- return p.nodes;
- }
- static ax::mojom::EventFrom event_from(const ui::AXTreeUpdate& p) {
- return p.event_from;
- }
- static std::vector<ui::AXEventIntent> event_intents(
- const ui::AXTreeUpdate& p) {
- return p.event_intents;
- }
-
- static bool Read(ax::mojom::AXTreeUpdateDataView data, ui::AXTreeUpdate* out);
-};
-
-} // namespace mojo
-
-#endif // UI_ACCESSIBILITY_MOJOM_AX_TREE_UPDATE_MOJOM_TRAITS_H_
diff --git a/third_party/accessibility/ax/mojom/ax_tree_update_mojom_traits_unittest.cc b/third_party/accessibility/ax/mojom/ax_tree_update_mojom_traits_unittest.cc
deleted file mode 100644
index 18a83b4..0000000
--- a/third_party/accessibility/ax/mojom/ax_tree_update_mojom_traits_unittest.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/mojom/ax_tree_update_mojom_traits.h"
-#include "mojo/public/cpp/test_support/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_tree_update.h"
-#include "ui/accessibility/mojom/ax_relative_bounds_mojom_traits.h"
-#include "ui/accessibility/mojom/ax_tree_update.mojom.h"
-
-using mojo::test::SerializeAndDeserialize;
-
-TEST(AXTreeUpdateMojomTraitsTest, TestSerializeAndDeserializeAXTreeUpdate) {
- ui::AXTreeUpdate input, output;
- input.has_tree_data = true;
- input.tree_data.focus_id = 1;
- input.node_id_to_clear = 2;
- input.root_id = 3;
- input.nodes.resize(2);
- input.nodes[0].role = ax::mojom::Role::kButton;
- input.nodes[1].id = 4;
- input.event_from = ax::mojom::EventFrom::kUser;
- EXPECT_TRUE(
- SerializeAndDeserialize<ax::mojom::AXTreeUpdate>(&input, &output));
- EXPECT_EQ(true, output.has_tree_data);
- EXPECT_EQ(1, output.tree_data.focus_id);
- EXPECT_EQ(2, output.node_id_to_clear);
- EXPECT_EQ(3, output.root_id);
- ASSERT_EQ(2U, output.nodes.size());
- EXPECT_EQ(ax::mojom::Role::kButton, output.nodes[0].role);
- EXPECT_EQ(4, output.nodes[1].id);
- EXPECT_EQ(ax::mojom::EventFrom::kUser, output.event_from);
-}
diff --git a/third_party/accessibility/ax/null_ax_action_target.cc b/third_party/accessibility/ax/null_ax_action_target.cc
deleted file mode 100644
index 239f374..0000000
--- a/third_party/accessibility/ax/null_ax_action_target.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/null_ax_action_target.h"
-
-namespace ui {
-
-AXActionTarget::Type NullAXActionTarget::GetType() const {
- return AXActionTarget::Type::kNull;
-}
-
-bool NullAXActionTarget::ClearAccessibilityFocus() const {
- return false;
-}
-
-bool NullAXActionTarget::Click() const {
- return false;
-}
-
-bool NullAXActionTarget::Decrement() const {
- return false;
-}
-
-bool NullAXActionTarget::Increment() const {
- return false;
-}
-
-bool NullAXActionTarget::Focus() const {
- return false;
-}
-
-gfx::Rect NullAXActionTarget::GetRelativeBounds() const {
- return gfx::Rect();
-}
-
-gfx::Point NullAXActionTarget::GetScrollOffset() const {
- return gfx::Point();
-}
-
-gfx::Point NullAXActionTarget::MinimumScrollOffset() const {
- return gfx::Point();
-}
-
-gfx::Point NullAXActionTarget::MaximumScrollOffset() const {
- return gfx::Point();
-}
-
-bool NullAXActionTarget::SetAccessibilityFocus() const {
- return false;
-}
-
-void NullAXActionTarget::SetScrollOffset(const gfx::Point& point) const {}
-
-bool NullAXActionTarget::SetSelected(bool selected) const {
- return false;
-}
-
-bool NullAXActionTarget::SetSelection(const AXActionTarget* anchor_object,
- int anchor_offset,
- const AXActionTarget* focus_object,
- int focus_offset) const {
- return false;
-}
-
-bool NullAXActionTarget::SetSequentialFocusNavigationStartingPoint() const {
- return false;
-}
-
-bool NullAXActionTarget::SetValue(const std::string& value) const {
- return false;
-}
-
-bool NullAXActionTarget::ShowContextMenu() const {
- return false;
-}
-
-bool NullAXActionTarget::ScrollToMakeVisible() const {
- return false;
-}
-
-bool NullAXActionTarget::ScrollToMakeVisibleWithSubFocus(
- const gfx::Rect& rect,
- ax::mojom::ScrollAlignment horizontal_scroll_alignment,
- ax::mojom::ScrollAlignment vertical_scroll_alignment,
- ax::mojom::ScrollBehavior scroll_behavior) const {
- return false;
-}
-
-bool NullAXActionTarget::ScrollToGlobalPoint(const gfx::Point& point) const {
- return false;
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/null_ax_action_target.h b/third_party/accessibility/ax/null_ax_action_target.h
deleted file mode 100644
index fd55809..0000000
--- a/third_party/accessibility/ax/null_ax_action_target.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_NULL_AX_ACTION_TARGET_H_
-#define UI_ACCESSIBILITY_NULL_AX_ACTION_TARGET_H_
-
-#include "ui/accessibility/ax_action_target.h"
-#include "ui/accessibility/ax_export.h"
-
-namespace ui {
-
-// A do-nothing action target.
-class AX_EXPORT NullAXActionTarget : public AXActionTarget {
- public:
- NullAXActionTarget() = default;
- ~NullAXActionTarget() override = default;
-
- protected:
- // AXActionTarget overrides.
- Type GetType() const override;
- bool ClearAccessibilityFocus() const override;
- bool Click() const override;
- bool Decrement() const override;
- bool Increment() const override;
- bool Focus() const override;
- gfx::Rect GetRelativeBounds() const override;
- gfx::Point GetScrollOffset() const override;
- gfx::Point MinimumScrollOffset() const override;
- gfx::Point MaximumScrollOffset() const override;
- bool SetAccessibilityFocus() const override;
- void SetScrollOffset(const gfx::Point& point) const override;
- bool SetSelected(bool selected) const override;
- bool SetSelection(const AXActionTarget* anchor_object,
- int anchor_offset,
- const AXActionTarget* focus_object,
- int focus_offset) const override;
- bool SetSequentialFocusNavigationStartingPoint() const override;
- bool SetValue(const std::string& value) const override;
- bool ShowContextMenu() const override;
- bool ScrollToMakeVisible() const override;
- bool ScrollToMakeVisibleWithSubFocus(
- const gfx::Rect& rect,
- ax::mojom::ScrollAlignment horizontal_scroll_alignment,
- ax::mojom::ScrollAlignment vertical_scroll_alignment,
- ax::mojom::ScrollBehavior scroll_behavior) const override;
- bool ScrollToGlobalPoint(const gfx::Point& point) const override;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_NULL_AX_ACTION_TARGET_H_
diff --git a/third_party/accessibility/ax/null_ax_action_target_unittest.cc b/third_party/accessibility/ax/null_ax_action_target_unittest.cc
deleted file mode 100644
index 13a51f9..0000000
--- a/third_party/accessibility/ax/null_ax_action_target_unittest.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/null_ax_action_target.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-
-namespace ui {
-
-TEST(NullAXActionTargetTest, TestMethods) {
- std::unique_ptr<AXActionTarget> action_target =
- std::make_unique<NullAXActionTarget>();
-
- EXPECT_EQ(AXActionTarget::Type::kNull, action_target->GetType());
- EXPECT_FALSE(action_target->ClearAccessibilityFocus());
- EXPECT_FALSE(action_target->Click());
- EXPECT_FALSE(action_target->Decrement());
- EXPECT_FALSE(action_target->Increment());
- EXPECT_FALSE(action_target->Focus());
- EXPECT_EQ(gfx::Rect(), action_target->GetRelativeBounds());
- EXPECT_EQ(gfx::Point(), action_target->GetScrollOffset());
- EXPECT_EQ(gfx::Point(), action_target->MinimumScrollOffset());
- EXPECT_EQ(gfx::Point(), action_target->MaximumScrollOffset());
- EXPECT_FALSE(action_target->SetAccessibilityFocus());
- EXPECT_FALSE(action_target->SetSelected(false));
- EXPECT_FALSE(action_target->SetSelection(nullptr, 0, nullptr, 0));
- EXPECT_FALSE(action_target->SetSequentialFocusNavigationStartingPoint());
- EXPECT_FALSE(action_target->SetValue(""));
- EXPECT_FALSE(action_target->ShowContextMenu());
- EXPECT_FALSE(action_target->ScrollToMakeVisible());
- EXPECT_FALSE(action_target->ScrollToMakeVisibleWithSubFocus(
- gfx::Rect(), ax::mojom::ScrollAlignment::kScrollAlignmentCenter,
- ax::mojom::ScrollAlignment::kScrollAlignmentCenter,
- ax::mojom::ScrollBehavior::kDoNotScrollIfVisible));
- EXPECT_FALSE(action_target->ScrollToGlobalPoint(gfx::Point()));
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/BUILD.gn b/third_party/accessibility/ax/platform/BUILD.gn
deleted file mode 100644
index 732f9af..0000000
--- a/third_party/accessibility/ax/platform/BUILD.gn
+++ /dev/null
@@ -1,141 +0,0 @@
-# Copyright 2020 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/features.gni")
-import("//build/config/linux/pkg_config.gni")
-import("//build/config/ui.gni")
-import("//mojo/public/tools/bindings/mojom.gni")
-import("//testing/libfuzzer/fuzzer_test.gni")
-import("//testing/test.gni")
-import("//tools/json_schema_compiler/json_schema_api.gni")
-import("//ui/base/ui_features.gni")
-
-if (is_win) {
- import("//build/toolchain/win/midl.gni")
-}
-
-if (is_win) {
- midl("ichromeaccessible") {
- sources = [ "ichromeaccessible.idl" ]
- }
-}
-
-if (is_android) {
- import("//build/config/android/rules.gni")
-}
-
-source_set("platform") {
- defines = [ "AX_IMPLEMENTATION" ]
-
- visibility = [ "//ui/accessibility" ]
-
- sources = [
- # Used by by browser_accessibility_state_impl.cc.
- "ax_platform_node.cc",
- "ax_platform_node.h",
- "ax_platform_node_delegate.h",
-
- # Used by browser_accessibility.cc.
- "ax_unique_id.cc",
- "ax_unique_id.h",
-
- # Used by accessibility_tree_formatter_blink.cc.
- "compute_attributes.cc",
- "compute_attributes.h",
-
- # Used by //ui/accessibility:ax_assistant.
- "ax_android_constants.cc",
- "ax_android_constants.h",
-
- # Used by //ui/views/views/ax_virtual_view.h.
- "ax_platform_node_base.cc",
- "ax_platform_node_base.h",
- "ax_platform_node_delegate_base.cc",
- "ax_platform_node_delegate_base.h",
-
- # Used by //chrome/test/browser_tests/browser_view_browsertest.cc
- "ax_platform_node_test_helper.cc",
- "ax_platform_node_test_helper.h",
- ]
-
- public_deps = [
- "//ui/accessibility:ax_base",
- "//ui/display",
- ]
-
- if (has_native_accessibility) {
- sources += [
- "ax_fragment_root_delegate_win.h",
- "ax_fragment_root_win.cc",
- "ax_fragment_root_win.h",
- "ax_platform_node_delegate_utils_win.cc",
- "ax_platform_node_delegate_utils_win.h",
- "ax_platform_node_textchildprovider_win.cc",
- "ax_platform_node_textchildprovider_win.h",
- "ax_platform_node_textprovider_win.cc",
- "ax_platform_node_textprovider_win.h",
- "ax_platform_node_textrangeprovider_win.cc",
- "ax_platform_node_textrangeprovider_win.h",
- "ax_platform_node_win.cc",
- "ax_platform_node_win.h",
- "ax_platform_relation_win.cc",
- "ax_platform_relation_win.h",
- "ax_platform_text_boundary.cc",
- "ax_platform_text_boundary.h",
- "ax_system_caret_win.cc",
- "ax_system_caret_win.h",
- "uia_registrar_win.cc",
- "uia_registrar_win.h",
- ]
-
- if (is_win) {
- public_deps += [
- "//third_party/iaccessible2",
- "//ui/accessibility/platform:ichromeaccessible",
- ]
-
- libs = [
- "oleacc.lib",
- "uiautomationcore.lib",
- ]
- }
-
- if (is_mac) {
- sources += [
- "ax_platform_node_mac.h",
- "ax_platform_node_mac.mm",
- ]
-
- frameworks = [
- "AppKit.framework",
- "Foundation.framework",
- ]
- }
-
- if (use_atk) {
- sources += [
- "atk_util_auralinux.cc",
- "atk_util_auralinux.h",
- "atk_util_auralinux_gtk.cc",
- "ax_platform_atk_hyperlink.cc",
- "ax_platform_atk_hyperlink.h",
- "ax_platform_node_auralinux.cc",
- "ax_platform_node_auralinux.h",
- ]
-
- # ax_platform_text_boundary.h includes atk.h, so ATK is needed
- # as a public config to ensure anything that includes this is
- # able to find atk.h.
- public_configs = [ "//build/config/linux/atk" ]
-
- if (use_glib) {
- configs += [ "//build/config/linux:glib" ]
- }
-
- if (use_x11) {
- public_deps += [ "//ui/gfx/x" ]
- }
- }
- }
-}
diff --git a/third_party/accessibility/ax/platform/OWNERS b/third_party/accessibility/ax/platform/OWNERS
deleted file mode 100644
index aa76e7d..0000000
--- a/third_party/accessibility/ax/platform/OWNERS
+++ /dev/null
@@ -1,14 +0,0 @@
-# For ATK / AuraLinux
-jdiggs@igalia.com
-mrobinson@igalia.com
-
-# For Windows / UIA
-per-file *_win*=kschmi@microsoft.com
-per-file *_win*=kbabbitt@microsoft.com
-per-file *_win*=iapres@microsoft.com
-per-file *_base*=kschmi@microsoft.com
-per-file *_base*=kbabbitt@microsoft.com
-per-file *_base*=iapres@microsoft.com
-per-file *test*=kschmi@microsoft.com
-per-file *test*=kbabbitt@microsoft.com
-per-file *test*=iapres@microsoft.com
diff --git a/third_party/accessibility/ax/platform/atk_util_auralinux.cc b/third_party/accessibility/ax/platform/atk_util_auralinux.cc
deleted file mode 100644
index d8021d7..0000000
--- a/third_party/accessibility/ax/platform/atk_util_auralinux.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <atk/atk.h>
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-
-#include "base/environment.h"
-#include "base/memory/singleton.h"
-#include "base/no_destructor.h"
-#include "ui/accessibility/platform/atk_util_auralinux.h"
-#include "ui/accessibility/platform/ax_platform_node.h"
-#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
-
-namespace {
-
-const char* kAccessibilityEnabledVariables[] = {
- "ACCESSIBILITY_ENABLED",
- "GNOME_ACCESSIBILITY",
- "QT_ACCESSIBILITY",
-};
-
-//
-// AtkUtilAuraLinux definition and implementation.
-//
-struct AtkUtilAuraLinux {
- AtkUtil parent;
-};
-
-struct AtkUtilAuraLinuxClass {
- AtkUtilClass parent_class;
-};
-
-G_DEFINE_TYPE(AtkUtilAuraLinux, atk_util_auralinux, ATK_TYPE_UTIL)
-
-static void atk_util_auralinux_init(AtkUtilAuraLinux* ax_util) {}
-
-static AtkObject* AtkUtilAuraLinuxGetRoot() {
- ui::AXPlatformNode* application = ui::AXPlatformNodeAuraLinux::application();
- if (application) {
- return application->GetNativeViewAccessible();
- }
- return nullptr;
-}
-
-using KeySnoopFuncMap = std::map<guint, std::pair<AtkKeySnoopFunc, gpointer>>;
-static KeySnoopFuncMap& GetActiveKeySnoopFunctions() {
- static base::NoDestructor<KeySnoopFuncMap> active_key_snoop_functions;
- return *active_key_snoop_functions;
-}
-
-using AXPlatformNodeSet = std::set<ui::AXPlatformNodeAuraLinux*>;
-static AXPlatformNodeSet& GetNodesWithPostponedEvents() {
- static base::NoDestructor<AXPlatformNodeSet> nodes_with_postponed_events_list;
- return *nodes_with_postponed_events_list;
-}
-
-static void RunPostponedEvents() {
- for (ui::AXPlatformNodeAuraLinux* entry : GetNodesWithPostponedEvents()) {
- entry->RunPostponedEvents();
- }
- GetNodesWithPostponedEvents().clear();
-}
-
-static guint AtkUtilAuraLinuxAddKeyEventListener(
- AtkKeySnoopFunc key_snoop_function,
- gpointer data) {
- static guint current_key_event_listener_id = 0;
-
- // AtkUtilAuraLinuxAddKeyEventListener is called by
- // spi_atk_register_event_listeners in the at-spi2-atk library after it has
- // initialized all its other listeners. Our internal knowledge of the
- // internals of the AT-SPI/ATK bridge allows us to use this call as an
- // indication of AT-SPI being ready, so we can finally run any events that had
- // been waiting.
- ui::AtkUtilAuraLinux::GetInstance()->SetAtSpiReady(true);
-
- current_key_event_listener_id++;
- GetActiveKeySnoopFunctions()[current_key_event_listener_id] =
- std::make_pair(key_snoop_function, data);
- return current_key_event_listener_id;
-}
-
-static void AtkUtilAuraLinuxRemoveKeyEventListener(guint listener_id) {
- GetActiveKeySnoopFunctions().erase(listener_id);
-}
-
-static void atk_util_auralinux_class_init(AtkUtilAuraLinuxClass* klass) {
- AtkUtilClass* atk_class = ATK_UTIL_CLASS(g_type_class_peek(ATK_TYPE_UTIL));
-
- atk_class->get_root = AtkUtilAuraLinuxGetRoot;
- atk_class->get_toolkit_name = []() { return "Chromium"; };
- atk_class->get_toolkit_version = []() { return "1.0"; };
- atk_class->add_key_event_listener = AtkUtilAuraLinuxAddKeyEventListener;
- atk_class->remove_key_event_listener = AtkUtilAuraLinuxRemoveKeyEventListener;
-}
-
-} // namespace
-
-namespace ui {
-
-// static
-AtkUtilAuraLinux* AtkUtilAuraLinux::GetInstance() {
- return base::Singleton<AtkUtilAuraLinux>::get();
-}
-
-bool AtkUtilAuraLinux::ShouldEnableAccessibility() {
- std::unique_ptr<base::Environment> env(base::Environment::Create());
- for (const auto* variable : kAccessibilityEnabledVariables) {
- std::string enable_accessibility;
- env->GetVar(variable, &enable_accessibility);
- if (enable_accessibility == "1")
- return true;
- }
-
- return false;
-}
-
-void AtkUtilAuraLinux::InitializeAsync() {
- static bool initialized = false;
-
- if (initialized || !ShouldEnableAccessibility())
- return;
-
- initialized = true;
-
- // Register our util class.
- g_type_class_unref(g_type_class_ref(atk_util_auralinux_get_type()));
-
- PlatformInitializeAsync();
-}
-
-void AtkUtilAuraLinux::InitializeForTesting() {
- std::unique_ptr<base::Environment> env(base::Environment::Create());
- env->SetVar(kAccessibilityEnabledVariables[0], "1");
-
- InitializeAsync();
-}
-
-// static
-// Disable CFI-icall since the key snooping function could be in another DSO.
-__attribute__((no_sanitize("cfi-icall"))) DiscardAtkKeyEvent
-AtkUtilAuraLinux::HandleAtkKeyEvent(AtkKeyEventStruct* key_event) {
- DCHECK(key_event);
-
- if (!ui::AXPlatformNode::GetAccessibilityMode().has_mode(
- ui::AXMode::kNativeAPIs))
- return DiscardAtkKeyEvent::Retain;
-
- GetInstance()->InitializeAsync();
-
- bool discard = false;
- for (auto& entry : GetActiveKeySnoopFunctions()) {
- AtkKeySnoopFunc key_snoop_function = entry.second.first;
- gpointer data = entry.second.second;
-
- // We want to ensure that all functions are called. We will discard this
- // event if at least one function suggests that we do it, but we still
- // need to call the functions that follow it in the map iterator.
- if (key_snoop_function(key_event, data) != 0)
- discard = true;
- }
- return discard ? DiscardAtkKeyEvent::Discard : DiscardAtkKeyEvent::Retain;
-}
-
-bool AtkUtilAuraLinux::IsAtSpiReady() {
- return at_spi_ready_;
-}
-
-void AtkUtilAuraLinux::SetAtSpiReady(bool ready) {
- at_spi_ready_ = ready;
- if (ready)
- RunPostponedEvents();
-}
-
-void AtkUtilAuraLinux::PostponeEventsFor(AXPlatformNodeAuraLinux* node) {
- GetNodesWithPostponedEvents().insert(node);
-}
-
-void AtkUtilAuraLinux::CancelPostponedEventsFor(AXPlatformNodeAuraLinux* node) {
- GetNodesWithPostponedEvents().erase(node);
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/atk_util_auralinux.h b/third_party/accessibility/ax/platform/atk_util_auralinux.h
deleted file mode 100644
index e0e8ba6..0000000
--- a/third_party/accessibility/ax/platform/atk_util_auralinux.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_ATK_UTIL_AURALINUX_H_
-#define UI_ACCESSIBILITY_PLATFORM_ATK_UTIL_AURALINUX_H_
-
-#include <atk/atk.h>
-
-#include "base/macros.h"
-#include "base/memory/singleton.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
-
-namespace ui {
-
-// These values are duplicates of the GDK values that can be found in
-// <gdk/gdktypes.h>. ATK expects the GDK values, but we don't want to depend on
-// GDK here.
-typedef enum {
- kAtkShiftMask = 1 << 0,
- kAtkLockMask = 1 << 1,
- kAtkControlMask = 1 << 2,
- kAtkMod1Mask = 1 << 3,
- kAtkMod2Mask = 1 << 4,
- kAtkMod3Mask = 1 << 5,
- kAtkMod4Mask = 1 << 6,
- KAtkMod5Mask = 1 << 7,
-} AtkKeyModifierMask;
-
-enum DiscardAtkKeyEvent { Discard, Retain };
-
-// This singleton class initializes ATK (accessibility toolkit) and
-// registers an implementation of the AtkUtil class, a global class that
-// every accessible application needs to register once.
-class AX_EXPORT AtkUtilAuraLinux {
- public:
- // Get the single instance of this class.
- static AtkUtilAuraLinux* GetInstance();
-
- AtkUtilAuraLinux() = default;
-
- void InitializeAsync();
- void InitializeForTesting();
-
- bool IsAtSpiReady();
- void SetAtSpiReady(bool ready);
-
- // Nodes with postponed events will get the function RunPostponedEvents()
- // called as soon as AT-SPI is detected to be ready
- void PostponeEventsFor(AXPlatformNodeAuraLinux* node);
-
- void CancelPostponedEventsFor(AXPlatformNodeAuraLinux* node);
-
- static DiscardAtkKeyEvent HandleAtkKeyEvent(AtkKeyEventStruct* key_event);
-
- private:
- friend struct base::DefaultSingletonTraits<AtkUtilAuraLinux>;
-
- bool ShouldEnableAccessibility();
-
- void PlatformInitializeAsync();
-
- bool at_spi_ready_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(AtkUtilAuraLinux);
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_ATK_UTIL_AURALINUX_H_
diff --git a/third_party/accessibility/ax/platform/atk_util_auralinux_gtk.cc b/third_party/accessibility/ax/platform/atk_util_auralinux_gtk.cc
deleted file mode 100644
index fde59b2..0000000
--- a/third_party/accessibility/ax/platform/atk_util_auralinux_gtk.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <atk-bridge.h>
-
-#include "base/environment.h"
-#include "ui/accessibility/platform/atk_util_auralinux.h"
-
-namespace ui {
-
-void AtkUtilAuraLinux::PlatformInitializeAsync() {
- // AT bridge enabling was disabled before loading GTK to avoid
- // getting GTK implementation ATK root.
- std::unique_ptr<base::Environment> env(base::Environment::Create());
- env->UnSetVar("NO_AT_BRIDGE");
- atk_bridge_adaptor_init(nullptr, nullptr);
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/atk_util_auralinux_unittest.cc b/third_party/accessibility/ax/platform/atk_util_auralinux_unittest.cc
deleted file mode 100644
index 11342de..0000000
--- a/third_party/accessibility/ax/platform/atk_util_auralinux_unittest.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <atk/atk.h>
-
-#include <string>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/platform/atk_util_auralinux.h"
-#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
-#include "ui/accessibility/platform/ax_platform_node_unittest.h"
-#include "ui/accessibility/platform/test_ax_node_wrapper.h"
-
-namespace ui {
-
-class AtkUtilAuraLinuxTest : public AXPlatformNodeTest {
- public:
- AtkUtilAuraLinuxTest() {
- AXPlatformNode::NotifyAddAXModeFlags(kAXModeComplete);
- // We need to create a platform node in order to install it as the root
- // ATK node. The ATK bridge will complain if we try to use it without a
- // root node installed.
- AXNodeData root;
- root.id = 1;
- Init(root);
-
- TestAXNodeWrapper* wrapper =
- TestAXNodeWrapper::GetOrCreate(GetTree(), GetRootAsAXNode());
- if (!wrapper)
- NOTREACHED();
- AXPlatformNodeAuraLinux::SetApplication(wrapper->ax_platform_node());
-
- AtkUtilAuraLinux::GetInstance()->InitializeForTesting();
- }
-
- ~AtkUtilAuraLinuxTest() override {
- TestAXNodeWrapper* wrapper =
- TestAXNodeWrapper::GetOrCreate(GetTree(), GetRootAsAXNode());
- if (!wrapper)
- NOTREACHED();
- g_object_unref(wrapper->ax_platform_node()->GetNativeViewAccessible());
- }
-
- AtkUtilAuraLinuxTest(const AtkUtilAuraLinuxTest&) = delete;
- AtkUtilAuraLinuxTest& operator=(const AtkUtilAuraLinuxTest&) = delete;
-};
-
-TEST_F(AtkUtilAuraLinuxTest, KeySnooping) {
- AtkKeySnoopFunc key_snoop_func = reinterpret_cast<AtkKeySnoopFunc>(
- +[](AtkKeyEventStruct* key_event, int* keyval_seen) {
- *keyval_seen = key_event->keyval;
- });
-
- int keyval_seen = 0;
- guint listener_id = atk_add_key_event_listener(key_snoop_func, &keyval_seen);
-
- AtkKeyEventStruct atk_key_event;
- atk_key_event.type = ATK_KEY_EVENT_PRESS;
- atk_key_event.state = 0;
- atk_key_event.keyval = 55;
- atk_key_event.keycode = 10;
- atk_key_event.timestamp = 10;
- atk_key_event.string = nullptr;
- atk_key_event.length = 0;
-
- AtkUtilAuraLinux* atk_util = AtkUtilAuraLinux::GetInstance();
- atk_util->HandleAtkKeyEvent(&atk_key_event);
- // AX mode is enabled and Key snooping works.
- EXPECT_EQ(keyval_seen, 55);
-
- TestAXNodeWrapper* wrapper =
- TestAXNodeWrapper::GetOrCreate(GetTree(), GetRootAsAXNode());
- DCHECK(wrapper);
- AXMode prev_mode = wrapper->ax_platform_node()->ax_mode_;
- // Disables AX mode.
- wrapper->ax_platform_node()->ax_mode_ = 0;
- keyval_seen = 0;
- atk_util->HandleAtkKeyEvent(&atk_key_event);
- // When AX mode is not enabled, Key snooping doesn't work.
- EXPECT_EQ(keyval_seen, 0);
-
- // Restores the previous AX mode.
- wrapper->ax_platform_node()->ax_mode_ = prev_mode;
- keyval_seen = 0;
- atk_util->HandleAtkKeyEvent(&atk_key_event);
- // AX mode is set again, Key snooping works.
- EXPECT_EQ(keyval_seen, 55);
-
- atk_remove_key_event_listener(listener_id);
-
- keyval_seen = 0;
- atk_util->HandleAtkKeyEvent(&atk_key_event);
-
- EXPECT_EQ(keyval_seen, 0);
-}
-
-TEST_F(AtkUtilAuraLinuxTest, AtSpiReady) {
- AtkUtilAuraLinux* atk_util = AtkUtilAuraLinux::GetInstance();
-
- EXPECT_FALSE(atk_util->IsAtSpiReady());
-
- // In a normal browser execution, when a key event listener is added it means
- // the AT-SPI bridge has done it as part of its initialization, so it is set
- // as enabled.
- AtkKeySnoopFunc key_snoop_func =
- reinterpret_cast<AtkKeySnoopFunc>(+[](AtkKeyEventStruct* key_event) {});
- atk_add_key_event_listener(key_snoop_func, nullptr);
-
- EXPECT_TRUE(atk_util->IsAtSpiReady());
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_android_constants.cc b/third_party/accessibility/ax/platform/ax_android_constants.cc
deleted file mode 100644
index f3f350c..0000000
--- a/third_party/accessibility/ax/platform/ax_android_constants.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_android_constants.h"
-
-namespace ui {
-
-const char kAXAbsListViewClassname[] = "android.widget.AbsListView";
-const char kAXButtonClassname[] = "android.widget.Button";
-const char kAXCheckBoxClassname[] = "android.widget.CheckBox";
-const char kAXCheckedTextViewClassname[] = " android.widget.CheckedTextView";
-const char kAXCompoundButtonClassname[] = "android.widget.CompoundButton";
-const char kAXDialogClassname[] = "android.app.Dialog";
-const char kAXEditTextClassname[] = "android.widget.EditText";
-const char kAXGridViewClassname[] = "android.widget.GridView";
-const char kAXHorizontalScrollViewClassname[] =
- "android.widget.HorizontalScrollView";
-const char kAXImageClassname[] = "android.widget.Image";
-const char kAXImageButtonClassname[] = "android.widget.ImageButton";
-const char kAXImageViewClassname[] = "android.widget.ImageView";
-const char kAXListViewClassname[] = "android.widget.ListView";
-const char kAXMenuItemClassname[] = "android.view.MenuItem";
-const char kAXPagerClassname[] = "android.support.v4.view.ViewPager";
-const char kAXProgressBarClassname[] = "android.widget.ProgressBar";
-const char kAXRadioButtonClassname[] = "android.widget.RadioButton";
-const char kAXScrollViewClassname[] = "android.widget.ScrollView";
-const char kAXSeekBarClassname[] = "android.widget.SeekBar";
-const char kAXSpinnerClassname[] = "android.widget.Spinner";
-const char kAXSwitchClassname[] = "android.widget.Switch";
-const char kAXTabWidgetClassname[] = "android.widget.TabWidget";
-const char kAXTextViewClassname[] = "android.widget.TextView";
-const char kAXToggleButtonClassname[] = "android.widget.ToggleButton";
-const char kAXViewClassname[] = "android.view.View";
-const char kAXViewGroupClassname[] = "android.view.ViewGroup";
-const char kAXWebViewClassname[] = "android.webkit.WebView";
-const base::char16 kSecurePasswordBullet = 0x2022;
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_android_constants.h b/third_party/accessibility/ax/platform/ax_android_constants.h
deleted file mode 100644
index a224e22..0000000
--- a/third_party/accessibility/ax/platform/ax_android_constants.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_ANDROID_CONSTANTS_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_ANDROID_CONSTANTS_H_
-
-#include "base/strings/string16.h"
-#include "ui/accessibility/ax_export.h"
-
-namespace ui {
-
-// Classnames.
-
-AX_EXPORT extern const char kAXAbsListViewClassname[];
-AX_EXPORT extern const char kAXButtonClassname[];
-AX_EXPORT extern const char kAXCheckBoxClassname[];
-AX_EXPORT extern const char kAXCompoundButtonClassname[];
-AX_EXPORT extern const char kAXCheckedTextViewClassname[];
-AX_EXPORT extern const char kAXDialogClassname[];
-AX_EXPORT extern const char kAXEditTextClassname[];
-AX_EXPORT extern const char kAXGridViewClassname[];
-AX_EXPORT extern const char kAXHorizontalScrollViewClassname[];
-AX_EXPORT extern const char kAXImageClassname[];
-AX_EXPORT extern const char kAXImageButtonClassname[];
-AX_EXPORT extern const char kAXImageViewClassname[];
-AX_EXPORT extern const char kAXListViewClassname[];
-AX_EXPORT extern const char kAXMenuItemClassname[];
-AX_EXPORT extern const char kAXPagerClassname[];
-AX_EXPORT extern const char kAXProgressBarClassname[];
-AX_EXPORT extern const char kAXRadioButtonClassname[];
-AX_EXPORT extern const char kAXScrollViewClassname[];
-AX_EXPORT extern const char kAXSeekBarClassname[];
-AX_EXPORT extern const char kAXSwitchClassname[];
-AX_EXPORT extern const char kAXSpinnerClassname[];
-AX_EXPORT extern const char kAXTabWidgetClassname[];
-AX_EXPORT extern const char kAXTextViewClassname[];
-AX_EXPORT extern const char kAXToggleButtonClassname[];
-AX_EXPORT extern const char kAXViewClassname[];
-AX_EXPORT extern const char kAXViewGroupClassname[];
-AX_EXPORT extern const char kAXWebViewClassname[];
-AX_EXPORT extern const base::char16 kSecurePasswordBullet;
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_ANDROID_CONSTANTS_H_
diff --git a/third_party/accessibility/ax/platform/ax_fragment_root_delegate_win.h b/third_party/accessibility/ax/platform/ax_fragment_root_delegate_win.h
deleted file mode 100644
index 628607a..0000000
--- a/third_party/accessibility/ax/platform/ax_fragment_root_delegate_win.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_FRAGMENT_ROOT_DELEGATE_WIN_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_FRAGMENT_ROOT_DELEGATE_WIN_H_
-
-#include "ui/gfx/native_widget_types.h"
-
-namespace ui {
-
-// Delegate interface for clients of AXFragmentRootWin. This allows the client
-// to relate the fragment root to its neighbors in a loosely coupled way.
-class AXFragmentRootDelegateWin {
- public:
- // In our design, a fragment root can have at most one child.
- // See AXFragmentRootWin for more details.
- virtual gfx::NativeViewAccessible GetChildOfAXFragmentRoot() = 0;
-
- // Optionally returns a parent node for the fragment root. This is used, for
- // example, to place the web content fragment at the correct spot in the
- // browser UI's accessibility tree.
- // If a fragment root returns no parent, the OS will use HWND parent-child
- // relationships to establish the fragment root's location in the tree.
- virtual gfx::NativeViewAccessible GetParentOfAXFragmentRoot() = 0;
-
- // Return true if the window should be treated as an accessible control or
- // false if the window should be considered a structural detail that should
- // not be exposed to assistive technology users. See AXFragmentRootWin for
- // more details.
- virtual bool IsAXFragmentRootAControlElement() = 0;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_FRAGMENT_ROOT_DELEGATE_WIN_H_
diff --git a/third_party/accessibility/ax/platform/ax_fragment_root_win.cc b/third_party/accessibility/ax/platform/ax_fragment_root_win.cc
deleted file mode 100644
index ea4544e..0000000
--- a/third_party/accessibility/ax/platform/ax_fragment_root_win.cc
+++ /dev/null
@@ -1,444 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_fragment_root_win.h"
-
-#include <unordered_map>
-
-#include "base/no_destructor.h"
-#include "base/strings/string_number_conversions.h"
-#include "ui/accessibility/platform/ax_fragment_root_delegate_win.h"
-#include "ui/accessibility/platform/ax_platform_node_win.h"
-#include "ui/accessibility/platform/uia_registrar_win.h"
-#include "ui/base/win/atl_module.h"
-
-namespace ui {
-
-class AXFragmentRootPlatformNodeWin : public AXPlatformNodeWin,
- public IItemContainerProvider,
- public IRawElementProviderFragmentRoot,
- public IRawElementProviderAdviseEvents {
- public:
- BEGIN_COM_MAP(AXFragmentRootPlatformNodeWin)
- COM_INTERFACE_ENTRY(IItemContainerProvider)
- COM_INTERFACE_ENTRY(IRawElementProviderFragmentRoot)
- COM_INTERFACE_ENTRY(IRawElementProviderAdviseEvents)
- COM_INTERFACE_ENTRY_CHAIN(AXPlatformNodeWin)
- END_COM_MAP()
-
- static AXFragmentRootPlatformNodeWin* Create(
- AXPlatformNodeDelegate* delegate) {
- // Make sure ATL is initialized in this module.
- win::CreateATLModuleIfNeeded();
-
- CComObject<AXFragmentRootPlatformNodeWin>* instance = nullptr;
- HRESULT hr =
- CComObject<AXFragmentRootPlatformNodeWin>::CreateInstance(&instance);
- DCHECK(SUCCEEDED(hr));
- instance->Init(delegate);
- instance->AddRef();
- return instance;
- }
-
- //
- // IItemContainerProvider methods.
- //
- IFACEMETHODIMP FindItemByProperty(
- IRawElementProviderSimple* start_after_element,
- PROPERTYID property_id,
- VARIANT value,
- IRawElementProviderSimple** result) override {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ITEMCONTAINER_FINDITEMBYPROPERTY);
- UIA_VALIDATE_CALL_1_ARG(result);
- *result = nullptr;
-
- // We currently only support the custom UIA property ID for unique id.
- if (property_id ==
- UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId() &&
- value.vt == VT_BSTR) {
- int32_t ax_unique_id;
- if (!base::StringToInt(value.bstrVal, &ax_unique_id))
- return S_OK;
-
- // In the Windows accessibility platform implementation, id 0 represents
- // self; a positive id represents the immediate descendants; and a
- // negative id represents a unique id that can be mapped to any node.
- if (AXPlatformNodeWin* result_platform_node =
- static_cast<AXPlatformNodeWin*>(GetFromUniqueId(-ax_unique_id))) {
- if (start_after_element) {
- Microsoft::WRL::ComPtr<AXPlatformNodeWin> start_after_platform_node;
- if (!SUCCEEDED(start_after_element->QueryInterface(
- IID_PPV_ARGS(&start_after_platform_node))))
- return E_INVALIDARG;
-
- // We want |result| to be nullptr if it comes before or is equal to
- // |start_after_element|.
- if (start_after_platform_node->CompareTo(*result_platform_node) >= 0)
- return S_OK;
- }
-
- return result_platform_node->QueryInterface(IID_PPV_ARGS(result));
- }
- }
-
- return E_INVALIDARG;
- }
-
- //
- // IRawElementProviderSimple methods.
- //
-
- IFACEMETHODIMP get_HostRawElementProvider(
- IRawElementProviderSimple** host_element_provider) override {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_HOST_RAW_ELEMENT_PROVIDER);
- UIA_VALIDATE_CALL_1_ARG(host_element_provider);
-
- HWND hwnd = GetDelegate()->GetTargetForNativeAccessibilityEvent();
- return UiaHostProviderFromHwnd(hwnd, host_element_provider);
- }
-
- IFACEMETHODIMP GetPatternProvider(PATTERNID pattern_id,
- IUnknown** result) override {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PATTERN_PROVIDER);
- UIA_VALIDATE_CALL_1_ARG(result);
- *result = nullptr;
-
- if (pattern_id == UIA_ItemContainerPatternId) {
- AddRef();
- *result = static_cast<IItemContainerProvider*>(this);
- return S_OK;
- }
-
- return AXPlatformNodeWin::GetPatternProviderImpl(pattern_id, result);
- }
-
- IFACEMETHODIMP GetPropertyValue(PROPERTYID property_id,
- VARIANT* result) override {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PROPERTY_VALUE);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- switch (property_id) {
- default:
- // UIA has a built-in provider that will expose values for several
- // properties based on the HWND. This information is useful to someone
- // examining the accessibility tree using tools such as Inspect. Return
- // VT_EMPTY for most properties so that we don't override values from
- // the default provider with blank data.
- result->vt = VT_EMPTY;
- break;
-
- case UIA_IsControlElementPropertyId:
- case UIA_IsContentElementPropertyId:
- // Override IsControlElement and IsContentElement to fine tune which
- // fragment roots appear in the control and content views.
- result->vt = VT_BOOL;
- result->boolVal =
- static_cast<AXFragmentRootWin*>(GetDelegate())->IsControlElement()
- ? VARIANT_TRUE
- : VARIANT_FALSE;
- break;
- }
-
- return S_OK;
- }
-
- //
- // IRawElementProviderFragment methods.
- //
-
- IFACEMETHODIMP get_FragmentRoot(
- IRawElementProviderFragmentRoot** fragment_root) override {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_FRAGMENTROOT);
- UIA_VALIDATE_CALL_1_ARG(fragment_root);
-
- QueryInterface(IID_PPV_ARGS(fragment_root));
- return S_OK;
- }
-
- //
- // IRawElementProviderFragmentRoot methods.
- //
- IFACEMETHODIMP ElementProviderFromPoint(
- double screen_physical_pixel_x,
- double screen_physical_pixel_y,
- IRawElementProviderFragment** element_provider) override {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ELEMENT_PROVIDER_FROM_POINT);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_ELEMENT_PROVIDER_FROM_POINT);
- UIA_VALIDATE_CALL_1_ARG(element_provider);
-
- *element_provider = nullptr;
-
- gfx::NativeViewAccessible hit_element = nullptr;
-
- // Descend the tree until we get a non-hit or can't go any further.
- AXPlatformNode* node_to_test = this;
- do {
- gfx::NativeViewAccessible test_result =
- node_to_test->GetDelegate()->HitTestSync(screen_physical_pixel_x,
- screen_physical_pixel_y);
- if (test_result != nullptr && test_result != hit_element) {
- hit_element = test_result;
- node_to_test = AXPlatformNode::FromNativeViewAccessible(test_result);
- } else {
- node_to_test = nullptr;
- }
- } while (node_to_test);
-
- if (hit_element)
- hit_element->QueryInterface(element_provider);
-
- return S_OK;
- }
-
- IFACEMETHODIMP GetFocus(IRawElementProviderFragment** focus) override {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_FOCUS);
- UIA_VALIDATE_CALL_1_ARG(focus);
-
- *focus = nullptr;
-
- gfx::NativeViewAccessible focused_element = nullptr;
-
- // GetFocus() can return a node at the root of a subtree, for example when
- // transitioning from Views into web content. In such cases we want to
- // continue drilling to retrieve the actual focused element.
- AXPlatformNode* node_to_test = this;
- do {
- gfx::NativeViewAccessible test_result =
- node_to_test->GetDelegate()->GetFocus();
- if (test_result != nullptr && test_result != focused_element) {
- focused_element = test_result;
- node_to_test =
- AXPlatformNode::FromNativeViewAccessible(focused_element);
- } else {
- node_to_test = nullptr;
- }
- } while (node_to_test);
-
- if (focused_element)
- focused_element->QueryInterface(IID_PPV_ARGS(focus));
-
- return S_OK;
- }
-
- //
- // IRawElementProviderAdviseEvents methods.
- //
- IFACEMETHODIMP AdviseEventAdded(EVENTID event_id,
- SAFEARRAY* property_ids) override {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ADVISE_EVENT_ADDED);
- if (event_id == UIA_LiveRegionChangedEventId) {
- live_region_change_listeners_++;
-
- if (live_region_change_listeners_ == 1) {
- // Fire a LiveRegionChangedEvent for each live-region to tell the
- // newly-attached assistive technology about the regions.
- //
- // Ideally we'd be able to direct these events to only the
- // newly-attached AT, but we don't have that capability, so we only
- // fire events when the *first* AT attaches. (A common scenario will
- // be an attached screen-reader, then a software-keyboard attaches to
- // handle an input field; we don't want the screen-reader to announce
- // that every live-region has changed.) There isn't a perfect solution,
- // but this heuristic seems to work well in practice.
- FireLiveRegionChangeRecursive();
- }
- }
- return S_OK;
- }
-
- IFACEMETHODIMP AdviseEventRemoved(EVENTID event_id,
- SAFEARRAY* property_ids) override {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ADVISE_EVENT_REMOVED);
- if (event_id == UIA_LiveRegionChangedEventId) {
- DCHECK(live_region_change_listeners_ > 0);
- live_region_change_listeners_--;
- }
- return S_OK;
- }
-
- private:
- int32_t live_region_change_listeners_ = 0;
-};
-
-class AXFragmentRootMapWin {
- public:
- static AXFragmentRootMapWin& GetInstance() {
- static base::NoDestructor<AXFragmentRootMapWin> instance;
- return *instance;
- }
-
- void AddFragmentRoot(gfx::AcceleratedWidget widget,
- AXFragmentRootWin* fragment_root) {
- map_[widget] = fragment_root;
- }
-
- void RemoveFragmentRoot(gfx::AcceleratedWidget widget) { map_.erase(widget); }
-
- ui::AXFragmentRootWin* GetFragmentRoot(gfx::AcceleratedWidget widget) const {
- const auto& entry = map_.find(widget);
- if (entry != map_.end())
- return entry->second;
-
- return nullptr;
- }
-
- ui::AXFragmentRootWin* GetFragmentRootParentOf(
- gfx::NativeViewAccessible accessible) const {
- for (const auto& entry : map_) {
- AXPlatformNodeDelegate* child = entry.second->GetChildNodeDelegate();
- if (child && (child->GetNativeViewAccessible() == accessible))
- return entry.second;
- }
- return nullptr;
- }
-
- private:
- std::unordered_map<gfx::AcceleratedWidget, AXFragmentRootWin*> map_;
-};
-
-AXFragmentRootWin::AXFragmentRootWin(gfx::AcceleratedWidget widget,
- AXFragmentRootDelegateWin* delegate)
- : widget_(widget), delegate_(delegate) {
- platform_node_ = ui::AXFragmentRootPlatformNodeWin::Create(this);
- AXFragmentRootMapWin::GetInstance().AddFragmentRoot(widget, this);
-}
-
-AXFragmentRootWin::~AXFragmentRootWin() {
- AXFragmentRootMapWin::GetInstance().RemoveFragmentRoot(widget_);
- platform_node_->Destroy();
- platform_node_ = nullptr;
-}
-
-AXFragmentRootWin* AXFragmentRootWin::GetForAcceleratedWidget(
- gfx::AcceleratedWidget widget) {
- return AXFragmentRootMapWin::GetInstance().GetFragmentRoot(widget);
-}
-
-// static
-AXFragmentRootWin* AXFragmentRootWin::GetFragmentRootParentOf(
- gfx::NativeViewAccessible accessible) {
- return AXFragmentRootMapWin::GetInstance().GetFragmentRootParentOf(
- accessible);
-}
-
-gfx::NativeViewAccessible AXFragmentRootWin::GetNativeViewAccessible() {
- // The fragment root is the entry point from the operating system for UI
- // Automation. Signal observers when we're asked for a platform object on it.
- for (WinAccessibilityAPIUsageObserver& observer :
- GetWinAccessibilityAPIUsageObserverList()) {
- observer.OnUIAutomationUsed();
- }
- return platform_node_.Get();
-}
-
-bool AXFragmentRootWin::IsControlElement() {
- return delegate_->IsAXFragmentRootAControlElement();
-}
-
-gfx::NativeViewAccessible AXFragmentRootWin::GetParent() {
- return delegate_->GetParentOfAXFragmentRoot();
-}
-
-int AXFragmentRootWin::GetChildCount() const {
- return delegate_->GetChildOfAXFragmentRoot() ? 1 : 0;
-}
-
-gfx::NativeViewAccessible AXFragmentRootWin::ChildAtIndex(int index) {
- if (index == 0) {
- return delegate_->GetChildOfAXFragmentRoot();
- }
-
- return nullptr;
-}
-
-gfx::NativeViewAccessible AXFragmentRootWin::GetNextSibling() {
- int child_index = GetIndexInParentOfChild();
- if (child_index >= 0) {
- AXPlatformNodeDelegate* parent = GetParentNodeDelegate();
- if (parent && child_index < (parent->GetChildCount() - 1))
- return GetParentNodeDelegate()->ChildAtIndex(child_index + 1);
- }
-
- return nullptr;
-}
-
-gfx::NativeViewAccessible AXFragmentRootWin::GetPreviousSibling() {
- int child_index = GetIndexInParentOfChild();
- if (child_index > 0)
- return GetParentNodeDelegate()->ChildAtIndex(child_index - 1);
-
- return nullptr;
-}
-
-gfx::NativeViewAccessible AXFragmentRootWin::HitTestSync(int x, int y) const {
- AXPlatformNodeDelegate* child_delegate = GetChildNodeDelegate();
- if (child_delegate)
- return child_delegate->HitTestSync(x, y);
-
- return nullptr;
-}
-
-gfx::NativeViewAccessible AXFragmentRootWin::GetFocus() {
- AXPlatformNodeDelegate* child_delegate = GetChildNodeDelegate();
- if (child_delegate)
- return child_delegate->GetFocus();
-
- return nullptr;
-}
-
-const ui::AXUniqueId& AXFragmentRootWin::GetUniqueId() const {
- return unique_id_;
-}
-
-gfx::AcceleratedWidget
-AXFragmentRootWin::GetTargetForNativeAccessibilityEvent() {
- return widget_;
-}
-
-AXPlatformNode* AXFragmentRootWin::GetFromTreeIDAndNodeID(
- const ui::AXTreeID& ax_tree_id,
- int32_t node_id) {
- AXPlatformNodeDelegate* child_delegate = GetChildNodeDelegate();
- if (child_delegate)
- return child_delegate->GetFromTreeIDAndNodeID(ax_tree_id, node_id);
-
- return nullptr;
-}
-
-AXPlatformNodeDelegate* AXFragmentRootWin::GetParentNodeDelegate() const {
- gfx::NativeViewAccessible parent = delegate_->GetParentOfAXFragmentRoot();
- if (parent)
- return ui::AXPlatformNode::FromNativeViewAccessible(parent)->GetDelegate();
-
- return nullptr;
-}
-
-AXPlatformNodeDelegate* AXFragmentRootWin::GetChildNodeDelegate() const {
- gfx::NativeViewAccessible child = delegate_->GetChildOfAXFragmentRoot();
- if (child)
- return ui::AXPlatformNode::FromNativeViewAccessible(child)->GetDelegate();
-
- return nullptr;
-}
-
-int AXFragmentRootWin::GetIndexInParentOfChild() const {
- AXPlatformNodeDelegate* parent = GetParentNodeDelegate();
-
- if (!parent)
- return 0;
-
- AXPlatformNodeDelegate* child = GetChildNodeDelegate();
- if (child) {
- int child_count = parent->GetChildCount();
- for (int child_index = 0; child_index < child_count; child_index++) {
- if (ui::AXPlatformNode::FromNativeViewAccessible(
- parent->ChildAtIndex(child_index))
- ->GetDelegate() == child)
- return child_index;
- }
- }
- return 0;
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_fragment_root_win.h b/third_party/accessibility/ax/platform/ax_fragment_root_win.h
deleted file mode 100644
index f8cb803..0000000
--- a/third_party/accessibility/ax/platform/ax_fragment_root_win.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_FRAGMENT_ROOT_WIN_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_FRAGMENT_ROOT_WIN_H_
-
-#include "ui/accessibility/platform/ax_platform_node_delegate_base.h"
-
-#include <wrl/client.h>
-
-namespace ui {
-
-class AXFragmentRootDelegateWin;
-class AXFragmentRootPlatformNodeWin;
-
-// UI Automation on Windows requires the root of a multi-element provider to
-// implement IRawElementProviderFragmentRoot. Our internal accessibility trees
-// may not know their roots for right away; for example, web content may
-// deserialize the document for an iframe before the host document. Because of
-// this, and because COM rules require that the list of interfaces returned by
-// QueryInterface remain static over the lifetime of an object instance, we
-// implement IRawElementProviderFragmentRoot on its own node for each HWND, with
-// the root of our internal accessibility tree for that HWND as its sole child.
-//
-// Since UIA derives some information from the underlying HWND hierarchy, we
-// expose one fragment root per HWND. The class that owns the HWND is expected
-// to own the corresponding AXFragmentRootWin.
-class AX_EXPORT AXFragmentRootWin : public ui::AXPlatformNodeDelegateBase {
- public:
- AXFragmentRootWin(gfx::AcceleratedWidget widget,
- AXFragmentRootDelegateWin* delegate);
- ~AXFragmentRootWin() override;
-
- // Fragment roots register themselves in a map upon creation and unregister
- // upon destruction. This method provides a lookup, which allows the internal
- // accessibility root to navigate back to the corresponding fragment root.
- static AXFragmentRootWin* GetForAcceleratedWidget(
- gfx::AcceleratedWidget widget);
-
- // If the given NativeViewAccessible is the direct descendant of a fragment
- // root, return the corresponding fragment root.
- static AXFragmentRootWin* GetFragmentRootParentOf(
- gfx::NativeViewAccessible accessible);
-
- // Returns the NativeViewAccessible for this fragment root.
- gfx::NativeViewAccessible GetNativeViewAccessible() override;
-
- // Assistive technologies will typically use UI Automation's control or
- // content view rather than the raw view.
- // Returns true if the fragment root should be included in the control and
- // content views or false if it should be excluded.
- bool IsControlElement();
-
- // If a child node is available, return its delegate.
- AXPlatformNodeDelegate* GetChildNodeDelegate() const;
-
- private:
- // AXPlatformNodeDelegate overrides.
- gfx::NativeViewAccessible GetParent() override;
- int GetChildCount() const override;
- gfx::NativeViewAccessible ChildAtIndex(int index) override;
- gfx::NativeViewAccessible GetNextSibling() override;
- gfx::NativeViewAccessible GetPreviousSibling() override;
- gfx::NativeViewAccessible HitTestSync(int x, int y) const override;
- gfx::NativeViewAccessible GetFocus() override;
- const ui::AXUniqueId& GetUniqueId() const override;
- gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
- AXPlatformNode* GetFromTreeIDAndNodeID(const ui::AXTreeID& ax_tree_id,
- int32_t id) override;
-
- // A fragment root does not correspond to any node in the platform neutral
- // accessibility tree. Rather, the fragment root's child is a child of the
- // fragment root's parent. This helper computes the child's index in the
- // parent's array of children.
- int GetIndexInParentOfChild() const;
-
- // If a parent node is available, return its delegate.
- AXPlatformNodeDelegate* GetParentNodeDelegate() const;
-
- gfx::AcceleratedWidget widget_;
- AXFragmentRootDelegateWin* const delegate_;
- Microsoft::WRL::ComPtr<ui::AXFragmentRootPlatformNodeWin> platform_node_;
- ui::AXUniqueId unique_id_;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_FRAGMENT_ROOT_WIN_H_
diff --git a/third_party/accessibility/ax/platform/ax_fragment_root_win_unittest.cc b/third_party/accessibility/ax/platform/ax_fragment_root_win_unittest.cc
deleted file mode 100644
index e0e03af..0000000
--- a/third_party/accessibility/ax/platform/ax_fragment_root_win_unittest.cc
+++ /dev/null
@@ -1,697 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_fragment_root_win.h"
-#include "ui/accessibility/accessibility_switches.h"
-#include "ui/accessibility/platform/ax_platform_node_win.h"
-#include "ui/accessibility/platform/ax_platform_node_win_unittest.h"
-#include "ui/accessibility/platform/test_ax_node_wrapper.h"
-
-#include <UIAutomationClient.h>
-#include <UIAutomationCoreApi.h>
-
-#include "base/auto_reset.h"
-#include "base/win/scoped_safearray.h"
-#include "base/win/scoped_variant.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/platform/uia_registrar_win.h"
-
-using base::win::ScopedVariant;
-using Microsoft::WRL::ComPtr;
-
-namespace ui {
-
-#define EXPECT_UIA_BSTR_EQ(node, property_id, expected) \
- { \
- ScopedVariant expectedVariant(expected); \
- ASSERT_EQ(VT_BSTR, expectedVariant.type()); \
- ASSERT_NE(nullptr, expectedVariant.ptr()->bstrVal); \
- ScopedVariant actual; \
- ASSERT_HRESULT_SUCCEEDED( \
- node->GetPropertyValue(property_id, actual.Receive())); \
- ASSERT_EQ(VT_BSTR, actual.type()); \
- ASSERT_NE(nullptr, actual.ptr()->bstrVal); \
- EXPECT_STREQ(expectedVariant.ptr()->bstrVal, actual.ptr()->bstrVal); \
- }
-
-class AXFragmentRootTest : public AXPlatformNodeWinTest {
- public:
- AXFragmentRootTest() = default;
- ~AXFragmentRootTest() override = default;
- AXFragmentRootTest(const AXFragmentRootTest&) = delete;
- AXFragmentRootTest& operator=(const AXFragmentRootTest&) = delete;
-};
-
-TEST_F(AXFragmentRootTest, UIAFindItemByPropertyUniqueId) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.SetName("root");
- root.child_ids = {2, 3};
-
- AXNodeData text1;
- text1.id = 2;
- text1.role = ax::mojom::Role::kStaticText;
- text1.SetName("text1");
-
- AXNodeData button;
- button.id = 3;
- button.role = ax::mojom::Role::kButton;
- button.SetName("button");
- button.child_ids = {4};
-
- AXNodeData text2;
- text2.id = 4;
- text2.role = ax::mojom::Role::kStaticText;
- text2.SetName("text2");
-
- Init(root, text1, button, text2);
- InitFragmentRoot();
-
- ComPtr<IRawElementProviderSimple> root_raw_element_provider_simple;
- ax_fragment_root_->GetNativeViewAccessible()->QueryInterface(
- IID_PPV_ARGS(&root_raw_element_provider_simple));
- ComPtr<IRawElementProviderSimple> text1_raw_element_provider_simple =
- GetIRawElementProviderSimpleFromChildIndex(0);
- ComPtr<IRawElementProviderSimple> button_raw_element_provider_simple =
- GetIRawElementProviderSimpleFromChildIndex(1);
-
- AXNode* text1_node = GetRootAsAXNode()->children()[0];
- AXNode* button_node = GetRootAsAXNode()->children()[1];
-
- ComPtr<IItemContainerProvider> item_container_provider;
- EXPECT_HRESULT_SUCCEEDED(root_raw_element_provider_simple->GetPatternProvider(
- UIA_ItemContainerPatternId, &item_container_provider));
- ASSERT_NE(nullptr, item_container_provider.Get());
-
- ScopedVariant unique_id_variant;
- int32_t unique_id;
- ComPtr<IRawElementProviderSimple> result;
-
- // When |start_after_element| is an invalid element, we should fail at finding
- // the item.
- {
- unique_id = AXPlatformNodeFromNode(GetRootAsAXNode())->GetUniqueId();
- unique_id_variant.Set(
- SysAllocString(base::NumberToString16(-unique_id).c_str()));
-
- ComPtr<IRawElementProviderSimple> invalid_element_provider_simple;
- EXPECT_HRESULT_SUCCEEDED(
- MockIRawElementProviderSimple::CreateMockIRawElementProviderSimple(
- &invalid_element_provider_simple));
-
- EXPECT_HRESULT_FAILED(item_container_provider->FindItemByProperty(
- invalid_element_provider_simple.Get(),
- UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- result.Reset();
- unique_id_variant.Release();
- }
-
- // Fetch the AxUniqueId of "root", and verify we can retrieve its
- // corresponding IRawElementProviderSimple through FindItemByProperty().
- {
- unique_id = AXPlatformNodeFromNode(GetRootAsAXNode())->GetUniqueId();
- unique_id_variant.Set(
- SysAllocString(base::NumberToString16(-unique_id).c_str()));
-
- // When |start_after_element| of FindItemByProperty() is nullptr, we should
- // be able to find "text1".
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- nullptr, UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_UIA_BSTR_EQ(result, UIA_NamePropertyId, L"root");
- result.Reset();
-
- // When |start_after_element| of FindItemByProperty() is "text1", there
- // should be no element found, since "text1" comes after the element we are
- // looking for.
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- text1_raw_element_provider_simple.Get(),
- UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_EQ(nullptr, result.Get());
- result.Reset();
-
- // When |start_after_element| of FindItemByProperty() is "button", there
- // should be no element found, since "button" comes after the element we are
- // looking for.
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- button_raw_element_provider_simple.Get(),
- UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_EQ(nullptr, result.Get());
-
- result.Reset();
- unique_id_variant.Release();
- }
-
- // Fetch the AxUniqueId of "text1", and verify if we can retrieve its
- // corresponding IRawElementProviderSimple through FindItemByProperty().
- {
- unique_id = AXPlatformNodeFromNode(text1_node)->GetUniqueId();
- unique_id_variant.Set(
- SysAllocString(base::NumberToString16(-unique_id).c_str()));
-
- // When |start_after_element| of FindItemByProperty() is nullptr, we should
- // be able to find "text1".
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- nullptr, UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_UIA_BSTR_EQ(result, UIA_NamePropertyId, L"text1");
- result.Reset();
-
- // When |start_after_element| of FindItemByProperty() is "text1", there
- // should be no element found, since "text1" equals the element we are
- // looking for.
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- text1_raw_element_provider_simple.Get(),
- UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_EQ(nullptr, result.Get());
- result.Reset();
-
- // When |start_after_element| of FindItemByProperty() is "button", there
- // should be no element found, since "button" comes after the element we are
- // looking for.
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- button_raw_element_provider_simple.Get(),
- UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_EQ(nullptr, result.Get());
- result.Reset();
- unique_id_variant.Release();
- }
-
- // Fetch the AxUniqueId of "button", and verify we can retrieve its
- // corresponding IRawElementProviderSimple through FindItemByProperty().
- {
- unique_id = AXPlatformNodeFromNode(button_node)->GetUniqueId();
- unique_id_variant.Set(
- SysAllocString(base::NumberToString16(-unique_id).c_str()));
-
- // When |start_after_element| of FindItemByProperty() is nullptr, we should
- // be able to find "button".
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- nullptr, UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_UIA_BSTR_EQ(result, UIA_NamePropertyId, L"button");
- result.Reset();
-
- // When |start_after_element| of FindItemByProperty() is "text1", we should
- // be able to find "button".
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- text1_raw_element_provider_simple.Get(),
- UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_UIA_BSTR_EQ(result, UIA_NamePropertyId, L"button");
- result.Reset();
-
- // When |start_after_element| of FindItemByProperty() is "button", there
- // should be no element found, since "button" equals the element we are
- // looking for.
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- button_raw_element_provider_simple.Get(),
- UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_EQ(nullptr, result.Get());
- result.Reset();
- unique_id_variant.Release();
- }
-
- // Fetch the AxUniqueId of "text2", and verify we can retrieve its
- // corresponding IRawElementProviderSimple through FindItemByProperty().
- {
- unique_id =
- AXPlatformNodeFromNode(button_node->children()[0])->GetUniqueId();
- unique_id_variant.Set(
- SysAllocString(base::NumberToString16(-unique_id).c_str()));
-
- // When |start_after_element| of FindItemByProperty() is nullptr, we should
- // be able to find "text2".
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- nullptr, UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_UIA_BSTR_EQ(result, UIA_NamePropertyId, L"text2");
-
- // When |start_after_element| of FindItemByProperty() is root, we should
- // be able to find "text2".
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- root_raw_element_provider_simple.Get(),
- UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_UIA_BSTR_EQ(result, UIA_NamePropertyId, L"text2");
-
- // When |start_after_element| of FindItemByProperty() is "text1", we should
- // be able to find "text2".
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- text1_raw_element_provider_simple.Get(),
- UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_UIA_BSTR_EQ(result, UIA_NamePropertyId, L"text2");
-
- // When |start_after_element| of FindItemByProperty() is "button", we should
- // be able to find "text2".
- EXPECT_HRESULT_SUCCEEDED(item_container_provider->FindItemByProperty(
- button_raw_element_provider_simple.Get(),
- UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId(),
- unique_id_variant, &result));
- EXPECT_UIA_BSTR_EQ(result, UIA_NamePropertyId, L"text2");
- }
-}
-
-TEST_F(AXFragmentRootTest, TestUIAGetFragmentRoot) {
- AXNodeData root;
- Init(root);
- InitFragmentRoot();
-
- ComPtr<IRawElementProviderFragmentRoot> expected_fragment_root =
- GetFragmentRoot();
- ComPtr<IRawElementProviderFragment> fragment_provider;
- expected_fragment_root.As(&fragment_provider);
-
- ComPtr<IRawElementProviderFragmentRoot> actual_fragment_root;
- EXPECT_HRESULT_SUCCEEDED(
- fragment_provider->get_FragmentRoot(&actual_fragment_root));
- EXPECT_EQ(expected_fragment_root.Get(), actual_fragment_root.Get());
-}
-
-TEST_F(AXFragmentRootTest, TestUIAElementProviderFromPoint) {
- AXNodeData root_data;
- root_data.id = 1;
- root_data.relative_bounds.bounds = gfx::RectF(0, 0, 80, 80);
-
- AXNodeData element1_data;
- element1_data.id = 2;
- element1_data.relative_bounds.bounds = gfx::RectF(0, 0, 50, 50);
- root_data.child_ids.push_back(element1_data.id);
-
- AXNodeData element2_data;
- element2_data.id = 3;
- element2_data.relative_bounds.bounds = gfx::RectF(0, 50, 30, 30);
- root_data.child_ids.push_back(element2_data.id);
-
- Init(root_data, element1_data, element2_data);
- InitFragmentRoot();
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* element1_node = root_node->children()[0];
- AXNode* element2_node = root_node->children()[1];
-
- ComPtr<IRawElementProviderFragmentRoot> fragment_root_prov(GetFragmentRoot());
- ComPtr<IRawElementProviderFragment> root_provider(
- GetRootIRawElementProviderFragment());
- ComPtr<IRawElementProviderFragment> element1_provider =
- QueryInterfaceFromNode<IRawElementProviderFragment>(element1_node);
- ComPtr<IRawElementProviderFragment> element2_provider =
- QueryInterfaceFromNode<IRawElementProviderFragment>(element2_node);
-
- ComPtr<IRawElementProviderFragment> provider_from_point;
- EXPECT_HRESULT_SUCCEEDED(fragment_root_prov->ElementProviderFromPoint(
- 23, 31, &provider_from_point));
- EXPECT_EQ(element1_provider.Get(), provider_from_point.Get());
-
- EXPECT_HRESULT_SUCCEEDED(fragment_root_prov->ElementProviderFromPoint(
- 23, 67, &provider_from_point));
- EXPECT_EQ(element2_provider.Get(), provider_from_point.Get());
-
- EXPECT_HRESULT_SUCCEEDED(fragment_root_prov->ElementProviderFromPoint(
- 47, 67, &provider_from_point));
- EXPECT_EQ(root_provider.Get(), provider_from_point.Get());
-
- // This is on node 1 with scale factor of 1.5.
- std::unique_ptr<base::AutoReset<float>> scale_factor_reset =
- TestAXNodeWrapper::SetScaleFactor(1.5);
- EXPECT_HRESULT_SUCCEEDED(fragment_root_prov->ElementProviderFromPoint(
- 60, 60, &provider_from_point));
- EXPECT_EQ(element1_provider.Get(), provider_from_point.Get());
-}
-
-TEST_F(AXFragmentRootTest, TestUIAGetFocus) {
- AXNodeData root_data;
- root_data.id = 1;
-
- AXNodeData element1_data;
- element1_data.id = 2;
- root_data.child_ids.push_back(element1_data.id);
-
- AXNodeData element2_data;
- element2_data.id = 3;
- root_data.child_ids.push_back(element2_data.id);
-
- Init(root_data, element1_data, element2_data);
- InitFragmentRoot();
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* element1_node = root_node->children()[0];
- AXNode* element2_node = root_node->children()[1];
-
- ComPtr<IRawElementProviderFragmentRoot> fragment_root_prov(GetFragmentRoot());
- ComPtr<IRawElementProviderFragment> root_provider(
- GetRootIRawElementProviderFragment());
- ComPtr<IRawElementProviderFragment> element1_provider =
- QueryInterfaceFromNode<IRawElementProviderFragment>(element1_node);
- ComPtr<IRawElementProviderFragment> element2_provider =
- QueryInterfaceFromNode<IRawElementProviderFragment>(element2_node);
-
- ComPtr<IRawElementProviderFragment> focused_fragment;
- EXPECT_HRESULT_SUCCEEDED(root_provider->SetFocus());
- EXPECT_HRESULT_SUCCEEDED(fragment_root_prov->GetFocus(&focused_fragment));
- EXPECT_EQ(root_provider.Get(), focused_fragment.Get());
-
- EXPECT_HRESULT_SUCCEEDED(element1_provider->SetFocus());
- EXPECT_HRESULT_SUCCEEDED(fragment_root_prov->GetFocus(&focused_fragment));
- EXPECT_EQ(element1_provider.Get(), focused_fragment.Get());
-
- EXPECT_HRESULT_SUCCEEDED(element2_provider->SetFocus());
- EXPECT_HRESULT_SUCCEEDED(fragment_root_prov->GetFocus(&focused_fragment));
- EXPECT_EQ(element2_provider.Get(), focused_fragment.Get());
-}
-
-TEST_F(AXFragmentRootTest, TestUIAErrorHandling) {
- AXNodeData root;
- Init(root);
- InitFragmentRoot();
-
- ComPtr<IRawElementProviderSimple> simple_provider =
- GetRootIRawElementProviderSimple();
- ComPtr<IRawElementProviderFragment> fragment_provider =
- GetRootIRawElementProviderFragment();
- ComPtr<IRawElementProviderFragmentRoot> fragment_root_provider =
- GetFragmentRoot();
-
- SetTree(std::make_unique<AXTree>());
- ax_fragment_root_.reset(nullptr);
-
- ComPtr<IRawElementProviderSimple> returned_simple_provider;
- ComPtr<IRawElementProviderFragment> returned_fragment_provider;
- ComPtr<IRawElementProviderFragmentRoot> returned_fragment_root_provider;
- base::win::ScopedSafearray returned_runtime_id;
-
- EXPECT_EQ(
- static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- simple_provider->get_HostRawElementProvider(&returned_simple_provider));
-
- EXPECT_EQ(
- static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- fragment_provider->get_FragmentRoot(&returned_fragment_root_provider));
-
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- fragment_provider->GetRuntimeId(returned_runtime_id.Receive()));
-
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- fragment_root_provider->ElementProviderFromPoint(
- 67, 23, &returned_fragment_provider));
-
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- fragment_root_provider->GetFocus(&returned_fragment_provider));
-}
-
-TEST_F(AXFragmentRootTest, TestGetChildCount) {
- AXNodeData root;
- Init(root);
- InitFragmentRoot();
-
- AXPlatformNodeDelegate* fragment_root = ax_fragment_root_.get();
- EXPECT_EQ(1, fragment_root->GetChildCount());
-
- test_fragment_root_delegate_->child_ = nullptr;
- EXPECT_EQ(0, fragment_root->GetChildCount());
-}
-
-TEST_F(AXFragmentRootTest, TestChildAtIndex) {
- AXNodeData root;
- Init(root);
- InitFragmentRoot();
-
- gfx::NativeViewAccessible native_view_accessible =
- AXPlatformNodeFromNode(GetRootAsAXNode())->GetNativeViewAccessible();
- AXPlatformNodeDelegate* fragment_root = ax_fragment_root_.get();
- EXPECT_EQ(native_view_accessible, fragment_root->ChildAtIndex(0));
- EXPECT_EQ(nullptr, fragment_root->ChildAtIndex(1));
-
- test_fragment_root_delegate_->child_ = nullptr;
- EXPECT_EQ(nullptr, fragment_root->ChildAtIndex(0));
-}
-
-TEST_F(AXFragmentRootTest, TestGetParent) {
- AXNodeData root;
- Init(root);
- InitFragmentRoot();
-
- AXPlatformNodeDelegate* fragment_root = ax_fragment_root_.get();
- EXPECT_EQ(nullptr, fragment_root->GetParent());
-
- gfx::NativeViewAccessible native_view_accessible =
- AXPlatformNodeFromNode(GetRootAsAXNode())->GetNativeViewAccessible();
- test_fragment_root_delegate_->parent_ = native_view_accessible;
- EXPECT_EQ(native_view_accessible, fragment_root->GetParent());
-}
-
-TEST_F(AXFragmentRootTest, TestGetPropertyValue) {
- AXNodeData root;
- Init(root);
- InitFragmentRoot();
-
- ComPtr<IRawElementProviderSimple> root_provider;
- ax_fragment_root_->GetNativeViewAccessible()->QueryInterface(
- IID_PPV_ARGS(&root_provider));
-
- // IsControlElement and IsContentElement should follow the setting on the
- // fragment root delegate.
- test_fragment_root_delegate_->is_control_element_ = true;
- ScopedVariant result;
- EXPECT_HRESULT_SUCCEEDED(root_provider->GetPropertyValue(
- UIA_IsControlElementPropertyId, result.Receive()));
- EXPECT_EQ(result.type(), VT_BOOL);
- EXPECT_EQ(result.ptr()->boolVal, VARIANT_TRUE);
- EXPECT_HRESULT_SUCCEEDED(root_provider->GetPropertyValue(
- UIA_IsContentElementPropertyId, result.Receive()));
- EXPECT_EQ(result.type(), VT_BOOL);
- EXPECT_EQ(result.ptr()->boolVal, VARIANT_TRUE);
-
- test_fragment_root_delegate_->is_control_element_ = false;
- EXPECT_HRESULT_SUCCEEDED(root_provider->GetPropertyValue(
- UIA_IsControlElementPropertyId, result.Receive()));
- EXPECT_EQ(result.type(), VT_BOOL);
- EXPECT_EQ(result.ptr()->boolVal, VARIANT_FALSE);
- EXPECT_HRESULT_SUCCEEDED(root_provider->GetPropertyValue(
- UIA_IsContentElementPropertyId, result.Receive()));
- EXPECT_EQ(result.type(), VT_BOOL);
- EXPECT_EQ(result.ptr()->boolVal, VARIANT_FALSE);
-
- // Other properties should return VT_EMPTY.
- EXPECT_HRESULT_SUCCEEDED(root_provider->GetPropertyValue(
- UIA_ControlTypePropertyId, result.Receive()));
- EXPECT_EQ(result.type(), VT_EMPTY);
-}
-
-TEST_F(AXFragmentRootTest, TestUIAMultipleFragmentRoots) {
- // Consider the following platform-neutral tree:
- //
- // N1
- // _____/ \_____
- // / \
- // N2---N3---N4---N5
- // / \ / \
- // N6---N7 N8---N9
- //
- // N3 and N5 are nodes for which we need a fragment root. This will correspond
- // to the following tree in UIA:
- //
- // U1
- // _____/ \_____
- // / \
- // U2---R3---U4---R5
- // | |
- // U3 U5
- // / \ / \
- // U6---U7 U8---U9
-
- ui::AXNodeData top_fragment_root_n1;
- top_fragment_root_n1.id = 1;
-
- ui::AXNodeData sibling_n2;
- sibling_n2.id = 2;
-
- ui::AXNodeData child_fragment_root_n3;
- child_fragment_root_n3.id = 3;
-
- ui::AXNodeData sibling_n6;
- sibling_n6.id = 6;
- ui::AXNodeData sibling_n7;
- sibling_n7.id = 7;
-
- child_fragment_root_n3.child_ids = {6, 7};
-
- ui::AXNodeData sibling_n4;
- sibling_n4.id = 4;
-
- ui::AXNodeData child_fragment_root_n5;
- child_fragment_root_n5.id = 5;
-
- ui::AXNodeData sibling_n8;
- sibling_n8.id = 8;
- ui::AXNodeData sibling_n9;
- sibling_n9.id = 9;
-
- child_fragment_root_n5.child_ids = {8, 9};
- top_fragment_root_n1.child_ids = {2, 3, 4, 5};
-
- ui::AXTreeUpdate update;
- update.has_tree_data = true;
- update.root_id = top_fragment_root_n1.id;
- update.nodes = {top_fragment_root_n1,
- sibling_n2,
- child_fragment_root_n3,
- sibling_n6,
- sibling_n7,
- sibling_n4,
- child_fragment_root_n5,
- sibling_n8,
- sibling_n9};
- update.tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
-
- Init(update);
- InitFragmentRoot();
-
- AXNode* root_node = GetRootAsAXNode();
-
- // Set up other fragment roots
- AXNode* child_fragment_root_n3_node = root_node->children()[1];
- std::unique_ptr<TestFragmentRootDelegate> n3_fragment_root_delegate =
- std::make_unique<TestFragmentRootDelegate>();
- std::unique_ptr<AXFragmentRootWin> n3_fragment_root(InitNodeAsFragmentRoot(
- child_fragment_root_n3_node, n3_fragment_root_delegate.get()));
-
- AXNode* child_fragment_root_n5_node = root_node->children()[3];
- std::unique_ptr<TestFragmentRootDelegate> n5_fragment_root_delegate =
- std::make_unique<TestFragmentRootDelegate>();
- std::unique_ptr<AXFragmentRootWin> n5_fragment_root(InitNodeAsFragmentRoot(
- child_fragment_root_n5_node, n5_fragment_root_delegate.get()));
-
- // Test navigation from root fragment
- ComPtr<IRawElementProviderFragmentRoot> root_fragment_root =
- GetFragmentRoot();
- ComPtr<IRawElementProviderFragment> root_fragment;
- root_fragment_root.As(&root_fragment);
-
- ComPtr<IRawElementProviderFragment> test_fragment;
- EXPECT_HRESULT_SUCCEEDED(
- root_fragment->Navigate(NavigateDirection_Parent, &test_fragment));
- EXPECT_EQ(nullptr, test_fragment.Get());
-
- EXPECT_HRESULT_SUCCEEDED(
- root_fragment->Navigate(NavigateDirection_NextSibling, &test_fragment));
- EXPECT_EQ(nullptr, test_fragment.Get());
-
- EXPECT_HRESULT_SUCCEEDED(root_fragment->Navigate(
- NavigateDirection_PreviousSibling, &test_fragment));
- EXPECT_EQ(nullptr, test_fragment.Get());
-
- EXPECT_HRESULT_SUCCEEDED(
- root_fragment->Navigate(NavigateDirection_FirstChild, &test_fragment));
- ComPtr<IUnknown> root_child_unknown = test_fragment_root_delegate_->child_;
- ComPtr<IRawElementProviderFragment> root_child_fragment;
- root_child_unknown.As(&root_child_fragment);
- EXPECT_EQ(root_child_fragment.Get(), test_fragment.Get());
-
- EXPECT_HRESULT_SUCCEEDED(
- root_fragment->Navigate(NavigateDirection_LastChild, &test_fragment));
- EXPECT_EQ(root_child_fragment.Get(), test_fragment.Get());
-
- // Test navigation from first child root (R3)
- ComPtr<IRawElementProviderFragmentRoot> n3_fragment_root_provider;
- n3_fragment_root->GetNativeViewAccessible()->QueryInterface(
- IID_PPV_ARGS(&n3_fragment_root_provider));
-
- ComPtr<IRawElementProviderFragment> n3_fragment;
- n3_fragment_root_provider.As(&n3_fragment);
- EXPECT_HRESULT_SUCCEEDED(
- n3_fragment->Navigate(NavigateDirection_Parent, &test_fragment));
- EXPECT_EQ(root_child_fragment.Get(), test_fragment.Get());
-
- AXNode* sibling_n2_node = root_node->children()[0];
- EXPECT_HRESULT_SUCCEEDED(
- n3_fragment->Navigate(NavigateDirection_PreviousSibling, &test_fragment));
- EXPECT_EQ(IRawElementProviderFragmentFromNode(sibling_n2_node).Get(),
- test_fragment.Get());
-
- AXNode* sibling_n4_node = root_node->children()[2];
- EXPECT_HRESULT_SUCCEEDED(
- n3_fragment->Navigate(NavigateDirection_NextSibling, &test_fragment));
- EXPECT_EQ(IRawElementProviderFragmentFromNode(sibling_n4_node).Get(),
- test_fragment.Get());
-
- EXPECT_HRESULT_SUCCEEDED(
- n3_fragment->Navigate(NavigateDirection_FirstChild, &test_fragment));
- EXPECT_EQ(
- IRawElementProviderFragmentFromNode(child_fragment_root_n3_node).Get(),
- test_fragment.Get());
- EXPECT_HRESULT_SUCCEEDED(
- n3_fragment->Navigate(NavigateDirection_LastChild, &test_fragment));
- EXPECT_EQ(
- IRawElementProviderFragmentFromNode(child_fragment_root_n3_node).Get(),
- test_fragment.Get());
-
- // Test navigation from second child root (R5)
- ComPtr<IRawElementProviderFragmentRoot> n5_fragment_root_provider;
- n5_fragment_root->GetNativeViewAccessible()->QueryInterface(
- IID_PPV_ARGS(&n5_fragment_root_provider));
-
- ComPtr<IRawElementProviderFragment> n5_fragment;
- n5_fragment_root_provider.As(&n5_fragment);
- EXPECT_HRESULT_SUCCEEDED(
- n5_fragment->Navigate(NavigateDirection_Parent, &test_fragment));
- EXPECT_EQ(root_child_fragment.Get(), test_fragment.Get());
- EXPECT_HRESULT_SUCCEEDED(
- n5_fragment->Navigate(NavigateDirection_NextSibling, &test_fragment));
- EXPECT_EQ(nullptr, test_fragment.Get());
- EXPECT_HRESULT_SUCCEEDED(
- n5_fragment->Navigate(NavigateDirection_PreviousSibling, &test_fragment));
- EXPECT_EQ(IRawElementProviderFragmentFromNode(sibling_n4_node).Get(),
- test_fragment.Get());
- EXPECT_HRESULT_SUCCEEDED(
- n5_fragment->Navigate(NavigateDirection_FirstChild, &test_fragment));
- EXPECT_EQ(
- IRawElementProviderFragmentFromNode(child_fragment_root_n5_node).Get(),
- test_fragment.Get());
- EXPECT_HRESULT_SUCCEEDED(
- n5_fragment->Navigate(NavigateDirection_LastChild, &test_fragment));
- EXPECT_EQ(
- IRawElementProviderFragmentFromNode(child_fragment_root_n5_node).Get(),
- test_fragment.Get());
-}
-
-TEST_F(AXFragmentRootTest, TestFragmentRootMap) {
- AXNodeData root;
- Init(root);
-
- // There should be nothing in the map before we create a fragment root.
- // Call GetForAcceleratedWidget() first to ensure that querying for a
- // fragment root doesn't inadvertently create an empty entry in the map
- // (https://crbug.com/1071185).
- EXPECT_EQ(nullptr, AXFragmentRootWin::GetForAcceleratedWidget(
- gfx::kMockAcceleratedWidget));
- EXPECT_EQ(nullptr, AXFragmentRootWin::GetFragmentRootParentOf(
- GetRootIAccessible().Get()));
-
- // After initializing a fragment root, we should be able to retrieve it using
- // its accelerated widget, or as the parent of its child.
- InitFragmentRoot();
- EXPECT_EQ(ax_fragment_root_.get(), AXFragmentRootWin::GetForAcceleratedWidget(
- gfx::kMockAcceleratedWidget));
- EXPECT_EQ(ax_fragment_root_.get(), AXFragmentRootWin::GetFragmentRootParentOf(
- GetRootIAccessible().Get()));
-
- // After deleting a fragment root, it should no longer be reachable from the
- // map.
- ax_fragment_root_.reset();
- EXPECT_EQ(nullptr, AXFragmentRootWin::GetForAcceleratedWidget(
- gfx::kMockAcceleratedWidget));
- EXPECT_EQ(nullptr, AXFragmentRootWin::GetFragmentRootParentOf(
- GetRootIAccessible().Get()));
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_atk_hyperlink.cc b/third_party/accessibility/ax/platform/ax_platform_atk_hyperlink.cc
deleted file mode 100644
index be91def..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_atk_hyperlink.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_atk_hyperlink.h"
-
-#include <string>
-#include <utility>
-
-#include "ui/accessibility/ax_enum_util.h"
-#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-
-namespace ui {
-
-struct _AXPlatformAtkHyperlinkPrivate {
- AXPlatformNodeAuraLinux* platform_node = nullptr;
-};
-
-static gpointer kAXPlatformAtkHyperlinkParentClass = nullptr;
-
-static AXPlatformNodeAuraLinux* ToAXPlatformNodeAuraLinux(
- AXPlatformAtkHyperlink* atk_hyperlink) {
- if (!atk_hyperlink)
- return nullptr;
- return atk_hyperlink->priv->platform_node;
-}
-
-static void AXPlatformAtkHyperlinkFinalize(GObject* self) {
- AX_PLATFORM_ATK_HYPERLINK(self)->priv->~AXPlatformAtkHyperlinkPrivate();
- G_OBJECT_CLASS(kAXPlatformAtkHyperlinkParentClass)->finalize(self);
-}
-
-static gchar* AXPlatformAtkHyperlinkGetUri(AtkHyperlink* atk_hyperlink,
- gint index) {
- AXPlatformNodeAuraLinux* obj =
- ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink));
- if (!obj)
- return nullptr;
-
- if (index != 0)
- return nullptr;
-
- return g_strdup(
- obj->GetStringAttribute(ax::mojom::StringAttribute::kUrl).c_str());
-}
-
-static AtkObject* AXPlatformAtkHyperlinkGetObject(AtkHyperlink* atk_hyperlink,
- gint index) {
- AXPlatformNodeAuraLinux* obj =
- ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink));
- if (!obj)
- return nullptr;
-
- if (index != 0)
- return nullptr;
-
- return ATK_OBJECT(obj->GetNativeViewAccessible());
-}
-
-static gint AXPlatformAtkHyperlinkGetNAnchors(AtkHyperlink* atk_hyperlink) {
- AXPlatformNodeAuraLinux* obj =
- ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink));
-
- return obj ? 1 : 0;
-}
-
-static gboolean AXPlatformAtkHyperlinkIsValid(AtkHyperlink* atk_hyperlink) {
- AXPlatformNodeAuraLinux* obj =
- ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink));
-
- return obj ? TRUE : FALSE;
-}
-
-static gboolean AXPlatformAtkHyperlinkIsSelectedLink(
- AtkHyperlink* atk_hyperlink) {
- AXPlatformNodeAuraLinux* obj =
- ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink));
- if (!obj)
- return false;
-
- return obj->GetDelegate()->GetFocus() == obj->GetNativeViewAccessible();
-}
-
-static int AXPlatformAtkHyperlinkGetStartIndex(AtkHyperlink* atk_hyperlink) {
- g_return_val_if_fail(IS_AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink), 0);
- AXPlatformAtkHyperlink* link = AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink);
- base::Optional<std::pair<int, int>> indices =
- link->priv->platform_node->GetEmbeddedObjectIndices();
- return indices.has_value() ? indices->first : 0;
-}
-
-static int AXPlatformAtkHyperlinkGetEndIndex(AtkHyperlink* atk_hyperlink) {
- g_return_val_if_fail(IS_AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink), 0);
- AXPlatformAtkHyperlink* link = AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink);
- base::Optional<std::pair<int, int>> indices =
- link->priv->platform_node->GetEmbeddedObjectIndices();
- return indices.has_value() ? indices->second : 0;
-}
-
-static void AXPlatformAtkHyperlinkClassInit(AtkHyperlinkClass* klass) {
- GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
- kAXPlatformAtkHyperlinkParentClass = g_type_class_peek_parent(klass);
-
- g_type_class_add_private(gobject_class,
- sizeof(AXPlatformAtkHyperlinkPrivate));
-
- gobject_class->finalize = AXPlatformAtkHyperlinkFinalize;
- klass->get_uri = AXPlatformAtkHyperlinkGetUri;
- klass->get_object = AXPlatformAtkHyperlinkGetObject;
- klass->is_valid = AXPlatformAtkHyperlinkIsValid;
- klass->get_n_anchors = AXPlatformAtkHyperlinkGetNAnchors;
- klass->is_selected_link = AXPlatformAtkHyperlinkIsSelectedLink;
- klass->get_start_index = AXPlatformAtkHyperlinkGetStartIndex;
- klass->get_end_index = AXPlatformAtkHyperlinkGetEndIndex;
-}
-
-//
-// AtkAction interface.
-//
-
-static AXPlatformNodeAuraLinux* ToAXPlatformNodeAuraLinuxFromHyperlinkAction(
- AtkAction* atk_action) {
- if (!IS_AX_PLATFORM_ATK_HYPERLINK(atk_action))
- return nullptr;
-
- return ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_action));
-}
-
-static gboolean ax_platform_atk_hyperlink_do_action(AtkAction* action,
- gint index) {
- g_return_val_if_fail(ATK_IS_ACTION(action), FALSE);
- g_return_val_if_fail(!index, FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- ToAXPlatformNodeAuraLinuxFromHyperlinkAction(action);
- if (!obj)
- return FALSE;
-
- obj->DoDefaultAction();
-
- return TRUE;
-}
-
-static gint ax_platform_atk_hyperlink_get_n_actions(AtkAction* action) {
- g_return_val_if_fail(ATK_IS_ACTION(action), FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- ToAXPlatformNodeAuraLinuxFromHyperlinkAction(action);
- if (!obj)
- return 0;
-
- return 1;
-}
-
-static const gchar* ax_platform_atk_hyperlink_get_description(AtkAction* action,
- gint index) {
- g_return_val_if_fail(ATK_IS_ACTION(action), FALSE);
- g_return_val_if_fail(!index, FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- ToAXPlatformNodeAuraLinuxFromHyperlinkAction(action);
- if (!obj)
- return nullptr;
-
- // Not implemented
- return nullptr;
-}
-
-static const gchar* ax_platform_atk_hyperlink_get_keybinding(AtkAction* action,
- gint index) {
- g_return_val_if_fail(ATK_IS_ACTION(action), FALSE);
- g_return_val_if_fail(!index, FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- ToAXPlatformNodeAuraLinuxFromHyperlinkAction(action);
- if (!obj)
- return nullptr;
-
- return obj->GetStringAttribute(ax::mojom::StringAttribute::kAccessKey)
- .c_str();
-}
-
-static const gchar* ax_platform_atk_hyperlink_get_name(AtkAction* atk_action,
- gint index) {
- g_return_val_if_fail(ATK_IS_ACTION(atk_action), FALSE);
- g_return_val_if_fail(!index, FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- ToAXPlatformNodeAuraLinuxFromHyperlinkAction(atk_action);
- if (!obj)
- return nullptr;
-
- int action;
- if (!obj->GetIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb,
- &action))
- return nullptr;
- std::string action_verb =
- ui::ToString(static_cast<ax::mojom::DefaultActionVerb>(action));
- ATK_AURALINUX_RETURN_STRING(action_verb);
-}
-
-static const gchar* ax_platform_atk_hyperlink_get_localized_name(
- AtkAction* atk_action,
- gint index) {
- g_return_val_if_fail(ATK_IS_ACTION(atk_action), FALSE);
- g_return_val_if_fail(!index, FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- ToAXPlatformNodeAuraLinuxFromHyperlinkAction(atk_action);
- if (!obj)
- return nullptr;
-
- int action;
- if (!obj->GetIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb,
- &action))
- return nullptr;
- std::string action_verb =
- ui::ToLocalizedString(static_cast<ax::mojom::DefaultActionVerb>(action));
- ATK_AURALINUX_RETURN_STRING(action_verb);
-}
-
-static void atk_action_interface_init(AtkActionIface* iface) {
- iface->do_action = ax_platform_atk_hyperlink_do_action;
- iface->get_n_actions = ax_platform_atk_hyperlink_get_n_actions;
- iface->get_description = ax_platform_atk_hyperlink_get_description;
- iface->get_keybinding = ax_platform_atk_hyperlink_get_keybinding;
- iface->get_name = ax_platform_atk_hyperlink_get_name;
- iface->get_localized_name = ax_platform_atk_hyperlink_get_localized_name;
-}
-
-void ax_platform_atk_hyperlink_set_object(
- AXPlatformAtkHyperlink* atk_hyperlink,
- AXPlatformNodeAuraLinux* platform_node) {
- g_return_if_fail(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink));
- atk_hyperlink->priv->platform_node = platform_node;
-}
-
-static void AXPlatformAtkHyperlinkInit(AXPlatformAtkHyperlink* self, gpointer) {
- AXPlatformAtkHyperlinkPrivate* priv =
- G_TYPE_INSTANCE_GET_PRIVATE(self, ax_platform_atk_hyperlink_get_type(),
- AXPlatformAtkHyperlinkPrivate);
- self->priv = priv;
- new (priv) AXPlatformAtkHyperlinkPrivate();
-}
-
-GType ax_platform_atk_hyperlink_get_type() {
- static volatile gsize type_volatile = 0;
-
- AXPlatformNodeAuraLinux::EnsureGTypeInit();
-
- if (g_once_init_enter(&type_volatile)) {
- static const GTypeInfo tinfo = {
- sizeof(AXPlatformAtkHyperlinkClass),
- (GBaseInitFunc) nullptr,
- (GBaseFinalizeFunc) nullptr,
- (GClassInitFunc)AXPlatformAtkHyperlinkClassInit,
- (GClassFinalizeFunc) nullptr,
- nullptr, /* class data */
- sizeof(AXPlatformAtkHyperlink), /* instance size */
- 0, /* nb preallocs */
- (GInstanceInitFunc)AXPlatformAtkHyperlinkInit,
- nullptr /* value table */
- };
-
- static const GInterfaceInfo actionInfo = {
- (GInterfaceInitFunc)(GInterfaceInitFunc)atk_action_interface_init,
- (GInterfaceFinalizeFunc)0, 0};
-
- GType type = g_type_register_static(
- ATK_TYPE_HYPERLINK, "AXPlatformAtkHyperlink", &tinfo, GTypeFlags(0));
- g_type_add_interface_static(type, ATK_TYPE_ACTION, &actionInfo);
- g_once_init_leave(&type_volatile, type);
- }
-
- return type_volatile;
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_atk_hyperlink.h b/third_party/accessibility/ax/platform/ax_platform_atk_hyperlink.h
deleted file mode 100644
index 30e9112..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_atk_hyperlink.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_ATK_HYPERLINK_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_ATK_HYPERLINK_H_
-
-#include <atk/atk.h>
-
-namespace ui {
-
-class AXPlatformNodeAuraLinux;
-
-G_BEGIN_DECLS
-
-#define AX_PLATFORM_ATK_HYPERLINK_TYPE (ax_platform_atk_hyperlink_get_type())
-#define AX_PLATFORM_ATK_HYPERLINK(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), AX_PLATFORM_ATK_HYPERLINK_TYPE, \
- AXPlatformAtkHyperlink))
-#define AX_PLATFORM_ATK_HYPERLINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), AX_PLATFORM_ATK_HYPERLINK_TYPE, \
- AXPlatformAtkHyperlinkClass))
-#define IS_AX_PLATFORM_ATK_HYPERLINK(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), AX_PLATFORM_ATK_HYPERLINK_TYPE))
-#define IS_AX_PLATFORM_ATK_HYPERLINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), AX_PLATFORM_ATK_HYPERLINK_TYPE))
-#define AX_PLATFORM_ATK_HYPERLINK_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), AX_PLATFORM_ATK_HYPERLINK_TYPE, \
- AXPlatformAtkHyperlinkClass))
-
-typedef struct _AXPlatformAtkHyperlink AXPlatformAtkHyperlink;
-typedef struct _AXPlatformAtkHyperlinkClass AXPlatformAtkHyperlinkClass;
-typedef struct _AXPlatformAtkHyperlinkPrivate AXPlatformAtkHyperlinkPrivate;
-
-struct _AXPlatformAtkHyperlink {
- AtkHyperlink parent;
-
- /*< private >*/
- AXPlatformAtkHyperlinkPrivate* priv;
-};
-
-struct _AXPlatformAtkHyperlinkClass {
- AtkHyperlinkClass parent_class;
-};
-
-GType ax_platform_atk_hyperlink_get_type(void) G_GNUC_CONST;
-void ax_platform_atk_hyperlink_set_object(AXPlatformAtkHyperlink* hyperlink,
- AXPlatformNodeAuraLinux* obj);
-
-G_END_DECLS
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_ATK_HYPERLINK_H_
diff --git a/third_party/accessibility/ax/platform/ax_platform_node.cc b/third_party/accessibility/ax/platform/ax_platform_node.cc
index c0a7427..e81b121 100644
--- a/third_party/accessibility/ax/platform/ax_platform_node.cc
+++ b/third_party/accessibility/ax/platform/ax_platform_node.cc
@@ -2,25 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/platform/ax_platform_node.h"
+#include "ax_platform_node.h"
-#include "base/debug/crash_logging.h"
-#include "base/lazy_instance.h"
-#include "build/build_config.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-#include "ui/base/buildflags.h"
+#include "ax/ax_node_data.h"
+#include "ax_build/build_config.h"
+#include "ax_platform_node_delegate.h"
namespace ui {
-// static
-base::LazyInstance<base::ObserverList<AXModeObserver>::Unchecked>::Leaky
- AXPlatformNode::ax_mode_observers_ = LAZY_INSTANCE_INITIALIZER;
+std::vector<AXModeObserver*> AXPlatformNode::ax_mode_observers_;
-// static
-base::LazyInstance<AXPlatformNode::NativeWindowHandlerCallback>::Leaky
- AXPlatformNode::native_window_handler_ = LAZY_INSTANCE_INITIALIZER;
-
+std::function<AXPlatformNode::NativeWindowHandlerCallback>
+ AXPlatformNode::native_window_handler_;
// static
AXMode AXPlatformNode::ax_mode_;
@@ -30,23 +23,14 @@
// static
AXPlatformNode* AXPlatformNode::FromNativeWindow(
gfx::NativeWindow native_window) {
- if (native_window_handler_.Get())
- return native_window_handler_.Get().Run(native_window);
+ if (native_window_handler_)
+ return native_window_handler_(native_window);
return nullptr;
}
-#if !BUILDFLAG_INTERNAL_HAS_NATIVE_ACCESSIBILITY()
-// static
-AXPlatformNode* AXPlatformNode::FromNativeViewAccessible(
- gfx::NativeViewAccessible accessible) {
- return nullptr;
-}
-#endif // !BUILDFLAG_INTERNAL_HAS_NATIVE_ACCESSIBILITY()
-
-// static
void AXPlatformNode::RegisterNativeWindowHandler(
- AXPlatformNode::NativeWindowHandlerCallback handler) {
- native_window_handler_.Get() = handler;
+ std::function<AXPlatformNode::NativeWindowHandlerCallback> handler) {
+ native_window_handler_ = handler;
}
AXPlatformNode::AXPlatformNode() {}
@@ -56,7 +40,7 @@
void AXPlatformNode::Destroy() {}
int32_t AXPlatformNode::GetUniqueId() const {
- DCHECK(GetDelegate()) << "|GetUniqueId| must be called after |Init|.";
+ BASE_DCHECK(GetDelegate());
return GetDelegate() ? GetDelegate()->GetUniqueId().Get() : -1;
}
@@ -82,12 +66,13 @@
// static
void AXPlatformNode::AddAXModeObserver(AXModeObserver* observer) {
- ax_mode_observers_.Get().AddObserver(observer);
+ ax_mode_observers_.push_back(observer);
}
// static
void AXPlatformNode::RemoveAXModeObserver(AXModeObserver* observer) {
- ax_mode_observers_.Get().RemoveObserver(observer);
+ ax_mode_observers_.erase(std::find(ax_mode_observers_.begin(),
+ ax_mode_observers_.end(), observer));
}
// static
@@ -100,8 +85,8 @@
return; // No change.
ax_mode_ = new_ax_mode;
- for (auto& observer : ax_mode_observers_.Get())
- observer.OnAXModeAdded(mode_flags);
+ for (AXModeObserver* observer : ax_mode_observers_)
+ observer->OnAXModeAdded(mode_flags);
}
// static
diff --git a/third_party/accessibility/ax/platform/ax_platform_node.h b/third_party/accessibility/ax/platform/ax_platform_node.h
index e8ad7ed..07de969 100644
--- a/third_party/accessibility/ax/platform/ax_platform_node.h
+++ b/third_party/accessibility/ax/platform/ax_platform_node.h
@@ -8,15 +8,13 @@
#include <ostream>
#include <string>
-#include "base/callback.h"
-#include "base/lazy_instance.h"
-#include "base/observer_list.h"
-#include "build/build_config.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_mode.h"
-#include "ui/accessibility/ax_mode_observer.h"
-#include "ui/gfx/native_widget_types.h"
+#include "ax/ax_enums.h"
+#include "ax/ax_export.h"
+#include "ax/ax_mode.h"
+#include "ax/ax_mode_observer.h"
+#include "ax_build/build_config.h"
+#include "base/macros.h"
+#include "gfx/native_widget_types.h"
namespace ui {
@@ -29,8 +27,7 @@
// own the AXPlatformNode instance (or otherwise manage its lifecycle).
class AX_EXPORT AXPlatformNode {
public:
- using NativeWindowHandlerCallback =
- base::RepeatingCallback<AXPlatformNode*(gfx::NativeWindow)>;
+ typedef AXPlatformNode* NativeWindowHandlerCallback(gfx::NativeWindow);
// Create an appropriate platform-specific instance. The delegate owns the
// AXPlatformNode instance (or manages its lifecycle in some other way).
@@ -46,7 +43,8 @@
// Provide a function that returns the AXPlatformNode at the root of the
// tree for a native window.
- static void RegisterNativeWindowHandler(NativeWindowHandlerCallback handler);
+ static void RegisterNativeWindowHandler(
+ std::function<NativeWindowHandlerCallback> handler);
// Register and unregister to receive notifications about AXMode changes
// for this node.
@@ -83,7 +81,7 @@
#if defined(OS_APPLE)
// Fire a platform-specific notification to announce |text|.
- virtual void AnnounceText(const base::string16& text) = 0;
+ virtual void AnnounceText(const std::u16string& text) = 0;
#endif
// Return this object's delegate.
@@ -113,14 +111,8 @@
virtual ~AXPlatformNode();
private:
- FRIEND_TEST_ALL_PREFIXES(AtkUtilAuraLinuxTest, KeySnooping);
-
- // Global ObserverList for AXMode changes.
- static base::LazyInstance<
- base::ObserverList<AXModeObserver>::Unchecked>::Leaky ax_mode_observers_;
-
- static base::LazyInstance<NativeWindowHandlerCallback>::Leaky
- native_window_handler_;
+ static std::vector<AXModeObserver*> ax_mode_observers_;
+ static std::function<NativeWindowHandlerCallback> native_window_handler_;
static AXMode ax_mode_;
@@ -131,7 +123,7 @@
bool is_primary_web_contents_for_window_ = false;
- DISALLOW_COPY_AND_ASSIGN(AXPlatformNode);
+ BASE_DISALLOW_COPY_AND_ASSIGN(AXPlatformNode);
};
} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_auralinux.cc b/third_party/accessibility/ax/platform/ax_platform_node_auralinux.cc
deleted file mode 100644
index 3f34264..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_auralinux.cc
+++ /dev/null
@@ -1,5077 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
-
-#include <dlfcn.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/command_line.h"
-#include "base/compiler_specific.h"
-#include "base/debug/leak_annotations.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/no_destructor.h"
-#include "base/numerics/ranges.h"
-#include "base/optional.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversion_utils.h"
-#include "base/strings/utf_string_conversions.h"
-#include "build/build_config.h"
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_enum_util.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_mode_observer.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_tree_data.h"
-#include "ui/accessibility/platform/atk_util_auralinux.h"
-#include "ui/accessibility/platform/ax_platform_atk_hyperlink.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate_base.h"
-#include "ui/accessibility/platform/ax_platform_text_boundary.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-
-#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 10, 0)
-#define ATK_210
-#endif
-
-#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 12, 0)
-#define ATK_212
-#endif
-
-#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 16, 0)
-#define ATK_216
-#endif
-
-#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 26, 0)
-#define ATK_226
-#endif
-
-#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 30, 0)
-#define ATK_230
-#endif
-
-#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 32, 0)
-#define ATK_232
-#endif
-
-#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 34, 0)
-#define ATK_234
-#endif
-
-namespace ui {
-
-namespace {
-
-// IMPORTANT!
-// These values are written to logs. Do not renumber or delete
-// existing items; add new entries to the end of the list.
-enum class UmaAtkApi {
- kGetName = 0,
- kGetDescription = 1,
- kGetNChildren = 2,
- kRefChild = 3,
- kGetIndexInParent = 4,
- kGetParent = 5,
- kRefRelationSet = 6,
- kGetAttributes = 7,
- kGetRole = 8,
- kRefStateSet = 9,
- // This must always be the last enum. It's okay for its value to
- // increase, but none of the other enum values may change.
- kMaxValue = kRefStateSet,
-};
-
-void RecordAccessibilityAtkApi(UmaAtkApi enum_value) {
- UMA_HISTOGRAM_ENUMERATION("Accessibility.ATK-APIs", enum_value);
-}
-
-// When accepting input from clients calling the API, an ATK character offset
-// of -1 can often represent the length of the string.
-static const int kStringLengthOffset = -1;
-
-// We must forward declare this because it is used by the traditional GObject
-// type manipulation macros.
-namespace atk_object {
-GType GetType();
-} // namespace atk_object
-
-//
-// ax_platform_node_auralinux AtkObject definition and implementation.
-//
-#define AX_PLATFORM_NODE_AURALINUX_TYPE (atk_object::GetType())
-#define AX_PLATFORM_NODE_AURALINUX(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), AX_PLATFORM_NODE_AURALINUX_TYPE, \
- AXPlatformNodeAuraLinuxObject))
-#define AX_PLATFORM_NODE_AURALINUX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), AX_PLATFORM_NODE_AURALINUX_TYPE, \
- AXPlatformNodeAuraLinuxClass))
-#define IS_AX_PLATFORM_NODE_AURALINUX(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), AX_PLATFORM_NODE_AURALINUX_TYPE))
-#define IS_AX_PLATFORM_NODE_AURALINUX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), AX_PLATFORM_NODE_AURALINUX_TYPE))
-#define AX_PLATFORM_NODE_AURALINUX_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), AX_PLATFORM_NODE_AURALINUX_TYPE, \
- AXPlatformNodeAuraLinuxClass))
-
-typedef struct _AXPlatformNodeAuraLinuxObject AXPlatformNodeAuraLinuxObject;
-typedef struct _AXPlatformNodeAuraLinuxClass AXPlatformNodeAuraLinuxClass;
-
-struct _AXPlatformNodeAuraLinuxObject {
- AtkObject parent;
- AXPlatformNodeAuraLinux* m_object;
-};
-
-struct _AXPlatformNodeAuraLinuxClass {
- AtkObjectClass parent_class;
-};
-
-// The root-level Application object that's the parent of all top-level windows.
-AXPlatformNode* g_root_application = nullptr;
-
-// The last AtkObject with keyboard focus. Tracking this is required to emit the
-// ATK_STATE_FOCUSED change to false.
-AtkObject* g_current_focused = nullptr;
-
-// The last AtkObject which was the active descendant in the currently-focused
-// object (example: The highlighted option within a focused select element).
-// As with g_current_focused, we track this to emit events when this object is
-// no longer the active descendant.
-AtkObject* g_current_active_descendant = nullptr;
-
-// The last object which was selected. Tracking this is required because
-// widgets in the browser UI only emit notifications upon becoming selected,
-// but clients also expect notifications when items become unselected.
-AXPlatformNodeAuraLinux* g_current_selected = nullptr;
-
-// The AtkObject with role=ATK_ROLE_FRAME that represents the toplevel desktop
-// window with focus. If this window is not one of our windows, this value
-// should be null. This is a weak pointer as well, so its value will also be
-// null if if the AtkObject is destroyed.
-AtkObject* g_active_top_level_frame = nullptr;
-
-AtkObject* g_active_views_dialog = nullptr;
-
-#if defined(ATK_216)
-constexpr AtkRole kStaticRole = ATK_ROLE_STATIC;
-constexpr AtkRole kSubscriptRole = ATK_ROLE_SUBSCRIPT;
-constexpr AtkRole kSuperscriptRole = ATK_ROLE_SUPERSCRIPT;
-#else
-constexpr AtkRole kStaticRole = ATK_ROLE_TEXT;
-constexpr AtkRole kSubscriptRole = ATK_ROLE_TEXT;
-constexpr AtkRole kSuperscriptRole = ATK_ROLE_TEXT;
-#endif
-
-#if defined(ATK_226)
-constexpr AtkRole kAtkFootnoteRole = ATK_ROLE_FOOTNOTE;
-#else
-constexpr AtkRole kAtkFootnoteRole = ATK_ROLE_LIST_ITEM;
-#endif
-
-#if defined(ATK_234)
-constexpr AtkRole kAtkRoleContentDeletion = ATK_ROLE_CONTENT_DELETION;
-constexpr AtkRole kAtkRoleContentInsertion = ATK_ROLE_CONTENT_INSERTION;
-#else
-constexpr AtkRole kAtkRoleContentDeletion = ATK_ROLE_SECTION;
-constexpr AtkRole kAtkRoleContentInsertion = ATK_ROLE_SECTION;
-#endif
-
-using GetTypeFunc = GType (*)();
-using GetColumnHeaderCellsFunc = GPtrArray* (*)(AtkTableCell* cell);
-using GetRowHeaderCellsFunc = GPtrArray* (*)(AtkTableCell* cell);
-using GetRowColumnSpanFunc = bool (*)(AtkTableCell* cell,
- gint* row,
- gint* column,
- gint* row_span,
- gint* col_span);
-
-static GetTypeFunc g_atk_table_cell_get_type;
-static GetColumnHeaderCellsFunc g_atk_table_cell_get_column_header_cells;
-static GetRowHeaderCellsFunc g_atk_table_cell_get_row_header_cells;
-static GetRowColumnSpanFunc g_atk_table_cell_get_row_column_span;
-
-// The ATK API often requires pointers to be used as out arguments, while
-// allowing for those pointers to be null if the caller is not interested in
-// the value. This function is a simpler helper to avoid continually checking
-// for null and to help prevent forgetting to check for null.
-void SetIntPointerValueIfNotNull(int* pointer, int value) {
- if (pointer)
- *pointer = value;
-}
-
-#if defined(ATK_230)
-bool SupportsAtkComponentScrollingInterface() {
- return dlsym(RTLD_DEFAULT, "atk_component_scroll_to_point");
-}
-#endif
-
-#if defined(ATK_232)
-bool SupportsAtkTextScrollingInterface() {
- return dlsym(RTLD_DEFAULT, "atk_text_scroll_substring_to_point");
-}
-#endif
-
-AtkObject* FindAtkObjectParentFrame(AtkObject* atk_object) {
- AXPlatformNodeAuraLinux* node =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- while (node) {
- if (node->GetAtkRole() == ATK_ROLE_FRAME)
- return node->GetNativeViewAccessible();
- node = AXPlatformNodeAuraLinux::FromAtkObject(node->GetParent());
- }
- return nullptr;
-}
-
-AtkObject* FindAtkObjectToplevelParentDocument(AtkObject* atk_object) {
- AXPlatformNodeAuraLinux* node =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- AtkObject* toplevel_document = nullptr;
- while (node) {
- if (node->GetAtkRole() == ATK_ROLE_DOCUMENT_WEB)
- toplevel_document = node->GetNativeViewAccessible();
- node = AXPlatformNodeAuraLinux::FromAtkObject(node->GetParent());
- }
- return toplevel_document;
-}
-
-bool IsFrameAncestorOfAtkObject(AtkObject* frame, AtkObject* atk_object) {
- AtkObject* current_frame = FindAtkObjectParentFrame(atk_object);
- while (current_frame) {
- if (current_frame == frame)
- return true;
- AXPlatformNodeAuraLinux* frame_node =
- AXPlatformNodeAuraLinux::FromAtkObject(current_frame);
- current_frame = FindAtkObjectParentFrame(frame_node->GetParent());
- }
- return false;
-}
-
-// Returns a stack of AtkObjects of activated popup menus. Since each popup
-// menu and submenu has its own native window, we want to properly manage the
-// activated state for their containing frames.
-std::vector<AtkObject*>& GetActiveMenus() {
- static base::NoDestructor<std::vector<AtkObject*>> active_menus;
- return *active_menus;
-}
-
-std::map<AtkObject*, FindInPageResultInfo>& GetActiveFindInPageResults() {
- static base::NoDestructor<std::map<AtkObject*, FindInPageResultInfo>>
- active_results;
- return *active_results;
-}
-
-// The currently active frame is g_active_top_level_frame, unless there is an
-// active menu. If there is an active menu the parent frame of the
-// most-recently opened active menu should be the currently active frame.
-AtkObject* ComputeActiveTopLevelFrame() {
- if (!GetActiveMenus().empty())
- return FindAtkObjectParentFrame(GetActiveMenus().back());
- return g_active_top_level_frame;
-}
-
-const char* GetUniqueAccessibilityGTypeName(
- ImplementedAtkInterfaces interface_mask) {
- // 37 characters is enough for "AXPlatformNodeAuraLinux%x" with any integer
- // value.
- static char name[37];
- snprintf(name, sizeof(name), "AXPlatformNodeAuraLinux%x",
- interface_mask.value());
- return name;
-}
-
-void SetWeakGPtrToAtkObject(AtkObject** weak_pointer, AtkObject* new_value) {
- DCHECK(weak_pointer);
- if (*weak_pointer == new_value)
- return;
-
- if (*weak_pointer) {
- g_object_remove_weak_pointer(G_OBJECT(*weak_pointer),
- reinterpret_cast<void**>(weak_pointer));
- }
-
- *weak_pointer = new_value;
-
- if (new_value) {
- g_object_add_weak_pointer(G_OBJECT(new_value),
- reinterpret_cast<void**>(weak_pointer));
- }
-}
-
-void SetActiveTopLevelFrame(AtkObject* new_top_level_frame) {
- SetWeakGPtrToAtkObject(&g_active_top_level_frame, new_top_level_frame);
-}
-
-AXCoordinateSystem AtkCoordTypeToAXCoordinateSystem(
- AtkCoordType coordinate_type) {
- switch (coordinate_type) {
- case ATK_XY_SCREEN:
- return AXCoordinateSystem::kScreenDIPs;
- case ATK_XY_WINDOW:
- return AXCoordinateSystem::kRootFrame;
-#if defined(ATK_230)
- case ATK_XY_PARENT:
- // AXCoordinateSystem does not support parent coordinates.
- NOTIMPLEMENTED();
- return AXCoordinateSystem::kFrame;
-#endif
- default:
- return AXCoordinateSystem::kScreenDIPs;
- }
-}
-
-const char* BuildDescriptionFromHeaders(AXPlatformNodeDelegate* delegate,
- const std::vector<int32_t>& ids) {
- std::vector<std::string> names;
- for (const auto& node_id : ids) {
- if (AXPlatformNode* header = delegate->GetFromNodeID(node_id)) {
- if (AtkObject* atk_header = header->GetNativeViewAccessible())
- names.push_back(atk_object_get_name(atk_header));
- }
- }
-
- std::string result = base::JoinString(names, " ");
-
-#if defined(LEAK_SANITIZER) && !defined(OS_NACL)
- // http://crbug.com/982839
- // atk_table_get_column_description and atk_table_get_row_description return
- // const gchar*, which suggests the caller does not gain ownership of the
- // returned string. The g_strdup below causes a new allocation, which does not
- // fit that pattern and causes a leak in tests.
- ScopedLeakSanitizerDisabler lsan_disabler;
-#endif
-
- return g_strdup(result.c_str());
-}
-
-gfx::Point FindAtkObjectParentCoords(AtkObject* atk_object) {
- if (!atk_object)
- return gfx::Point(0, 0);
-
- AXPlatformNodeAuraLinux* node =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (node->GetAtkRole() == ATK_ROLE_FRAME) {
- int x, y;
- atk_component_get_extents(ATK_COMPONENT(atk_object), &x, &y, nullptr,
- nullptr, ATK_XY_WINDOW);
- gfx::Point window_coords(x, y);
- return window_coords;
- }
- atk_object = node->GetParent();
-
- return FindAtkObjectParentCoords(atk_object);
-}
-
-AtkAttributeSet* PrependAtkAttributeToAtkAttributeSet(
- const char* name,
- const char* value,
- AtkAttributeSet* attribute_set) {
- AtkAttribute* attribute =
- static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute)));
- attribute->name = g_strdup(name);
- attribute->value = g_strdup(value);
- return g_slist_prepend(attribute_set, attribute);
-}
-
-AtkObject* GetActiveDescendantOfCurrentFocused() {
- if (!g_current_focused)
- return nullptr;
-
- auto* node = AXPlatformNodeAuraLinux::FromAtkObject(g_current_focused);
- if (!node)
- return nullptr;
-
- int32_t id =
- node->GetIntAttribute(ax::mojom::IntAttribute::kActivedescendantId);
- if (auto* descendant = node->GetDelegate()->GetFromNodeID(id))
- return descendant->GetNativeViewAccessible();
-
- return nullptr;
-}
-
-void PrependTextAttributeToSet(const std::string& attribute,
- const std::string& value,
- AtkAttributeSet** attributes) {
- DCHECK(attributes);
-
- AtkAttribute* new_attribute =
- static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute)));
- new_attribute->name = g_strdup(attribute.c_str());
- new_attribute->value = g_strdup(value.c_str());
- *attributes = g_slist_prepend(*attributes, new_attribute);
-}
-
-void PrependAtkTextAttributeToSet(const AtkTextAttribute attribute,
- const std::string& value,
- AtkAttributeSet** attributes) {
- PrependTextAttributeToSet(atk_text_attribute_get_name(attribute), value,
- attributes);
-}
-
-std::string ToAtkTextAttributeColor(const std::string color) {
- // The platform-independent color string is in the form "rgb(r, g, b)",
- // but ATK expects a string like "r, g, b". We convert the string here
- // by stripping away the unnecessary characters.
- DCHECK(base::StartsWith(color, "rgb(", base::CompareCase::INSENSITIVE_ASCII));
- DCHECK(base::EndsWith(color, ")", base::CompareCase::INSENSITIVE_ASCII));
- return color.substr(4, color.length() - 5);
-}
-
-AtkAttributeSet* ToAtkAttributeSet(const TextAttributeList& attributes) {
- AtkAttributeSet* copied_attributes = nullptr;
- for (const auto& attribute : attributes) {
- if (attribute.first == "background-color") {
- PrependAtkTextAttributeToSet(ATK_TEXT_ATTR_BG_COLOR,
- ToAtkTextAttributeColor(attribute.second),
- &copied_attributes);
- } else if (attribute.first == "color") {
- PrependAtkTextAttributeToSet(ATK_TEXT_ATTR_FG_COLOR,
- ToAtkTextAttributeColor(attribute.second),
- &copied_attributes);
- } else if (attribute.first == "font-family") {
- PrependAtkTextAttributeToSet(ATK_TEXT_ATTR_FAMILY_NAME, attribute.second,
- &copied_attributes);
- } else if (attribute.first == "font-size") {
- PrependAtkTextAttributeToSet(ATK_TEXT_ATTR_SIZE, attribute.second,
- &copied_attributes);
- } else if (attribute.first == "font-weight" && attribute.second == "bold") {
- PrependAtkTextAttributeToSet(ATK_TEXT_ATTR_WEIGHT, "700",
- &copied_attributes);
- } else if (attribute.first == "font-style") {
- PrependAtkTextAttributeToSet(ATK_TEXT_ATTR_STYLE, "italic",
- &copied_attributes);
- } else if (attribute.first == "text-line-through-style") {
- PrependAtkTextAttributeToSet(ATK_TEXT_ATTR_STRIKETHROUGH, "true",
- &copied_attributes);
- } else if (attribute.first == "text-underline-style") {
- PrependAtkTextAttributeToSet(ATK_TEXT_ATTR_UNDERLINE, "single",
- &copied_attributes);
- } else if (attribute.first == "invalid") {
- PrependAtkTextAttributeToSet(ATK_TEXT_ATTR_INVALID, attribute.second,
- &copied_attributes);
- PrependAtkTextAttributeToSet(ATK_TEXT_ATTR_UNDERLINE, "error",
- &copied_attributes);
- } else if (attribute.first == "language") {
- PrependAtkTextAttributeToSet(ATK_TEXT_ATTR_LANGUAGE, attribute.second,
- &copied_attributes);
- } else if (attribute.first == "writing-mode") {
- PrependAtkTextAttributeToSet(ATK_TEXT_ATTR_DIRECTION, attribute.second,
- &copied_attributes);
- } else if (attribute.first == "text-position") {
- PrependTextAttributeToSet(attribute.first, attribute.second,
- &copied_attributes);
- }
- }
-
- return g_slist_reverse(copied_attributes);
-}
-
-namespace atk_component {
-
-void GetExtents(AtkComponent* atk_component,
- gint* x,
- gint* y,
- gint* width,
- gint* height,
- AtkCoordType coord_type) {
- g_return_if_fail(ATK_IS_COMPONENT(atk_component));
-
- if (x)
- *x = 0;
- if (y)
- *y = 0;
- if (width)
- *width = 0;
- if (height)
- *height = 0;
-
- AtkObject* atk_object = ATK_OBJECT(atk_component);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return;
-
- obj->GetExtents(x, y, width, height, coord_type);
-}
-
-void GetPosition(AtkComponent* atk_component,
- gint* x,
- gint* y,
- AtkCoordType coord_type) {
- g_return_if_fail(ATK_IS_COMPONENT(atk_component));
-
- if (x)
- *x = 0;
- if (y)
- *y = 0;
-
- AtkObject* atk_object = ATK_OBJECT(atk_component);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return;
-
- obj->GetPosition(x, y, coord_type);
-}
-
-void GetSize(AtkComponent* atk_component, gint* width, gint* height) {
- g_return_if_fail(ATK_IS_COMPONENT(atk_component));
-
- if (width)
- *width = 0;
- if (height)
- *height = 0;
-
- AtkObject* atk_object = ATK_OBJECT(atk_component);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return;
-
- obj->GetSize(width, height);
-}
-
-AtkObject* RefAccesibleAtPoint(AtkComponent* atk_component,
- gint x,
- gint y,
- AtkCoordType coord_type) {
- g_return_val_if_fail(ATK_IS_COMPONENT(atk_component), nullptr);
- AtkObject* atk_object = ATK_OBJECT(atk_component);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- AtkObject* result = obj->HitTestSync(x, y, coord_type);
- if (result)
- g_object_ref(result);
- return result;
-}
-
-gboolean GrabFocus(AtkComponent* atk_component) {
- g_return_val_if_fail(ATK_IS_COMPONENT(atk_component), FALSE);
- AtkObject* atk_object = ATK_OBJECT(atk_component);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return FALSE;
-
- return obj->GrabFocus();
-}
-
-#if defined(ATK_230)
-gboolean ScrollTo(AtkComponent* atk_component, AtkScrollType scroll_type) {
- g_return_val_if_fail(ATK_IS_COMPONENT(atk_component), FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_component));
- if (!obj)
- return FALSE;
-
- obj->ScrollNodeIntoView(scroll_type);
- return TRUE;
-}
-
-gboolean ScrollToPoint(AtkComponent* atk_component,
- AtkCoordType atk_coord_type,
- gint x,
- gint y) {
- g_return_val_if_fail(ATK_IS_COMPONENT(atk_component), FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_component));
- if (!obj)
- return FALSE;
-
- obj->ScrollToPoint(atk_coord_type, x, y);
- return TRUE;
-}
-#endif
-
-void Init(AtkComponentIface* iface) {
- iface->get_extents = GetExtents;
- iface->get_position = GetPosition;
- iface->get_size = GetSize;
- iface->ref_accessible_at_point = RefAccesibleAtPoint;
- iface->grab_focus = GrabFocus;
-#if defined(ATK_230)
- if (SupportsAtkComponentScrollingInterface()) {
- iface->scroll_to = ScrollTo;
- iface->scroll_to_point = ScrollToPoint;
- }
-#endif
-}
-
-const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
- nullptr, nullptr};
-
-} // namespace atk_component
-
-namespace atk_action {
-
-gboolean DoAction(AtkAction* atk_action, gint index) {
- g_return_val_if_fail(ATK_IS_ACTION(atk_action), FALSE);
- g_return_val_if_fail(!index, FALSE);
-
- AtkObject* atk_object = ATK_OBJECT(atk_action);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return FALSE;
-
- return obj->DoDefaultAction();
-}
-
-gint GetNActions(AtkAction* atk_action) {
- g_return_val_if_fail(ATK_IS_ACTION(atk_action), 0);
-
- AtkObject* atk_object = ATK_OBJECT(atk_action);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return 0;
-
- return 1;
-}
-
-const gchar* GetDescription(AtkAction*, gint) {
- // Not implemented. Right now Orca does not provide this and
- // Chromium is not providing a string for the action description.
- return nullptr;
-}
-
-const gchar* GetName(AtkAction* atk_action, gint index) {
- g_return_val_if_fail(ATK_IS_ACTION(atk_action), nullptr);
- g_return_val_if_fail(!index, nullptr);
-
- AtkObject* atk_object = ATK_OBJECT(atk_action);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- return obj->GetDefaultActionName();
-}
-
-const gchar* GetKeybinding(AtkAction* atk_action, gint index) {
- g_return_val_if_fail(ATK_IS_ACTION(atk_action), nullptr);
- g_return_val_if_fail(!index, nullptr);
-
- AtkObject* atk_object = ATK_OBJECT(atk_action);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- return obj->GetStringAttribute(ax::mojom::StringAttribute::kAccessKey)
- .c_str();
-}
-
-void Init(AtkActionIface* iface) {
- iface->do_action = DoAction;
- iface->get_n_actions = GetNActions;
- iface->get_description = GetDescription;
- iface->get_name = GetName;
- iface->get_keybinding = GetKeybinding;
-}
-
-const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
- nullptr, nullptr};
-
-} // namespace atk_action
-
-namespace atk_document {
-
-const gchar* GetDocumentAttributeValue(AtkDocument* atk_doc,
- const gchar* attribute) {
- g_return_val_if_fail(ATK_IS_DOCUMENT(atk_doc), nullptr);
-
- AtkObject* atk_object = ATK_OBJECT(atk_doc);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- return obj->GetDocumentAttributeValue(attribute);
-}
-
-AtkAttributeSet* GetDocumentAttributes(AtkDocument* atk_doc) {
- g_return_val_if_fail(ATK_IS_DOCUMENT(atk_doc), 0);
-
- AtkObject* atk_object = ATK_OBJECT(atk_doc);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- return obj->GetDocumentAttributes();
-}
-
-void Init(AtkDocumentIface* iface) {
- iface->get_document_attribute_value = GetDocumentAttributeValue;
- iface->get_document_attributes = GetDocumentAttributes;
-}
-
-const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
- nullptr, nullptr};
-
-} // namespace atk_document
-
-namespace atk_image {
-
-void GetImagePosition(AtkImage* atk_img,
- gint* x,
- gint* y,
- AtkCoordType coord_type) {
- g_return_if_fail(ATK_IMAGE(atk_img));
-
- AtkObject* atk_object = ATK_OBJECT(atk_img);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return;
-
- obj->GetPosition(x, y, coord_type);
-}
-
-const gchar* GetImageDescription(AtkImage* atk_img) {
- g_return_val_if_fail(ATK_IMAGE(atk_img), nullptr);
-
- AtkObject* atk_object = ATK_OBJECT(atk_img);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- return obj->GetStringAttribute(ax::mojom::StringAttribute::kDescription)
- .c_str();
-}
-
-void GetImageSize(AtkImage* atk_img, gint* width, gint* height) {
- g_return_if_fail(ATK_IMAGE(atk_img));
-
- AtkObject* atk_object = ATK_OBJECT(atk_img);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return;
-
- obj->GetSize(width, height);
-}
-
-void Init(AtkImageIface* iface) {
- iface->get_image_position = GetImagePosition;
- iface->get_image_description = GetImageDescription;
- iface->get_image_size = GetImageSize;
-}
-
-const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
- nullptr, nullptr};
-
-} // namespace atk_image
-
-namespace atk_value {
-
-void GetCurrentValue(AtkValue* atk_value, GValue* value) {
- g_return_if_fail(ATK_IS_VALUE(atk_value));
-
- AtkObject* atk_object = ATK_OBJECT(atk_value);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return;
-
- obj->GetFloatAttributeInGValue(ax::mojom::FloatAttribute::kValueForRange,
- value);
-}
-
-void GetMinimumValue(AtkValue* atk_value, GValue* value) {
- g_return_if_fail(ATK_IS_VALUE(atk_value));
-
- AtkObject* atk_object = ATK_OBJECT(atk_value);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return;
-
- obj->GetFloatAttributeInGValue(ax::mojom::FloatAttribute::kMinValueForRange,
- value);
-}
-
-void GetMaximumValue(AtkValue* atk_value, GValue* value) {
- g_return_if_fail(ATK_IS_VALUE(atk_value));
-
- AtkObject* atk_object = ATK_OBJECT(atk_value);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return;
-
- obj->GetFloatAttributeInGValue(ax::mojom::FloatAttribute::kMaxValueForRange,
- value);
-}
-
-void GetMinimumIncrement(AtkValue* atk_value, GValue* value) {
- g_return_if_fail(ATK_IS_VALUE(atk_value));
-
- AtkObject* atk_object = ATK_OBJECT(atk_value);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return;
-
- obj->GetFloatAttributeInGValue(ax::mojom::FloatAttribute::kStepValueForRange,
- value);
-}
-
-gboolean SetCurrentValue(AtkValue* atk_value, const GValue* value) {
- g_return_val_if_fail(ATK_IS_VALUE(atk_value), FALSE);
-
- AtkObject* atk_object = ATK_OBJECT(atk_value);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return FALSE;
-
- std::string new_value;
- switch (G_VALUE_TYPE(value)) {
- case G_TYPE_FLOAT:
- new_value = base::NumberToString(g_value_get_float(value));
- break;
- case G_TYPE_INT:
- new_value = base::NumberToString(g_value_get_int(value));
- break;
- case G_TYPE_INT64:
- new_value = base::NumberToString(g_value_get_int64(value));
- break;
- case G_TYPE_STRING:
- new_value = g_value_get_string(value);
- break;
- default:
- return FALSE;
- }
-
- AXActionData data;
- data.action = ax::mojom::Action::kSetValue;
- data.value = new_value;
- obj->GetDelegate()->AccessibilityPerformAction(data);
- return TRUE;
-}
-
-void Init(AtkValueIface* iface) {
- iface->get_current_value = GetCurrentValue;
- iface->get_maximum_value = GetMaximumValue;
- iface->get_minimum_value = GetMinimumValue;
- iface->get_minimum_increment = GetMinimumIncrement;
- iface->set_current_value = SetCurrentValue;
-}
-
-const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
- nullptr, nullptr};
-
-} // namespace atk_value
-
-namespace atk_hyperlink {
-
-AtkHyperlink* GetHyperlink(AtkHyperlinkImpl* atk_hyperlink_impl) {
- g_return_val_if_fail(ATK_HYPERLINK_IMPL(atk_hyperlink_impl), 0);
-
- AtkObject* atk_object = ATK_OBJECT(atk_hyperlink_impl);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return 0;
-
- AtkHyperlink* atk_hyperlink = obj->GetAtkHyperlink();
- g_object_ref(atk_hyperlink);
-
- return atk_hyperlink;
-}
-
-void Init(AtkHyperlinkImplIface* iface) {
- iface->get_hyperlink = GetHyperlink;
-}
-
-const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
- nullptr, nullptr};
-
-} // namespace atk_hyperlink
-
-namespace atk_hypertext {
-
-AtkHyperlink* GetLink(AtkHypertext* hypertext, int index) {
- g_return_val_if_fail(ATK_HYPERTEXT(hypertext), 0);
- auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(hypertext));
- if (!obj)
- return nullptr;
-
- const AXHypertext& ax_hypertext = obj->GetAXHypertext();
- if (index > static_cast<int>(ax_hypertext.hyperlinks.size()) || index < 0)
- return nullptr;
-
- int32_t id = ax_hypertext.hyperlinks[index];
- auto* link = static_cast<AXPlatformNodeAuraLinux*>(
- AXPlatformNodeBase::GetFromUniqueId(id));
- if (!link)
- return nullptr;
-
- return link->GetAtkHyperlink();
-}
-
-int GetNLinks(AtkHypertext* hypertext) {
- g_return_val_if_fail(ATK_HYPERTEXT(hypertext), 0);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(hypertext));
- return obj ? obj->GetAXHypertext().hyperlinks.size() : 0;
-}
-
-int GetLinkIndex(AtkHypertext* hypertext, int char_index) {
- g_return_val_if_fail(ATK_HYPERTEXT(hypertext), 0);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(hypertext));
- if (!obj)
- return -1;
-
- auto it = obj->GetAXHypertext().hyperlink_offset_to_index.find(char_index);
- if (it == obj->GetAXHypertext().hyperlink_offset_to_index.end())
- return -1;
- return it->second;
-}
-
-void Init(AtkHypertextIface* iface) {
- iface->get_link = GetLink;
- iface->get_n_links = GetNLinks;
- iface->get_link_index = GetLinkIndex;
-}
-
-const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
- nullptr, nullptr};
-
-} // namespace atk_hypertext
-
-namespace atk_text {
-
-gchar* GetText(AtkText* atk_text, gint start_offset, gint end_offset) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), nullptr);
-
- AtkObject* atk_object = ATK_OBJECT(atk_text);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- base::string16 text = obj->GetHypertext();
-
- start_offset = obj->UnicodeToUTF16OffsetInText(start_offset);
- if (start_offset < 0 || start_offset >= static_cast<int>(text.size()))
- return nullptr;
-
- if (end_offset < 0) {
- end_offset = text.size();
- } else {
- end_offset = obj->UnicodeToUTF16OffsetInText(end_offset);
- end_offset = base::ClampToRange(int{text.size()}, start_offset, end_offset);
- }
-
- DCHECK_GE(start_offset, 0);
- DCHECK_GE(end_offset, start_offset);
-
- return g_strdup(
- base::UTF16ToUTF8(text.substr(start_offset, end_offset - start_offset))
- .c_str());
-}
-
-gint GetCharacterCount(AtkText* atk_text) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), 0);
-
- AtkObject* atk_object = ATK_OBJECT(atk_text);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return 0;
-
- return obj->UTF16ToUnicodeOffsetInText(obj->GetHypertext().length());
-}
-
-gunichar GetCharacterAtOffset(AtkText* atk_text, int offset) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), 0);
-
- AtkObject* atk_object = ATK_OBJECT(atk_text);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return 0;
-
- base::string16 text = obj->GetHypertext();
- int32_t text_length = text.length();
-
- offset = obj->UnicodeToUTF16OffsetInText(offset);
- int32_t limited_offset = base::ClampToRange(offset, 0, text_length);
-
- uint32_t code_point;
- base::ReadUnicodeCharacter(text.c_str(), text_length + 1, &limited_offset,
- &code_point);
- return code_point;
-}
-
-gint GetOffsetAtPoint(AtkText* text, gint x, gint y, AtkCoordType coords) {
- g_return_val_if_fail(ATK_IS_TEXT(text), -1);
-
- AtkObject* atk_object = ATK_OBJECT(text);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return -1;
-
- return obj->GetTextOffsetAtPoint(x, y, coords);
-}
-
-// This function returns a single character as a UTF-8 encoded C string because
-// the character may be encoded into more than one byte.
-char* GetCharacter(AtkText* atk_text,
- int offset,
- int* start_offset,
- int* end_offset) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), nullptr);
-
- *start_offset = -1;
- *end_offset = -1;
-
- AtkObject* atk_object = ATK_OBJECT(atk_text);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- if (offset < 0 || offset >= GetCharacterCount(atk_text))
- return nullptr;
-
- char* text = GetText(atk_text, offset, offset + 1);
- if (!text)
- return nullptr;
-
- *start_offset = offset;
- *end_offset = offset + 1;
- return text;
-}
-
-char* GetTextWithBoundaryType(AtkText* atk_text,
- int offset,
- ax::mojom::TextBoundary boundary,
- int* start_offset_ptr,
- int* end_offset_ptr) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), nullptr);
-
- AtkObject* atk_object = ATK_OBJECT(atk_text);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- if (offset < 0 || offset >= atk_text_get_character_count(atk_text))
- return nullptr;
-
- // The offset that we receive from the API is a Unicode character offset.
- // Since we calculate boundaries in terms of UTF-16 code point offsets, we
- // need to convert this input value.
- offset = obj->UnicodeToUTF16OffsetInText(offset);
-
- int start_offset = obj->FindTextBoundary(
- boundary, offset, ax::mojom::MoveDirection::kBackward,
- ax::mojom::TextAffinity::kDownstream);
- int end_offset = obj->FindTextBoundary(boundary, offset,
- ax::mojom::MoveDirection::kForward,
- ax::mojom::TextAffinity::kDownstream);
- if (start_offset < 0 || end_offset < 0)
- return nullptr;
-
- DCHECK_LE(start_offset, end_offset)
- << "Start offset should be less than or equal the end offset.";
-
- // The ATK API is also expecting Unicode character offsets as output
- // values.
- *start_offset_ptr = obj->UTF16ToUnicodeOffsetInText(start_offset);
- *end_offset_ptr = obj->UTF16ToUnicodeOffsetInText(end_offset);
-
- base::string16 text = obj->GetHypertext();
- DCHECK_LE(end_offset, static_cast<int>(text.size()));
-
- base::string16 substr = text.substr(start_offset, end_offset - start_offset);
- return g_strdup(base::UTF16ToUTF8(substr).c_str());
-}
-
-char* GetTextAtOffset(AtkText* atk_text,
- int offset,
- AtkTextBoundary atk_boundary,
- int* start_offset,
- int* end_offset) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), nullptr);
- ax::mojom::TextBoundary boundary = FromAtkTextBoundary(atk_boundary);
- return GetTextWithBoundaryType(atk_text, offset, boundary, start_offset,
- end_offset);
-}
-
-char* GetTextAfterOffset(AtkText* atk_text,
- int offset,
- AtkTextBoundary boundary,
- int* start_offset,
- int* end_offset) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), nullptr);
-
- if (boundary != ATK_TEXT_BOUNDARY_CHAR) {
- *start_offset = -1;
- *end_offset = -1;
- return nullptr;
- }
-
- // ATK does not offer support for the special negative index and we don't
- // want to do arithmetic on that value below.
- if (offset == kStringLengthOffset)
- return nullptr;
-
- return GetCharacter(atk_text, offset + 1, start_offset, end_offset);
-}
-
-char* GetTextBeforeOffset(AtkText* atk_text,
- int offset,
- AtkTextBoundary boundary,
- int* start_offset,
- int* end_offset) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), nullptr);
-
- if (boundary != ATK_TEXT_BOUNDARY_CHAR) {
- *start_offset = -1;
- *end_offset = -1;
- return nullptr;
- }
-
- // ATK does not offer support for the special negative index and we don't
- // want to do arithmetic on that value below.
- if (offset == kStringLengthOffset)
- return nullptr;
-
- return GetCharacter(atk_text, offset - 1, start_offset, end_offset);
-}
-
-gint GetCaretOffset(AtkText* atk_text) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), -1);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_text));
- if (!obj)
- return -1;
- return obj->GetCaretOffset();
-}
-
-gboolean SetCaretOffset(AtkText* atk_text, gint offset) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_text));
- if (!obj)
- return FALSE;
- if (!obj->SetCaretOffset(offset))
- return FALSE;
-
- // Orca expects atk_text_set_caret_offset to either focus the target element
- // or set the sequential focus navigation starting point there.
- int utf16_offset = obj->UnicodeToUTF16OffsetInText(offset);
- obj->GrabFocusOrSetSequentialFocusNavigationStartingPointAtOffset(
- utf16_offset);
-
- return TRUE;
-}
-
-int GetNSelections(AtkText* atk_text) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), 0);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_text));
- if (!obj)
- return 0;
-
- if (obj->HasSelection())
- return 1;
-
- base::Optional<FindInPageResultInfo> result =
- obj->GetSelectionOffsetsFromFindInPage();
- if (result.has_value() && result->node == ATK_OBJECT(atk_text))
- return 1;
-
- return 0;
-}
-
-gchar* GetSelection(AtkText* atk_text,
- int selection_num,
- int* start_offset,
- int* end_offset) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), nullptr);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_text));
- if (!obj)
- return nullptr;
- if (selection_num != 0)
- return nullptr;
-
- return obj->GetSelectionWithText(start_offset, end_offset);
-}
-
-gboolean RemoveSelection(AtkText* atk_text, int selection_num) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), FALSE);
-
- if (selection_num != 0)
- return FALSE;
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_text));
- if (!obj)
- return FALSE;
-
- // Simply collapse the selection to the position of the caret if a caret is
- // visible, otherwise set the selection to 0.
- int selection_end = obj->UTF16ToUnicodeOffsetInText(
- obj->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd));
- return SetCaretOffset(atk_text, selection_end);
-}
-
-gboolean SetSelection(AtkText* atk_text,
- int selection_num,
- int start_offset,
- int end_offset) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), FALSE);
-
- if (selection_num != 0)
- return FALSE;
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_text));
- if (!obj)
- return FALSE;
-
- return obj->SetTextSelectionForAtkText(start_offset, end_offset);
-}
-
-gboolean AddSelection(AtkText* atk_text, int start_offset, int end_offset) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), FALSE);
-
- // We only support one selection.
- return SetSelection(atk_text, 0, start_offset, end_offset);
-}
-
-#if defined(ATK_210)
-char* GetStringAtOffset(AtkText* atk_text,
- int offset,
- AtkTextGranularity atk_granularity,
- int* start_offset,
- int* end_offset) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), nullptr);
-
- *start_offset = -1;
- *end_offset = -1;
-
- ax::mojom::TextBoundary boundary = FromAtkTextGranularity(atk_granularity);
- return GetTextWithBoundaryType(atk_text, offset, boundary, start_offset,
- end_offset);
-}
-#endif
-
-#if defined(ATK_230)
-gfx::Rect GetUnclippedParentHypertextRangeBoundsRect(
- AXPlatformNodeDelegate* ax_platform_node_delegate,
- const int start_offset,
- const int end_offset) {
- const AXPlatformNode* parent_platform_node =
- AXPlatformNode::FromNativeViewAccessible(
- ax_platform_node_delegate->GetParent());
- if (!parent_platform_node)
- return gfx::Rect();
-
- const AXPlatformNodeDelegate* parent_ax_platform_node_delegate =
- parent_platform_node->GetDelegate();
- if (!parent_ax_platform_node_delegate)
- return gfx::Rect();
-
- return ax_platform_node_delegate->GetHypertextRangeBoundsRect(
- start_offset, end_offset, AXCoordinateSystem::kRootFrame,
- AXClippingBehavior::kUnclipped) -
- parent_ax_platform_node_delegate
- ->GetBoundsRect(AXCoordinateSystem::kRootFrame,
- AXClippingBehavior::kClipped)
- .OffsetFromOrigin();
-}
-#endif
-
-void GetCharacterExtents(AtkText* atk_text,
- int offset,
- int* x,
- int* y,
- int* width,
- int* height,
- AtkCoordType coordinate_type) {
- g_return_if_fail(ATK_IS_TEXT(atk_text));
-
- gfx::Rect rect;
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_text));
- if (obj) {
- switch (coordinate_type) {
-#if defined(ATK_230)
- case ATK_XY_PARENT:
- rect = GetUnclippedParentHypertextRangeBoundsRect(obj->GetDelegate(),
- offset, offset + 1);
- break;
-#endif
- default:
- rect = obj->GetDelegate()->GetHypertextRangeBoundsRect(
- obj->UnicodeToUTF16OffsetInText(offset),
- obj->UnicodeToUTF16OffsetInText(offset + 1),
- AtkCoordTypeToAXCoordinateSystem(coordinate_type),
- AXClippingBehavior::kUnclipped);
- break;
- }
- }
-
- if (x)
- *x = rect.x();
- if (y)
- *y = rect.y();
- if (width)
- *width = rect.width();
- if (height)
- *height = rect.height();
-}
-
-void GetRangeExtents(AtkText* atk_text,
- int start_offset,
- int end_offset,
- AtkCoordType coordinate_type,
- AtkTextRectangle* out_rectangle) {
- g_return_if_fail(ATK_IS_TEXT(atk_text));
-
- if (!out_rectangle)
- return;
-
- gfx::Rect rect;
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_text));
- if (obj) {
- switch (coordinate_type) {
-#if defined(ATK_230)
- case ATK_XY_PARENT:
- rect = GetUnclippedParentHypertextRangeBoundsRect(
- obj->GetDelegate(), start_offset, end_offset);
- break;
-#endif
- default:
- rect = obj->GetDelegate()->GetHypertextRangeBoundsRect(
- obj->UnicodeToUTF16OffsetInText(start_offset),
- obj->UnicodeToUTF16OffsetInText(end_offset),
- AtkCoordTypeToAXCoordinateSystem(coordinate_type),
- AXClippingBehavior::kUnclipped);
- break;
- }
- }
-
- out_rectangle->x = rect.x();
- out_rectangle->y = rect.y();
- out_rectangle->width = rect.width();
- out_rectangle->height = rect.height();
-}
-
-AtkAttributeSet* GetRunAttributes(AtkText* atk_text,
- gint offset,
- gint* start_offset,
- gint* end_offset) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), nullptr);
-
- SetIntPointerValueIfNotNull(start_offset, -1);
- SetIntPointerValueIfNotNull(end_offset, -1);
-
- if (offset < 0 || offset > GetCharacterCount(atk_text))
- return nullptr;
-
- AtkObject* atk_object = ATK_OBJECT(atk_text);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- return ToAtkAttributeSet(
- obj->GetTextAttributes(offset, start_offset, end_offset));
-}
-
-AtkAttributeSet* GetDefaultAttributes(AtkText* atk_text) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), nullptr);
-
- AtkObject* atk_object = ATK_OBJECT(atk_text);
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
- return ToAtkAttributeSet(obj->GetDefaultTextAttributes());
-}
-
-#if defined(ATK_232)
-gboolean ScrollSubstringTo(AtkText* atk_text,
- gint start_offset,
- gint end_offset,
- AtkScrollType scroll_type) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_text));
- if (!obj)
- return FALSE;
-
- return obj->ScrollSubstringIntoView(scroll_type, start_offset, end_offset);
-}
-
-gboolean ScrollSubstringToPoint(AtkText* atk_text,
- gint start_offset,
- gint end_offset,
- AtkCoordType atk_coord_type,
- gint x,
- gint y) {
- g_return_val_if_fail(ATK_IS_TEXT(atk_text), FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_text));
- if (!obj)
- return FALSE;
-
- return obj->ScrollSubstringToPoint(start_offset, end_offset, atk_coord_type,
- x, y);
-}
-#endif // ATK_232
-
-void Init(AtkTextIface* iface) {
- iface->get_text = GetText;
- iface->get_character_count = GetCharacterCount;
- iface->get_character_at_offset = GetCharacterAtOffset;
- iface->get_offset_at_point = GetOffsetAtPoint;
- iface->get_text_after_offset = GetTextAfterOffset;
- iface->get_text_before_offset = GetTextBeforeOffset;
- iface->get_text_at_offset = GetTextAtOffset;
- iface->get_caret_offset = GetCaretOffset;
- iface->set_caret_offset = SetCaretOffset;
- iface->get_character_extents = GetCharacterExtents;
- iface->get_range_extents = GetRangeExtents;
- iface->get_n_selections = GetNSelections;
- iface->get_selection = GetSelection;
- iface->add_selection = AddSelection;
- iface->remove_selection = RemoveSelection;
- iface->set_selection = SetSelection;
-
- iface->get_run_attributes = GetRunAttributes;
- iface->get_default_attributes = GetDefaultAttributes;
-
-#if defined(ATK_210)
- iface->get_string_at_offset = GetStringAtOffset;
-#endif
-
-#if defined(ATK_232)
- if (SupportsAtkTextScrollingInterface()) {
- iface->scroll_substring_to = ScrollSubstringTo;
- iface->scroll_substring_to_point = ScrollSubstringToPoint;
- }
-#endif
-}
-
-const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
- nullptr, nullptr};
-
-} // namespace atk_text
-
-namespace atk_window {
-void Init(AtkWindowIface* iface) {}
-const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
- nullptr, nullptr};
-} // namespace atk_window
-
-namespace atk_selection {
-
-gboolean AddSelection(AtkSelection* selection, gint index) {
- g_return_val_if_fail(ATK_IS_SELECTION(selection), FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(selection));
- if (!obj)
- return FALSE;
- if (index < 0 || index >= obj->GetChildCount())
- return FALSE;
-
- AXPlatformNodeAuraLinux* child =
- AXPlatformNodeAuraLinux::FromAtkObject(obj->ChildAtIndex(index));
- if (!child)
- return FALSE;
-
- if (!child->SupportsSelectionWithAtkSelection())
- return FALSE;
-
- bool selected = child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected);
- if (selected)
- return TRUE;
-
- AXActionData data;
- data.action = ax::mojom::Action::kDoDefault;
- return child->GetDelegate()->AccessibilityPerformAction(data);
-}
-
-gboolean ClearSelection(AtkSelection* selection) {
- g_return_val_if_fail(ATK_IS_SELECTION(selection), FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(selection));
- if (!obj)
- return FALSE;
-
- int child_count = obj->GetChildCount();
- bool success = true;
- for (int i = 0; i < child_count; ++i) {
- AXPlatformNodeAuraLinux* child =
- AXPlatformNodeAuraLinux::FromAtkObject(obj->ChildAtIndex(i));
- if (!child)
- continue;
-
- if (!child->SupportsSelectionWithAtkSelection())
- continue;
-
- bool selected =
- child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected);
- if (!selected)
- continue;
-
- AXActionData data;
- data.action = ax::mojom::Action::kDoDefault;
- success = success && child->GetDelegate()->AccessibilityPerformAction(data);
- }
-
- return success;
-}
-
-AtkObject* RefSelection(AtkSelection* selection, gint requested_child_index) {
- g_return_val_if_fail(ATK_IS_SELECTION(selection), nullptr);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(selection));
- if (!obj)
- return nullptr;
-
- if (auto* selected_child = obj->GetSelectedItem(requested_child_index)) {
- if (AtkObject* atk_object = selected_child->GetNativeViewAccessible()) {
- g_object_ref(atk_object);
- return atk_object;
- }
- }
-
- return nullptr;
-}
-
-gint GetSelectionCount(AtkSelection* selection) {
- g_return_val_if_fail(ATK_IS_SELECTION(selection), 0);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(selection));
- if (!obj)
- return 0;
-
- return obj->GetSelectionCount();
-}
-
-gboolean IsChildSelected(AtkSelection* selection, gint index) {
- g_return_val_if_fail(ATK_IS_SELECTION(selection), FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(selection));
- if (!obj)
- return FALSE;
- if (index < 0 || index >= obj->GetChildCount())
- return FALSE;
-
- AXPlatformNodeAuraLinux* child =
- AXPlatformNodeAuraLinux::FromAtkObject(obj->ChildAtIndex(index));
- return child && child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected);
-}
-
-gboolean RemoveSelection(AtkSelection* selection,
- gint index_into_selected_children) {
- g_return_val_if_fail(ATK_IS_SELECTION(selection), FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(selection));
- if (!obj)
- return FALSE;
-
- int child_count = obj->GetChildCount();
- for (int i = 0; i < child_count; ++i) {
- AXPlatformNodeAuraLinux* child =
- AXPlatformNodeAuraLinux::FromAtkObject(obj->ChildAtIndex(i));
- if (!child)
- continue;
-
- bool selected =
- child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected);
- if (selected && index_into_selected_children == 0) {
- if (!child->SupportsSelectionWithAtkSelection())
- return FALSE;
-
- AXActionData data;
- data.action = ax::mojom::Action::kDoDefault;
- return child->GetDelegate()->AccessibilityPerformAction(data);
- } else if (selected) {
- index_into_selected_children--;
- }
- }
-
- return FALSE;
-}
-
-gboolean SelectAllSelection(AtkSelection* selection) {
- g_return_val_if_fail(ATK_IS_SELECTION(selection), FALSE);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(selection));
- if (!obj)
- return FALSE;
-
- int child_count = obj->GetChildCount();
- bool success = true;
- for (int i = 0; i < child_count; ++i) {
- AXPlatformNodeAuraLinux* child =
- AXPlatformNodeAuraLinux::FromAtkObject(obj->ChildAtIndex(i));
- if (!child)
- continue;
-
- if (!child->SupportsSelectionWithAtkSelection())
- continue;
-
- bool selected =
- child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected);
- if (selected)
- continue;
-
- AXActionData data;
- data.action = ax::mojom::Action::kDoDefault;
- success = success && child->GetDelegate()->AccessibilityPerformAction(data);
- }
-
- return success;
-}
-
-void Init(AtkSelectionIface* iface) {
- iface->add_selection = AddSelection;
- iface->clear_selection = ClearSelection;
- iface->ref_selection = RefSelection;
- iface->get_selection_count = GetSelectionCount;
- iface->is_child_selected = IsChildSelected;
- iface->remove_selection = RemoveSelection;
- iface->select_all_selection = SelectAllSelection;
-}
-
-const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
- nullptr, nullptr};
-
-} // namespace atk_selection
-
-namespace atk_table {
-
-AtkObject* RefAt(AtkTable* table, gint row, gint column) {
- g_return_val_if_fail(ATK_IS_TABLE(table), nullptr);
-
- if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table))) {
- if (AXPlatformNodeBase* cell = obj->GetTableCell(row, column)) {
- if (AtkObject* atk_cell = cell->GetNativeViewAccessible()) {
- g_object_ref(atk_cell);
- return atk_cell;
- }
- }
- }
-
- return nullptr;
-}
-
-gint GetIndexAt(AtkTable* table, gint row, gint column) {
- g_return_val_if_fail(ATK_IS_TABLE(table), -1);
-
- if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table))) {
- if (const AXPlatformNodeBase* cell = obj->GetTableCell(row, column)) {
- DCHECK(cell->GetTableCellIndex().has_value());
- return cell->GetTableCellIndex().value();
- }
- }
-
- return -1;
-}
-
-gint GetColumnAtIndex(AtkTable* table, gint index) {
- g_return_val_if_fail(ATK_IS_TABLE(table), -1);
-
- if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table))) {
- if (const AXPlatformNodeBase* cell = obj->GetTableCell(index)) {
- DCHECK(cell->GetTableColumn().has_value());
- return cell->GetTableColumn().value();
- }
- }
-
- return -1;
-}
-
-gint GetRowAtIndex(AtkTable* table, gint index) {
- g_return_val_if_fail(ATK_IS_TABLE(table), -1);
-
- if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table))) {
- if (const AXPlatformNodeBase* cell = obj->GetTableCell(index)) {
- DCHECK(cell->GetTableRow().has_value());
- return cell->GetTableRow().value();
- }
- }
-
- return -1;
-}
-
-gint GetNColumns(AtkTable* table) {
- g_return_val_if_fail(ATK_IS_TABLE(table), 0);
-
- if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table))) {
- // If the object is not a table, we return 0.
- return obj->GetTableColumnCount().value_or(0);
- }
-
- return 0;
-}
-
-gint GetNRows(AtkTable* table) {
- g_return_val_if_fail(ATK_IS_TABLE(table), 0);
-
- if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table))) {
- // If the object is not a table, we return 0.
- return obj->GetTableRowCount().value_or(0);
- }
-
- return 0;
-}
-
-gint GetColumnExtentAt(AtkTable* table, gint row, gint column) {
- g_return_val_if_fail(ATK_IS_TABLE(table), 0);
-
- if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table))) {
- if (const AXPlatformNodeBase* cell = obj->GetTableCell(row, column)) {
- DCHECK(cell->GetTableColumnSpan().has_value());
- return cell->GetTableColumnSpan().value();
- }
- }
-
- return 0;
-}
-
-gint GetRowExtentAt(AtkTable* table, gint row, gint column) {
- g_return_val_if_fail(ATK_IS_TABLE(table), 0);
-
- if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table))) {
- if (const AXPlatformNodeBase* cell = obj->GetTableCell(row, column)) {
- DCHECK(cell->GetTableRowSpan().has_value());
- return cell->GetTableRowSpan().value();
- }
- }
-
- return 0;
-}
-
-AtkObject* GetColumnHeader(AtkTable* table, gint column) {
- g_return_val_if_fail(ATK_IS_TABLE(table), nullptr);
-
- auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table));
- if (!obj)
- return nullptr;
-
- // AtkTable supports only one column header object. So return the first one
- // we find. In the case of multiple headers, ATs can fall back on the column
- // description.
- std::vector<int32_t> ids = obj->GetDelegate()->GetColHeaderNodeIds(column);
- for (const auto& node_id : ids) {
- if (AXPlatformNode* header = obj->GetDelegate()->GetFromNodeID(node_id)) {
- if (AtkObject* atk_header = header->GetNativeViewAccessible()) {
- g_object_ref(atk_header);
- return atk_header;
- }
- }
- }
-
- return nullptr;
-}
-
-AtkObject* GetRowHeader(AtkTable* table, gint row) {
- g_return_val_if_fail(ATK_IS_TABLE(table), nullptr);
-
- auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table));
- if (!obj)
- return nullptr;
-
- // AtkTable supports only one row header object. So return the first one
- // we find. In the case of multiple headers, ATs can fall back on the row
- // description.
- std::vector<int32_t> ids = obj->GetDelegate()->GetRowHeaderNodeIds(row);
- for (const auto& node_id : ids) {
- if (AXPlatformNode* header = obj->GetDelegate()->GetFromNodeID(node_id)) {
- if (AtkObject* atk_header = header->GetNativeViewAccessible()) {
- g_object_ref(atk_header);
- return atk_header;
- }
- }
- }
-
- return nullptr;
-}
-
-AtkObject* GetCaption(AtkTable* table) {
- g_return_val_if_fail(ATK_IS_TABLE(table), nullptr);
-
- if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table))) {
- if (auto* caption = obj->GetTableCaption())
- return caption->GetNativeViewAccessible();
- }
-
- return nullptr;
-}
-
-const gchar* GetColumnDescription(AtkTable* table, gint column) {
- g_return_val_if_fail(ATK_IS_TABLE(table), nullptr);
-
- auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table));
- if (!obj)
- return nullptr;
-
- std::vector<int32_t> ids = obj->GetDelegate()->GetColHeaderNodeIds(column);
- return BuildDescriptionFromHeaders(obj->GetDelegate(), ids);
-}
-
-const gchar* GetRowDescription(AtkTable* table, gint row) {
- g_return_val_if_fail(ATK_IS_TABLE(table), nullptr);
-
- auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(table));
- if (!obj)
- return nullptr;
-
- std::vector<int32_t> ids = obj->GetDelegate()->GetRowHeaderNodeIds(row);
- return BuildDescriptionFromHeaders(obj->GetDelegate(), ids);
-}
-
-void Init(AtkTableIface* iface) {
- iface->ref_at = RefAt;
- iface->get_index_at = GetIndexAt;
- iface->get_column_at_index = GetColumnAtIndex;
- iface->get_row_at_index = GetRowAtIndex;
- iface->get_n_columns = GetNColumns;
- iface->get_n_rows = GetNRows;
- iface->get_column_extent_at = GetColumnExtentAt;
- iface->get_row_extent_at = GetRowExtentAt;
- iface->get_column_header = GetColumnHeader;
- iface->get_row_header = GetRowHeader;
- iface->get_caption = GetCaption;
- iface->get_column_description = GetColumnDescription;
- iface->get_row_description = GetRowDescription;
-}
-
-const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
- nullptr, nullptr};
-
-} // namespace atk_table
-
-// The ATK table cell interface was added in ATK 2.12.
-#if defined(ATK_212)
-
-namespace atk_table_cell {
-
-gint GetColumnSpan(AtkTableCell* cell) {
- DCHECK(g_atk_table_cell_get_type);
- g_return_val_if_fail(
- G_TYPE_CHECK_INSTANCE_TYPE((cell), AtkTableCellInterface::GetType()), 0);
-
- if (const AXPlatformNodeBase* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(cell))) {
- // If the object is not a cell, we return 0.
- return obj->GetTableColumnSpan().value_or(0);
- }
-
- return 0;
-}
-
-GPtrArray* GetColumnHeaderCells(AtkTableCell* cell) {
- DCHECK(g_atk_table_cell_get_type);
- g_return_val_if_fail(
- G_TYPE_CHECK_INSTANCE_TYPE((cell), AtkTableCellInterface::GetType()),
- nullptr);
-
- GPtrArray* array = g_ptr_array_new_with_free_func(g_object_unref);
-
- auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(cell));
- if (!obj)
- return array;
-
- // AtkTableCell is implemented on cells, row headers, and column headers.
- // Calling GetColHeaderNodeIds() on a column header cell will include that
- // column header, along with any other column headers in the column which
- // may or may not describe the header cell in question. Therefore, just return
- // headers for non-header cells.
- if (obj->GetAtkRole() != ATK_ROLE_TABLE_CELL)
- return array;
-
- base::Optional<int> col_index = obj->GetTableColumn();
- if (!col_index)
- return array;
-
- const std::vector<int32_t> ids =
- obj->GetDelegate()->GetColHeaderNodeIds(*col_index);
- for (const auto& node_id : ids) {
- if (AXPlatformNode* node = obj->GetDelegate()->GetFromNodeID(node_id)) {
- if (AtkObject* atk_node = node->GetNativeViewAccessible()) {
- g_ptr_array_add(array, g_object_ref(atk_node));
- }
- }
- }
-
- return array;
-}
-
-gboolean GetCellPosition(AtkTableCell* cell, gint* row, gint* column) {
- DCHECK(g_atk_table_cell_get_type);
- g_return_val_if_fail(
- G_TYPE_CHECK_INSTANCE_TYPE((cell), AtkTableCellInterface::GetType()),
- FALSE);
-
- if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(cell))) {
- base::Optional<int> row_index = obj->GetTableRow();
- base::Optional<int> col_index = obj->GetTableColumn();
- if (!row_index || !col_index)
- return false;
-
- *row = *row_index;
- *column = *col_index;
- return true;
- }
-
- return false;
-}
-
-gint GetRowSpan(AtkTableCell* cell) {
- DCHECK(g_atk_table_cell_get_type);
- g_return_val_if_fail(
- G_TYPE_CHECK_INSTANCE_TYPE((cell), AtkTableCellInterface::GetType()), 0);
-
- if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(cell))) {
- // If the object is not a cell, we return 0.
- return obj->GetTableRowSpan().value_or(0);
- }
-
- return 0;
-}
-
-GPtrArray* GetRowHeaderCells(AtkTableCell* cell) {
- DCHECK(g_atk_table_cell_get_type);
- g_return_val_if_fail(
- G_TYPE_CHECK_INSTANCE_TYPE((cell), AtkTableCellInterface::GetType()),
- nullptr);
-
- GPtrArray* array = g_ptr_array_new_with_free_func(g_object_unref);
-
- auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(cell));
- if (!obj)
- return array;
-
- // AtkTableCell is implemented on cells, row headers, and column headers.
- // Calling GetRowHeaderNodeIds() on a row header cell will include that
- // row header, along with any other row headers in the row which may or
- // may not describe the header cell in question. Therefore, just return
- // headers for non-header cells.
- if (obj->GetAtkRole() != ATK_ROLE_TABLE_CELL)
- return array;
-
- base::Optional<int> row_index = obj->GetTableRow();
- if (!row_index)
- return array;
-
- const std::vector<int32_t> ids =
- obj->GetDelegate()->GetRowHeaderNodeIds(*row_index);
- for (const auto& node_id : ids) {
- if (AXPlatformNode* node = obj->GetDelegate()->GetFromNodeID(node_id)) {
- if (AtkObject* atk_node = node->GetNativeViewAccessible()) {
- g_ptr_array_add(array, g_object_ref(atk_node));
- }
- }
- }
-
- return array;
-}
-
-AtkObject* GetTable(AtkTableCell* cell) {
- DCHECK(g_atk_table_cell_get_type);
- g_return_val_if_fail(
- G_TYPE_CHECK_INSTANCE_TYPE((cell), AtkTableCellInterface::GetType()),
- nullptr);
-
- if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(cell))) {
- if (auto* table = obj->GetTable())
- return table->GetNativeViewAccessible();
- }
-
- return nullptr;
-}
-
-using AtkTableCellIface = struct _AtkTableCellIface;
-
-void Init(AtkTableCellIface* iface) {
- iface->get_column_span = GetColumnSpan;
- iface->get_column_header_cells = GetColumnHeaderCells;
- iface->get_position = GetCellPosition;
- iface->get_row_span = GetRowSpan;
- iface->get_row_header_cells = GetRowHeaderCells;
- iface->get_table = GetTable;
-}
-
-const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
- nullptr, nullptr};
-
-} // namespace atk_table_cell
-
-#endif // ATK_212
-
-namespace atk_object {
-
-gpointer kAXPlatformNodeAuraLinuxParentClass = nullptr;
-
-const gchar* GetName(AtkObject* atk_object) {
- g_return_val_if_fail(ATK_IS_OBJECT(atk_object), nullptr);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- if (!obj->IsNameExposed())
- return nullptr;
-
- ax::mojom::NameFrom name_from = obj->GetData().GetNameFrom();
- if (obj->GetName().empty() &&
- name_from != ax::mojom::NameFrom::kAttributeExplicitlyEmpty)
- return nullptr;
-
- obj->accessible_name_ = obj->GetName();
- return obj->accessible_name_.c_str();
-}
-
-const gchar* AtkGetName(AtkObject* atk_object) {
- RecordAccessibilityAtkApi(UmaAtkApi::kGetName);
- return GetName(atk_object);
-}
-
-const gchar* GetDescription(AtkObject* atk_object) {
- g_return_val_if_fail(ATK_IS_OBJECT(atk_object), nullptr);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- return obj->GetStringAttribute(ax::mojom::StringAttribute::kDescription)
- .c_str();
-}
-
-const gchar* AtkGetDescription(AtkObject* atk_object) {
- RecordAccessibilityAtkApi(UmaAtkApi::kGetDescription);
- return GetDescription(atk_object);
-}
-
-gint GetNChildren(AtkObject* atk_object) {
- g_return_val_if_fail(ATK_IS_OBJECT(atk_object), 0);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return 0;
-
- return obj->GetChildCount();
-}
-
-gint AtkGetNChildren(AtkObject* atk_object) {
- RecordAccessibilityAtkApi(UmaAtkApi::kGetNChildren);
- return GetNChildren(atk_object);
-}
-
-AtkObject* RefChild(AtkObject* atk_object, gint index) {
- g_return_val_if_fail(ATK_IS_OBJECT(atk_object), nullptr);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- if (index < 0 || index >= obj->GetChildCount())
- return nullptr;
-
- AtkObject* result = obj->ChildAtIndex(index);
- if (result)
- g_object_ref(result);
- return result;
-}
-
-AtkObject* AtkRefChild(AtkObject* atk_object, gint index) {
- RecordAccessibilityAtkApi(UmaAtkApi::kRefChild);
- return RefChild(atk_object, index);
-}
-
-gint GetIndexInParent(AtkObject* atk_object) {
- g_return_val_if_fail(ATK_IS_OBJECT(atk_object), -1);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return -1;
-
- return obj->GetIndexInParent().value_or(-1);
-}
-
-gint AtkGetIndexInParent(AtkObject* atk_object) {
- RecordAccessibilityAtkApi(UmaAtkApi::kGetIndexInParent);
- return GetIndexInParent(atk_object);
-}
-
-AtkObject* GetParent(AtkObject* atk_object) {
- g_return_val_if_fail(ATK_IS_OBJECT(atk_object), nullptr);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- return obj->GetParent();
-}
-
-AtkObject* AtkGetParent(AtkObject* atk_object) {
- RecordAccessibilityAtkApi(UmaAtkApi::kGetParent);
- return GetParent(atk_object);
-}
-
-AtkRelationSet* RefRelationSet(AtkObject* atk_object) {
- g_return_val_if_fail(ATK_IS_OBJECT(atk_object), nullptr);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return atk_relation_set_new();
- return obj->GetAtkRelations();
-}
-
-AtkRelationSet* AtkRefRelationSet(AtkObject* atk_object) {
- RecordAccessibilityAtkApi(UmaAtkApi::kRefRelationSet);
- // Enables AX mode. Most AT does not call AtkRefRelationSet, but Orca does,
- // which is why it's a good signal to enable accessibility for Orca users
- // without too many false positives.
- AXPlatformNodeAuraLinux::EnableAXMode();
- return RefRelationSet(atk_object);
-}
-
-AtkAttributeSet* GetAttributes(AtkObject* atk_object) {
- g_return_val_if_fail(ATK_IS_OBJECT(atk_object), nullptr);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return nullptr;
-
- return obj->GetAtkAttributes();
-}
-
-AtkAttributeSet* AtkGetAttributes(AtkObject* atk_object) {
- RecordAccessibilityAtkApi(UmaAtkApi::kGetAttributes);
- // Enables AX mode. Most AT does not call AtkGetAttributes, but Orca does,
- // which is why it's a good signal to enable accessibility for Orca users
- // without too many false positives.
- AXPlatformNodeAuraLinux::EnableAXMode();
- return GetAttributes(atk_object);
-}
-
-AtkRole GetRole(AtkObject* atk_object) {
- g_return_val_if_fail(ATK_IS_OBJECT(atk_object), ATK_ROLE_INVALID);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj)
- return ATK_ROLE_INVALID;
- return obj->GetAtkRole();
-}
-
-AtkRole AtkGetRole(AtkObject* atk_object) {
- RecordAccessibilityAtkApi(UmaAtkApi::kGetRole);
- return GetRole(atk_object);
-}
-
-AtkStateSet* RefStateSet(AtkObject* atk_object) {
- g_return_val_if_fail(ATK_IS_OBJECT(atk_object), nullptr);
-
- AtkStateSet* atk_state_set =
- ATK_OBJECT_CLASS(kAXPlatformNodeAuraLinuxParentClass)
- ->ref_state_set(atk_object);
-
- AXPlatformNodeAuraLinux* obj =
- AXPlatformNodeAuraLinux::FromAtkObject(atk_object);
- if (!obj) {
- atk_state_set_add_state(atk_state_set, ATK_STATE_DEFUNCT);
- } else {
- obj->GetAtkState(atk_state_set);
- }
- return atk_state_set;
-}
-
-AtkStateSet* AtkRefStateSet(AtkObject* atk_object) {
- RecordAccessibilityAtkApi(UmaAtkApi::kRefStateSet);
- return RefStateSet(atk_object);
-}
-
-void Initialize(AtkObject* atk_object, gpointer data) {
- if (ATK_OBJECT_CLASS(kAXPlatformNodeAuraLinuxParentClass)->initialize) {
- ATK_OBJECT_CLASS(kAXPlatformNodeAuraLinuxParentClass)
- ->initialize(atk_object, data);
- }
-
- AX_PLATFORM_NODE_AURALINUX(atk_object)->m_object =
- reinterpret_cast<AXPlatformNodeAuraLinux*>(data);
-}
-
-void Finalize(GObject* atk_object) {
- G_OBJECT_CLASS(kAXPlatformNodeAuraLinuxParentClass)->finalize(atk_object);
-}
-
-void ClassInit(gpointer class_pointer, gpointer /* class_data */) {
- GObjectClass* gobject_class = G_OBJECT_CLASS(class_pointer);
- kAXPlatformNodeAuraLinuxParentClass = g_type_class_peek_parent(gobject_class);
- gobject_class->finalize = Finalize;
-
- AtkObjectClass* atk_object_class = ATK_OBJECT_CLASS(gobject_class);
- atk_object_class->initialize = Initialize;
- atk_object_class->get_name = AtkGetName;
- atk_object_class->get_description = AtkGetDescription;
- atk_object_class->get_parent = AtkGetParent;
- atk_object_class->get_n_children = AtkGetNChildren;
- atk_object_class->ref_child = AtkRefChild;
- atk_object_class->get_role = AtkGetRole;
- atk_object_class->ref_state_set = AtkRefStateSet;
- atk_object_class->get_index_in_parent = AtkGetIndexInParent;
- atk_object_class->ref_relation_set = AtkRefRelationSet;
- atk_object_class->get_attributes = AtkGetAttributes;
-}
-
-GType GetType() {
- AXPlatformNodeAuraLinux::EnsureGTypeInit();
-
- static volatile gsize type_volatile = 0;
- if (g_once_init_enter(&type_volatile)) {
- static const GTypeInfo type_info = {
- sizeof(AXPlatformNodeAuraLinuxClass), // class_size
- nullptr, // base_init
- nullptr, // base_finalize
- atk_object::ClassInit,
- nullptr, // class_finalize
- nullptr, // class_data
- sizeof(AXPlatformNodeAuraLinuxObject), // instance_size
- 0, // n_preallocs
- nullptr, // instance_init
- nullptr // value_table
- };
-
- GType type = g_type_register_static(
- ATK_TYPE_OBJECT, "AXPlatformNodeAuraLinux", &type_info, GTypeFlags(0));
- g_once_init_leave(&type_volatile, type);
- }
-
- return type_volatile;
-}
-
-void Detach(AXPlatformNodeAuraLinuxObject* atk_object) {
- if (!atk_object->m_object)
- return;
-
- atk_object->m_object = nullptr;
- atk_object_notify_state_change(ATK_OBJECT(atk_object), ATK_STATE_DEFUNCT,
- TRUE);
-}
-
-} // namespace atk_object
-
-} // namespace
-
-// static
-NO_SANITIZE("cfi-icall")
-GType AtkTableCellInterface::GetType() {
- return g_atk_table_cell_get_type();
-}
-
-// static
-NO_SANITIZE("cfi-icall")
-GPtrArray* AtkTableCellInterface::GetColumnHeaderCells(AtkTableCell* cell) {
- return g_atk_table_cell_get_column_header_cells(cell);
-}
-
-// static
-NO_SANITIZE("cfi-icall")
-GPtrArray* AtkTableCellInterface::GetRowHeaderCells(AtkTableCell* cell) {
- return g_atk_table_cell_get_row_header_cells(cell);
-}
-
-// static
-NO_SANITIZE("cfi-icall")
-bool AtkTableCellInterface::GetRowColumnSpan(AtkTableCell* cell,
- gint* row,
- gint* column,
- gint* row_span,
- gint* col_span) {
- return g_atk_table_cell_get_row_column_span(cell, row, column, row_span,
- col_span);
-}
-
-// static
-bool AtkTableCellInterface::Exists() {
- g_atk_table_cell_get_type = reinterpret_cast<GetTypeFunc>(
- dlsym(RTLD_DEFAULT, "atk_table_cell_get_type"));
- g_atk_table_cell_get_column_header_cells =
- reinterpret_cast<GetColumnHeaderCellsFunc>(
- dlsym(RTLD_DEFAULT, "atk_table_cell_get_column_header_cells"));
- g_atk_table_cell_get_row_header_cells =
- reinterpret_cast<GetRowHeaderCellsFunc>(
- dlsym(RTLD_DEFAULT, "atk_table_cell_get_row_header_cells"));
- g_atk_table_cell_get_row_column_span = reinterpret_cast<GetRowColumnSpanFunc>(
- dlsym(RTLD_DEFAULT, "atk_table_cell_get_row_column_span"));
- return *g_atk_table_cell_get_type;
-}
-
-void AXPlatformNodeAuraLinux::EnsureGTypeInit() {
-#if !GLIB_CHECK_VERSION(2, 36, 0)
- static bool first_time = true;
- if (UNLIKELY(first_time)) {
- g_type_init();
- first_time = false;
- }
-#endif
-}
-
-// static
-ImplementedAtkInterfaces AXPlatformNodeAuraLinux::GetGTypeInterfaceMask(
- const AXNodeData& data) {
- // The default implementation set includes the AtkComponent and AtkAction
- // interfaces, which are provided by all the AtkObjects that we produce.
- ImplementedAtkInterfaces interface_mask;
-
- if (!IsImageOrVideo(data.role)) {
- interface_mask.Add(ImplementedAtkInterfaces::Value::kText);
- if (!data.IsPlainTextField())
- interface_mask.Add(ImplementedAtkInterfaces::Value::kHypertext);
- }
-
- if (data.IsRangeValueSupported())
- interface_mask.Add(ImplementedAtkInterfaces::Value::kValue);
-
- if (ui::IsDocument(data.role))
- interface_mask.Add(ImplementedAtkInterfaces::Value::kDocument);
-
- if (IsImage(data.role))
- interface_mask.Add(ImplementedAtkInterfaces::Value::kImage);
-
- // The AtkHyperlinkImpl interface allows getting a AtkHyperlink from an
- // AtkObject. It is indeed implemented by actual web hyperlinks, but also by
- // objects that will become embedded objects in ATK hypertext, so the name is
- // a bit of a misnomer from the ATK API.
- if (IsLink(data.role) || data.role == ax::mojom::Role::kAnchor ||
- !ui::IsText(data.role)) {
- interface_mask.Add(ImplementedAtkInterfaces::Value::kHyperlink);
- }
-
- if (data.role == ax::mojom::Role::kWindow)
- interface_mask.Add(ImplementedAtkInterfaces::Value::kWindow);
-
- if (IsContainerWithSelectableChildren(data.role))
- interface_mask.Add(ImplementedAtkInterfaces::Value::kSelection);
-
- if (IsTableLike(data.role))
- interface_mask.Add(ImplementedAtkInterfaces::Value::kTable);
-
- // Because the TableCell Interface is only supported in ATK version 2.12 and
- // later, GetAccessibilityGType has a runtime check to verify we have a recent
- // enough version. If we don't, GetAccessibilityGType will exclude
- // AtkTableCell from the supported interfaces and none of its methods or
- // properties will be exposed to assistive technologies.
- if (IsCellOrTableHeader(data.role))
- interface_mask.Add(ImplementedAtkInterfaces::Value::kTableCell);
-
- return interface_mask;
-}
-
-GType AXPlatformNodeAuraLinux::GetAccessibilityGType() {
- static const GTypeInfo type_info = {
- sizeof(AXPlatformNodeAuraLinuxClass),
- (GBaseInitFunc) nullptr,
- (GBaseFinalizeFunc) nullptr,
- (GClassInitFunc) nullptr,
- (GClassFinalizeFunc) nullptr,
- nullptr, /* class data */
- sizeof(AXPlatformNodeAuraLinuxObject), /* instance size */
- 0, /* nb preallocs */
- (GInstanceInitFunc) nullptr,
- nullptr /* value table */
- };
-
- const char* atk_type_name = GetUniqueAccessibilityGTypeName(interface_mask_);
- GType type = g_type_from_name(atk_type_name);
- if (type)
- return type;
-
- type = g_type_register_static(AX_PLATFORM_NODE_AURALINUX_TYPE, atk_type_name,
- &type_info, GTypeFlags(0));
-
- // The AtkComponent and AtkAction interfaces are always supported.
- g_type_add_interface_static(type, ATK_TYPE_COMPONENT, &atk_component::Info);
- g_type_add_interface_static(type, ATK_TYPE_ACTION, &atk_action::Info);
-
- if (interface_mask_.Implements(ImplementedAtkInterfaces::Value::kDocument))
- g_type_add_interface_static(type, ATK_TYPE_DOCUMENT, &atk_document::Info);
- if (interface_mask_.Implements(ImplementedAtkInterfaces::Value::kImage))
- g_type_add_interface_static(type, ATK_TYPE_IMAGE, &atk_image::Info);
- if (interface_mask_.Implements(ImplementedAtkInterfaces::Value::kValue))
- g_type_add_interface_static(type, ATK_TYPE_VALUE, &atk_value::Info);
- if (interface_mask_.Implements(ImplementedAtkInterfaces::Value::kHyperlink)) {
- g_type_add_interface_static(type, ATK_TYPE_HYPERLINK_IMPL,
- &atk_hyperlink::Info);
- }
- if (interface_mask_.Implements(ImplementedAtkInterfaces::Value::kHypertext))
- g_type_add_interface_static(type, ATK_TYPE_HYPERTEXT, &atk_hypertext::Info);
- if (interface_mask_.Implements(ImplementedAtkInterfaces::Value::kText))
- g_type_add_interface_static(type, ATK_TYPE_TEXT, &atk_text::Info);
- if (interface_mask_.Implements(ImplementedAtkInterfaces::Value::kWindow))
- g_type_add_interface_static(type, ATK_TYPE_WINDOW, &atk_window::Info);
- if (interface_mask_.Implements(ImplementedAtkInterfaces::Value::kSelection))
- g_type_add_interface_static(type, ATK_TYPE_SELECTION, &atk_selection::Info);
- if (interface_mask_.Implements(ImplementedAtkInterfaces::Value::kTable))
- g_type_add_interface_static(type, ATK_TYPE_TABLE, &atk_table::Info);
-
- if (interface_mask_.Implements(ImplementedAtkInterfaces::Value::kTableCell)) {
- // Run-time check to ensure AtkTableCell is supported (requires ATK 2.12).
- if (AtkTableCellInterface::Exists()) {
- g_type_add_interface_static(type, AtkTableCellInterface::GetType(),
- &atk_table_cell::Info);
- }
- }
-
- return type;
-}
-
-void AXPlatformNodeAuraLinux::SetDocumentParentOnFrameIfNecessary() {
- if (GetAtkRole() != ATK_ROLE_DOCUMENT_WEB)
- return;
-
- if (!GetDelegate()->IsWebContent())
- return;
-
- AtkObject* parent_atk_object = GetParent();
- AXPlatformNodeAuraLinux* parent =
- AXPlatformNodeAuraLinux::FromAtkObject(parent_atk_object);
- if (!parent)
- return;
-
- if (parent->GetDelegate()->IsWebContent())
- return;
-
- AXPlatformNodeAuraLinux* frame = AXPlatformNodeAuraLinux::FromAtkObject(
- FindAtkObjectParentFrame(parent_atk_object));
- if (!frame)
- return;
-
- frame->SetDocumentParent(parent_atk_object);
-}
-
-AtkObject* AXPlatformNodeAuraLinux::FindPrimaryWebContentDocument() {
- // It could get multiple web contents since additional web content is added,
- // when the DevTools window is opened.
- std::vector<AtkObject*> web_content_candidates;
- for (auto child_iterator_ptr = GetDelegate()->ChildrenBegin();
- *child_iterator_ptr != *GetDelegate()->ChildrenEnd();
- ++(*child_iterator_ptr)) {
- AtkObject* child = child_iterator_ptr->GetNativeViewAccessible();
- auto* child_node = AXPlatformNodeAuraLinux::FromAtkObject(child);
- if (!child_node)
- continue;
- if (!child_node->GetDelegate()->IsWebContent())
- continue;
- if (child_node->GetAtkRole() != ATK_ROLE_DOCUMENT_WEB)
- continue;
- web_content_candidates.push_back(child);
- }
-
- if (web_content_candidates.empty())
- return nullptr;
-
- // If it finds just one web content, return it.
- if (web_content_candidates.size() == 1)
- return web_content_candidates[0];
-
- for (auto* object : web_content_candidates) {
- auto* child_node = AXPlatformNodeAuraLinux::FromAtkObject(object);
- // If it is a primary web contents, return it.
- if (child_node->IsPrimaryWebContentsForWindow())
- return object;
- }
- return nullptr;
-}
-
-bool AXPlatformNodeAuraLinux::IsWebDocumentForRelations() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return false;
- AXPlatformNodeAuraLinux* parent = FromAtkObject(GetParent());
- if (!parent || !GetDelegate()->IsWebContent() ||
- GetAtkRole() != ATK_ROLE_DOCUMENT_WEB)
- return false;
- return parent->FindPrimaryWebContentDocument() == atk_object;
-}
-
-AtkObject* AXPlatformNodeAuraLinux::CreateAtkObject() {
- if (GetData().role != ax::mojom::Role::kApplication &&
- !GetDelegate()->IsToplevelBrowserWindow() &&
- !GetAccessibilityMode().has_mode(AXMode::kNativeAPIs))
- return nullptr;
- if (GetDelegate()->IsChildOfLeaf())
- return nullptr;
- EnsureGTypeInit();
- interface_mask_ = GetGTypeInterfaceMask(GetData());
- GType type = GetAccessibilityGType();
- AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, nullptr));
-
- atk_object_initialize(atk_object, this);
-
- SetDocumentParentOnFrameIfNecessary();
-
- return ATK_OBJECT(atk_object);
-}
-
-void AXPlatformNodeAuraLinux::DestroyAtkObjects() {
- if (atk_hyperlink_) {
- ax_platform_atk_hyperlink_set_object(
- AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink_), nullptr);
- g_object_unref(atk_hyperlink_);
- atk_hyperlink_ = nullptr;
- }
-
- if (atk_object_) {
- // We explicitly clear g_current_focused and g_current_active_descendant
- // just in case there is another reference to atk_object_ somewhere.
- if (atk_object_ == g_current_focused)
- SetWeakGPtrToAtkObject(&g_current_focused, nullptr);
- if (atk_object_ == g_current_active_descendant)
- SetWeakGPtrToAtkObject(&g_current_active_descendant, nullptr);
- atk_object::Detach(AX_PLATFORM_NODE_AURALINUX(atk_object_));
-
- g_object_unref(atk_object_);
- atk_object_ = nullptr;
- }
-}
-
-// static
-AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) {
- AXPlatformNodeAuraLinux* node = new AXPlatformNodeAuraLinux();
- node->Init(delegate);
- return node;
-}
-
-// static
-AXPlatformNode* AXPlatformNode::FromNativeViewAccessible(
- gfx::NativeViewAccessible accessible) {
- return AXPlatformNodeAuraLinux::FromAtkObject(accessible);
-}
-
-//
-// AXPlatformNodeAuraLinux implementation.
-//
-
-// static
-AXPlatformNodeAuraLinux* AXPlatformNodeAuraLinux::FromAtkObject(
- const AtkObject* atk_object) {
- if (!atk_object)
- return nullptr;
-
- if (IS_AX_PLATFORM_NODE_AURALINUX(atk_object)) {
- AXPlatformNodeAuraLinuxObject* platform_object =
- AX_PLATFORM_NODE_AURALINUX(atk_object);
- return platform_object->m_object;
- }
-
- return nullptr;
-}
-
-// static
-void AXPlatformNodeAuraLinux::SetApplication(AXPlatformNode* application) {
- g_root_application = application;
-}
-
-// static
-AXPlatformNode* AXPlatformNodeAuraLinux::application() {
- return g_root_application;
-}
-
-// static
-void AXPlatformNodeAuraLinux::StaticInitialize() {
- AtkUtilAuraLinux::GetInstance()->InitializeAsync();
-}
-
-// static
-void AXPlatformNodeAuraLinux::EnableAXMode() {
- AXPlatformNode::NotifyAddAXModeFlags(kAXModeComplete);
-}
-
-AtkRole AXPlatformNodeAuraLinux::GetAtkRole() const {
- switch (GetData().role) {
- case ax::mojom::Role::kAlert:
- return ATK_ROLE_NOTIFICATION;
- case ax::mojom::Role::kAlertDialog:
- return ATK_ROLE_ALERT;
- case ax::mojom::Role::kAnchor:
- return ATK_ROLE_LINK;
- case ax::mojom::Role::kComment:
- case ax::mojom::Role::kSuggestion:
- return ATK_ROLE_SECTION;
- case ax::mojom::Role::kApplication:
- // Only use ATK_ROLE_APPLICATION for elements with no parent, since it
- // is only for top level app windows and not ARIA applications.
- if (!GetParent()) {
- return ATK_ROLE_APPLICATION;
- } else {
- return ATK_ROLE_EMBEDDED;
- }
- case ax::mojom::Role::kArticle:
- return ATK_ROLE_ARTICLE;
- case ax::mojom::Role::kAudio:
- return ATK_ROLE_AUDIO;
- case ax::mojom::Role::kBanner:
- case ax::mojom::Role::kHeader:
- return ATK_ROLE_LANDMARK;
- case ax::mojom::Role::kBlockquote:
- return ATK_ROLE_BLOCK_QUOTE;
- case ax::mojom::Role::kCaret:
- return ATK_ROLE_UNKNOWN;
- case ax::mojom::Role::kButton:
- return ATK_ROLE_PUSH_BUTTON;
- case ax::mojom::Role::kCanvas:
- return ATK_ROLE_CANVAS;
- case ax::mojom::Role::kCaption:
- return ATK_ROLE_CAPTION;
- case ax::mojom::Role::kCell:
- return ATK_ROLE_TABLE_CELL;
- case ax::mojom::Role::kCheckBox:
- return ATK_ROLE_CHECK_BOX;
- case ax::mojom::Role::kSwitch:
- return ATK_ROLE_TOGGLE_BUTTON;
- case ax::mojom::Role::kColorWell:
- return ATK_ROLE_PUSH_BUTTON;
- case ax::mojom::Role::kColumn:
- return ATK_ROLE_UNKNOWN;
- case ax::mojom::Role::kColumnHeader:
- return ATK_ROLE_COLUMN_HEADER;
- case ax::mojom::Role::kComboBoxGrouping:
- return ATK_ROLE_COMBO_BOX;
- case ax::mojom::Role::kComboBoxMenuButton:
- return ATK_ROLE_COMBO_BOX;
- case ax::mojom::Role::kComplementary:
- return ATK_ROLE_LANDMARK;
- case ax::mojom::Role::kContentDeletion:
- return kAtkRoleContentDeletion;
- case ax::mojom::Role::kContentInsertion:
- return kAtkRoleContentInsertion;
- case ax::mojom::Role::kContentInfo:
- case ax::mojom::Role::kFooter:
- return ATK_ROLE_LANDMARK;
- case ax::mojom::Role::kDate:
- return ATK_ROLE_DATE_EDITOR;
- case ax::mojom::Role::kDateTime:
- return ATK_ROLE_DATE_EDITOR;
- case ax::mojom::Role::kDefinition:
- case ax::mojom::Role::kDescriptionListDetail:
- return ATK_ROLE_DESCRIPTION_VALUE;
- case ax::mojom::Role::kDescriptionList:
- return ATK_ROLE_DESCRIPTION_LIST;
- case ax::mojom::Role::kDescriptionListTerm:
- return ATK_ROLE_DESCRIPTION_TERM;
- case ax::mojom::Role::kDetails:
- return ATK_ROLE_PANEL;
- case ax::mojom::Role::kDialog:
- return ATK_ROLE_DIALOG;
- case ax::mojom::Role::kDirectory:
- return ATK_ROLE_LIST;
- case ax::mojom::Role::kDisclosureTriangle:
- return ATK_ROLE_TOGGLE_BUTTON;
- case ax::mojom::Role::kDocCover:
- return ATK_ROLE_IMAGE;
- case ax::mojom::Role::kDocBackLink:
- case ax::mojom::Role::kDocBiblioRef:
- case ax::mojom::Role::kDocGlossRef:
- case ax::mojom::Role::kDocNoteRef:
- return ATK_ROLE_LINK;
- case ax::mojom::Role::kDocBiblioEntry:
- case ax::mojom::Role::kDocEndnote:
- return ATK_ROLE_LIST_ITEM;
- case ax::mojom::Role::kDocNotice:
- case ax::mojom::Role::kDocTip:
- return ATK_ROLE_COMMENT;
- case ax::mojom::Role::kDocFootnote:
- return kAtkFootnoteRole;
- case ax::mojom::Role::kDocPageBreak:
- return ATK_ROLE_SEPARATOR;
- case ax::mojom::Role::kDocAcknowledgments:
- case ax::mojom::Role::kDocAfterword:
- case ax::mojom::Role::kDocAppendix:
- case ax::mojom::Role::kDocBibliography:
- case ax::mojom::Role::kDocChapter:
- case ax::mojom::Role::kDocConclusion:
- case ax::mojom::Role::kDocCredits:
- case ax::mojom::Role::kDocEndnotes:
- case ax::mojom::Role::kDocEpilogue:
- case ax::mojom::Role::kDocErrata:
- case ax::mojom::Role::kDocForeword:
- case ax::mojom::Role::kDocGlossary:
- case ax::mojom::Role::kDocIndex:
- case ax::mojom::Role::kDocIntroduction:
- case ax::mojom::Role::kDocPageList:
- case ax::mojom::Role::kDocPart:
- case ax::mojom::Role::kDocPreface:
- case ax::mojom::Role::kDocPrologue:
- case ax::mojom::Role::kDocToc:
- return ATK_ROLE_LANDMARK;
- case ax::mojom::Role::kDocAbstract:
- case ax::mojom::Role::kDocColophon:
- case ax::mojom::Role::kDocCredit:
- case ax::mojom::Role::kDocDedication:
- case ax::mojom::Role::kDocEpigraph:
- case ax::mojom::Role::kDocExample:
- case ax::mojom::Role::kDocPullquote:
- case ax::mojom::Role::kDocQna:
- return ATK_ROLE_SECTION;
- case ax::mojom::Role::kDocSubtitle:
- return ATK_ROLE_HEADING;
- case ax::mojom::Role::kDocument:
- return ATK_ROLE_DOCUMENT_FRAME;
- case ax::mojom::Role::kEmbeddedObject:
- return ATK_ROLE_EMBEDDED;
- case ax::mojom::Role::kForm:
- // TODO(accessibility) Forms which lack an accessible name are no longer
- // exposed as forms. http://crbug.com/874384. Forms which have accessible
- // names should be exposed as ATK_ROLE_LANDMARK according to Core AAM.
- return ATK_ROLE_FORM;
- case ax::mojom::Role::kFigure:
- case ax::mojom::Role::kFeed:
- return ATK_ROLE_PANEL;
- case ax::mojom::Role::kGenericContainer:
- case ax::mojom::Role::kFooterAsNonLandmark:
- case ax::mojom::Role::kHeaderAsNonLandmark:
- return ATK_ROLE_SECTION;
- case ax::mojom::Role::kGraphicsDocument:
- return ATK_ROLE_DOCUMENT_FRAME;
- case ax::mojom::Role::kGraphicsObject:
- return ATK_ROLE_PANEL;
- case ax::mojom::Role::kGraphicsSymbol:
- return ATK_ROLE_IMAGE;
- case ax::mojom::Role::kGrid:
- return ATK_ROLE_TABLE;
- case ax::mojom::Role::kGroup:
- return ATK_ROLE_PANEL;
- case ax::mojom::Role::kHeading:
- return ATK_ROLE_HEADING;
- case ax::mojom::Role::kIframe:
- case ax::mojom::Role::kIframePresentational:
- return ATK_ROLE_INTERNAL_FRAME;
- case ax::mojom::Role::kIgnored:
- return ATK_ROLE_REDUNDANT_OBJECT;
- case ax::mojom::Role::kImage:
- return ATK_ROLE_IMAGE;
- case ax::mojom::Role::kImageMap:
- return ATK_ROLE_IMAGE_MAP;
- case ax::mojom::Role::kInlineTextBox:
- return kStaticRole;
- case ax::mojom::Role::kInputTime:
- return ATK_ROLE_DATE_EDITOR;
- case ax::mojom::Role::kLabelText:
- return ATK_ROLE_LABEL;
- case ax::mojom::Role::kLegend:
- return ATK_ROLE_LABEL;
- // Layout table objects are treated the same as Role::kGenericContainer.
- case ax::mojom::Role::kLayoutTable:
- return ATK_ROLE_SECTION;
- case ax::mojom::Role::kLayoutTableCell:
- return ATK_ROLE_SECTION;
- case ax::mojom::Role::kLayoutTableRow:
- return ATK_ROLE_SECTION;
- case ax::mojom::Role::kLineBreak:
- // TODO(Accessibility) Having a separate accessible object for line breaks
- // is inconsistent with other implementations. http://crbug.com/873144#c1.
- return kStaticRole;
- case ax::mojom::Role::kLink:
- return ATK_ROLE_LINK;
- case ax::mojom::Role::kList:
- return ATK_ROLE_LIST;
- case ax::mojom::Role::kListBox:
- return ATK_ROLE_LIST_BOX;
- // TODO(Accessibility) Use ATK_ROLE_MENU_ITEM inside a combo box, see how
- // ax_platform_node_win.cc code does this.
- case ax::mojom::Role::kListBoxOption:
- return ATK_ROLE_LIST_ITEM;
- case ax::mojom::Role::kListGrid:
- return ATK_ROLE_TABLE;
- case ax::mojom::Role::kListItem:
- return ATK_ROLE_LIST_ITEM;
- case ax::mojom::Role::kListMarker:
- if (!GetChildCount()) {
- // There's only a name attribute when using Legacy layout. With Legacy
- // layout, list markers have no child and are considered as StaticText.
- // We consider a list marker as a group in LayoutNG since it has
- // a text child node.
- return kStaticRole;
- }
- return ATK_ROLE_PANEL;
- case ax::mojom::Role::kLog:
- return ATK_ROLE_LOG;
- case ax::mojom::Role::kMain:
- return ATK_ROLE_LANDMARK;
- case ax::mojom::Role::kMark:
- return kStaticRole;
- case ax::mojom::Role::kMath:
- return ATK_ROLE_MATH;
- case ax::mojom::Role::kMarquee:
- return ATK_ROLE_MARQUEE;
- case ax::mojom::Role::kMenu:
- return ATK_ROLE_MENU;
- case ax::mojom::Role::kMenuBar:
- return ATK_ROLE_MENU_BAR;
- case ax::mojom::Role::kMenuItem:
- return ATK_ROLE_MENU_ITEM;
- case ax::mojom::Role::kMenuItemCheckBox:
- return ATK_ROLE_CHECK_MENU_ITEM;
- case ax::mojom::Role::kMenuItemRadio:
- return ATK_ROLE_RADIO_MENU_ITEM;
- case ax::mojom::Role::kMenuListPopup:
- return ATK_ROLE_MENU;
- case ax::mojom::Role::kMenuListOption:
- return ATK_ROLE_MENU_ITEM;
- case ax::mojom::Role::kMeter:
- return ATK_ROLE_LEVEL_BAR;
- case ax::mojom::Role::kNavigation:
- return ATK_ROLE_LANDMARK;
- case ax::mojom::Role::kNote:
- return ATK_ROLE_COMMENT;
- case ax::mojom::Role::kPane:
- case ax::mojom::Role::kScrollView:
- return ATK_ROLE_PANEL;
- case ax::mojom::Role::kParagraph:
- return ATK_ROLE_PARAGRAPH;
- case ax::mojom::Role::kPdfActionableHighlight:
- return ATK_ROLE_PUSH_BUTTON;
- case ax::mojom::Role::kPluginObject:
- return ATK_ROLE_EMBEDDED;
- case ax::mojom::Role::kPopUpButton: {
- std::string html_tag =
- GetData().GetStringAttribute(ax::mojom::StringAttribute::kHtmlTag);
- if (html_tag == "select")
- return ATK_ROLE_COMBO_BOX;
- return ATK_ROLE_PUSH_BUTTON;
- }
- case ax::mojom::Role::kPortal:
- return ATK_ROLE_PUSH_BUTTON;
- case ax::mojom::Role::kPre:
- return ATK_ROLE_SECTION;
- case ax::mojom::Role::kProgressIndicator:
- return ATK_ROLE_PROGRESS_BAR;
- case ax::mojom::Role::kRadioButton:
- return ATK_ROLE_RADIO_BUTTON;
- case ax::mojom::Role::kRadioGroup:
- return ATK_ROLE_PANEL;
- case ax::mojom::Role::kRegion:
- return ATK_ROLE_LANDMARK;
- case ax::mojom::Role::kRootWebArea:
- return ATK_ROLE_DOCUMENT_WEB;
- case ax::mojom::Role::kRow:
- return ATK_ROLE_TABLE_ROW;
- case ax::mojom::Role::kRowGroup:
- return ATK_ROLE_PANEL;
- case ax::mojom::Role::kRowHeader:
- return ATK_ROLE_ROW_HEADER;
- case ax::mojom::Role::kRuby:
- return kStaticRole;
- case ax::mojom::Role::kRubyAnnotation:
- // TODO(accessibility) Panels are generally for containers of widgets.
- // This should probably be a section (if a container) or static if text.
- return ATK_ROLE_PANEL;
- case ax::mojom::Role::kSection: {
- if (GetName().empty()) {
- // Do not use ARIA mapping for nameless <section>.
- return ATK_ROLE_SECTION;
- } else {
- // Use ARIA mapping.
- return ATK_ROLE_LANDMARK;
- }
- }
- case ax::mojom::Role::kScrollBar:
- return ATK_ROLE_SCROLL_BAR;
- case ax::mojom::Role::kSearch:
- return ATK_ROLE_LANDMARK;
- case ax::mojom::Role::kSlider:
- case ax::mojom::Role::kSliderThumb:
- return ATK_ROLE_SLIDER;
- case ax::mojom::Role::kSpinButton:
- return ATK_ROLE_SPIN_BUTTON;
- case ax::mojom::Role::kSplitter:
- return ATK_ROLE_SEPARATOR;
- case ax::mojom::Role::kStaticText: {
- switch (static_cast<ax::mojom::TextPosition>(
- GetIntAttribute(ax::mojom::IntAttribute::kTextPosition))) {
- case ax::mojom::TextPosition::kSubscript:
- return kSubscriptRole;
- case ax::mojom::TextPosition::kSuperscript:
- return kSuperscriptRole;
- default:
- break;
- }
- return kStaticRole;
- }
- case ax::mojom::Role::kStatus:
- return ATK_ROLE_STATUSBAR;
- case ax::mojom::Role::kSvgRoot:
- return ATK_ROLE_DOCUMENT_FRAME;
- case ax::mojom::Role::kTab:
- return ATK_ROLE_PAGE_TAB;
- case ax::mojom::Role::kTable:
- return ATK_ROLE_TABLE;
- case ax::mojom::Role::kTableHeaderContainer:
- // TODO(accessibility) This mapping is correct, but it doesn't seem to be
- // used. We don't necessarily want to always expose these containers, but
- // we must do so if they are focusable. http://crbug.com/874043
- return ATK_ROLE_PANEL;
- case ax::mojom::Role::kTabList:
- return ATK_ROLE_PAGE_TAB_LIST;
- case ax::mojom::Role::kTabPanel:
- return ATK_ROLE_SCROLL_PANE;
- case ax::mojom::Role::kTerm:
- // TODO(accessibility) This mapping should also be applied to the dfn
- // element. http://crbug.com/874411
- return ATK_ROLE_DESCRIPTION_TERM;
- case ax::mojom::Role::kTitleBar:
- return ATK_ROLE_TITLE_BAR;
- case ax::mojom::Role::kTextField:
- case ax::mojom::Role::kSearchBox:
- if (GetData().HasState(ax::mojom::State::kProtected))
- return ATK_ROLE_PASSWORD_TEXT;
- return ATK_ROLE_ENTRY;
- case ax::mojom::Role::kTextFieldWithComboBox:
- return ATK_ROLE_COMBO_BOX;
- case ax::mojom::Role::kAbbr:
- case ax::mojom::Role::kCode:
- case ax::mojom::Role::kEmphasis:
- case ax::mojom::Role::kStrong:
- case ax::mojom::Role::kTime:
- return kStaticRole;
- case ax::mojom::Role::kTimer:
- return ATK_ROLE_TIMER;
- case ax::mojom::Role::kToggleButton:
- return ATK_ROLE_TOGGLE_BUTTON;
- case ax::mojom::Role::kToolbar:
- return ATK_ROLE_TOOL_BAR;
- case ax::mojom::Role::kTooltip:
- return ATK_ROLE_TOOL_TIP;
- case ax::mojom::Role::kTree:
- return ATK_ROLE_TREE;
- case ax::mojom::Role::kTreeItem:
- return ATK_ROLE_TREE_ITEM;
- case ax::mojom::Role::kTreeGrid:
- return ATK_ROLE_TREE_TABLE;
- case ax::mojom::Role::kVideo:
- return ATK_ROLE_VIDEO;
- case ax::mojom::Role::kWebArea:
- case ax::mojom::Role::kWebView:
- return ATK_ROLE_DOCUMENT_WEB;
- case ax::mojom::Role::kWindow:
- // In ATK elements with ATK_ROLE_FRAME are windows with titles and
- // buttons, while those with ATK_ROLE_WINDOW are windows without those
- // elements.
- return ATK_ROLE_FRAME;
- case ax::mojom::Role::kClient:
- case ax::mojom::Role::kDesktop:
- return ATK_ROLE_PANEL;
- case ax::mojom::Role::kFigcaption:
- return ATK_ROLE_CAPTION;
- case ax::mojom::Role::kUnknown:
- // When we are not in web content, assume that a node with an unknown
- // role is a view (which often have the unknown role).
- return !GetDelegate()->IsWebContent() ? ATK_ROLE_PANEL : ATK_ROLE_UNKNOWN;
- case ax::mojom::Role::kImeCandidate:
- case ax::mojom::Role::kKeyboard:
- case ax::mojom::Role::kNone:
- case ax::mojom::Role::kPresentational:
- return ATK_ROLE_REDUNDANT_OBJECT;
- }
-}
-
-void AXPlatformNodeAuraLinux::GetAtkState(AtkStateSet* atk_state_set) {
- AXNodeData data = GetData();
-
- bool menu_active = !GetActiveMenus().empty();
- if (!menu_active && atk_object_ == g_active_top_level_frame)
- atk_state_set_add_state(atk_state_set, ATK_STATE_ACTIVE);
- if (menu_active &&
- FindAtkObjectParentFrame(GetActiveMenus().back()) == atk_object_)
- atk_state_set_add_state(atk_state_set, ATK_STATE_ACTIVE);
-
- if (atk_object_ && atk_object_ == g_active_views_dialog)
- atk_state_set_add_state(atk_state_set, ATK_STATE_ACTIVE);
-
- bool is_minimized = delegate_->IsMinimized();
- if (is_minimized && data.role == ax::mojom::Role::kWindow)
- atk_state_set_add_state(atk_state_set, ATK_STATE_ICONIFIED);
-
- if (data.HasState(ax::mojom::State::kCollapsed))
- atk_state_set_add_state(atk_state_set, ATK_STATE_EXPANDABLE);
- if (data.HasState(ax::mojom::State::kDefault))
- atk_state_set_add_state(atk_state_set, ATK_STATE_DEFAULT);
- if ((data.HasState(ax::mojom::State::kEditable) ||
- data.HasState(ax::mojom::State::kRichlyEditable)) &&
- data.GetRestriction() != ax::mojom::Restriction::kReadOnly) {
- atk_state_set_add_state(atk_state_set, ATK_STATE_EDITABLE);
- }
- if (data.HasState(ax::mojom::State::kExpanded)) {
- atk_state_set_add_state(atk_state_set, ATK_STATE_EXPANDABLE);
- atk_state_set_add_state(atk_state_set, ATK_STATE_EXPANDED);
- }
- if (data.HasState(ax::mojom::State::kFocusable) ||
- SelectionAndFocusAreTheSame())
- atk_state_set_add_state(atk_state_set, ATK_STATE_FOCUSABLE);
- if (data.HasState(ax::mojom::State::kHorizontal))
- atk_state_set_add_state(atk_state_set, ATK_STATE_HORIZONTAL);
- if (!data.HasState(ax::mojom::State::kInvisible)) {
- atk_state_set_add_state(atk_state_set, ATK_STATE_VISIBLE);
- if (!delegate_->IsOffscreen() && !is_minimized)
- atk_state_set_add_state(atk_state_set, ATK_STATE_SHOWING);
- }
- if (data.HasState(ax::mojom::State::kMultiselectable))
- atk_state_set_add_state(atk_state_set, ATK_STATE_MULTISELECTABLE);
- if (data.HasState(ax::mojom::State::kRequired))
- atk_state_set_add_state(atk_state_set, ATK_STATE_REQUIRED);
- if (data.HasState(ax::mojom::State::kVertical))
- atk_state_set_add_state(atk_state_set, ATK_STATE_VERTICAL);
- if (data.HasState(ax::mojom::State::kVisited))
- atk_state_set_add_state(atk_state_set, ATK_STATE_VISITED);
- if (data.HasIntAttribute(ax::mojom::IntAttribute::kInvalidState) &&
- data.GetIntAttribute(ax::mojom::IntAttribute::kInvalidState) !=
- static_cast<int32_t>(ax::mojom::InvalidState::kFalse))
- atk_state_set_add_state(atk_state_set, ATK_STATE_INVALID_ENTRY);
-#if defined(ATK_216)
- if (IsPlatformCheckable())
- atk_state_set_add_state(atk_state_set, ATK_STATE_CHECKABLE);
- if (data.HasIntAttribute(ax::mojom::IntAttribute::kHasPopup))
- atk_state_set_add_state(atk_state_set, ATK_STATE_HAS_POPUP);
-#endif
- if (data.GetBoolAttribute(ax::mojom::BoolAttribute::kBusy))
- atk_state_set_add_state(atk_state_set, ATK_STATE_BUSY);
- if (data.GetBoolAttribute(ax::mojom::BoolAttribute::kModal))
- atk_state_set_add_state(atk_state_set, ATK_STATE_MODAL);
- if (data.IsSelectable())
- atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTABLE);
- if (data.GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
- atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTED);
-
- if (IsPlainTextField() || IsRichTextField()) {
- atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTABLE_TEXT);
- if (data.HasState(ax::mojom::State::kMultiline))
- atk_state_set_add_state(atk_state_set, ATK_STATE_MULTI_LINE);
- else
- atk_state_set_add_state(atk_state_set, ATK_STATE_SINGLE_LINE);
- }
-
- if (!GetStringAttribute(ax::mojom::StringAttribute::kAutoComplete).empty() ||
- data.HasState(ax::mojom::State::kAutofillAvailable))
- atk_state_set_add_state(atk_state_set, ATK_STATE_SUPPORTS_AUTOCOMPLETION);
-
- // Checked state
- const auto checked_state = GetData().GetCheckedState();
- if (checked_state == ax::mojom::CheckedState::kTrue ||
- checked_state == ax::mojom::CheckedState::kMixed) {
- atk_state_set_add_state(atk_state_set, GetAtkStateTypeForCheckableNode());
- }
-
- if (data.GetRestriction() != ax::mojom::Restriction::kDisabled) {
- if (IsReadOnlySupported(data.role) && data.IsReadOnlyOrDisabled()) {
-#if defined(ATK_216)
- atk_state_set_add_state(atk_state_set, ATK_STATE_READ_ONLY);
-#endif
- } else {
- atk_state_set_add_state(atk_state_set, ATK_STATE_ENABLED);
- atk_state_set_add_state(atk_state_set, ATK_STATE_SENSITIVE);
- }
- }
-
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- if (delegate_->GetFocus() == atk_object)
- atk_state_set_add_state(atk_state_set, ATK_STATE_FOCUSED);
-
- // It is insufficient to compare with g_current_activedescendant due to both
- // timing and event ordering for objects which implement AtkSelection and also
- // have an active descendant. For instance, if we check the state set of a
- // selectable child, it will only have ATK_STATE_FOCUSED if we've processed
- // the activedescendant change.
- if (GetActiveDescendantOfCurrentFocused() == atk_object)
- atk_state_set_add_state(atk_state_set, ATK_STATE_FOCUSED);
-}
-
-struct AtkIntRelation {
- ax::mojom::IntAttribute attribute;
- AtkRelationType relation;
- base::Optional<AtkRelationType> reverse_relation;
-};
-
-static AtkIntRelation kIntRelations[] = {
- {ax::mojom::IntAttribute::kMemberOfId, ATK_RELATION_MEMBER_OF,
- base::nullopt},
- {ax::mojom::IntAttribute::kPopupForId, ATK_RELATION_POPUP_FOR,
- base::nullopt},
-#if defined(ATK_226)
- {ax::mojom::IntAttribute::kErrormessageId, ATK_RELATION_ERROR_MESSAGE,
- ATK_RELATION_ERROR_FOR},
-#endif
-};
-
-struct AtkIntListRelation {
- ax::mojom::IntListAttribute attribute;
- AtkRelationType relation;
- base::Optional<AtkRelationType> reverse_relation;
-};
-
-static AtkIntListRelation kIntListRelations[] = {
- {ax::mojom::IntListAttribute::kControlsIds, ATK_RELATION_CONTROLLER_FOR,
- ATK_RELATION_CONTROLLED_BY},
-#if defined(ATK_226)
- {ax::mojom::IntListAttribute::kDetailsIds, ATK_RELATION_DETAILS,
- ATK_RELATION_DETAILS_FOR},
-#endif
- {ax::mojom::IntListAttribute::kDescribedbyIds, ATK_RELATION_DESCRIBED_BY,
- ATK_RELATION_DESCRIPTION_FOR},
- {ax::mojom::IntListAttribute::kFlowtoIds, ATK_RELATION_FLOWS_TO,
- ATK_RELATION_FLOWS_FROM},
- {ax::mojom::IntListAttribute::kLabelledbyIds, ATK_RELATION_LABELLED_BY,
- ATK_RELATION_LABEL_FOR},
-};
-
-void AXPlatformNodeAuraLinux::AddRelationToSet(AtkRelationSet* relation_set,
- AtkRelationType relation,
- AXPlatformNode* target) {
- DCHECK(target);
-
- // Avoid adding self-referential relations.
- if (target == this)
- return;
-
- // If we were compiled with a newer version of ATK than the runtime version,
- // it's possible that we might try to add a relation that doesn't exist in
- // the runtime version of the AtkRelationType enum. This will cause a runtime
- // error, so return early here if we are about to do that.
- static base::Optional<int> max_relation_type = base::nullopt;
- if (!max_relation_type.has_value()) {
- GEnumClass* enum_class =
- G_ENUM_CLASS(g_type_class_ref(atk_relation_type_get_type()));
- max_relation_type = enum_class->maximum;
- g_type_class_unref(enum_class);
- }
- if (relation > max_relation_type.value())
- return;
-
- atk_relation_set_add_relation_by_type(relation_set, relation,
- target->GetNativeViewAccessible());
-}
-
-AtkRelationSet* AXPlatformNodeAuraLinux::GetAtkRelations() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return nullptr;
-
- AtkRelationSet* relation_set = atk_relation_set_new();
-
- if (IsWebDocumentForRelations()) {
- AtkObject* parent_frame = FindAtkObjectParentFrame(atk_object);
- if (parent_frame) {
- atk_relation_set_add_relation_by_type(
- relation_set, ATK_RELATION_EMBEDDED_BY, parent_frame);
- }
- }
-
- if (auto* document_parent = FromAtkObject(document_parent_)) {
- AtkObject* document = document_parent->FindPrimaryWebContentDocument();
- if (document) {
- atk_relation_set_add_relation_by_type(relation_set, ATK_RELATION_EMBEDS,
- document);
- }
- }
-
- // For each possible relation defined by an IntAttribute, we test that
- // attribute and then look for reverse relations. AddRelationToSet handles
- // discarding self-referential relations.
- for (unsigned i = 0; i < G_N_ELEMENTS(kIntRelations); i++) {
- const AtkIntRelation& relation = kIntRelations[i];
-
- if (AXPlatformNode* target =
- GetDelegate()->GetTargetNodeForRelation(relation.attribute))
- AddRelationToSet(relation_set, relation.relation, target);
-
- if (!relation.reverse_relation.has_value())
- continue;
-
- std::set<AXPlatformNode*> target_ids =
- GetDelegate()->GetReverseRelations(relation.attribute);
- for (AXPlatformNode* target : target_ids) {
- AddRelationToSet(relation_set, relation.reverse_relation.value(), target);
- }
- }
-
- // Now we do the same for each possible relation defined by an
- // IntListAttribute. In this case we need to handle each target in the list.
- for (const auto& relation : kIntListRelations) {
- std::vector<AXPlatformNode*> targets =
- GetDelegate()->GetTargetNodesForRelation(relation.attribute);
- for (AXPlatformNode* target : targets) {
- AddRelationToSet(relation_set, relation.relation, target);
- }
-
- if (!relation.reverse_relation.has_value())
- continue;
-
- std::set<AXPlatformNode*> reverse_target_ids =
- GetDelegate()->GetReverseRelations(relation.attribute);
- for (AXPlatformNode* target : reverse_target_ids) {
- AddRelationToSet(relation_set, relation.reverse_relation.value(), target);
- }
- }
-
- return relation_set;
-}
-
-AXPlatformNodeAuraLinux::AXPlatformNodeAuraLinux() = default;
-
-AXPlatformNodeAuraLinux::~AXPlatformNodeAuraLinux() {
- if (g_current_selected == this)
- g_current_selected = nullptr;
-
- DestroyAtkObjects();
-
- if (window_activate_event_postponed_)
- AtkUtilAuraLinux::GetInstance()->CancelPostponedEventsFor(this);
-
- SetWeakGPtrToAtkObject(&document_parent_, nullptr);
-}
-
-void AXPlatformNodeAuraLinux::Destroy() {
- DestroyAtkObjects();
- AXPlatformNodeBase::Destroy();
-}
-
-void AXPlatformNodeAuraLinux::Init(AXPlatformNodeDelegate* delegate) {
- // Initialize ATK.
- AXPlatformNodeBase::Init(delegate);
-
- // Only create the AtkObject if we know enough information.
- if (GetData().role != ax::mojom::Role::kUnknown)
- GetOrCreateAtkObject();
-}
-
-bool AXPlatformNodeAuraLinux::IsPlatformCheckable() const {
- if (GetData().role == ax::mojom::Role::kToggleButton)
- return false;
-
- return AXPlatformNodeBase::IsPlatformCheckable();
-}
-
-base::Optional<int> AXPlatformNodeAuraLinux::GetIndexInParent() {
- AXPlatformNode* parent =
- AXPlatformNode::FromNativeViewAccessible(GetParent());
- // Even though the node doesn't have its parent, GetParent() could return the
- // application. Since the detached view has the kUnknown role and the
- // restriction is kDisabled, it early returns before finding the index.
- if (parent == AXPlatformNodeAuraLinux::application() &&
- GetData().role == ax::mojom::Role::kUnknown &&
- GetData().GetRestriction() == ax::mojom::Restriction::kDisabled) {
- return base::nullopt;
- }
-
- return AXPlatformNodeBase::GetIndexInParent();
-}
-
-void AXPlatformNodeAuraLinux::EnsureAtkObjectIsValid() {
- if (atk_object_) {
- // If the object's role changes and that causes its
- // interface mask to change, we need to create a new
- // AtkObject for it.
- ImplementedAtkInterfaces interface_mask = GetGTypeInterfaceMask(GetData());
- if (interface_mask != interface_mask_)
- DestroyAtkObjects();
- }
-
- if (!atk_object_) {
- GetOrCreateAtkObject();
- }
-}
-
-gfx::NativeViewAccessible AXPlatformNodeAuraLinux::GetNativeViewAccessible() {
- return GetOrCreateAtkObject();
-}
-
-gfx::NativeViewAccessible AXPlatformNodeAuraLinux::GetOrCreateAtkObject() {
- if (!atk_object_) {
- atk_object_ = CreateAtkObject();
- }
- return atk_object_;
-}
-
-void AXPlatformNodeAuraLinux::OnActiveDescendantChanged() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- // Active-descendant-changed notifications are typically only relevant when
- // the change is within the focused widget.
- if (!g_current_focused)
- return;
- if (auto* focused_node = FromAtkObject(g_current_focused)) {
- if (!focused_node->IsDescendantOf(this))
- return;
- }
-
- AtkObject* descendant = GetActiveDescendantOfCurrentFocused();
- if (descendant == g_current_active_descendant)
- return;
-
- // If selection and focus are the same, when the active descendant changes
- // as a result of selection, a focus event will be emitted. We don't want to
- // emit duplicate notifications.
- {
- auto* node = FromAtkObject(descendant);
- if (node && node->SelectionAndFocusAreTheSame())
- return;
- }
-
- // While there is an ATK active-descendant-changed event, it is meant for
- // objects which manage their descendants (and claim to do so). The Core-AAM
- // specification states that focus events should be emitted when the active
- // descendant changes. This behavior is also consistent with Gecko.
- if (g_current_active_descendant) {
- g_signal_emit_by_name(g_current_active_descendant, "focus-event", false);
- atk_object_notify_state_change(ATK_OBJECT(g_current_active_descendant),
- ATK_STATE_FOCUSED, false);
- }
-
- SetWeakGPtrToAtkObject(&g_current_active_descendant, descendant);
- if (g_current_active_descendant) {
- g_signal_emit_by_name(g_current_active_descendant, "focus-event", true);
- atk_object_notify_state_change(ATK_OBJECT(g_current_active_descendant),
- ATK_STATE_FOCUSED, true);
- }
-}
-
-void AXPlatformNodeAuraLinux::OnCheckedStateChanged() {
- AtkObject* obj = GetOrCreateAtkObject();
- if (!obj)
- return;
-
- atk_object_notify_state_change(
- ATK_OBJECT(obj), GetAtkStateTypeForCheckableNode(),
- GetData().GetCheckedState() != ax::mojom::CheckedState::kFalse);
-}
-
-void AXPlatformNodeAuraLinux::OnEnabledChanged() {
- AtkObject* obj = GetOrCreateAtkObject();
- if (!obj)
- return;
-
- atk_object_notify_state_change(
- obj, ATK_STATE_ENABLED,
- GetData().GetRestriction() != ax::mojom::Restriction::kDisabled);
-}
-
-void AXPlatformNodeAuraLinux::OnExpandedStateChanged(bool is_expanded) {
- // When a list box is expanded, it becomes visible. This means that it might
- // now have a different role (the role for hidden Views is kUnknown). We
- // need to recreate the AtkObject in this case because a change in roles
- // might imply a change in ATK interfaces implemented.
- EnsureAtkObjectIsValid();
-
- AtkObject* obj = GetOrCreateAtkObject();
- if (!obj)
- return;
-
- atk_object_notify_state_change(obj, ATK_STATE_EXPANDED, is_expanded);
-}
-
-void AXPlatformNodeAuraLinux::OnMenuPopupStart() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- AtkObject* parent_frame = FindAtkObjectParentFrame(atk_object);
- if (!parent_frame)
- return;
-
- // Exit early if kMenuPopupStart is sent multiple times for the same menu.
- std::vector<AtkObject*>& active_menus = GetActiveMenus();
- bool menu_already_open = !active_menus.empty();
- if (menu_already_open && active_menus.back() == atk_object)
- return;
-
- // We also want to inform the AT that menu the is now showing. Normally this
- // event is not fired because the menu will be created with the
- // ATK_STATE_SHOWING already set to TRUE.
- atk_object_notify_state_change(atk_object, ATK_STATE_SHOWING, TRUE);
-
- // We need to compute this before modifying the active menu stack.
- AtkObject* previous_active_frame = ComputeActiveTopLevelFrame();
-
- active_menus.push_back(atk_object);
-
- // We exit early if the newly activated menu has the same AtkWindow as the
- // previous one.
- if (previous_active_frame == parent_frame)
- return;
- if (previous_active_frame) {
- g_signal_emit_by_name(previous_active_frame, "deactivate");
- atk_object_notify_state_change(previous_active_frame, ATK_STATE_ACTIVE,
- FALSE);
- }
- g_signal_emit_by_name(parent_frame, "activate");
- atk_object_notify_state_change(parent_frame, ATK_STATE_ACTIVE, TRUE);
-}
-
-void AXPlatformNodeAuraLinux::OnMenuPopupEnd() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- AtkObject* parent_frame = FindAtkObjectParentFrame(atk_object);
- if (!parent_frame)
- return;
-
- atk_object_notify_state_change(atk_object, ATK_STATE_SHOWING, FALSE);
-
- // kMenuPopupHide may be called multiple times for the same menu, so only
- // remove it if our parent frame matches the most recently opened menu.
- std::vector<AtkObject*>& active_menus = GetActiveMenus();
- DCHECK(!active_menus.empty())
- << "Asymmetrical menupopupend events -- too many";
-
- active_menus.pop_back();
- AtkObject* new_active_item = ComputeActiveTopLevelFrame();
- if (new_active_item != parent_frame) {
- // Newly activated menu has the different AtkWindow as the previous one.
- g_signal_emit_by_name(parent_frame, "deactivate");
- atk_object_notify_state_change(parent_frame, ATK_STATE_ACTIVE, FALSE);
- if (new_active_item) {
- g_signal_emit_by_name(new_active_item, "activate");
- atk_object_notify_state_change(new_active_item, ATK_STATE_ACTIVE, TRUE);
- }
- }
-
- // All menus are closed.
- if (active_menus.empty())
- OnAllMenusEnded();
-}
-
-void AXPlatformNodeAuraLinux::ResendFocusSignalsForCurrentlyFocusedNode() {
- auto* frame = FromAtkObject(g_active_top_level_frame);
- if (!frame)
- return;
-
- AtkObject* focused_node = frame->GetDelegate()->GetFocus();
- if (!focused_node)
- return;
-
- g_signal_emit_by_name(focused_node, "focus-event", true);
- atk_object_notify_state_change(focused_node, ATK_STATE_FOCUSED, true);
-}
-
-// All menus have closed.
-void AXPlatformNodeAuraLinux::OnAllMenusEnded() {
- if (!GetActiveMenus().empty() && g_active_top_level_frame &&
- ComputeActiveTopLevelFrame() != g_active_top_level_frame) {
- g_signal_emit_by_name(g_active_top_level_frame, "activate");
- atk_object_notify_state_change(g_active_top_level_frame, ATK_STATE_ACTIVE,
- TRUE);
- }
-
- GetActiveMenus().clear();
- ResendFocusSignalsForCurrentlyFocusedNode();
-}
-
-void AXPlatformNodeAuraLinux::OnWindowActivated() {
- AtkObject* parent_frame = FindAtkObjectParentFrame(GetOrCreateAtkObject());
- if (!parent_frame || parent_frame == g_active_top_level_frame)
- return;
-
- SetActiveTopLevelFrame(parent_frame);
-
- g_signal_emit_by_name(parent_frame, "activate");
- atk_object_notify_state_change(parent_frame, ATK_STATE_ACTIVE, TRUE);
-
- // We also send a focus event for the currently focused element, so that
- // the user knows where the focus is when the toplevel window regains focus.
- if (g_current_focused &&
- IsFrameAncestorOfAtkObject(parent_frame, g_current_focused)) {
- g_signal_emit_by_name(g_current_focused, "focus-event", true);
- atk_object_notify_state_change(ATK_OBJECT(g_current_focused),
- ATK_STATE_FOCUSED, true);
- }
-}
-
-void AXPlatformNodeAuraLinux::OnWindowDeactivated() {
- AtkObject* parent_frame = FindAtkObjectParentFrame(GetOrCreateAtkObject());
- if (!parent_frame || parent_frame != g_active_top_level_frame)
- return;
-
- SetActiveTopLevelFrame(nullptr);
-
- g_signal_emit_by_name(parent_frame, "deactivate");
- atk_object_notify_state_change(parent_frame, ATK_STATE_ACTIVE, FALSE);
-}
-
-void AXPlatformNodeAuraLinux::OnWindowVisibilityChanged() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- if (GetAtkRole() != ATK_ROLE_FRAME)
- return;
-
- bool minimized = delegate_->IsMinimized();
- if (minimized == was_minimized_)
- return;
-
- was_minimized_ = minimized;
- if (minimized)
- g_signal_emit_by_name(atk_object, "minimize");
- else
- g_signal_emit_by_name(atk_object, "restore");
- atk_object_notify_state_change(atk_object, ATK_STATE_ICONIFIED, minimized);
-}
-
-void AXPlatformNodeAuraLinux::OnScrolledToAnchor() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
- DCHECK(ATK_IS_TEXT(atk_object));
- g_signal_emit_by_name(atk_object, "text-caret-moved", 0);
-}
-
-void AXPlatformNodeAuraLinux::SetActiveViewsDialog() {
- AtkObject* old_views_dialog = g_active_views_dialog;
- AtkObject* new_views_dialog = nullptr;
-
- AtkObject* parent = GetOrCreateAtkObject();
- if (!parent)
- return;
-
- if (!GetDelegate()->IsWebContent()) {
- while (parent) {
- if (atk_object::GetRole(parent) == ATK_ROLE_DIALOG) {
- new_views_dialog = parent;
- break;
- }
- parent = atk_object::GetParent(parent);
- }
- }
-
- if (old_views_dialog == new_views_dialog)
- return;
-
- SetWeakGPtrToAtkObject(&g_active_views_dialog, new_views_dialog);
- if (old_views_dialog)
- atk_object_notify_state_change(old_views_dialog, ATK_STATE_ACTIVE, FALSE);
- if (new_views_dialog)
- atk_object_notify_state_change(new_views_dialog, ATK_STATE_ACTIVE, TRUE);
-}
-
-void AXPlatformNodeAuraLinux::OnFocused() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- if (atk_object::GetRole(atk_object) == ATK_ROLE_FRAME) {
- OnWindowActivated();
- return;
- }
-
- if (atk_object == g_current_focused)
- return;
-
- SetActiveViewsDialog();
-
- AtkObject* old_effective_focus = g_current_active_descendant
- ? g_current_active_descendant
- : g_current_focused;
- if (old_effective_focus) {
- g_signal_emit_by_name(old_effective_focus, "focus-event", false);
- atk_object_notify_state_change(ATK_OBJECT(old_effective_focus),
- ATK_STATE_FOCUSED, false);
- }
-
- SetWeakGPtrToAtkObject(&g_current_focused, atk_object);
- AtkObject* descendant = GetActiveDescendantOfCurrentFocused();
- SetWeakGPtrToAtkObject(&g_current_active_descendant, descendant);
-
- AtkObject* new_effective_focus = g_current_active_descendant
- ? g_current_active_descendant
- : g_current_focused;
- g_signal_emit_by_name(new_effective_focus, "focus-event", true);
- atk_object_notify_state_change(ATK_OBJECT(new_effective_focus),
- ATK_STATE_FOCUSED, true);
-}
-
-void AXPlatformNodeAuraLinux::OnSelected() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
- if (g_current_selected && !g_current_selected->GetData().GetBoolAttribute(
- ax::mojom::BoolAttribute::kSelected)) {
- atk_object_notify_state_change(
- ATK_OBJECT(g_current_selected->GetOrCreateAtkObject()),
- ATK_STATE_SELECTED, false);
- }
-
- g_current_selected = this;
- if (ATK_IS_OBJECT(atk_object)) {
- atk_object_notify_state_change(ATK_OBJECT(atk_object), ATK_STATE_SELECTED,
- true);
- }
-
- if (SelectionAndFocusAreTheSame())
- OnFocused();
-}
-
-void AXPlatformNodeAuraLinux::OnSelectedChildrenChanged() {
- AtkObject* obj = GetOrCreateAtkObject();
- if (!obj)
- return;
-
- g_signal_emit_by_name(obj, "selection-changed", true);
-}
-
-bool AXPlatformNodeAuraLinux::SelectionAndFocusAreTheSame() {
- if (AXPlatformNodeBase* container = GetSelectionContainer()) {
- ax::mojom::Role role = container->GetData().role;
-
- // In the browser UI, menus and their descendants emit selection-related
- // events only, but we also want to emit platform focus-related events,
- // so we treat selection and focus the same for browser UI.
- if (role == ax::mojom::Role::kMenuBar || role == ax::mojom::Role::kMenu)
- return !GetDelegate()->IsWebContent();
- if (role == ax::mojom::Role::kListBox &&
- !container->GetData().HasState(ax::mojom::State::kMultiselectable)) {
- return container->GetDelegate()->GetFocus() ==
- container->GetNativeViewAccessible();
- }
- }
-
- // TODO(accessibility): GetSelectionContainer returns nullptr when the current
- // object is a descendant of a select element with a size of 1. Intentional?
- // For now, handle that scenario here.
- //
- // If the selection is changing on a collapsed select element, focus remains
- // on the select element and not the newly-selected descendant.
- if (AXPlatformNodeBase* parent = FromAtkObject(GetParent())) {
- if (parent->GetData().role == ax::mojom::Role::kMenuListPopup)
- return !parent->GetData().HasState(ax::mojom::State::kInvisible);
- }
-
- return false;
-}
-
-bool AXPlatformNodeAuraLinux::EmitsAtkTextEvents() const {
- // Objects which do not implement AtkText cannot emit AtkText events.
- if (!atk_object_ || !ATK_IS_TEXT(atk_object_))
- return false;
-
- // Objects which do implement AtkText, but are ignored or invisible should not
- // emit AtkText events.
- if (IsInvisibleOrIgnored())
- return false;
-
- // If this node is not a static text node, it supports the full AtkText
- // interface.
- if (GetAtkRole() != kStaticRole)
- return true;
-
- // If this node has children it is not a static text leaf node and supports
- // the full AtkText interface.
- if (GetChildCount())
- return true;
-
- return false;
-}
-
-void AXPlatformNodeAuraLinux::GetFullSelection(int32_t* anchor_node_id,
- int* anchor_offset,
- int32_t* focus_node_id,
- int* focus_offset) {
- DCHECK(anchor_node_id);
- DCHECK(anchor_offset);
- DCHECK(focus_node_id);
- DCHECK(focus_offset);
-
- if (IsPlainTextField() &&
- GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, anchor_offset) &&
- GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, focus_offset)) {
- int32_t node_id = GetData().id != -1 ? GetData().id : GetUniqueId();
- *anchor_node_id = *focus_node_id = node_id;
- return;
- }
-
- AXTree::Selection selection = GetDelegate()->GetUnignoredSelection();
- *anchor_node_id = selection.anchor_object_id;
- *anchor_offset = selection.anchor_offset;
- *focus_node_id = selection.focus_object_id;
- *focus_offset = selection.focus_offset;
-}
-
-AXPlatformNodeAuraLinux& AXPlatformNodeAuraLinux::FindEditableRootOrDocument() {
- if (GetAtkRole() == ATK_ROLE_DOCUMENT_WEB)
- return *this;
- if (GetData().GetBoolAttribute(ax::mojom::BoolAttribute::kEditableRoot))
- return *this;
- if (auto* parent = FromAtkObject(GetParent()))
- return parent->FindEditableRootOrDocument();
- return *this;
-}
-
-AXPlatformNodeAuraLinux* AXPlatformNodeAuraLinux::FindCommonAncestor(
- AXPlatformNodeAuraLinux* other) {
- if (this == other || other->IsDescendantOf(this))
- return this;
- if (auto* parent = FromAtkObject(GetParent()))
- return parent->FindCommonAncestor(other);
- return nullptr;
-}
-
-void AXPlatformNodeAuraLinux::UpdateSelectionInformation(int32_t anchor_node_id,
- int anchor_offset,
- int32_t focus_node_id,
- int focus_offset) {
- had_nonzero_width_selection =
- focus_node_id != anchor_node_id || focus_offset != anchor_offset;
- current_caret_ = std::make_pair(focus_node_id, focus_offset);
-}
-
-void AXPlatformNodeAuraLinux::EmitSelectionChangedSignal(bool had_selection) {
- if (!EmitsAtkTextEvents()) {
- if (auto* parent = FromAtkObject(GetParent()))
- parent->EmitSelectionChangedSignal(had_selection);
- return;
- }
-
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
- DCHECK(ATK_IS_TEXT(atk_object));
-
- // ATK does not consider a collapsed selection a selection, so
- // when the collapsed selection changes (caret movement), we should
- // avoid sending text-selection-changed events.
- if (HasSelection() || had_selection)
- g_signal_emit_by_name(atk_object, "text-selection-changed");
-}
-
-void AXPlatformNodeAuraLinux::EmitCaretChangedSignal() {
- if (!EmitsAtkTextEvents()) {
- if (auto* parent = FromAtkObject(GetParent()))
- parent->EmitCaretChangedSignal();
- return;
- }
-
- DCHECK(HasCaret());
- std::pair<int, int> selection = GetSelectionOffsetsForAtk();
-
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- DCHECK(ATK_IS_TEXT(atk_object));
- g_signal_emit_by_name(atk_object, "text-caret-moved",
- UTF16ToUnicodeOffsetInText(selection.second));
-}
-
-void AXPlatformNodeAuraLinux::OnTextAttributesChanged() {
- if (!EmitsAtkTextEvents()) {
- if (auto* parent = FromAtkObject(GetParent()))
- parent->OnTextAttributesChanged();
- return;
- }
-
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- DCHECK(ATK_IS_TEXT(atk_object));
- g_signal_emit_by_name(atk_object, "text-attributes-changed");
-}
-
-void AXPlatformNodeAuraLinux::OnTextSelectionChanged() {
- int32_t anchor_node_id, focus_node_id;
- int anchor_offset, focus_offset;
- GetFullSelection(&anchor_node_id, &anchor_offset, &focus_node_id,
- &focus_offset);
-
- auto* anchor_node = static_cast<AXPlatformNodeAuraLinux*>(
- GetDelegate()->GetFromNodeID(anchor_node_id));
- auto* focus_node = static_cast<AXPlatformNodeAuraLinux*>(
- GetDelegate()->GetFromNodeID(focus_node_id));
- if (!anchor_node || !focus_node)
- return;
-
- AXPlatformNodeAuraLinux& editable_root = FindEditableRootOrDocument();
- AXPlatformNodeAuraLinux* common_ancestor =
- focus_node->FindCommonAncestor(anchor_node);
- if (common_ancestor) {
- common_ancestor->EmitSelectionChangedSignal(
- editable_root.HadNonZeroWidthSelection());
- }
-
- // It's possible for the selection to change and for the caret to stay in
- // place. This might happen if the selection is totally reset with a
- // different anchor node, but the same focus node. We should avoid sending a
- // caret changed signal in that case.
- std::pair<int32_t, int> prev_caret = editable_root.GetCurrentCaret();
- if (prev_caret.first != focus_node_id || prev_caret.second != focus_offset)
- focus_node->EmitCaretChangedSignal();
-
- editable_root.UpdateSelectionInformation(anchor_node_id, anchor_offset,
- focus_node_id, focus_offset);
-}
-
-bool AXPlatformNodeAuraLinux::SupportsSelectionWithAtkSelection() {
- return SupportsToggle(GetData().role) ||
- GetData().role == ax::mojom::Role::kListBoxOption;
-}
-
-void AXPlatformNodeAuraLinux::OnDescriptionChanged() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- std::string description;
- GetStringAttribute(ax::mojom::StringAttribute::kDescription, &description);
-
- AtkPropertyValues property_values;
- property_values.property_name = "accessible-description";
- property_values.new_value = G_VALUE_INIT;
- g_value_init(&property_values.new_value, G_TYPE_STRING);
- g_value_set_string(&property_values.new_value, description.c_str());
- g_signal_emit_by_name(G_OBJECT(atk_object),
- "property-change::accessible-description",
- &property_values, nullptr);
- g_value_unset(&property_values.new_value);
-}
-
-void AXPlatformNodeAuraLinux::OnSortDirectionChanged() {
- AXPlatformNodeBase* table = GetTable();
- if (!table)
- return;
-
- AtkObject* atk_table = table->GetNativeViewAccessible();
- DCHECK(ATK_IS_TABLE(atk_table));
-
- if (GetData().role == ax::mojom::Role::kColumnHeader)
- g_signal_emit_by_name(atk_table, "row-reordered");
- else if (GetData().role == ax::mojom::Role::kRowHeader)
- g_signal_emit_by_name(atk_table, "column-reordered");
-}
-
-void AXPlatformNodeAuraLinux::OnValueChanged() {
- // For the AtkText interface to work on non-web content nodes, we need to
- // update the nodes' hypertext and trigger text change signals when the value
- // changes. Otherwise, for web and PDF content, this is handled by
- // "BrowserAccessibilityAuraLinux".
- if (!GetDelegate()->IsWebContent())
- UpdateHypertext();
-
- if (!GetData().IsRangeValueSupported())
- return;
-
- float float_val;
- if (!GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange, &float_val))
- return;
-
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- AtkPropertyValues property_values;
- property_values.property_name = "accessible-value";
-
- property_values.new_value = G_VALUE_INIT;
- g_value_init(&property_values.new_value, G_TYPE_DOUBLE);
- g_value_set_double(&property_values.new_value,
- static_cast<double>(float_val));
- g_signal_emit_by_name(G_OBJECT(atk_object),
- "property-change::accessible-value", &property_values,
- nullptr);
-}
-
-void AXPlatformNodeAuraLinux::OnNameChanged() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object) {
- return;
- }
- std::string previous_accessible_name = accessible_name_;
- // Calling atk_object_get_name will update the value of accessible_name_.
- if (!g_strcmp0(atk_object::GetName(atk_object),
- previous_accessible_name.c_str()))
- return;
-
- g_object_notify(G_OBJECT(atk_object), "accessible-name");
-}
-
-void AXPlatformNodeAuraLinux::OnDocumentTitleChanged() {
- if (!g_active_top_level_frame)
- return;
-
- // We always want to notify on the top frame.
- AXPlatformNodeAuraLinux* window = FromAtkObject(g_active_top_level_frame);
- if (window)
- window->OnNameChanged();
-}
-
-void AXPlatformNodeAuraLinux::OnSubtreeCreated() {
- // We might not have a parent, in that case we don't need to send the event.
- // We also don't want to notify if this is an ignored node
- if (!GetParent() || GetData().IsIgnored())
- return;
-
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- g_signal_emit_by_name(GetParent(), "children-changed::add",
- GetIndexInParent().value_or(-1), atk_object);
-}
-
-void AXPlatformNodeAuraLinux::OnSubtreeWillBeDeleted() {
- // There is a chance there won't be a parent as we're in the deletion process.
- // We also don't want to notify if this is an ignored node
- if (!GetParent() || GetData().IsIgnored())
- return;
-
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- g_signal_emit_by_name(GetParent(), "children-changed::remove",
- GetIndexInParent().value_or(-1), atk_object);
-}
-
-void AXPlatformNodeAuraLinux::OnParentChanged() {
- if (!atk_object_)
- return;
-
- AtkPropertyValues property_values;
- property_values.property_name = "accessible-parent";
- property_values.new_value = G_VALUE_INIT;
- g_value_init(&property_values.new_value, G_TYPE_OBJECT);
- g_value_set_object(&property_values.new_value, GetParent());
- g_signal_emit_by_name(G_OBJECT(atk_object_),
- "property-change::accessible-parent", &property_values,
- nullptr);
- g_value_unset(&property_values.new_value);
-}
-
-void AXPlatformNodeAuraLinux::OnInvalidStatusChanged() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- atk_object_notify_state_change(
- ATK_OBJECT(atk_object), ATK_STATE_INVALID_ENTRY,
- GetData().GetInvalidState() != ax::mojom::InvalidState::kFalse);
-}
-
-void AXPlatformNodeAuraLinux::OnAlertShown() {
- DCHECK(ui::IsAlert(GetData().role));
- atk_object_notify_state_change(ATK_OBJECT(GetOrCreateAtkObject()),
- ATK_STATE_SHOWING, TRUE);
-}
-
-void AXPlatformNodeAuraLinux::RunPostponedEvents() {
- if (window_activate_event_postponed_) {
- OnWindowActivated();
- window_activate_event_postponed_ = false;
- }
-}
-
-void AXPlatformNodeAuraLinux::NotifyAccessibilityEvent(
- ax::mojom::Event event_type) {
- if (!GetOrCreateAtkObject())
- return;
- AXPlatformNodeBase::NotifyAccessibilityEvent(event_type);
- switch (event_type) {
- // kMenuStart/kMenuEnd: the menu system has started / stopped.
- // kMenuPopupStart/kMenuPopupEnd: an individual menu/submenu has
- // opened/closed.
- case ax::mojom::Event::kMenuPopupStart:
- OnMenuPopupStart();
- break;
- case ax::mojom::Event::kMenuPopupEnd:
- OnMenuPopupEnd();
- break;
- case ax::mojom::Event::kActiveDescendantChanged:
- OnActiveDescendantChanged();
- break;
- case ax::mojom::Event::kCheckedStateChanged:
- OnCheckedStateChanged();
- break;
- case ax::mojom::Event::kExpandedChanged:
- case ax::mojom::Event::kStateChanged:
- OnExpandedStateChanged(GetData().HasState(ax::mojom::State::kExpanded));
- break;
- case ax::mojom::Event::kFocus:
- case ax::mojom::Event::kFocusContext:
- OnFocused();
- break;
- case ax::mojom::Event::kSelection:
- OnSelected();
- // When changing tabs also fire a name changed event.
- if (GetData().role == ax::mojom::Role::kTab)
- OnDocumentTitleChanged();
- break;
- case ax::mojom::Event::kSelectedChildrenChanged:
- OnSelectedChildrenChanged();
- break;
- case ax::mojom::Event::kTextChanged:
- OnNameChanged();
- break;
- case ax::mojom::Event::kTextSelectionChanged:
- OnTextSelectionChanged();
- break;
- case ax::mojom::Event::kValueChanged:
- OnValueChanged();
- break;
- case ax::mojom::Event::kInvalidStatusChanged:
- OnInvalidStatusChanged();
- break;
- case ax::mojom::Event::kWindowActivated:
- if (AtkUtilAuraLinux::GetInstance()->IsAtSpiReady()) {
- OnWindowActivated();
- } else {
- AtkUtilAuraLinux::GetInstance()->PostponeEventsFor(this);
- window_activate_event_postponed_ = true;
- }
- break;
- case ax::mojom::Event::kWindowDeactivated:
- if (AtkUtilAuraLinux::GetInstance()->IsAtSpiReady()) {
- OnWindowDeactivated();
- } else {
- AtkUtilAuraLinux::GetInstance()->CancelPostponedEventsFor(this);
- window_activate_event_postponed_ = false;
- }
- break;
- case ax::mojom::Event::kWindowVisibilityChanged:
- OnWindowVisibilityChanged();
- break;
- case ax::mojom::Event::kLoadComplete:
- case ax::mojom::Event::kDocumentTitleChanged:
- // Sometimes, e.g. upon navigating away from the page, the tree is
- // rebuilt rather than modified. The kDocumentTitleChanged event occurs
- // prior to the rebuild and so is added on the previous root node. When
- // the tree is rebuilt and the old node removed, the events on the old
- // node are removed and no new kDocumentTitleChanged will be emitted. To
- // ensure we still fire the event, though, we also pay attention to
- // kLoadComplete.
- OnDocumentTitleChanged();
- break;
- case ax::mojom::Event::kAlert:
- OnAlertShown();
- break;
- default:
- break;
- }
-}
-
-base::Optional<std::pair<int, int>>
-AXPlatformNodeAuraLinux::GetEmbeddedObjectIndicesForId(int id) {
- auto iterator =
- std::find(hypertext_.hyperlinks.begin(), hypertext_.hyperlinks.end(), id);
- if (iterator == hypertext_.hyperlinks.end())
- return base::nullopt;
- int hyperlink_index = std::distance(hypertext_.hyperlinks.begin(), iterator);
-
- auto offset = std::find_if(hypertext_.hyperlink_offset_to_index.begin(),
- hypertext_.hyperlink_offset_to_index.end(),
- [&](const std::pair<int32_t, int32_t>& pair) {
- return pair.second == hyperlink_index;
- });
- if (offset == hypertext_.hyperlink_offset_to_index.end())
- return base::nullopt;
-
- return std::make_pair(UTF16ToUnicodeOffsetInText(offset->first),
- UTF16ToUnicodeOffsetInText(offset->first + 1));
-}
-
-base::Optional<std::pair<int, int>>
-AXPlatformNodeAuraLinux::GetEmbeddedObjectIndices() {
- auto* parent = FromAtkObject(GetParent());
- if (!parent)
- return base::nullopt;
- return parent->GetEmbeddedObjectIndicesForId(GetUniqueId());
-}
-
-void AXPlatformNodeAuraLinux::UpdateHypertext() {
- EnsureAtkObjectIsValid();
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- AXHypertext old_hypertext = hypertext_;
- base::OffsetAdjuster::Adjustments old_adjustments = GetHypertextAdjustments();
-
- UpdateComputedHypertext();
- text_unicode_adjustments_ = base::nullopt;
- offset_to_text_attributes_.clear();
-
- if ((!GetData().HasState(ax::mojom::State::kEditable) ||
- GetData().GetRestriction() == ax::mojom::Restriction::kReadOnly) &&
- !IsInLiveRegion()) {
- return;
- }
-
- if (!EmitsAtkTextEvents())
- return;
-
- size_t shared_prefix, old_len, new_len;
- ComputeHypertextRemovedAndInserted(old_hypertext, &shared_prefix, &old_len,
- &new_len);
- if (old_len > 0) {
- base::string16 removed_substring =
- old_hypertext.hypertext.substr(shared_prefix, old_len);
-
- size_t shared_unicode_prefix = shared_prefix;
- base::OffsetAdjuster::AdjustOffset(old_adjustments, &shared_unicode_prefix);
- size_t shared_unicode_suffix = shared_prefix + old_len;
- base::OffsetAdjuster::AdjustOffset(old_adjustments, &shared_unicode_suffix);
-
- g_signal_emit_by_name(
- atk_object, "text-remove",
- shared_unicode_prefix, // position of removal
- shared_unicode_suffix - shared_prefix, // length of removal
- base::UTF16ToUTF8(removed_substring).c_str());
- }
-
- if (new_len > 0) {
- base::string16 inserted_substring =
- hypertext_.hypertext.substr(shared_prefix, new_len);
- size_t shared_unicode_prefix = UTF16ToUnicodeOffsetInText(shared_prefix);
- size_t shared_unicode_suffix =
- UTF16ToUnicodeOffsetInText(shared_prefix + new_len);
- g_signal_emit_by_name(
- atk_object, "text-insert",
- shared_unicode_prefix, // position of insertion
- shared_unicode_suffix - shared_unicode_prefix, // length of insertion
- base::UTF16ToUTF8(inserted_substring).c_str());
- }
-}
-
-const AXHypertext& AXPlatformNodeAuraLinux::GetAXHypertext() {
- return hypertext_;
-}
-
-const base::OffsetAdjuster::Adjustments&
-AXPlatformNodeAuraLinux::GetHypertextAdjustments() {
- if (text_unicode_adjustments_.has_value())
- return *text_unicode_adjustments_;
-
- text_unicode_adjustments_.emplace();
-
- base::string16 text = GetHypertext();
- int32_t text_length = text.size();
- for (int32_t i = 0; i < text_length; i++) {
- uint32_t code_point;
- size_t original_i = i;
- base::ReadUnicodeCharacter(text.c_str(), text_length + 1, &i, &code_point);
-
- if ((i - original_i + 1) != 1) {
- text_unicode_adjustments_->push_back(
- base::OffsetAdjuster::Adjustment(original_i, i - original_i + 1, 1));
- }
- }
-
- return *text_unicode_adjustments_;
-}
-
-size_t AXPlatformNodeAuraLinux::UTF16ToUnicodeOffsetInText(
- size_t utf16_offset) {
- size_t unicode_offset = utf16_offset;
- base::OffsetAdjuster::AdjustOffset(GetHypertextAdjustments(),
- &unicode_offset);
- return unicode_offset;
-}
-
-size_t AXPlatformNodeAuraLinux::UnicodeToUTF16OffsetInText(int unicode_offset) {
- if (unicode_offset == kStringLengthOffset)
- return GetHypertext().size();
-
- size_t utf16_offset = unicode_offset;
- base::OffsetAdjuster::UnadjustOffset(GetHypertextAdjustments(),
- &utf16_offset);
- return utf16_offset;
-}
-
-int AXPlatformNodeAuraLinux::GetTextOffsetAtPoint(int x,
- int y,
- AtkCoordType atk_coord_type) {
- if (!GetExtentsRelativeToAtkCoordinateType(atk_coord_type).Contains(x, y))
- return -1;
-
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return -1;
-
- int count = atk_text::GetCharacterCount(ATK_TEXT(atk_object));
- for (int i = 0; i < count; i++) {
- int out_x, out_y, out_width, out_height;
- atk_text::GetCharacterExtents(ATK_TEXT(atk_object), i, &out_x, &out_y,
- &out_width, &out_height, atk_coord_type);
- gfx::Rect rect(out_x, out_y, out_width, out_height);
- if (rect.Contains(x, y))
- return i;
- }
- return -1;
-}
-
-gfx::Vector2d AXPlatformNodeAuraLinux::GetParentOriginInScreenCoordinates()
- const {
- AtkObject* parent = GetParent();
- if (!parent)
- return gfx::Vector2d();
-
- const AXPlatformNode* parent_node =
- AXPlatformNode::FromNativeViewAccessible(parent);
- if (!parent)
- return gfx::Vector2d();
-
- return parent_node->GetDelegate()
- ->GetBoundsRect(AXCoordinateSystem::kScreenDIPs,
- AXClippingBehavior::kUnclipped)
- .OffsetFromOrigin();
-}
-
-gfx::Vector2d AXPlatformNodeAuraLinux::GetParentFrameOriginInScreenCoordinates()
- const {
- AtkObject* frame = FindAtkObjectParentFrame(atk_object_);
- if (!frame)
- return gfx::Vector2d();
-
- const AXPlatformNode* frame_node =
- AXPlatformNode::FromNativeViewAccessible(frame);
- if (!frame_node)
- return gfx::Vector2d();
-
- return frame_node->GetDelegate()
- ->GetBoundsRect(AXCoordinateSystem::kScreenDIPs,
- AXClippingBehavior::kUnclipped)
- .OffsetFromOrigin();
-}
-
-gfx::Rect AXPlatformNodeAuraLinux::GetExtentsRelativeToAtkCoordinateType(
- AtkCoordType coord_type) const {
- gfx::Rect extents = delegate_->GetBoundsRect(AXCoordinateSystem::kScreenDIPs,
- AXClippingBehavior::kUnclipped);
- switch (coord_type) {
- case ATK_XY_SCREEN:
- break;
- case ATK_XY_WINDOW: {
- gfx::Vector2d window_origin = -GetParentFrameOriginInScreenCoordinates();
- extents.Offset(window_origin);
- break;
- }
-#if defined(ATK_230)
- case ATK_XY_PARENT: {
- gfx::Vector2d parent_origin = -GetParentOriginInScreenCoordinates();
- extents.Offset(parent_origin);
- break;
- }
-#endif
- }
-
- return extents;
-}
-
-void AXPlatformNodeAuraLinux::GetExtents(gint* x,
- gint* y,
- gint* width,
- gint* height,
- AtkCoordType coord_type) {
- gfx::Rect extents = GetExtentsRelativeToAtkCoordinateType(coord_type);
- if (x)
- *x = extents.x();
- if (y)
- *y = extents.y();
- if (width)
- *width = extents.width();
- if (height)
- *height = extents.height();
-}
-
-void AXPlatformNodeAuraLinux::GetPosition(gint* x,
- gint* y,
- AtkCoordType coord_type) {
- gfx::Rect extents = GetExtentsRelativeToAtkCoordinateType(coord_type);
- if (x)
- *x = extents.x();
- if (y)
- *y = extents.y();
-}
-
-void AXPlatformNodeAuraLinux::GetSize(gint* width, gint* height) {
- gfx::Rect rect_size = gfx::ToEnclosingRect(GetData().relative_bounds.bounds);
- if (width)
- *width = rect_size.width();
- if (height)
- *height = rect_size.height();
-}
-
-gfx::NativeViewAccessible
-AXPlatformNodeAuraLinux::HitTestSync(gint x, gint y, AtkCoordType coord_type) {
- gfx::Point scroll_to(x, y);
- scroll_to = ConvertPointToScreenCoordinates(scroll_to, coord_type);
-
- AXPlatformNode* current_result = this;
- while (true) {
- gfx::NativeViewAccessible hit_child =
- current_result->GetDelegate()->HitTestSync(scroll_to.x(),
- scroll_to.y());
- if (!hit_child)
- return nullptr;
- AXPlatformNode* hit_child_node =
- AXPlatformNode::FromNativeViewAccessible(hit_child);
- if (!hit_child_node || !hit_child_node->IsDescendantOf(current_result))
- break;
-
- // If we get the same node, we're done.
- if (hit_child_node == current_result)
- break;
-
- // Continue to check recursively. That's because HitTestSync may have
- // returned the best result within a particular accessibility tree,
- // but we might need to recurse further in a tree of a different type
- // (for example, from Views to Web).
- current_result = hit_child_node;
- }
- return current_result->GetNativeViewAccessible();
-}
-
-bool AXPlatformNodeAuraLinux::GrabFocus() {
- AXActionData action_data;
- action_data.action = ax::mojom::Action::kFocus;
- return delegate_->AccessibilityPerformAction(action_data);
-}
-
-bool AXPlatformNodeAuraLinux::FocusFirstFocusableAncestorInWebContent() {
- if (!GetDelegate()->IsWebContent())
- return false;
-
- // Don't cross document boundaries in order to avoid having this operation
- // cross iframe boundaries or escape to non-document UI elements.
- if (GetAtkRole() == ATK_ROLE_DOCUMENT_WEB)
- return false;
-
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return false;
-
- if (GetData().HasState(ax::mojom::State::kFocusable) ||
- SelectionAndFocusAreTheSame()) {
- if (g_current_focused != atk_object)
- GrabFocus();
- return true;
- }
-
- auto* parent = FromAtkObject(GetParent());
- if (!parent)
- return false;
-
- // If any of the siblings of this element are focusable, focusing the parent
- // would be like moving the focus position backward, so we should fall back
- // to setting the sequential focus navigation starting point.
- for (auto child_iterator_ptr = parent->GetDelegate()->ChildrenBegin();
- *child_iterator_ptr != *parent->GetDelegate()->ChildrenEnd();
- ++(*child_iterator_ptr)) {
- auto* child = FromAtkObject(child_iterator_ptr->GetNativeViewAccessible());
- if (!child || child == this)
- continue;
-
- if (child->GetData().HasState(ax::mojom::State::kFocusable) ||
- child->SelectionAndFocusAreTheSame()) {
- return false;
- }
- }
-
- return parent->FocusFirstFocusableAncestorInWebContent();
-}
-
-bool AXPlatformNodeAuraLinux::SetSequentialFocusNavigationStartingPoint() {
- AXActionData action_data;
- action_data.action =
- ax::mojom::Action::kSetSequentialFocusNavigationStartingPoint;
- return delegate_->AccessibilityPerformAction(action_data);
-}
-
-bool AXPlatformNodeAuraLinux::
- GrabFocusOrSetSequentialFocusNavigationStartingPoint() {
- // First we try to grab focus on this node if any ancestor in the same
- // document is focusable. Otherwise we set the sequential navigation starting
- // point.
- if (!FocusFirstFocusableAncestorInWebContent())
- return SetSequentialFocusNavigationStartingPoint();
- else
- return true;
-}
-
-bool AXPlatformNodeAuraLinux::
- GrabFocusOrSetSequentialFocusNavigationStartingPointAtOffset(int offset) {
- int child_count = delegate_->GetChildCount();
- if (IsPlainTextField() || child_count == 0)
- return GrabFocusOrSetSequentialFocusNavigationStartingPoint();
-
- // When this node has children, we walk through them to figure out what child
- // node should get focus. We are essentially repeating the process used when
- // building the hypertext here.
- int current_offset = 0;
- for (int i = 0; i < child_count; ++i) {
- auto* child = FromAtkObject(delegate_->ChildAtIndex(i));
- if (!child)
- continue;
-
- if (child->IsText()) {
- current_offset += child->GetName().size();
- } else {
- // Add an offset for the embedded character.
- current_offset += 1;
- }
-
- // If the offset is larger than our size, try to work with the last child,
- // which is also the behavior of SetCaretOffset.
- if (offset <= current_offset || i == child_count - 1)
- return child->GrabFocusOrSetSequentialFocusNavigationStartingPoint();
- }
-
- NOTREACHED();
- return false;
-}
-
-bool AXPlatformNodeAuraLinux::DoDefaultAction() {
- AXActionData action_data;
- action_data.action = ax::mojom::Action::kDoDefault;
- return delegate_->AccessibilityPerformAction(action_data);
-}
-
-const gchar* AXPlatformNodeAuraLinux::GetDefaultActionName() {
- int action;
- if (!GetIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb, &action))
- return nullptr;
-
- std::string action_verb =
- ui::ToString(static_cast<ax::mojom::DefaultActionVerb>(action));
- ATK_AURALINUX_RETURN_STRING(action_verb);
-}
-
-AtkAttributeSet* AXPlatformNodeAuraLinux::GetAtkAttributes() {
- AtkAttributeSet* attribute_list = nullptr;
- ComputeAttributes(&attribute_list);
- return attribute_list;
-}
-
-AtkStateType AXPlatformNodeAuraLinux::GetAtkStateTypeForCheckableNode() {
- if (GetData().GetCheckedState() == ax::mojom::CheckedState::kMixed)
- return ATK_STATE_INDETERMINATE;
- if (IsPlatformCheckable())
- return ATK_STATE_CHECKED;
- return ATK_STATE_PRESSED;
-}
-
-// AtkDocumentHelpers
-
-const gchar* AXPlatformNodeAuraLinux::GetDocumentAttributeValue(
- const gchar* attribute) const {
- if (!g_ascii_strcasecmp(attribute, "DocType"))
- return delegate_->GetTreeData().doctype.c_str();
- else if (!g_ascii_strcasecmp(attribute, "MimeType"))
- return delegate_->GetTreeData().mimetype.c_str();
- else if (!g_ascii_strcasecmp(attribute, "Title"))
- return delegate_->GetTreeData().title.c_str();
- else if (!g_ascii_strcasecmp(attribute, "URI"))
- return delegate_->GetTreeData().url.c_str();
-
- return nullptr;
-}
-
-AtkAttributeSet* AXPlatformNodeAuraLinux::GetDocumentAttributes() const {
- AtkAttributeSet* attribute_set = nullptr;
- const gchar* doc_attributes[] = {"DocType", "MimeType", "Title", "URI"};
- const gchar* value = nullptr;
-
- for (unsigned i = 0; i < G_N_ELEMENTS(doc_attributes); i++) {
- value = GetDocumentAttributeValue(doc_attributes[i]);
- if (value) {
- attribute_set = PrependAtkAttributeToAtkAttributeSet(
- doc_attributes[i], value, attribute_set);
- }
- }
-
- return attribute_set;
-}
-
-//
-// AtkHyperlink helpers
-//
-
-AtkHyperlink* AXPlatformNodeAuraLinux::GetAtkHyperlink() {
- if (atk_hyperlink_)
- return atk_hyperlink_;
-
- atk_hyperlink_ =
- ATK_HYPERLINK(g_object_new(AX_PLATFORM_ATK_HYPERLINK_TYPE, 0));
- ax_platform_atk_hyperlink_set_object(
- AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink_), this);
- return atk_hyperlink_;
-}
-
-//
-// Misc helpers
-//
-
-void AXPlatformNodeAuraLinux::GetFloatAttributeInGValue(
- ax::mojom::FloatAttribute attr,
- GValue* value) {
- float float_val;
- if (GetFloatAttribute(attr, &float_val)) {
- memset(value, 0, sizeof(*value));
- g_value_init(value, G_TYPE_FLOAT);
- g_value_set_float(value, float_val);
- }
-}
-
-void AXPlatformNodeAuraLinux::AddAttributeToList(const char* name,
- const char* value,
- AtkAttributeSet** attributes) {
- *attributes = PrependAtkAttributeToAtkAttributeSet(name, value, *attributes);
-}
-
-void AXPlatformNodeAuraLinux::SetDocumentParent(
- AtkObject* new_document_parent) {
- DCHECK(GetAtkRole() == ATK_ROLE_FRAME);
- SetWeakGPtrToAtkObject(&document_parent_, new_document_parent);
-}
-
-bool AXPlatformNodeAuraLinux::IsNameExposed() {
- const AXNodeData& data = GetData();
- switch (data.role) {
- case ax::mojom::Role::kListMarker:
- return !GetChildCount();
- default:
- return true;
- }
-}
-
-int AXPlatformNodeAuraLinux::GetCaretOffset() {
- if (!HasCaret()) {
- base::Optional<FindInPageResultInfo> result =
- GetSelectionOffsetsFromFindInPage();
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return -1;
- if (result.has_value() && result->node == atk_object)
- return UTF16ToUnicodeOffsetInText(result->end_offset);
- return -1;
- }
-
- std::pair<int, int> selection = GetSelectionOffsetsForAtk();
- return UTF16ToUnicodeOffsetInText(selection.second);
-}
-
-bool AXPlatformNodeAuraLinux::SetCaretOffset(int offset) {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return false;
-
- int character_count = atk_text_get_character_count(ATK_TEXT(atk_object));
- if (offset < 0 || offset > character_count)
- offset = character_count;
-
- // Even if we don't change anything, we still want to act like we
- // were successful.
- if (offset == GetCaretOffset() && !HasSelection())
- return true;
-
- offset = UnicodeToUTF16OffsetInText(offset);
- if (!SetHypertextSelection(offset, offset))
- return false;
-
- return true;
-}
-
-bool AXPlatformNodeAuraLinux::SetTextSelectionForAtkText(int start_offset,
- int end_offset) {
- start_offset = UnicodeToUTF16OffsetInText(start_offset);
- end_offset = UnicodeToUTF16OffsetInText(end_offset);
-
- base::string16 text = GetHypertext();
- if (start_offset < 0 || start_offset > int{text.length()})
- return false;
- if (end_offset < 0 || end_offset > int{text.length()})
- return false;
-
- // We must put these in the correct order so that we can do
- // a comparison with the existing start and end below.
- if (end_offset < start_offset)
- std::swap(start_offset, end_offset);
-
- // Even if we don't change anything, we still want to act like we
- // were successful.
- std::pair<int, int> old_offsets = GetSelectionOffsetsForAtk();
- if (old_offsets.first == start_offset && old_offsets.second == end_offset)
- return true;
-
- if (!SetHypertextSelection(start_offset, end_offset))
- return false;
-
- return true;
-}
-
-bool AXPlatformNodeAuraLinux::HasSelection() {
- std::pair<int, int> selection = GetSelectionOffsetsForAtk();
- return selection.first >= 0 && selection.second >= 0 &&
- selection.first != selection.second;
-}
-
-void AXPlatformNodeAuraLinux::GetSelectionExtents(int* start_offset,
- int* end_offset) {
- if (start_offset)
- *start_offset = 0;
- if (end_offset)
- *end_offset = 0;
-
- std::pair<int, int> selection = GetSelectionOffsetsForAtk();
- if (selection.first < 0 || selection.second < 0 ||
- selection.first == selection.second)
- return;
-
- // We should ignore the direction of the selection when exposing start and
- // end offsets. According to the ATK documentation the end offset is always
- // the offset immediately past the end of the selection. This wouldn't make
- // sense if end < start.
- if (selection.second < selection.first)
- std::swap(selection.first, selection.second);
-
- selection.first = UTF16ToUnicodeOffsetInText(selection.first);
- selection.second = UTF16ToUnicodeOffsetInText(selection.second);
-
- if (start_offset)
- *start_offset = selection.first;
- if (end_offset)
- *end_offset = selection.second;
-}
-
-// Since this method doesn't return a static gchar*, we expect the caller of
-// atk_text_get_selection to free the return value.
-gchar* AXPlatformNodeAuraLinux::GetSelectionWithText(int* start_offset,
- int* end_offset) {
- int selection_start, selection_end;
- GetSelectionExtents(&selection_start, &selection_end);
-
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return nullptr;
-
- if (selection_start < 0 || selection_end < 0 ||
- selection_start == selection_end) {
- base::Optional<FindInPageResultInfo> find_in_page_result =
- GetSelectionOffsetsFromFindInPage();
- if (!find_in_page_result.has_value() ||
- find_in_page_result->node != atk_object) {
- *start_offset = 0;
- *end_offset = 0;
- return nullptr;
- }
-
- selection_start = find_in_page_result->start_offset;
- selection_end = find_in_page_result->end_offset;
- }
-
- selection_start = UTF16ToUnicodeOffsetInText(selection_start);
- selection_end = UTF16ToUnicodeOffsetInText(selection_end);
- if (selection_start < 0 || selection_end < 0 ||
- selection_start == selection_end) {
- return nullptr;
- }
-
- if (start_offset)
- *start_offset = selection_start;
- if (end_offset)
- *end_offset = selection_end;
- return atk_text::GetText(ATK_TEXT(atk_object), selection_start,
- selection_end);
-}
-
-bool AXPlatformNodeAuraLinux::IsInLiveRegion() {
- return GetData().HasStringAttribute(
- ax::mojom::StringAttribute::kContainerLiveStatus);
-}
-
-#if defined(ATK_230)
-void AXPlatformNodeAuraLinux::ScrollToPoint(AtkCoordType atk_coord_type,
- int x,
- int y) {
- gfx::Point scroll_to(x, y);
- scroll_to = ConvertPointToScreenCoordinates(scroll_to, atk_coord_type);
-
- AXActionData action_data;
- action_data.target_node_id = GetData().id;
- action_data.action = ax::mojom::Action::kScrollToPoint;
- action_data.target_point = scroll_to;
- GetDelegate()->AccessibilityPerformAction(action_data);
-}
-
-void AXPlatformNodeAuraLinux::ScrollNodeRectIntoView(
- gfx::Rect rect,
- AtkScrollType atk_scroll_type) {
- AXActionData action_data;
- action_data.target_node_id = GetData().id;
- action_data.action = ax::mojom::Action::kScrollToMakeVisible;
- action_data.target_rect = rect;
-
- action_data.scroll_behavior = ax::mojom::ScrollBehavior::kScrollIfVisible;
- action_data.horizontal_scroll_alignment = ax::mojom::ScrollAlignment::kNone;
- action_data.vertical_scroll_alignment = ax::mojom::ScrollAlignment::kNone;
-
- switch (atk_scroll_type) {
- case ATK_SCROLL_TOP_LEFT:
- action_data.vertical_scroll_alignment =
- ax::mojom::ScrollAlignment::kScrollAlignmentTop;
- action_data.horizontal_scroll_alignment =
- ax::mojom::ScrollAlignment::kScrollAlignmentLeft;
- break;
- case ATK_SCROLL_BOTTOM_RIGHT:
- action_data.horizontal_scroll_alignment =
- ax::mojom::ScrollAlignment::kScrollAlignmentRight;
- action_data.vertical_scroll_alignment =
- ax::mojom::ScrollAlignment::kScrollAlignmentBottom;
- break;
- case ATK_SCROLL_TOP_EDGE:
- action_data.vertical_scroll_alignment =
- ax::mojom::ScrollAlignment::kScrollAlignmentTop;
- break;
- case ATK_SCROLL_BOTTOM_EDGE:
- action_data.vertical_scroll_alignment =
- ax::mojom::ScrollAlignment::kScrollAlignmentBottom;
- break;
- case ATK_SCROLL_LEFT_EDGE:
- action_data.horizontal_scroll_alignment =
- ax::mojom::ScrollAlignment::kScrollAlignmentLeft;
- break;
- case ATK_SCROLL_RIGHT_EDGE:
- action_data.horizontal_scroll_alignment =
- ax::mojom::ScrollAlignment::kScrollAlignmentRight;
- break;
- case ATK_SCROLL_ANYWHERE:
- action_data.horizontal_scroll_alignment =
- ax::mojom::ScrollAlignment::kScrollAlignmentClosestEdge;
- action_data.vertical_scroll_alignment =
- ax::mojom::ScrollAlignment::kScrollAlignmentClosestEdge;
- break;
- }
-
- GetDelegate()->AccessibilityPerformAction(action_data);
-}
-
-void AXPlatformNodeAuraLinux::ScrollNodeIntoView(
- AtkScrollType atk_scroll_type) {
- gfx::Rect rect = GetDelegate()->GetBoundsRect(AXCoordinateSystem::kScreenDIPs,
- AXClippingBehavior::kUnclipped);
- rect -= rect.OffsetFromOrigin();
- ScrollNodeRectIntoView(rect, atk_scroll_type);
-}
-#endif // defined(ATK_230)
-
-#if defined(ATK_232)
-base::Optional<gfx::Rect>
-AXPlatformNodeAuraLinux::GetUnclippedHypertextRangeBoundsRect(int start_offset,
- int end_offset) {
- start_offset = UnicodeToUTF16OffsetInText(start_offset);
- end_offset = UnicodeToUTF16OffsetInText(end_offset);
-
- base::string16 text = GetHypertext();
- if (start_offset < 0 || start_offset > int{text.length()})
- return base::nullopt;
- if (end_offset < 0 || end_offset > int{text.length()})
- return base::nullopt;
-
- if (end_offset < start_offset)
- std::swap(start_offset, end_offset);
-
- return GetDelegate()->GetHypertextRangeBoundsRect(
- UnicodeToUTF16OffsetInText(start_offset),
- UnicodeToUTF16OffsetInText(end_offset), AXCoordinateSystem::kScreenDIPs,
- AXClippingBehavior::kUnclipped);
-}
-
-bool AXPlatformNodeAuraLinux::ScrollSubstringIntoView(
- AtkScrollType atk_scroll_type,
- int start_offset,
- int end_offset) {
- base::Optional<gfx::Rect> optional_rect =
- GetUnclippedHypertextRangeBoundsRect(start_offset, end_offset);
- if (!optional_rect.has_value())
- return false;
-
- gfx::Rect rect = *optional_rect;
- gfx::Rect node_rect = GetDelegate()->GetBoundsRect(
- AXCoordinateSystem::kScreenDIPs, AXClippingBehavior::kUnclipped);
- rect -= node_rect.OffsetFromOrigin();
- ScrollNodeRectIntoView(rect, atk_scroll_type);
-
- return true;
-}
-
-bool AXPlatformNodeAuraLinux::ScrollSubstringToPoint(
- int start_offset,
- int end_offset,
- AtkCoordType atk_coord_type,
- int x,
- int y) {
- base::Optional<gfx::Rect> optional_rect =
- GetUnclippedHypertextRangeBoundsRect(start_offset, end_offset);
- if (!optional_rect.has_value())
- return false;
-
- gfx::Rect rect = *optional_rect;
- gfx::Rect node_rect = GetDelegate()->GetBoundsRect(
- AXCoordinateSystem::kScreenDIPs, AXClippingBehavior::kUnclipped);
- ScrollToPoint(atk_coord_type, x - (rect.x() - node_rect.x()),
- y - (rect.y() - node_rect.y()));
-
- return true;
-}
-#endif // defined(ATK_232)
-
-void AXPlatformNodeAuraLinux::ComputeStylesIfNeeded() {
- if (!offset_to_text_attributes_.empty())
- return;
-
- default_text_attributes_ = ComputeTextAttributes();
- TextAttributeMap attributes_map =
- GetDelegate()->ComputeTextAttributeMap(default_text_attributes_);
- offset_to_text_attributes_.swap(attributes_map);
-}
-
-int AXPlatformNodeAuraLinux::FindStartOfStyle(
- int start_offset,
- ax::mojom::MoveDirection direction) {
- int text_length = GetHypertext().length();
- DCHECK_GE(start_offset, 0);
- DCHECK_LE(start_offset, text_length);
- DCHECK(!offset_to_text_attributes_.empty());
-
- switch (direction) {
- case ax::mojom::MoveDirection::kBackward: {
- auto iterator = offset_to_text_attributes_.upper_bound(start_offset);
- --iterator;
- return iterator->first;
- }
- case ax::mojom::MoveDirection::kForward: {
- const auto iterator =
- offset_to_text_attributes_.upper_bound(start_offset);
- if (iterator == offset_to_text_attributes_.end())
- return text_length;
- return iterator->first;
- }
- }
-
- NOTREACHED();
- return start_offset;
-}
-
-const TextAttributeList& AXPlatformNodeAuraLinux::GetTextAttributes(
- int offset,
- int* start_offset,
- int* end_offset) {
- ComputeStylesIfNeeded();
- DCHECK(!offset_to_text_attributes_.empty());
-
- int utf16_offset = UnicodeToUTF16OffsetInText(offset);
- int style_start =
- FindStartOfStyle(utf16_offset, ax::mojom::MoveDirection::kBackward);
- int style_end =
- FindStartOfStyle(utf16_offset, ax::mojom::MoveDirection::kForward);
-
- auto iterator = offset_to_text_attributes_.find(style_start);
- DCHECK(iterator != offset_to_text_attributes_.end());
-
- SetIntPointerValueIfNotNull(start_offset,
- UTF16ToUnicodeOffsetInText(style_start));
- SetIntPointerValueIfNotNull(end_offset,
- UTF16ToUnicodeOffsetInText(style_end));
-
- if (iterator == offset_to_text_attributes_.end())
- return default_text_attributes_;
-
- return iterator->second;
-}
-
-const TextAttributeList& AXPlatformNodeAuraLinux::GetDefaultTextAttributes() {
- ComputeStylesIfNeeded();
- return default_text_attributes_;
-}
-
-void AXPlatformNodeAuraLinux::TerminateFindInPage() {
- ForgetCurrentFindInPageResult();
-}
-
-void AXPlatformNodeAuraLinux::ActivateFindInPageResult(int start_offset,
- int end_offset) {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- DCHECK(ATK_IS_TEXT(atk_object));
-
- if (!EmitsAtkTextEvents()) {
- ActivateFindInPageInParent(start_offset, end_offset);
- return;
- }
-
- AtkObject* parent_doc = FindAtkObjectToplevelParentDocument(atk_object);
- if (!parent_doc)
- return;
-
- std::map<AtkObject*, FindInPageResultInfo>& active_results =
- GetActiveFindInPageResults();
- auto iterator = active_results.find(parent_doc);
- FindInPageResultInfo new_info = {atk_object, start_offset, end_offset};
- if (iterator != active_results.end() && iterator->second == new_info)
- return;
-
- active_results[parent_doc] = new_info;
- g_signal_emit_by_name(atk_object, "text-selection-changed");
- g_signal_emit_by_name(atk_object, "text-caret-moved",
- UTF16ToUnicodeOffsetInText(end_offset));
-}
-
-base::Optional<std::pair<int, int>>
-AXPlatformNodeAuraLinux::GetHypertextExtentsOfChild(
- AXPlatformNodeAuraLinux* child_to_find) {
- int current_offset = 0;
- for (auto child_iterator_ptr = GetDelegate()->ChildrenBegin();
- *child_iterator_ptr != *GetDelegate()->ChildrenEnd();
- ++(*child_iterator_ptr)) {
- auto* child = FromAtkObject(child_iterator_ptr->GetNativeViewAccessible());
- if (!child)
- continue;
-
- // If this object is a text only object, it is included directly into this
- // node's hypertext, otherwise it is represented as an embedded object
- // character.
- int size = child->IsText() ? child->GetName().size() : 1;
- if (child == child_to_find)
- return std::make_pair(current_offset, current_offset + size);
- current_offset += size;
- }
-
- return base::nullopt;
-}
-
-void AXPlatformNodeAuraLinux::ActivateFindInPageInParent(int start_offset,
- int end_offset) {
- auto* parent = FromAtkObject(GetParent());
- if (!parent)
- return;
-
- base::Optional<std::pair<int, int>> extents_in_parent =
- parent->GetHypertextExtentsOfChild(this);
- if (!extents_in_parent.has_value())
- return;
-
- DCHECK(IsText());
- parent->ActivateFindInPageResult(extents_in_parent->first + start_offset,
- extents_in_parent->first + end_offset);
-}
-
-void AXPlatformNodeAuraLinux::ForgetCurrentFindInPageResult() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return;
-
- AtkObject* parent_doc = FindAtkObjectToplevelParentDocument(atk_object);
- if (parent_doc)
- GetActiveFindInPageResults().erase(parent_doc);
-}
-
-base::Optional<FindInPageResultInfo>
-AXPlatformNodeAuraLinux::GetSelectionOffsetsFromFindInPage() {
- AtkObject* atk_object = GetOrCreateAtkObject();
- if (!atk_object)
- return base::nullopt;
-
- AtkObject* parent_doc = FindAtkObjectToplevelParentDocument(atk_object);
- if (!parent_doc)
- return base::nullopt;
-
- std::map<AtkObject*, FindInPageResultInfo>& active_results =
- GetActiveFindInPageResults();
- auto iterator = active_results.find(parent_doc);
- if (iterator == active_results.end())
- return base::nullopt;
-
- return iterator->second;
-}
-
-gfx::Point AXPlatformNodeAuraLinux::ConvertPointToScreenCoordinates(
- const gfx::Point& point,
- AtkCoordType atk_coord_type) {
- switch (atk_coord_type) {
- case ATK_XY_WINDOW:
- return point + GetParentFrameOriginInScreenCoordinates();
-#if defined(ATK_230)
- case ATK_XY_PARENT:
- return point + GetParentOriginInScreenCoordinates();
-#endif
- case ATK_XY_SCREEN:
- default:
- return point;
- }
-}
-
-std::pair<int, int> AXPlatformNodeAuraLinux::GetSelectionOffsetsForAtk() {
- // In web content we always want to look at the selection from the tree
- // instead of the selection that might be set via node attributes. This is
- // because the tree selection is the absolute truth about what is visually
- // selected, whereas node attributes might contain selection extents that are
- // no longer part of the visual selection.
- std::pair<int, int> selection;
- if (GetDelegate()->IsWebContent()) {
- AXTree::Selection unignored_selection =
- GetDelegate()->GetUnignoredSelection();
- GetSelectionOffsetsFromTree(&unignored_selection, &selection.first,
- &selection.second);
- } else {
- GetSelectionOffsets(&selection.first, &selection.second);
- }
- return selection;
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_auralinux.h b/third_party/accessibility/ax/platform/ax_platform_node_auralinux.h
deleted file mode 100644
index 60aca64..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_auralinux.h
+++ /dev/null
@@ -1,441 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_AURALINUX_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_AURALINUX_H_
-
-#include <atk/atk.h>
-
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/optional.h"
-#include "base/strings/utf_offset_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_position.h"
-#include "ui/accessibility/ax_range.h"
-#include "ui/accessibility/platform/ax_platform_node_base.h"
-
-// This deleter is used in order to ensure that we properly always free memory
-// used by AtkAttributeSet.
-struct AtkAttributeSetDeleter {
- void operator()(AtkAttributeSet* attributes) {
- atk_attribute_set_free(attributes);
- }
-};
-
-using AtkAttributes = std::unique_ptr<AtkAttributeSet, AtkAttributeSetDeleter>;
-
-// Some ATK interfaces require returning a (const gchar*), use
-// this macro to make it safe to return a pointer to a temporary
-// string.
-#define ATK_AURALINUX_RETURN_STRING(str_expr) \
- { \
- static std::string result; \
- result = (str_expr); \
- return result.c_str(); \
- }
-
-namespace ui {
-
-struct FindInPageResultInfo {
- AtkObject* node;
- int start_offset;
- int end_offset;
-
- bool operator==(const FindInPageResultInfo& other) const {
- return (node == other.node) && (start_offset == other.start_offset) &&
- (end_offset == other.end_offset);
- }
-};
-
-// AtkTableCell was introduced in ATK 2.12. Ubuntu Trusty has ATK 2.10.
-// Compile-time checks are in place for ATK versions that are older than 2.12.
-// However, we also need runtime checks in case the version we are building
-// against is newer than the runtime version. To prevent a runtime error, we
-// check that we have a version of ATK that supports AtkTableCell. If we do,
-// we dynamically load the symbol; if we don't, the interface is absent from
-// the accessible object and its methods will not be exposed or callable.
-// The definitions below ensure we have no missing symbols. Note that in
-// environments where we have ATK > 2.12, the definitions of AtkTableCell and
-// AtkTableCellIface below are overridden by the runtime version.
-// TODO(accessibility) Remove AtkTableCellInterface when 2.12 is the minimum
-// supported version.
-struct AX_EXPORT AtkTableCellInterface {
- typedef struct _AtkTableCell AtkTableCell;
- static GType GetType();
- static GPtrArray* GetColumnHeaderCells(AtkTableCell* cell);
- static GPtrArray* GetRowHeaderCells(AtkTableCell* cell);
- static bool GetRowColumnSpan(AtkTableCell* cell,
- gint* row,
- gint* column,
- gint* row_span,
- gint* col_span);
- static bool Exists();
-};
-
-// This class with an enum is used to generate a bitmask which tracks the ATK
-// interfaces that an AXPlatformNodeAuraLinux's ATKObject implements.
-class ImplementedAtkInterfaces {
- public:
- enum class Value {
- kDefault = 1 << 1,
- kDocument = 1 << 1,
- kHyperlink = 1 << 2,
- kHypertext = 1 << 3,
- kImage = 1 << 4,
- kSelection = 1 << 5,
- kTableCell = 1 << 6,
- kTable = 1 << 7,
- kText = 1 << 8,
- kValue = 1 << 9,
- kWindow = 1 << 10,
- };
-
- bool Implements(Value interface) const {
- return value_ & static_cast<int>(interface);
- }
-
- void Add(Value other) { value_ |= static_cast<int>(other); }
-
- bool operator!=(const ImplementedAtkInterfaces& other) {
- return value_ != other.value_;
- }
-
- int value() const { return value_; }
-
- private:
- int value_ = static_cast<int>(Value::kDefault);
-};
-
-// Implements accessibility on Aura Linux using ATK.
-class AX_EXPORT AXPlatformNodeAuraLinux : public AXPlatformNodeBase {
- public:
- AXPlatformNodeAuraLinux();
- ~AXPlatformNodeAuraLinux() override;
-
- static AXPlatformNodeAuraLinux* FromAtkObject(const AtkObject*);
-
- // Set or get the root-level Application object that's the parent of all
- // top-level windows.
- static void SetApplication(AXPlatformNode* application);
- static AXPlatformNode* application();
-
- static void EnsureGTypeInit();
-
- // Do asynchronous static initialization.
- static void StaticInitialize();
-
- // Enables AXMode calling AXPlatformNode::NotifyAddAXModeFlags. It's used
- // when ATK APIs are called.
- static void EnableAXMode();
-
- // EnsureAtkObjectIsValid will destroy and recreate |atk_object_| if the
- // interface mask is different. This partially relies on looking at the tree's
- // structure. This must not be called when the tree is unstable e.g. in the
- // middle of being unserialized.
- void EnsureAtkObjectIsValid();
- void Destroy() override;
-
- AtkRole GetAtkRole() const;
- void GetAtkState(AtkStateSet* state_set);
- AtkRelationSet* GetAtkRelations();
- void GetExtents(gint* x,
- gint* y,
- gint* width,
- gint* height,
- AtkCoordType coord_type);
- void GetPosition(gint* x, gint* y, AtkCoordType coord_type);
- void GetSize(gint* width, gint* height);
- gfx::NativeViewAccessible HitTestSync(gint x,
- gint y,
- AtkCoordType coord_type);
- bool GrabFocus();
- bool FocusFirstFocusableAncestorInWebContent();
- bool GrabFocusOrSetSequentialFocusNavigationStartingPointAtOffset(int offset);
- bool GrabFocusOrSetSequentialFocusNavigationStartingPoint();
- bool SetSequentialFocusNavigationStartingPoint();
- bool DoDefaultAction();
- const gchar* GetDefaultActionName();
- AtkAttributeSet* GetAtkAttributes();
-
- gfx::Vector2d GetParentOriginInScreenCoordinates() const;
- gfx::Vector2d GetParentFrameOriginInScreenCoordinates() const;
- gfx::Rect GetExtentsRelativeToAtkCoordinateType(
- AtkCoordType coord_type) const;
-
- // AtkDocument helpers
- const gchar* GetDocumentAttributeValue(const gchar* attribute) const;
- AtkAttributeSet* GetDocumentAttributes() const;
-
- // AtkHyperlink helpers
- AtkHyperlink* GetAtkHyperlink();
-
-#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 30, 0)
- void ScrollToPoint(AtkCoordType atk_coord_type, int x, int y);
- void ScrollNodeRectIntoView(gfx::Rect rect, AtkScrollType atk_scroll_type);
- void ScrollNodeIntoView(AtkScrollType atk_scroll_type);
-#endif // defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 30, 0)
-
-#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 32, 0)
- base::Optional<gfx::Rect> GetUnclippedHypertextRangeBoundsRect(
- int start_offset,
- int end_offset);
- bool ScrollSubstringIntoView(AtkScrollType atk_scroll_type,
- int start_offset,
- int end_offset);
- bool ScrollSubstringToPoint(int start_offset,
- int end_offset,
- AtkCoordType atk_coord_type,
- int x,
- int y);
-#endif // defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 32, 0)
-
- // Misc helpers
- void GetFloatAttributeInGValue(ax::mojom::FloatAttribute attr, GValue* value);
-
- // Event helpers
- void OnActiveDescendantChanged();
- void OnCheckedStateChanged();
- void OnEnabledChanged();
- void OnExpandedStateChanged(bool is_expanded);
- void OnFocused();
- void OnWindowActivated();
- void OnWindowDeactivated();
- void OnMenuPopupStart();
- void OnMenuPopupEnd();
- void OnAllMenusEnded();
- void OnSelected();
- void OnSelectedChildrenChanged();
- void OnTextAttributesChanged();
- void OnTextSelectionChanged();
- void OnValueChanged();
- void OnNameChanged();
- void OnDescriptionChanged();
- void OnSortDirectionChanged();
- void OnInvalidStatusChanged();
- void OnDocumentTitleChanged();
- void OnSubtreeCreated();
- void OnSubtreeWillBeDeleted();
- void OnParentChanged();
- void OnWindowVisibilityChanged();
- void OnScrolledToAnchor();
- void OnAlertShown();
- void RunPostponedEvents();
-
- void ResendFocusSignalsForCurrentlyFocusedNode();
- bool SupportsSelectionWithAtkSelection();
- bool SelectionAndFocusAreTheSame();
- void SetActiveViewsDialog();
-
- // AXPlatformNode overrides.
- // This has a side effect of creating the AtkObject if one does not already
- // exist.
- gfx::NativeViewAccessible GetNativeViewAccessible() override;
- void NotifyAccessibilityEvent(ax::mojom::Event event_type) override;
-
- // AXPlatformNodeBase overrides.
- void Init(AXPlatformNodeDelegate* delegate) override;
- bool IsPlatformCheckable() const override;
- base::Optional<int> GetIndexInParent() override;
-
- bool IsNameExposed();
-
- void UpdateHypertext();
- const AXHypertext& GetAXHypertext();
- const base::OffsetAdjuster::Adjustments& GetHypertextAdjustments();
- size_t UTF16ToUnicodeOffsetInText(size_t utf16_offset);
- size_t UnicodeToUTF16OffsetInText(int unicode_offset);
- int GetTextOffsetAtPoint(int x, int y, AtkCoordType atk_coord_type);
-
- // Called on a toplevel frame to set the document parent, which is the parent
- // of the toplevel document. This is used to properly express the ATK embeds
- // relationship between a toplevel frame and its embedded document.
- void SetDocumentParent(AtkObject* new_document_parent);
-
- int GetCaretOffset();
- bool SetCaretOffset(int offset);
- bool SetTextSelectionForAtkText(int start_offset, int end_offset);
- bool HasSelection();
-
- void GetSelectionExtents(int* start_offset, int* end_offset);
- gchar* GetSelectionWithText(int* start_offset, int* end_offset);
-
- // Return the text attributes for this node given an offset. The start
- // and end attributes will be assigned to the start_offset and end_offset
- // pointers if they are non-null. The return value AtkAttributeSet should
- // be freed with atk_attribute_set_free.
- const TextAttributeList& GetTextAttributes(int offset,
- int* start_offset,
- int* end_offset);
-
- // Return the default text attributes for this node. The default text
- // attributes are the ones that apply to the entire node. Attributes found at
- // a given offset can be thought of as overriding the default attribute.
- // The return value AtkAttributeSet should be freed with
- // atk_attribute_set_free.
- const TextAttributeList& GetDefaultTextAttributes();
-
- void ActivateFindInPageResult(int start_offset, int end_offset);
- void TerminateFindInPage();
-
- // If there is a find in page result for the toplevel document of this node,
- // return it, otherwise return base::nullopt;
- base::Optional<FindInPageResultInfo> GetSelectionOffsetsFromFindInPage();
-
- std::pair<int, int> GetSelectionOffsetsForAtk();
-
- // Get the embedded object ("hyperlink") indices for this object in the
- // parent. If this object doesn't have a parent or isn't embedded, return
- // nullopt.
- base::Optional<std::pair<int, int>> GetEmbeddedObjectIndices();
-
- std::string accessible_name_;
-
- protected:
- // Offsets for the AtkText API are calculated in UTF-16 code point offsets,
- // but the ATK APIs want all offsets to be in "characters," which we
- // understand to be Unicode character offsets. We keep a lazily generated set
- // of Adjustments to convert between UTF-16 and Unicode character offsets.
- base::Optional<base::OffsetAdjuster::Adjustments> text_unicode_adjustments_ =
- base::nullopt;
-
- void AddAttributeToList(const char* name,
- const char* value,
- PlatformAttributeList* attributes) override;
-
- private:
- using AXPositionInstance = AXNodePosition::AXPositionInstance;
- using AXPositionInstanceType = typename AXPositionInstance::element_type;
- using AXNodeRange = AXRange<AXPositionInstanceType>;
-
- // This is static to ensure that we aren't trying to access the rest of the
- // accessibility tree during node initialization.
- static ImplementedAtkInterfaces GetGTypeInterfaceMask(const AXNodeData& data);
-
- GType GetAccessibilityGType();
- AtkObject* CreateAtkObject();
- // Get or Create AtkObject. Note that it could return nullptr except
- // ax::mojom::Role::kApplication when the mode is not enabled.
- gfx::NativeViewAccessible GetOrCreateAtkObject();
- void DestroyAtkObjects();
- void AddRelationToSet(AtkRelationSet*,
- AtkRelationType,
- AXPlatformNode* target);
- bool IsInLiveRegion();
- base::Optional<std::pair<int, int>> GetEmbeddedObjectIndicesForId(int id);
-
- void ComputeStylesIfNeeded();
- int FindStartOfStyle(int start_offset, ax::mojom::MoveDirection direction);
-
- // Reset any find in page operations for the toplevel document of this node.
- void ForgetCurrentFindInPageResult();
-
- // Activate a find in page result for the toplevel document of this node.
- void ActivateFindInPageInParent(int start_offset, int end_offset);
-
- // If this node is the toplevel document node, find its parent and set it on
- // the toplevel frame which contains the node.
- void SetDocumentParentOnFrameIfNecessary();
-
- // Find the child which is a document containing the primary web content.
- AtkObject* FindPrimaryWebContentDocument();
-
- // Returns true if it is a web content for the relations.
- bool IsWebDocumentForRelations();
-
- // If a selection that intersects this node get the full selection
- // including start and end node ids.
- void GetFullSelection(int32_t* anchor_node_id,
- int* anchor_offset,
- int32_t* focus_node_id,
- int* focus_offset);
-
- // Returns true if this node's AtkObject is suitable for emitting AtkText
- // signals. ATs don't expect static text objects to emit AtkText signals.
- bool EmitsAtkTextEvents() const;
-
- // Find the first ancestor which is an editable root or a document. This node
- // will be one which contains a single selection.
- AXPlatformNodeAuraLinux& FindEditableRootOrDocument();
-
- // Find the first common ancestor between this node and a given node.
- AXPlatformNodeAuraLinux* FindCommonAncestor(AXPlatformNodeAuraLinux* other);
-
- // Update the selection information stored in this node. This should be
- // called on the editable root, the root node of the accessibility tree, or
- // the document (ie the node returned by FindEditableRootOrDocument()).
- void UpdateSelectionInformation(int32_t anchor_node_id,
- int anchor_offset,
- int32_t focus_node_id,
- int focus_offset);
-
- // Emit a GObject signal indicating a selection change.
- void EmitSelectionChangedSignal(bool had_selection);
-
- // Emit a GObject signal indicating that the caret has moved.
- void EmitCaretChangedSignal();
-
- bool HadNonZeroWidthSelection() const { return had_nonzero_width_selection; }
- std::pair<int32_t, int> GetCurrentCaret() const { return current_caret_; }
-
- // If the given argument can be found as a child of this node, return its
- // hypertext extents, otherwise return base::nullopt;
- base::Optional<std::pair<int, int>> GetHypertextExtentsOfChild(
- AXPlatformNodeAuraLinux* child);
-
- // The AtkStateType for a checkable node can vary depending on the role.
- AtkStateType GetAtkStateTypeForCheckableNode();
-
- gfx::Point ConvertPointToScreenCoordinates(const gfx::Point& point,
- AtkCoordType atk_coord_type);
-
- // Keep information of latest ImplementedAtkInterfaces mask to rebuild the
- // ATK object accordingly when the platform node changes.
- ImplementedAtkInterfaces interface_mask_;
-
- // We own a reference to these ref-counted objects.
- AtkObject* atk_object_ = nullptr;
- AtkHyperlink* atk_hyperlink_ = nullptr;
-
- // A weak pointers which help us track the ATK embeds relation.
- AtkObject* document_parent_ = nullptr;
-
- // Whether or not this node (if it is a frame or a window) was
- // minimized the last time it's visibility changed.
- bool was_minimized_ = false;
-
- // Information about the selection meant to be stored on the return value of
- // FindEditableRootOrDocument().
- //
- // Whether or not we previously had a selection where the anchor and focus
- // were not equal. This is what ATK consider a "selection."
- bool had_nonzero_width_selection = false;
-
- // Information about the current caret location (a node id and an offset).
- // This is used to track when the caret actually moves during a selection
- // change.
- std::pair<int32_t, int> current_caret_ = {-1, -1};
-
- // A map which converts between an offset in the node's hypertext and the
- // ATK text attributes at that offset.
- TextAttributeMap offset_to_text_attributes_;
-
- // The default ATK text attributes for this node.
- TextAttributeList default_text_attributes_;
-
- bool window_activate_event_postponed_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(AXPlatformNodeAuraLinux);
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_AURALINUX_H_
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_auralinux_unittest.cc b/third_party/accessibility/ax/platform/ax_platform_node_auralinux_unittest.cc
deleted file mode 100644
index 0840dde..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_auralinux_unittest.cc
+++ /dev/null
@@ -1,2701 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <atk/atk.h>
-#include <dlfcn.h>
-#include <utility>
-#include <vector>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/platform/atk_util_auralinux.h"
-#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
-#include "ui/accessibility/platform/ax_platform_node_unittest.h"
-#include "ui/accessibility/platform/test_ax_node_wrapper.h"
-
-namespace ui {
-
-class AXPlatformNodeAuraLinuxTest : public AXPlatformNodeTest {
- public:
- AXPlatformNodeAuraLinuxTest() = default;
- ~AXPlatformNodeAuraLinuxTest() override = default;
- AXPlatformNodeAuraLinuxTest(const AXPlatformNodeAuraLinuxTest&) = delete;
- AXPlatformNodeAuraLinuxTest& operator=(const AXPlatformNodeAuraLinuxTest&) =
- delete;
-
- void SetUp() override {
- AXPlatformNode::NotifyAddAXModeFlags(kAXModeComplete);
- }
-
- protected:
- AXPlatformNodeAuraLinux* GetPlatformNode(AXNode* node) {
- TestAXNodeWrapper* wrapper =
- TestAXNodeWrapper::GetOrCreate(GetTree(), node);
- if (!wrapper)
- return nullptr;
- return static_cast<AXPlatformNodeAuraLinux*>(wrapper->ax_platform_node());
- }
-
- AXPlatformNodeAuraLinux* GetRootPlatformNode() {
- return GetPlatformNode(GetRootAsAXNode());
- }
-
- AtkObject* AtkObjectFromNode(AXNode* node) {
- if (AXPlatformNode* ax_platform_node = GetPlatformNode(node)) {
- return ax_platform_node->GetNativeViewAccessible();
- } else {
- return nullptr;
- }
- }
-
- TestAXNodeWrapper* GetRootWrapper() {
- return TestAXNodeWrapper::GetOrCreate(GetTree(), GetRootAsAXNode());
- }
-
- AtkObject* GetRootAtkObject() { return AtkObjectFromNode(GetRootAsAXNode()); }
-};
-
-static void EnsureAtkObjectHasAttributeWithValue(AtkObject* atk_object,
- const gchar* attribute_name,
- const gchar* attribute_value) {
- AtkAttributeSet* attributes = atk_object_get_attributes(atk_object);
- bool saw_attribute = false;
-
- AtkAttributeSet* current = attributes;
- while (current) {
- AtkAttribute* attribute = static_cast<AtkAttribute*>(current->data);
-
- if (0 == strcmp(attribute_name, attribute->name)) {
- // Ensure that we only see this attribute once.
- ASSERT_FALSE(saw_attribute) << attribute_name;
-
- EXPECT_STREQ(attribute_value, attribute->value);
- saw_attribute = true;
- }
-
- current = current->next;
- }
-
- ASSERT_TRUE(saw_attribute);
- atk_attribute_set_free(attributes);
-}
-
-static void EnsureAtkObjectDoesNotHaveAttribute(AtkObject* atk_object,
- const gchar* attribute_name) {
- AtkAttributeSet* attributes = atk_object_get_attributes(atk_object);
- AtkAttributeSet* current = attributes;
- while (current) {
- AtkAttribute* attribute = static_cast<AtkAttribute*>(current->data);
- ASSERT_STRNE(attribute_name, attribute->name) << attribute_name;
- current = current->next;
- }
- atk_attribute_set_free(attributes);
-}
-
-static void SetStringAttributeOnNode(
- AXNode* ax_node,
- ax::mojom::StringAttribute attribute,
- const char* attribute_value,
- base::Optional<ax::mojom::Role> role = base::nullopt) {
- AXNodeData new_data = AXNodeData();
- new_data.role = role.value_or(ax::mojom::Role::kApplication);
- new_data.id = ax_node->data().id;
- new_data.AddStringAttribute(attribute, attribute_value);
- ax_node->SetData(new_data);
-}
-
-static void TestAtkObjectIntAttribute(
- AXNode* ax_node,
- AtkObject* atk_object,
- ax::mojom::IntAttribute mojom_attribute,
- const gchar* attribute_name,
- base::Optional<ax::mojom::Role> role = base::nullopt) {
- AXNodeData new_data = AXNodeData();
- new_data.role = role.value_or(ax::mojom::Role::kApplication);
- ax_node->SetData(new_data);
- EnsureAtkObjectDoesNotHaveAttribute(atk_object, attribute_name);
-
- std::pair<int, const char*> tests[] = {
- std::make_pair(0, "0"), std::make_pair(1, "1"),
- std::make_pair(2, "2"), std::make_pair(-100, "-100"),
- std::make_pair(1000, "1000"),
- };
-
- for (unsigned i = 0; i < G_N_ELEMENTS(tests); i++) {
- AXNodeData new_data = AXNodeData();
- new_data.role = role.value_or(ax::mojom::Role::kApplication);
- new_data.id = ax_node->data().id;
- new_data.AddIntAttribute(mojom_attribute, tests[i].first);
- ax_node->SetData(new_data);
- EnsureAtkObjectHasAttributeWithValue(atk_object, attribute_name,
- tests[i].second);
- }
-}
-
-static void TestAtkObjectStringAttribute(
- AXNode* ax_node,
- AtkObject* atk_object,
- ax::mojom::StringAttribute mojom_attribute,
- const gchar* attribute_name,
- base::Optional<ax::mojom::Role> role = base::nullopt) {
- AXNodeData new_data = AXNodeData();
- new_data.role = role.value_or(ax::mojom::Role::kApplication);
- ax_node->SetData(new_data);
- EnsureAtkObjectDoesNotHaveAttribute(atk_object, attribute_name);
-
- const char* tests[] = {
- "", "a string with spaces", "a string with , a comma",
- "\xE2\x98\xBA", // The smiley emoji.
- };
-
- for (unsigned i = 0; i < G_N_ELEMENTS(tests); i++) {
- SetStringAttributeOnNode(ax_node, mojom_attribute, tests[i], role);
- EnsureAtkObjectHasAttributeWithValue(atk_object, attribute_name, tests[i]);
- }
-}
-
-static void TestAtkObjectBoolAttribute(
- AXNode* ax_node,
- AtkObject* atk_object,
- ax::mojom::BoolAttribute mojom_attribute,
- const gchar* attribute_name,
- base::Optional<ax::mojom::Role> role = base::nullopt) {
- AXNodeData new_data = AXNodeData();
- new_data.role = role.value_or(ax::mojom::Role::kApplication);
- ax_node->SetData(new_data);
- EnsureAtkObjectDoesNotHaveAttribute(atk_object, attribute_name);
-
- new_data = AXNodeData();
- new_data.role = role.value_or(ax::mojom::Role::kApplication);
- new_data.id = ax_node->data().id;
- new_data.AddBoolAttribute(mojom_attribute, true);
- ax_node->SetData(new_data);
- EnsureAtkObjectHasAttributeWithValue(atk_object, attribute_name, "true");
-
- new_data = AXNodeData();
- new_data.role = role.value_or(ax::mojom::Role::kApplication);
- new_data.id = ax_node->data().id;
- new_data.AddBoolAttribute(mojom_attribute, false);
- ax_node->SetData(new_data);
- EnsureAtkObjectHasAttributeWithValue(atk_object, attribute_name, "false");
-}
-
-static bool AtkObjectHasState(AtkObject* atk_object, AtkStateType state) {
- AtkStateSet* state_set = atk_object_ref_state_set(atk_object);
- EXPECT_TRUE(ATK_IS_STATE_SET(state_set));
- bool in_state_set = atk_state_set_contains_state(state_set, state);
- g_object_unref(state_set);
- return in_state_set;
-}
-
-//
-// AtkObject tests
-//
-#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 16, 0)
-#define ATK_216
-#endif
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectDetachedObject) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.SetName("Name");
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- g_object_ref(root_obj);
-
- const gchar* name = atk_object_get_name(root_obj);
- EXPECT_STREQ("Name", name);
-
- AtkStateSet* state_set = atk_object_ref_state_set(root_obj);
- ASSERT_TRUE(ATK_IS_STATE_SET(state_set));
- EXPECT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_DEFUNCT));
- g_object_unref(state_set);
-
- // Create an empty tree.
- SetTree(std::make_unique<AXTree>());
- EXPECT_EQ(nullptr, atk_object_get_name(root_obj));
-
- state_set = atk_object_ref_state_set(root_obj);
- ASSERT_TRUE(ATK_IS_STATE_SET(state_set));
- EXPECT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_DEFUNCT));
- g_object_unref(state_set);
-
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectName) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.SetName("Name");
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- g_object_ref(root_obj);
-
- const gchar* name = atk_object_get_name(root_obj);
- EXPECT_STREQ("Name", name);
-
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectDescription) {
- AXNodeData root;
- root.id = 1;
- root.AddStringAttribute(ax::mojom::StringAttribute::kDescription,
- "Description");
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- g_object_ref(root_obj);
-
- const gchar* description = atk_object_get_description(root_obj);
- EXPECT_STREQ("Description", description);
-
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectRole) {
- AXNodeData root;
- root.id = 1;
- root.child_ids.push_back(2);
- root.role = ax::mojom::Role::kApplication;
-
- AXNodeData child;
- child.id = 2;
-
- Init(root, child);
- AXNode* child_node = GetRootAsAXNode()->children()[0];
-
- AtkObject* root_obj(AtkObjectFromNode(GetRootAsAXNode()));
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- g_object_ref(root_obj);
- EXPECT_EQ(ATK_ROLE_APPLICATION, atk_object_get_role(root_obj));
- g_object_unref(root_obj);
-
- child.role = ax::mojom::Role::kAlert;
- child_node->SetData(child);
- AtkObject* child_obj(AtkObjectFromNode(child_node));
- ASSERT_TRUE(ATK_IS_OBJECT(child_obj));
- g_object_ref(child_obj);
- EXPECT_EQ(ATK_ROLE_NOTIFICATION, atk_object_get_role(child_obj));
- g_object_unref(child_obj);
-
- child.role = ax::mojom::Role::kAlertDialog;
- child_node->SetData(child);
- child_obj = AtkObjectFromNode(child_node);
- ASSERT_TRUE(ATK_IS_OBJECT(child_obj));
- g_object_ref(child_obj);
- EXPECT_EQ(ATK_ROLE_ALERT, atk_object_get_role(child_obj));
- g_object_unref(child_obj);
-
- child.role = ax::mojom::Role::kButton;
- child_node->SetData(child);
- child_obj = AtkObjectFromNode(child_node);
- ASSERT_TRUE(ATK_IS_OBJECT(child_obj));
- g_object_ref(child_obj);
- EXPECT_EQ(ATK_ROLE_PUSH_BUTTON, atk_object_get_role(child_obj));
- g_object_unref(child_obj);
-
- child.role = ax::mojom::Role::kCanvas;
- child_node->SetData(child);
- child_obj = AtkObjectFromNode(child_node);
- ASSERT_TRUE(ATK_IS_OBJECT(child_obj));
- g_object_ref(child_obj);
- EXPECT_EQ(ATK_ROLE_CANVAS, atk_object_get_role(child_obj));
- g_object_unref(child_obj);
-
- child.role = ax::mojom::Role::kApplication;
- child_node->SetData(child);
- child_obj = AtkObjectFromNode(child_node);
- ASSERT_TRUE(ATK_IS_OBJECT(child_obj));
- g_object_ref(child_obj);
- EXPECT_EQ(ATK_ROLE_EMBEDDED, atk_object_get_role(child_obj));
- g_object_unref(child_obj);
-
- child.role = ax::mojom::Role::kWindow;
- child_node->SetData(child);
- child_obj = AtkObjectFromNode(child_node);
- ASSERT_TRUE(ATK_IS_OBJECT(child_obj));
- g_object_ref(child_obj);
- EXPECT_EQ(ATK_ROLE_FRAME, atk_object_get_role(child_obj));
- g_object_unref(child_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectState) {
- AXNodeData root;
- root.id = 1;
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- g_object_ref(root_obj);
-
- AtkStateSet* state_set = atk_object_ref_state_set(root_obj);
- ASSERT_TRUE(ATK_IS_STATE_SET(state_set));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_ENABLED));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_SENSITIVE));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_SHOWING));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_VISIBLE));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_BUSY));
-#if defined(ATK_216)
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_CHECKABLE));
-#endif
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_CHECKED));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_DEFAULT));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_EDITABLE));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDABLE));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDED));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_FOCUSABLE));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_FOCUSED));
-#if defined(ATK_216)
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_HAS_POPUP));
-#endif
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_HORIZONTAL));
- ASSERT_FALSE(
- atk_state_set_contains_state(state_set, ATK_STATE_INVALID_ENTRY));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_MODAL));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_MULTI_LINE));
- ASSERT_FALSE(
- atk_state_set_contains_state(state_set, ATK_STATE_MULTISELECTABLE));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_REQUIRED));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_SELECTABLE));
- ASSERT_FALSE(
- atk_state_set_contains_state(state_set, ATK_STATE_SELECTABLE_TEXT));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_SELECTED));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_SINGLE_LINE));
- ASSERT_FALSE(atk_state_set_contains_state(state_set,
- ATK_STATE_SUPPORTS_AUTOCOMPLETION));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_VERTICAL));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_VISITED));
- g_object_unref(state_set);
-
- root = AXNodeData();
- root.AddState(ax::mojom::State::kDefault);
- root.AddState(ax::mojom::State::kEditable);
- root.AddState(ax::mojom::State::kExpanded);
- root.AddState(ax::mojom::State::kFocusable);
- root.AddState(ax::mojom::State::kMultiselectable);
- root.AddState(ax::mojom::State::kRequired);
- root.AddState(ax::mojom::State::kVertical);
- root.AddBoolAttribute(ax::mojom::BoolAttribute::kBusy, true);
- root.SetInvalidState(ax::mojom::InvalidState::kTrue);
- root.AddStringAttribute(ax::mojom::StringAttribute::kAutoComplete, "foo");
- GetRootAsAXNode()->SetData(root);
-
- state_set = atk_object_ref_state_set(root_obj);
- ASSERT_TRUE(ATK_IS_STATE_SET(state_set));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_BUSY));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_DEFAULT));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_EDITABLE));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDABLE));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDED));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_FOCUSABLE));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_INVALID_ENTRY));
- ASSERT_TRUE(
- atk_state_set_contains_state(state_set, ATK_STATE_MULTISELECTABLE));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_REQUIRED));
- ASSERT_TRUE(atk_state_set_contains_state(state_set,
- ATK_STATE_SUPPORTS_AUTOCOMPLETION));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_VERTICAL));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_FOCUSED));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_HORIZONTAL));
- g_object_unref(state_set);
-
- root = AXNodeData();
- root.AddState(ax::mojom::State::kCollapsed);
- root.AddState(ax::mojom::State::kHorizontal);
- root.AddState(ax::mojom::State::kVisited);
- root.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- root.SetHasPopup(ax::mojom::HasPopup::kTrue);
- GetRootAsAXNode()->SetData(root);
-
- state_set = atk_object_ref_state_set(root_obj);
- ASSERT_TRUE(ATK_IS_STATE_SET(state_set));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDABLE));
-#if defined(ATK_216)
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_HAS_POPUP));
-#endif
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_HORIZONTAL));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_SELECTABLE));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_SELECTED));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_VISITED));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDED));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_VERTICAL));
- g_object_unref(state_set);
-
- root = AXNodeData();
- root.AddState(ax::mojom::State::kInvisible);
- root.AddBoolAttribute(ax::mojom::BoolAttribute::kModal, true);
- GetRootAsAXNode()->SetData(root);
-
- state_set = atk_object_ref_state_set(root_obj);
- ASSERT_TRUE(ATK_IS_STATE_SET(state_set));
- ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_MODAL));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_SHOWING));
- ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_VISIBLE));
- g_object_unref(state_set);
-
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectChildAndParent) {
- AXNodeData root;
- root.id = 1;
- root.child_ids.push_back(2);
- root.child_ids.push_back(3);
-
- AXNodeData button;
- button.role = ax::mojom::Role::kButton;
- button.id = 2;
-
- AXNodeData checkbox;
- checkbox.role = ax::mojom::Role::kCheckBox;
- checkbox.id = 3;
-
- Init(root, button, checkbox);
- AXNode* button_node = GetRootAsAXNode()->children()[0];
- AXNode* checkbox_node = GetRootAsAXNode()->children()[1];
- AtkObject* root_obj = GetRootAtkObject();
- AtkObject* button_obj = AtkObjectFromNode(button_node);
- AtkObject* checkbox_obj = AtkObjectFromNode(checkbox_node);
-
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- EXPECT_EQ(2, atk_object_get_n_accessible_children(root_obj));
- ASSERT_TRUE(ATK_IS_OBJECT(button_obj));
- EXPECT_EQ(0, atk_object_get_n_accessible_children(button_obj));
- ASSERT_TRUE(ATK_IS_OBJECT(checkbox_obj));
- EXPECT_EQ(0, atk_object_get_n_accessible_children(checkbox_obj));
-
- {
- AtkObject* result = atk_object_ref_accessible_child(root_obj, 0);
- EXPECT_TRUE(ATK_IS_OBJECT(root_obj));
- EXPECT_EQ(result, button_obj);
- g_object_unref(result);
- }
- {
- AtkObject* result = atk_object_ref_accessible_child(root_obj, 1);
- EXPECT_TRUE(ATK_IS_OBJECT(root_obj));
- EXPECT_EQ(result, checkbox_obj);
- g_object_unref(result);
- }
-
- // Now check parents.
- {
- AtkObject* result = atk_object_get_parent(button_obj);
- EXPECT_TRUE(ATK_IS_OBJECT(result));
- EXPECT_EQ(result, root_obj);
- }
- {
- AtkObject* result = atk_object_get_parent(checkbox_obj);
- EXPECT_TRUE(ATK_IS_OBJECT(result));
- EXPECT_EQ(result, root_obj);
- }
-
- // Test invalid indices.
- AtkObject* result = atk_object_ref_accessible_child(root_obj, -1);
- EXPECT_EQ(result, nullptr);
- result = atk_object_ref_accessible_child(root_obj, -88);
- EXPECT_EQ(result, nullptr);
- result = atk_object_ref_accessible_child(root_obj, 3);
- EXPECT_EQ(result, nullptr);
- result = atk_object_ref_accessible_child(root_obj, 1000);
- EXPECT_EQ(result, nullptr);
- result = atk_object_ref_accessible_child(root_obj, 828282);
- EXPECT_EQ(result, nullptr);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectIndexInParent) {
- AXNodeData root;
- root.id = 1;
- root.child_ids.push_back(2);
- root.child_ids.push_back(3);
-
- AXNodeData left;
- left.id = 2;
-
- AXNodeData right;
- right.id = 3;
-
- Init(root, left, right);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- g_object_ref(root_obj);
-
- AtkObject* left_obj = atk_object_ref_accessible_child(root_obj, 0);
- ASSERT_TRUE(ATK_IS_OBJECT(left_obj));
- AtkObject* right_obj = atk_object_ref_accessible_child(root_obj, 1);
- ASSERT_TRUE(ATK_IS_OBJECT(right_obj));
-
- EXPECT_EQ(0, atk_object_get_index_in_parent(left_obj));
- EXPECT_EQ(1, atk_object_get_index_in_parent(right_obj));
-
- g_object_unref(left_obj);
- g_object_unref(right_obj);
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectStringAttributes) {
- AXNodeData root_data;
- root_data.id = 1;
-
- Init(root_data);
-
- AXNode* root_node = GetRootAsAXNode();
- AtkObject* root_atk_object(AtkObjectFromNode(root_node));
- ASSERT_TRUE(ATK_IS_OBJECT(root_atk_object));
- g_object_ref(root_atk_object);
-
- std::pair<ax::mojom::StringAttribute, const char*> tests[] = {
- std::make_pair(ax::mojom::StringAttribute::kDisplay, "display"),
- std::make_pair(ax::mojom::StringAttribute::kHtmlTag, "tag"),
- std::make_pair(ax::mojom::StringAttribute::kRole, "xml-roles"),
- std::make_pair(ax::mojom::StringAttribute::kPlaceholder, "placeholder"),
- std::make_pair(ax::mojom::StringAttribute::kRoleDescription,
- "roledescription"),
- std::make_pair(ax::mojom::StringAttribute::kKeyShortcuts, "keyshortcuts"),
- std::make_pair(ax::mojom::StringAttribute::kLiveStatus, "live"),
- std::make_pair(ax::mojom::StringAttribute::kLiveRelevant, "relevant"),
- std::make_pair(ax::mojom::StringAttribute::kContainerLiveStatus,
- "container-live"),
- std::make_pair(ax::mojom::StringAttribute::kContainerLiveRelevant,
- "container-relevant"),
- };
-
- for (unsigned i = 0; i < G_N_ELEMENTS(tests); i++) {
- TestAtkObjectStringAttribute(root_node, root_atk_object, tests[i].first,
- tests[i].second);
- }
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectBoolAttributes) {
- AXNodeData root_data;
- root_data.id = 1;
-
- Init(root_data);
-
- AXNode* root_node = GetRootAsAXNode();
- AtkObject* root_atk_object(AtkObjectFromNode(root_node));
- ASSERT_TRUE(ATK_IS_OBJECT(root_atk_object));
- g_object_ref(root_atk_object);
-
- std::pair<ax::mojom::BoolAttribute, const char*> tests[] = {
- std::make_pair(ax::mojom::BoolAttribute::kLiveAtomic, "atomic"),
- std::make_pair(ax::mojom::BoolAttribute::kBusy, "busy"),
- std::make_pair(ax::mojom::BoolAttribute::kContainerLiveAtomic,
- "container-atomic"),
- std::make_pair(ax::mojom::BoolAttribute::kContainerLiveBusy,
- "container-busy"),
- };
-
- for (unsigned i = 0; i < G_N_ELEMENTS(tests); i++) {
- TestAtkObjectBoolAttribute(root_node, root_atk_object, tests[i].first,
- tests[i].second);
- }
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, DISABLED_TestAtkObjectIntAttributes) {
- AXNodeData root_data;
- root_data.id = 1;
- Init(root_data);
-
- AXNode* root_node = GetRootAsAXNode();
- AtkObject* root_atk_object(AtkObjectFromNode(root_node));
- ASSERT_TRUE(ATK_IS_OBJECT(root_atk_object));
- g_object_ref(root_atk_object);
-
- TestAtkObjectIntAttribute(root_node, root_atk_object,
- ax::mojom::IntAttribute::kHierarchicalLevel,
- "level");
- TestAtkObjectIntAttribute(root_node, root_atk_object,
- ax::mojom::IntAttribute::kAriaColumnCount,
- "colcount", ax::mojom::Role::kTable);
- TestAtkObjectIntAttribute(root_node, root_atk_object,
- ax::mojom::IntAttribute::kAriaColumnCount,
- "colcount", ax::mojom::Role::kGrid);
- TestAtkObjectIntAttribute(root_node, root_atk_object,
- ax::mojom::IntAttribute::kAriaColumnCount,
- "colcount", ax::mojom::Role::kTreeGrid);
-
- TestAtkObjectIntAttribute(root_node, root_atk_object,
- ax::mojom::IntAttribute::kAriaRowCount, "rowcount",
- ax::mojom::Role::kTable);
- TestAtkObjectIntAttribute(root_node, root_atk_object,
- ax::mojom::IntAttribute::kAriaRowCount, "rowcount",
- ax::mojom::Role::kGrid);
- TestAtkObjectIntAttribute(root_node, root_atk_object,
- ax::mojom::IntAttribute::kAriaRowCount, "rowcount",
- ax::mojom::Role::kTreeGrid);
-
- TestAtkObjectIntAttribute(root_node, root_atk_object,
- ax::mojom::IntAttribute::kAriaCellColumnIndex,
- "colindex", ax::mojom::Role::kCell);
- TestAtkObjectIntAttribute(root_node, root_atk_object,
- ax::mojom::IntAttribute::kAriaCellRowIndex,
- "rowindex", ax::mojom::Role::kCell);
-
- g_object_unref(root_atk_object);
-}
-
-//
-// AtkComponent tests
-//
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkComponentRefAtPoint) {
- AXNodeData root;
- root.id = 1;
- root.relative_bounds.bounds = gfx::RectF(0, 0, 30, 30);
-
- AXNodeData node1;
- node1.id = 2;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.relative_bounds.bounds = gfx::RectF(0, 0, 10, 10);
- node1.SetName("Name1");
- root.child_ids.push_back(node1.id);
-
- AXNodeData node2;
- node2.id = 3;
- node2.role = ax::mojom::Role::kGenericContainer;
- node2.relative_bounds.bounds = gfx::RectF(20, 20, 10, 10);
- node2.SetName("Name2");
- root.child_ids.push_back(node2.id);
-
- Init(root, node1, node2);
-
- AtkObject* root_obj(GetRootAtkObject());
- EXPECT_TRUE(ATK_IS_OBJECT(root_obj));
- EXPECT_TRUE(ATK_IS_COMPONENT(root_obj));
- g_object_ref(root_obj);
-
- AtkObject* child_obj = atk_component_ref_accessible_at_point(
- ATK_COMPONENT(root_obj), 50, 50, ATK_XY_SCREEN);
- EXPECT_EQ(nullptr, child_obj);
-
- // this is directly on node 1.
- child_obj = atk_component_ref_accessible_at_point(ATK_COMPONENT(root_obj), 5,
- 5, ATK_XY_SCREEN);
- ASSERT_NE(nullptr, child_obj);
- EXPECT_TRUE(ATK_IS_OBJECT(child_obj));
-
- const gchar* name = atk_object_get_name(child_obj);
- EXPECT_STREQ("Name1", name);
-
- g_object_unref(child_obj);
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkComponentsGetExtentsPositionSize) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kWindow;
- root.relative_bounds.bounds = gfx::RectF(10, 40, 800, 600);
- root.child_ids.push_back(2);
-
- AXNodeData child;
- child.id = 2;
- child.relative_bounds.bounds = gfx::RectF(100, 150, 200, 200);
- Init(root, child);
-
- TestAXNodeWrapper::SetGlobalCoordinateOffset(gfx::Vector2d(100, 200));
-
- AtkObject* root_obj = GetRootAtkObject();
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- ASSERT_TRUE(ATK_IS_COMPONENT(root_obj));
- g_object_ref(root_obj);
-
- gint x_left, y_top, width, height;
- atk_component_get_extents(ATK_COMPONENT(root_obj), &x_left, &y_top, &width,
- &height, ATK_XY_SCREEN);
- EXPECT_EQ(110, x_left);
- EXPECT_EQ(240, y_top);
- EXPECT_EQ(800, width);
- EXPECT_EQ(600, height);
-
- AtkObject* hit_test_result = atk_component_ref_accessible_at_point(
- ATK_COMPONENT(root_obj), x_left, y_top, ATK_XY_SCREEN);
- ASSERT_EQ(hit_test_result, root_obj);
- g_object_unref(hit_test_result);
-
- atk_component_get_position(ATK_COMPONENT(root_obj), &x_left, &y_top,
- ATK_XY_SCREEN);
- EXPECT_EQ(110, x_left);
- EXPECT_EQ(240, y_top);
-
- atk_component_get_extents(ATK_COMPONENT(root_obj), &x_left, &y_top, &width,
- &height, ATK_XY_WINDOW);
- EXPECT_EQ(0, x_left);
- EXPECT_EQ(0, y_top);
- EXPECT_EQ(800, width);
- EXPECT_EQ(600, height);
-
- hit_test_result = atk_component_ref_accessible_at_point(
- ATK_COMPONENT(root_obj), x_left + 2, y_top + 2, ATK_XY_WINDOW);
- ASSERT_EQ(hit_test_result, root_obj);
- g_object_unref(hit_test_result);
-
- atk_component_get_position(ATK_COMPONENT(root_obj), &x_left, &y_top,
- ATK_XY_WINDOW);
- EXPECT_EQ(0, x_left);
- EXPECT_EQ(0, y_top);
-
- atk_component_get_size(ATK_COMPONENT(root_obj), &width, &height);
- EXPECT_EQ(800, width);
- EXPECT_EQ(600, height);
-
- AXNode* child_node = GetRootAsAXNode()->children()[0];
- AtkObject* child_obj = AtkObjectFromNode(child_node);
- ASSERT_TRUE(ATK_IS_OBJECT(child_obj));
- ASSERT_TRUE(ATK_IS_COMPONENT(child_obj));
- g_object_ref(child_obj);
-
- atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width,
- &height, ATK_XY_SCREEN);
- EXPECT_EQ(200, x_left);
- EXPECT_EQ(350, y_top);
- EXPECT_EQ(200, width);
- EXPECT_EQ(200, height);
-
- hit_test_result = atk_component_ref_accessible_at_point(
- ATK_COMPONENT(root_obj), x_left, y_top, ATK_XY_SCREEN);
- ASSERT_EQ(hit_test_result, child_obj);
- g_object_unref(hit_test_result);
-
- atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width,
- &height, ATK_XY_WINDOW);
- EXPECT_EQ(90, x_left);
- EXPECT_EQ(110, y_top);
- EXPECT_EQ(200, width);
- EXPECT_EQ(200, height);
-
- hit_test_result = atk_component_ref_accessible_at_point(
- ATK_COMPONENT(root_obj), x_left, y_top, ATK_XY_WINDOW);
- ASSERT_EQ(hit_test_result, child_obj);
- g_object_unref(hit_test_result);
-
- atk_component_get_extents(ATK_COMPONENT(child_obj), nullptr, &y_top, &width,
- &height, ATK_XY_SCREEN);
- EXPECT_EQ(200, height);
- atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, nullptr, &width,
- &height, ATK_XY_SCREEN);
- EXPECT_EQ(200, x_left);
- atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, nullptr,
- &height, ATK_XY_SCREEN);
- EXPECT_EQ(350, y_top);
- atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width,
- nullptr, ATK_XY_SCREEN);
- EXPECT_EQ(200, width);
-
- g_object_unref(child_obj);
- g_object_unref(root_obj);
-
- // Un-set the global offset so that it doesn't affect subsequent tests.
- TestAXNodeWrapper::SetGlobalCoordinateOffset(gfx::Vector2d(0, 0));
-}
-
-#if ATK_CHECK_VERSION(2, 30, 0)
-typedef bool (*ScrollToPointFunc)(AtkComponent* component,
- AtkCoordType coords,
- gint x,
- gint y);
-typedef bool (*ScrollToFunc)(AtkComponent* component, AtkScrollType type);
-
-TEST_F(AXPlatformNodeAuraLinuxTest, AtkComponentScrollToPoint) {
- // There's a chance we may be compiled with a newer version of ATK and then
- // run with an older one, so we need to do a runtime check for this method
- // that is available in ATK 2.30 instead of linking directly.
- ScrollToPointFunc scroll_to_point = reinterpret_cast<ScrollToPointFunc>(
- dlsym(RTLD_DEFAULT, "atk_component_scroll_to_point"));
- if (!scroll_to_point) {
- LOG(WARNING) << "Skipping AtkComponentScrollToPoint"
- " because ATK version < 2.30 detected.";
- return;
- }
-
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.relative_bounds.bounds = gfx::RectF(0, 0, 2000, 2000);
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kStaticText;
- child1.relative_bounds.bounds = gfx::RectF(10, 10, 10, 10);
- root.child_ids.push_back(2);
-
- Init(root, child1);
-
- AXNode* child_node = GetRootAsAXNode()->children()[0];
- AtkObject* child_obj = AtkObjectFromNode(child_node);
- ASSERT_TRUE(ATK_IS_OBJECT(child_obj));
- ASSERT_TRUE(ATK_IS_COMPONENT(child_obj));
- g_object_ref(child_obj);
-
- int x_left, y_top, width, height;
- atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width,
- &height, ATK_XY_SCREEN);
- EXPECT_EQ(10, x_left);
- EXPECT_EQ(10, y_top);
- EXPECT_EQ(10, width);
- EXPECT_EQ(10, height);
-
- scroll_to_point(ATK_COMPONENT(child_obj), ATK_XY_SCREEN, 600, 650);
- atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width,
- &height, ATK_XY_SCREEN);
- EXPECT_EQ(610, x_left);
- EXPECT_EQ(660, y_top);
- EXPECT_EQ(10, width);
- EXPECT_EQ(10, height);
-
- scroll_to_point(ATK_COMPONENT(child_obj), ATK_XY_PARENT, 10, 10);
- atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width,
- &height, ATK_XY_SCREEN);
- // The test wrapper scrolls every element when scrolling, so this should be
- // 10 pixels to bottom and left of the current coordinates of the root.
- EXPECT_EQ(620, x_left);
- EXPECT_EQ(670, y_top);
- EXPECT_EQ(10, width);
- EXPECT_EQ(10, height);
-
- g_object_unref(child_obj);
-
- // Un-set the global offset so that it doesn't affect subsequent tests.
- TestAXNodeWrapper::SetGlobalCoordinateOffset(gfx::Vector2d(0, 0));
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, AtkComponentScrollTo) {
- // There's a chance we may be compiled with a newer version of ATK and then
- // run with an older one, so we need to do a runtime check for this method
- // that is available in ATK 2.30 instead of linking directly.
- ScrollToFunc scroll_to = reinterpret_cast<ScrollToFunc>(
- dlsym(RTLD_DEFAULT, "atk_component_scroll_to"));
- if (!scroll_to) {
- LOG(WARNING) << "Skipping AtkComponentScrollTo"
- " because ATK version < 2.30 detected.";
- return;
- }
-
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.relative_bounds.bounds = gfx::RectF(0, 0, 2000, 2000);
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kStaticText;
- child1.relative_bounds.bounds = gfx::RectF(10, 10, 10, 10);
- root.child_ids.push_back(2);
-
- Init(root, child1);
-
- AXNode* child_node = GetRootAsAXNode()->children()[0];
- AtkObject* child_obj = AtkObjectFromNode(child_node);
- ASSERT_TRUE(ATK_IS_OBJECT(child_obj));
- ASSERT_TRUE(ATK_IS_COMPONENT(child_obj));
- g_object_ref(child_obj);
-
- int x_left, y_top, width, height;
- atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width,
- &height, ATK_XY_SCREEN);
- EXPECT_EQ(10, x_left);
- EXPECT_EQ(10, y_top);
- EXPECT_EQ(10, width);
- EXPECT_EQ(10, height);
-
- scroll_to(ATK_COMPONENT(child_obj), ATK_SCROLL_ANYWHERE);
- atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width,
- &height, ATK_XY_SCREEN);
- EXPECT_EQ(0, x_left);
- EXPECT_EQ(0, y_top);
- EXPECT_EQ(10, width);
- EXPECT_EQ(10, height);
-
- // Un-set the global offset so that it doesn't affect subsequent tests.
- TestAXNodeWrapper::SetGlobalCoordinateOffset(gfx::Vector2d(0, 0));
-}
-#endif // ATK_CHECK_VERSION(2, 30, 0)
-
-//
-// AtkValue tests
-//
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetCurrentValue) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kSlider;
- root.AddFloatAttribute(ax::mojom::FloatAttribute::kValueForRange, 5.0);
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- ASSERT_TRUE(ATK_IS_VALUE(root_obj));
- g_object_ref(root_obj);
-
- GValue current_value = G_VALUE_INIT;
- atk_value_get_current_value(ATK_VALUE(root_obj), ¤t_value);
-
- EXPECT_EQ(G_TYPE_FLOAT, G_VALUE_TYPE(¤t_value));
- EXPECT_EQ(5.0, g_value_get_float(¤t_value));
-
- g_value_unset(¤t_value);
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMaximumValue) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kSlider;
- root.AddFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange, 5.0);
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- ASSERT_TRUE(ATK_IS_VALUE(root_obj));
- g_object_ref(root_obj);
-
- GValue max_value = G_VALUE_INIT;
- atk_value_get_maximum_value(ATK_VALUE(root_obj), &max_value);
-
- EXPECT_EQ(G_TYPE_FLOAT, G_VALUE_TYPE(&max_value));
- EXPECT_EQ(5.0, g_value_get_float(&max_value));
-
- g_value_unset(&max_value);
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMinimumValue) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kSlider;
- root.AddFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange, 5.0);
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- ASSERT_TRUE(ATK_IS_VALUE(root_obj));
- g_object_ref(root_obj);
-
- GValue min_value = G_VALUE_INIT;
- atk_value_get_minimum_value(ATK_VALUE(root_obj), &min_value);
-
- EXPECT_EQ(G_TYPE_FLOAT, G_VALUE_TYPE(&min_value));
- EXPECT_EQ(5.0, g_value_get_float(&min_value));
-
- g_value_unset(&min_value);
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMinimumIncrement) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kSlider;
- root.AddFloatAttribute(ax::mojom::FloatAttribute::kStepValueForRange, 5.0);
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- ASSERT_TRUE(ATK_IS_VALUE(root_obj));
- g_object_ref(root_obj);
-
- GValue increment = G_VALUE_INIT;
- atk_value_get_minimum_increment(ATK_VALUE(root_obj), &increment);
-
- EXPECT_EQ(G_TYPE_FLOAT, G_VALUE_TYPE(&increment));
- EXPECT_EQ(5.0, g_value_get_float(&increment));
-
- g_value_unset(&increment);
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueChangedSignal) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kSlider;
- root.AddFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange, 5.0);
- Init(root);
-
- AtkObject* root_object(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_object));
- ASSERT_TRUE(ATK_IS_VALUE(root_object));
- g_object_ref(root_object);
-
- bool saw_value_change = false;
- g_signal_connect(
- root_object, "property-change::accessible-value",
- G_CALLBACK(+[](AtkObject*, void* property, bool* saw_value_change) {
- *saw_value_change = true;
- }),
- &saw_value_change);
-
- GValue new_value = G_VALUE_INIT;
- g_value_init(&new_value, G_TYPE_FLOAT);
-
- g_value_set_float(&new_value, 24.0);
- ASSERT_TRUE(atk_value_set_current_value(ATK_VALUE(root_object), &new_value));
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kValueChanged);
-
- GValue current_value = G_VALUE_INIT;
- atk_value_get_current_value(ATK_VALUE(root_object), ¤t_value);
- EXPECT_EQ(G_TYPE_FLOAT, G_VALUE_TYPE(¤t_value));
- EXPECT_EQ(24.0, g_value_get_float(¤t_value));
- EXPECT_TRUE(saw_value_change);
-
- saw_value_change = false;
- g_value_set_float(&new_value, 100.0);
- ASSERT_TRUE(atk_value_set_current_value(ATK_VALUE(root_object), &new_value));
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kValueChanged);
-
- g_value_unset(¤t_value);
- atk_value_get_current_value(ATK_VALUE(root_object), ¤t_value);
- EXPECT_EQ(G_TYPE_FLOAT, G_VALUE_TYPE(¤t_value));
- EXPECT_EQ(100.0, g_value_get_float(¤t_value));
- EXPECT_TRUE(saw_value_change);
-
- g_value_unset(¤t_value);
- g_value_unset(&new_value);
- g_object_unref(root_object);
-}
-
-//
-// AtkHyperlinkImpl interface
-//
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkHyperlink) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kLink;
- root.AddStringAttribute(ax::mojom::StringAttribute::kUrl, "http://foo.com");
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- ASSERT_TRUE(ATK_IS_HYPERLINK_IMPL(root_obj));
- g_object_ref(root_obj);
-
- AtkHyperlink* hyperlink(
- atk_hyperlink_impl_get_hyperlink(ATK_HYPERLINK_IMPL(root_obj)));
- ASSERT_TRUE(ATK_IS_HYPERLINK(hyperlink));
-
- EXPECT_EQ(1, atk_hyperlink_get_n_anchors(hyperlink));
- gchar* uri = atk_hyperlink_get_uri(hyperlink, 0);
- EXPECT_STREQ("http://foo.com", uri);
- g_free(uri);
-
- g_object_unref(hyperlink);
- g_object_unref(root_obj);
-}
-
-//
-// AtkText interface
-//
-//
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextGetText) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTextField;
- root.AddStringAttribute(ax::mojom::StringAttribute::kValue, "A string.");
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- g_object_ref(root_obj);
-
- ASSERT_TRUE(ATK_IS_TEXT(root_obj));
- AtkText* atk_text = ATK_TEXT(root_obj);
-
- auto verify_text = [&](const char* expected, int start, int end) {
- char* actual = atk_text_get_text(atk_text, start, end);
- EXPECT_STREQ(expected, actual);
- g_free(actual);
- };
-
- verify_text("A string.", 0, -1);
- verify_text("A string.", 0, 20);
- verify_text("A string", 0, 8);
- verify_text("str", 2, 5);
- verify_text(".", 8, 9);
- verify_text("", 0, 0);
- verify_text(nullptr, -1, -1);
- verify_text(nullptr, 5, 2);
- verify_text(nullptr, 10, 20);
-
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextCharacterGranularity) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTextField;
- root.AddStringAttribute(ax::mojom::StringAttribute::kValue,
- "A decently long string \xE2\x98\xBA with an emoji.");
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- g_object_ref(root_obj);
-
- ASSERT_TRUE(ATK_IS_TEXT(root_obj));
- AtkText* atk_text = ATK_TEXT(root_obj);
-
- EXPECT_EQ(static_cast<gunichar>('d'),
- atk_text_get_character_at_offset(atk_text, 2));
- EXPECT_EQ(0u, atk_text_get_character_at_offset(atk_text, -1));
- EXPECT_EQ(0u, atk_text_get_character_at_offset(atk_text, 42342));
- EXPECT_EQ(0x263Au, atk_text_get_character_at_offset(atk_text, 23));
- EXPECT_EQ(static_cast<gunichar>(' '),
- atk_text_get_character_at_offset(atk_text, 24));
-
- auto verify_text = [&](const char* expected_text, char* text,
- int expected_start, int expected_end, int start,
- int end) {
- EXPECT_STREQ(expected_text, text);
- EXPECT_EQ(start, expected_start);
- EXPECT_EQ(end, expected_end);
- g_free(text);
- };
-
- auto verify_text_at_offset = [&](const char* expected_text, int offset,
- int expected_start, int expected_end) {
- testing::Message message;
- message << "While checking at offset " << offset;
- SCOPED_TRACE(message);
-
- int start = 0, end = 0;
- char* text = atk_text_get_text_at_offset(
- atk_text, offset, ATK_TEXT_BOUNDARY_CHAR, &start, &end);
- verify_text(expected_text, text, expected_start, expected_end, start, end);
- };
-
- verify_text_at_offset("d", 2, 2, 3);
- verify_text_at_offset(nullptr, -1, 0, 0);
- verify_text_at_offset(nullptr, 42342, 0, 0);
- verify_text_at_offset("\xE2\x98\xBA", 23, 23, 24);
- verify_text_at_offset(" ", 24, 24, 25);
-
- auto verify_text_after_offset = [&](const char* expected_text, int offset,
- int expected_start, int expected_end) {
- testing::Message message;
- message << "While checking after offset " << offset;
- SCOPED_TRACE(message);
-
- int start = 0, end = 0;
- char* text = atk_text_get_text_after_offset(
- atk_text, offset, ATK_TEXT_BOUNDARY_CHAR, &start, &end);
- verify_text(expected_text, text, expected_start, expected_end, start, end);
- };
-
- verify_text_after_offset("d", 1, 2, 3);
- verify_text_after_offset(nullptr, 42342, -1, -1);
- verify_text_after_offset("\xE2\x98\xBA", 22, 23, 24);
- verify_text_after_offset(" ", 23, 24, 25);
-
- // This boundary condition is enforced by ATK for some reason.
- verify_text_after_offset(nullptr, -1, 0, 0);
-
- auto verify_text_before_offset = [&](const char* expected_text, int offset,
- int expected_start, int expected_end) {
- testing::Message message;
- message << "While checking before offset " << offset;
- SCOPED_TRACE(message);
-
- int start = 0, end = 0;
- char* text = atk_text_get_text_before_offset(
- atk_text, offset, ATK_TEXT_BOUNDARY_CHAR, &start, &end);
- verify_text(expected_text, text, expected_start, expected_end, start, end);
- };
-
- verify_text_before_offset("d", 3, 2, 3);
- verify_text_before_offset(nullptr, 42342, -1, -1);
- verify_text_before_offset("\xE2\x98\xBA", 24, 23, 24);
- verify_text_before_offset(" ", 25, 24, 25);
- verify_text_after_offset(nullptr, -1, 0, 0);
-
- g_object_unref(root_obj);
-}
-
-struct GetTextSegmentTest {
- int offset;
- const char* content;
- int start_offset;
- int end_offset;
-};
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextWordGranularity) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTextField;
- root.AddStringAttribute(ax::mojom::StringAttribute::kValue,
- "A decently long string.");
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- g_object_ref(root_obj);
-
- ASSERT_TRUE(ATK_IS_TEXT(root_obj));
- AtkText* atk_text = ATK_TEXT(root_obj);
-
- static GetTextSegmentTest tests[] = {{0, "A ", 0, 2},
- {2, "decently ", 2, 11},
- {-1, nullptr, -1, -1},
- {1000, nullptr, -1, -1}};
-
- for (unsigned i = 0; i < G_N_ELEMENTS(tests); i++) {
- testing::Message message;
- message << "While checking at index " << tests[i].offset << " for \'"
- << tests[i].content << "\' at " << tests[i].start_offset << '-'
- << tests[i].end_offset << '.';
- SCOPED_TRACE(message);
-
- int start_offset = -1, end_offset = -1;
- char* content = atk_text_get_text_at_offset(atk_text, tests[i].offset,
- ATK_TEXT_BOUNDARY_WORD_START,
- &start_offset, &end_offset);
- EXPECT_STREQ(content, tests[i].content);
- EXPECT_EQ(start_offset, tests[i].start_offset);
- EXPECT_EQ(end_offset, tests[i].end_offset);
- g_free(content);
- }
-
-#if ATK_CHECK_VERSION(2, 10, 0)
- for (unsigned i = 0; i < G_N_ELEMENTS(tests); i++) {
- testing::Message message;
- message << "While checking at index " << tests[i].offset << " for \'"
- << tests[i].content << "\' at " << tests[i].start_offset << '-'
- << tests[i].end_offset << '.';
- SCOPED_TRACE(message);
-
- int start_offset = -1, end_offset = -1;
- char* content = atk_text_get_string_at_offset(atk_text, tests[i].offset,
- ATK_TEXT_GRANULARITY_WORD,
- &start_offset, &end_offset);
- ASSERT_STREQ(content, tests[i].content) << "with test index=" << i;
- ASSERT_EQ(start_offset, tests[i].start_offset) << "with test index=" << i;
- ASSERT_EQ(end_offset, tests[i].end_offset) << "with test index=" << i;
- g_free(content);
- }
-#endif
-
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextSentenceGranularity) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTextField;
- root.AddStringAttribute(ax::mojom::StringAttribute::kValue,
- "A short sentence. Another sentence. A third...");
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- g_object_ref(root_obj);
-
- ASSERT_TRUE(ATK_IS_TEXT(root_obj));
- AtkText* atk_text = ATK_TEXT(root_obj);
-
- static GetTextSegmentTest tests[] = {
- {0, "A short sentence. ", 0, 18},
- {20, "Another sentence. ", 18, 40},
- {37, "Another sentence. ", 18, 40},
- {49, "A third...", 40, 50},
- {-1, nullptr, -1, -1},
- {-1000, nullptr, -1, -1},
- {1000, nullptr, -1, -1},
- };
-
- for (unsigned i = 0; i < G_N_ELEMENTS(tests); i++) {
- testing::Message message;
- message << "While checking at index " << tests[i].offset << " for \'"
- << tests[i].content << "\' at " << tests[i].start_offset << '-'
- << tests[i].end_offset << '.';
- SCOPED_TRACE(message);
-
- int start_offset = -1, end_offset = -1;
- char* content = atk_text_get_text_at_offset(
- atk_text, tests[i].offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
- &start_offset, &end_offset);
- ASSERT_STREQ(content, tests[i].content);
- ASSERT_EQ(start_offset, tests[i].start_offset);
- ASSERT_EQ(end_offset, tests[i].end_offset);
- g_free(content);
- }
-
-#if ATK_CHECK_VERSION(2, 10, 0)
- for (unsigned i = 0; i < G_N_ELEMENTS(tests); i++) {
- testing::Message message;
- message << "While checking at index " << tests[i].offset << " for \'"
- << tests[i].content << "\' at " << tests[i].start_offset << '-'
- << tests[i].end_offset << '.';
- SCOPED_TRACE(message);
-
- int start_offset = -1, end_offset = -1;
- char* content = atk_text_get_string_at_offset(atk_text, tests[i].offset,
- ATK_TEXT_GRANULARITY_SENTENCE,
- &start_offset, &end_offset);
- ASSERT_STREQ(content, tests[i].content);
- ASSERT_EQ(start_offset, tests[i].start_offset);
- ASSERT_EQ(end_offset, tests[i].end_offset);
- g_free(content);
- }
-#endif
-
- g_object_unref(root_obj);
-}
-
-#if ATK_CHECK_VERSION(2, 10, 0)
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextParagraphGranularity) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTextField;
- root.AddStringAttribute(
- ax::mojom::StringAttribute::kValue,
- "A short paragraph. \nAnother paragraph.\nA third...");
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- g_object_ref(root_obj);
-
- ASSERT_TRUE(ATK_IS_TEXT(root_obj));
- AtkText* atk_text = ATK_TEXT(root_obj);
-
- static GetTextSegmentTest tests[] = {
- {0, "A short paragraph. ", 0, 19},
- {25, "Another paragraph.", 20, 38},
- {-1, nullptr, -1, -1},
- {12345, nullptr, -1, -1},
- };
-
- for (unsigned i = 0; i < G_N_ELEMENTS(tests); i++) {
- int start_offset = -1, end_offset = -1;
- char* content = atk_text_get_string_at_offset(
- atk_text, tests[i].offset, ATK_TEXT_GRANULARITY_PARAGRAPH,
- &start_offset, &end_offset);
- ASSERT_STREQ(content, tests[i].content) << "with test index=" << i;
- ASSERT_EQ(start_offset, tests[i].start_offset) << "with test index=" << i;
- ASSERT_EQ(end_offset, tests[i].end_offset) << "with test index=" << i;
- g_free(content);
- }
-#endif
-
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextWithNonBMPCharacters) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTextField;
-
- // The playing card emoji in this string should be considered a single
- // character offset for all AtkText API calls.
- static const char root_text[] =
- "\xF0\x9F\x83\x8f a decently long \xF0\x9F\x83\x8f string "
- "\xF0\x9F\x83\x8f.";
- root.AddStringAttribute(ax::mojom::StringAttribute::kValue, root_text);
- Init(root);
-
- AtkObject* root_obj(GetRootAtkObject());
- ASSERT_TRUE(ATK_IS_OBJECT(root_obj));
- g_object_ref(root_obj);
-
- ASSERT_TRUE(ATK_IS_TEXT(root_obj));
- AtkText* atk_text = ATK_TEXT(root_obj);
-
- int root_text_length = g_utf8_strlen(root_text, -1);
- ASSERT_EQ(atk_text_get_character_count(atk_text), root_text_length);
-
- for (int i = 0; i < root_text_length; i++) {
- testing::Message message;
- message << "Checking character at offset " << i;
- SCOPED_TRACE(message);
-
- gunichar character = atk_text_get_character_at_offset(atk_text, i);
- gunichar expected_character =
- g_utf8_get_char_validated(g_utf8_offset_to_pointer(root_text, i), -1);
- ASSERT_EQ(character, expected_character);
-
- int start_offset = -1, end_offset = -1;
- char* char_string = atk_text_get_text_at_offset(
- atk_text, i, ATK_TEXT_BOUNDARY_CHAR, &start_offset, &end_offset);
- character = g_utf8_get_char_validated(char_string, -1);
- ASSERT_EQ(character, expected_character);
- ASSERT_EQ(start_offset, i);
- ASSERT_EQ(end_offset, i + 1);
- g_free(char_string);
-
-#if ATK_CHECK_VERSION(2, 10, 0)
- start_offset = -1;
- end_offset = -1;
- char_string = atk_text_get_string_at_offset(
- atk_text, i, ATK_TEXT_GRANULARITY_CHAR, &start_offset, &end_offset);
-
- character = g_utf8_get_char_validated(char_string, -1);
- ASSERT_EQ(character, expected_character);
- ASSERT_EQ(start_offset, i);
- ASSERT_EQ(end_offset, i + 1);
- g_free(char_string);
-#endif
- }
-
- static GetTextSegmentTest tests[] = {{0, "\xF0\x9F\x83\x8f ", 0, 2},
- {6, "decently ", 4, 13}};
-
- for (unsigned i = 0; i < G_N_ELEMENTS(tests); i++) {
- int start_offset = -1, end_offset = -1;
- char* word = atk_text_get_text_at_offset(atk_text, tests[i].offset,
- ATK_TEXT_BOUNDARY_WORD_START,
- &start_offset, &end_offset);
- testing::Message message;
- message << "Checking test with index=" << i << " and expected text=\'"
- << tests[i].content << "\' at " << tests[1].start_offset << '-'
- << tests[1].end_offset << '.';
- SCOPED_TRACE(message);
-
- ASSERT_STREQ(word, tests[i].content);
- ASSERT_EQ(start_offset, tests[i].start_offset);
- ASSERT_EQ(end_offset, tests[i].end_offset);
-
- g_free(word);
- }
-
- g_object_unref(root_obj);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextCaretMoved) {
- Init(BuildTextField());
-
- AtkObject* root_atk_object(GetRootAtkObject());
- EXPECT_TRUE(ATK_IS_OBJECT(root_atk_object));
- g_object_ref(root_atk_object);
-
- ASSERT_TRUE(ATK_IS_TEXT(root_atk_object));
- AtkText* atk_text = ATK_TEXT(root_atk_object);
-
- int caret_position_from_event = -1;
- g_signal_connect(atk_text, "text-caret-moved",
- G_CALLBACK(+[](AtkText*, int new_position, gpointer data) {
- int* caret_position_from_event = static_cast<int*>(data);
- *caret_position_from_event = new_position;
- }),
- &caret_position_from_event);
-
- atk_text_set_caret_offset(atk_text, 4);
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
- ASSERT_EQ(atk_text_get_caret_offset(atk_text), 4);
- ASSERT_EQ(caret_position_from_event, 4);
-
- // Setting the same position should not trigger another event.
- caret_position_from_event = -1;
- atk_text_set_caret_offset(atk_text, 4);
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
- ASSERT_EQ(atk_text_get_caret_offset(atk_text), 4);
- ASSERT_EQ(caret_position_from_event, -1);
-
- int character_count = atk_text_get_character_count(atk_text);
- atk_text_set_caret_offset(atk_text, -1);
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
- ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count);
- ASSERT_EQ(caret_position_from_event, character_count);
-
- atk_text_set_caret_offset(atk_text, 0); // Reset position.
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
-
- caret_position_from_event = -1;
- atk_text_set_caret_offset(atk_text, -1000);
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
- ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count);
- ASSERT_EQ(caret_position_from_event, character_count);
-
- atk_text_set_caret_offset(atk_text, 0); // Reset position.
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
-
- caret_position_from_event = -1;
- atk_text_set_caret_offset(atk_text, 1000);
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
- ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count);
- ASSERT_EQ(caret_position_from_event, character_count);
-
- caret_position_from_event = -1;
- atk_text_set_caret_offset(atk_text, character_count - 1);
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
- ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count - 1);
- ASSERT_EQ(caret_position_from_event, character_count - 1);
-
- g_object_unref(root_atk_object);
-}
-
-class ActivationTester {
- public:
- explicit ActivationTester(AtkObject* target) : target_(target) {
- auto callback = G_CALLBACK(+[](AtkWindow*, bool* flag) { *flag = true; });
- activate_id_ =
- g_signal_connect(target, "activate", callback, &saw_activate_);
- deactivate_id_ =
- g_signal_connect(target, "deactivate", callback, &saw_deactivate_);
-
- DCHECK(activate_id_);
- DCHECK(deactivate_id_);
- DCHECK(activate_id_ != deactivate_id_);
- }
-
- bool IsActivatedInStateSet() {
- return AtkObjectHasState(target_, ATK_STATE_ACTIVE);
- }
-
- void Reset() {
- saw_activate_ = false;
- saw_deactivate_ = false;
- }
-
- virtual ~ActivationTester() {
- g_signal_handler_disconnect(target_, activate_id_);
- g_signal_handler_disconnect(target_, deactivate_id_);
- }
-
- AtkObject* target_;
- bool saw_activate_ = false;
- bool saw_deactivate_ = false;
- gulong activate_id_ = 0;
- gulong deactivate_id_ = 0;
-};
-
-//
-// AtkWindow interface and active state
-//
-//
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkWindowActive) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kWindow;
- root.child_ids.push_back(2);
-
- AXNodeData child;
- child.id = 2;
- child.role = ax::mojom::Role::kCheckBox;
-
- Init(root, child);
-
- AtkObject* root_atk_object(GetRootAtkObject());
- EXPECT_TRUE(ATK_IS_OBJECT(root_atk_object));
- g_object_ref(root_atk_object);
-
- EXPECT_TRUE(ATK_IS_WINDOW(root_atk_object));
-
- AXNode* checkbox_node = GetRootAsAXNode()->children()[0];
- AtkObject* checkbox_atk_obj = AtkObjectFromNode(checkbox_node);
-
- // Focus the checkbox to ensure that it also gets new focus events when
- // the toplevel window goes from unfocused to focused.
- GetPlatformNode(checkbox_node)
- ->NotifyAccessibilityEvent(ax::mojom::Event::kFocus);
-
- bool saw_active_focus_state_change = false;
- g_signal_connect(checkbox_atk_obj, "state-change",
- G_CALLBACK(+[](AtkObject* atkobject, gchar* state_changed,
- gboolean new_value, bool* flag) {
- if (!g_strcmp0(state_changed, "focused") && new_value)
- *flag = true;
- }),
- &saw_active_focus_state_change);
-
- // ATK window activated event will be held until AT-SPI bridge is ready. We
- // work that around by faking its state.
- ui::AtkUtilAuraLinux::GetInstance()->SetAtSpiReady(true);
-
- {
- ActivationTester tester(root_atk_object);
- EXPECT_FALSE(tester.IsActivatedInStateSet());
- static_cast<AXPlatformNodeAuraLinux*>(GetRootPlatformNode())
- ->NotifyAccessibilityEvent(ax::mojom::Event::kWindowActivated);
- EXPECT_TRUE(tester.saw_activate_);
- EXPECT_FALSE(tester.saw_deactivate_);
- EXPECT_TRUE(tester.IsActivatedInStateSet());
- EXPECT_TRUE(saw_active_focus_state_change);
- }
-
- {
- saw_active_focus_state_change = false;
-
- ActivationTester tester(root_atk_object);
- static_cast<AXPlatformNodeAuraLinux*>(GetRootPlatformNode())
- ->NotifyAccessibilityEvent(ax::mojom::Event::kWindowDeactivated);
- EXPECT_FALSE(tester.saw_activate_);
- EXPECT_TRUE(tester.saw_deactivate_);
- EXPECT_FALSE(tester.IsActivatedInStateSet());
- EXPECT_FALSE(saw_active_focus_state_change);
- }
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestPostponedAtkWindowActive) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kWindow;
- Init(root);
-
- AtkObject* root_atk_object(GetRootAtkObject());
- EXPECT_TRUE(ATK_IS_OBJECT(root_atk_object));
- g_object_ref(root_atk_object);
- EXPECT_TRUE(ATK_IS_WINDOW(root_atk_object));
-
- AtkUtilAuraLinux* atk_util = ui::AtkUtilAuraLinux::GetInstance();
-
- {
- ActivationTester tester(root_atk_object);
- EXPECT_FALSE(tester.IsActivatedInStateSet());
- static_cast<AXPlatformNodeAuraLinux*>(GetRootPlatformNode())
- ->NotifyAccessibilityEvent(ax::mojom::Event::kWindowActivated);
-
- // ATK window activated event will be held until AT-SPI bridge is ready.
- EXPECT_FALSE(tester.saw_activate_);
- EXPECT_FALSE(tester.saw_deactivate_);
-
- // We force the AT-SPI ready flag to flush any held events.
- atk_util->SetAtSpiReady(true);
- EXPECT_TRUE(tester.saw_activate_);
- EXPECT_FALSE(tester.saw_deactivate_);
- EXPECT_TRUE(tester.IsActivatedInStateSet());
- }
-
- {
- ActivationTester tester(root_atk_object);
-
- static_cast<AXPlatformNodeAuraLinux*>(GetRootPlatformNode())
- ->NotifyAccessibilityEvent(ax::mojom::Event::kWindowDeactivated);
-
- EXPECT_FALSE(tester.saw_activate_);
- EXPECT_TRUE(tester.saw_deactivate_);
- EXPECT_FALSE(tester.IsActivatedInStateSet());
- }
-
- {
- atk_util->SetAtSpiReady(false);
-
- ActivationTester tester(root_atk_object);
-
- static_cast<AXPlatformNodeAuraLinux*>(GetRootPlatformNode())
- ->NotifyAccessibilityEvent(ax::mojom::Event::kWindowActivated);
-
- // Window deactivated will cancel the previously held activated event.
- static_cast<AXPlatformNodeAuraLinux*>(GetRootPlatformNode())
- ->NotifyAccessibilityEvent(ax::mojom::Event::kWindowDeactivated);
-
- // We force the AT-SPI ready flag to flush any held events.
- atk_util->SetAtSpiReady(true);
-
- // No events seen because they cancelled each other.
- EXPECT_FALSE(tester.saw_activate_);
- EXPECT_FALSE(tester.saw_deactivate_);
- }
-
- g_object_unref(root_atk_object);
-}
-
-//
-// AtkWindow interface and iconified state
-//
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkWindowMinimized) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kWindow;
- Init(root);
-
- AtkObject* root_atk_object(GetRootAtkObject());
- EXPECT_TRUE(ATK_IS_OBJECT(root_atk_object));
- g_object_ref(root_atk_object);
-
- EXPECT_TRUE(ATK_IS_WINDOW(root_atk_object));
- EXPECT_FALSE(AtkObjectHasState(root_atk_object, ATK_STATE_ICONIFIED));
-
- GetRootWrapper()->set_minimized(true);
- EXPECT_TRUE(AtkObjectHasState(root_atk_object, ATK_STATE_ICONIFIED));
-
- bool saw_state_change = false;
- g_signal_connect(root_atk_object, "state-change",
- G_CALLBACK(+[](AtkObject* atkobject, gchar* state_changed,
- gboolean new_value, bool* flag) {
- if (!g_strcmp0(state_changed, "iconified"))
- *flag = true;
- }),
- &saw_state_change);
-
- AXPlatformNodeAuraLinux* root_node = GetRootPlatformNode();
- static_cast<AXPlatformNodeAuraLinux*>(root_node)->NotifyAccessibilityEvent(
- ax::mojom::Event::kWindowVisibilityChanged);
-
- EXPECT_TRUE(saw_state_change);
-
- saw_state_change = false;
- static_cast<AXPlatformNodeAuraLinux*>(root_node)->NotifyAccessibilityEvent(
- ax::mojom::Event::kWindowVisibilityChanged);
- EXPECT_FALSE(saw_state_change);
-
- GetRootWrapper()->set_minimized(false);
- static_cast<AXPlatformNodeAuraLinux*>(root_node)->NotifyAccessibilityEvent(
- ax::mojom::Event::kWindowVisibilityChanged);
- EXPECT_TRUE(saw_state_change);
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestFocusTriggersAtkWindowActive) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kWindow;
- root.child_ids.push_back(2);
-
- AXNodeData child_node_data;
- child_node_data.id = 2;
- child_node_data.role = ax::mojom::Role::kButton;
-
- Init(root, child_node_data);
-
- AtkObject* root_atk_object(GetRootAtkObject());
- EXPECT_TRUE(ATK_IS_OBJECT(root_atk_object));
- EXPECT_TRUE(ATK_IS_WINDOW(root_atk_object));
-
- g_object_ref(root_atk_object);
-
- AXNode* child_node = GetRootAsAXNode()->children()[0];
-
- // A focus event on a child node should not cause the window to
- // activate.
- {
- ActivationTester tester(root_atk_object);
- GetPlatformNode(child_node)
- ->NotifyAccessibilityEvent(ax::mojom::Event::kFocus);
- EXPECT_FALSE(tester.saw_activate_);
- EXPECT_FALSE(tester.saw_deactivate_);
- EXPECT_FALSE(tester.IsActivatedInStateSet());
- }
-
- // A focus event on the window itself should cause the window to activate.
- {
- ActivationTester tester(root_atk_object);
- GetRootPlatformNode()->NotifyAccessibilityEvent(ax::mojom::Event::kFocus);
- EXPECT_TRUE(tester.saw_activate_);
- EXPECT_FALSE(tester.saw_deactivate_);
- EXPECT_TRUE(tester.IsActivatedInStateSet());
- }
-
- // Since the window is already active, we shouldn't see another activation
- // event, but it should still be active.
- {
- ActivationTester tester(root_atk_object);
- GetRootPlatformNode()->NotifyAccessibilityEvent(ax::mojom::Event::kFocus);
- EXPECT_FALSE(tester.saw_activate_);
- EXPECT_FALSE(tester.saw_deactivate_);
- EXPECT_TRUE(tester.IsActivatedInStateSet());
- }
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkPopupWindowActive) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kApplication;
- root.child_ids.push_back(2);
- root.child_ids.push_back(4);
-
- AXNodeData window_node_data;
- window_node_data.id = 2;
- window_node_data.role = ax::mojom::Role::kWindow;
- window_node_data.child_ids.push_back(3);
-
- AXNodeData document_node_data;
- document_node_data.id = 3;
- document_node_data.role = ax::mojom::Role::kRootWebArea;
-
- AXNodeData menu_node_data;
- menu_node_data.id = 4;
- menu_node_data.role = ax::mojom::Role::kWindow;
- menu_node_data.child_ids.push_back(5);
-
- AXNodeData menu_item_data;
- menu_item_data.id = 5;
-
- Init(root, window_node_data, document_node_data, menu_node_data,
- menu_item_data);
-
- AtkObject* root_atk_object(GetRootAtkObject());
- EXPECT_TRUE(ATK_IS_OBJECT(root_atk_object));
- g_object_ref(root_atk_object);
-
- AXNode* window_node = GetRootAsAXNode()->children()[0];
- AtkObject* window_atk_node(AtkObjectFromNode(window_node));
-
- AXNode* document_node = window_node->children()[0];
- AtkObject* document_atk_node(AtkObjectFromNode(document_node));
- EXPECT_EQ(ATK_ROLE_DOCUMENT_WEB, atk_object_get_role(document_atk_node));
- int focus_events_on_original_node = 0;
- g_signal_connect(
- document_atk_node, "focus-event",
- G_CALLBACK(+[](AtkObject* atkobject, gint focused, int* focus_events) {
- if (focused)
- *focus_events += 1;
- }),
- &focus_events_on_original_node);
- atk_component_grab_focus(ATK_COMPONENT(document_atk_node));
-
- ActivationTester toplevel_tester(window_atk_node);
- GetPlatformNode(window_node)
- ->NotifyAccessibilityEvent(ax::mojom::Event::kWindowActivated);
- EXPECT_TRUE(toplevel_tester.saw_activate_);
- EXPECT_FALSE(toplevel_tester.saw_deactivate_);
- EXPECT_TRUE(toplevel_tester.IsActivatedInStateSet());
-
- toplevel_tester.Reset();
-
- AXNode* menu_node = GetRootAsAXNode()->children()[1];
- AtkObject* menu_atk_node(AtkObjectFromNode(menu_node));
- {
- ActivationTester tester(menu_atk_node);
- GetPlatformNode(menu_node)->NotifyAccessibilityEvent(
- ax::mojom::Event::kMenuPopupStart);
- EXPECT_TRUE(tester.saw_activate_);
- EXPECT_FALSE(tester.saw_deactivate_);
- EXPECT_TRUE(tester.IsActivatedInStateSet());
- EXPECT_EQ(focus_events_on_original_node, 0);
- }
-
- EXPECT_FALSE(toplevel_tester.saw_activate_);
- EXPECT_TRUE(toplevel_tester.saw_deactivate_);
-
- toplevel_tester.Reset();
-
- {
- ActivationTester tester(menu_atk_node);
- GetPlatformNode(menu_node)->NotifyAccessibilityEvent(
- ax::mojom::Event::kMenuPopupEnd);
- EXPECT_FALSE(tester.saw_activate_);
- EXPECT_TRUE(tester.saw_deactivate_);
- EXPECT_FALSE(tester.IsActivatedInStateSet());
- EXPECT_EQ(focus_events_on_original_node, 1);
- }
-
- // Now that the menu is definitively closed, activation should have returned
- // to the previously activated toplevel frame.
- EXPECT_TRUE(toplevel_tester.saw_activate_);
- EXPECT_FALSE(toplevel_tester.saw_deactivate_);
-
- // Now we test opening the menu and closing it without hiding any submenus.
- // The toplevel should lose and then regain focus.
- focus_events_on_original_node = 0;
- toplevel_tester.Reset();
-
- GetPlatformNode(menu_node)->NotifyAccessibilityEvent(
- ax::mojom::Event::kMenuPopupStart);
- GetPlatformNode(menu_node)->NotifyAccessibilityEvent(
- ax::mojom::Event::kMenuPopupEnd);
- EXPECT_TRUE(toplevel_tester.saw_activate_);
- EXPECT_TRUE(toplevel_tester.saw_deactivate_);
-
- // The menu has closed so the original node should have received focus again.
- EXPECT_EQ(focus_events_on_original_node, 1);
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkSelectionInterface) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kListBox;
- root.AddState(ax::mojom::State::kFocusable);
- root.AddState(ax::mojom::State::kMultiselectable);
- root.child_ids.push_back(2);
- root.child_ids.push_back(3);
- root.child_ids.push_back(4);
- root.child_ids.push_back(5);
-
- AXNodeData item_1;
- item_1.id = 2;
- item_1.role = ax::mojom::Role::kListBoxOption;
-
- AXNodeData item_2;
- item_2.id = 3;
- item_2.role = ax::mojom::Role::kListBoxOption;
-
- AXNodeData item_3;
- item_3.id = 4;
- item_3.role = ax::mojom::Role::kListBoxOption;
-
- // Add a final item which is not selectable.
- AXNodeData item_4;
- item_4.id = 5;
- item_4.role = ax::mojom::Role::kListItem;
-
- AXTreeUpdate update;
- update.root_id = 1;
- update.nodes.push_back(root);
- update.nodes.push_back(item_1);
- update.nodes.push_back(item_2);
- update.nodes.push_back(item_3);
- update.nodes.push_back(item_4);
- Init(update);
-
- AtkObject* root_atk_object(GetRootAtkObject());
- EXPECT_TRUE(ATK_IS_OBJECT(root_atk_object));
- g_object_ref(root_atk_object);
-
- ASSERT_TRUE(ATK_IS_SELECTION(root_atk_object));
-
- ASSERT_TRUE(ATK_IS_SELECTION(root_atk_object));
- AtkSelection* selection = ATK_SELECTION(root_atk_object);
- ASSERT_EQ(atk_selection_get_selection_count(selection), 0);
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 0));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 1));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 2));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 3));
-
- ASSERT_FALSE(atk_selection_is_child_selected(selection, -1));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, -100));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 4));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 3000));
-
- ASSERT_TRUE(atk_selection_select_all_selection(selection));
- ASSERT_EQ(atk_selection_get_selection_count(selection), 3);
- ASSERT_TRUE(atk_selection_is_child_selected(selection, 0));
- ASSERT_TRUE(atk_selection_is_child_selected(selection, 1));
- ASSERT_TRUE(atk_selection_is_child_selected(selection, 2));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 3));
-
- ASSERT_FALSE(atk_selection_is_child_selected(selection, -1));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, -100));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 4));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 3000));
-
- ASSERT_TRUE(atk_selection_clear_selection(selection));
- ASSERT_EQ(atk_selection_get_selection_count(selection), 0);
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 0));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 1));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 2));
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 3));
-
- ASSERT_TRUE(atk_selection_add_selection(selection, 1));
- ASSERT_EQ(atk_selection_get_selection_count(selection), 1);
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 0));
- ASSERT_TRUE(atk_selection_is_child_selected(selection, 1));
-
- // The index to this function is the index into the selected elements, not
- // into the children.
- ASSERT_TRUE(atk_selection_remove_selection(selection, 0));
- ASSERT_EQ(atk_selection_get_selection_count(selection), 0);
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 1));
-
- // We should not be able to select an item with a role that is not
- // selectable.
- ASSERT_FALSE(atk_selection_add_selection(selection, 3));
- ASSERT_EQ(atk_selection_get_selection_count(selection), 0);
- ASSERT_FALSE(atk_selection_is_child_selected(selection, 3));
-
- // Test some out of bounds use of atk_selection_add_selection.
- ASSERT_FALSE(atk_selection_add_selection(selection, -1));
- ASSERT_FALSE(atk_selection_add_selection(selection, -100));
- ASSERT_FALSE(atk_selection_add_selection(selection, 4));
- ASSERT_FALSE(atk_selection_add_selection(selection, 100));
- ASSERT_EQ(atk_selection_get_selection_count(selection), 0);
-
- ASSERT_TRUE(atk_selection_select_all_selection(selection));
- ASSERT_EQ(atk_selection_get_selection_count(selection), 3);
- ASSERT_FALSE(atk_selection_remove_selection(selection, -1));
- ASSERT_FALSE(atk_selection_remove_selection(selection, -100));
- ASSERT_FALSE(atk_selection_remove_selection(selection, 4));
- ASSERT_FALSE(atk_selection_remove_selection(selection, 100));
- ASSERT_EQ(atk_selection_get_selection_count(selection), 3);
-
- g_object_unref(root_atk_object);
-}
-
-// Tests GetPosInSet() and GetSetSize() functions of AXPlatformNodeBase.
-// PosInSet and SetSize must be tested separately from other IntAttributes
-// because they can be either assigned values or calculated dynamically.
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectSetSizePosInSet) {
- AXTreeUpdate update;
- update.root_id = 1;
- update.nodes.resize(4);
- update.nodes[0].id = 1;
- update.nodes[0].role = ax::mojom::Role::kRadioGroup;
- update.nodes[0].child_ids = {2, 3, 4};
- update.nodes[1].id = 2;
- update.nodes[1].role =
- ax::mojom::Role::kRadioButton; // kRadioButton posinset = 2, setsize = 5.
- update.nodes[1].AddIntAttribute(ax::mojom::IntAttribute::kPosInSet, 2);
- update.nodes[2].id = 3;
- update.nodes[2].role =
- ax::mojom::Role::kRadioButton; // kRadioButton posinset = 3, setsize = 5.
- update.nodes[3].id = 4;
- update.nodes[3].role =
- ax::mojom::Role::kRadioButton; // kRadioButton posinset = 5, stesize = 5
- update.nodes[3].AddIntAttribute(ax::mojom::IntAttribute::kPosInSet, 5);
- Init(update);
-
- AXNode* radiobutton1 = GetRootAsAXNode()->children()[0];
- AtkObject* radiobutton1_atk_object(AtkObjectFromNode(radiobutton1));
- EXPECT_TRUE(ATK_IS_OBJECT(radiobutton1_atk_object));
-
- AXNode* radiobutton2 = GetRootAsAXNode()->children()[1];
- AtkObject* radiobutton2_atk_object(AtkObjectFromNode(radiobutton2));
- EXPECT_TRUE(ATK_IS_OBJECT(radiobutton2_atk_object));
-
- AXNode* radiobutton3 = GetRootAsAXNode()->children()[2];
- AtkObject* radiobutton3_atk_object(AtkObjectFromNode(radiobutton3));
- EXPECT_TRUE(ATK_IS_OBJECT(radiobutton3_atk_object));
-
- // Notice that setsize was never assigned to any of the kRadioButtons, but was
- // inferred.
- EnsureAtkObjectHasAttributeWithValue(radiobutton1_atk_object, "posinset",
- "2");
- EnsureAtkObjectHasAttributeWithValue(radiobutton1_atk_object, "setsize", "5");
- EnsureAtkObjectHasAttributeWithValue(radiobutton2_atk_object, "posinset",
- "3");
- EnsureAtkObjectHasAttributeWithValue(radiobutton2_atk_object, "setsize", "5");
- EnsureAtkObjectHasAttributeWithValue(radiobutton3_atk_object, "posinset",
- "5");
- EnsureAtkObjectHasAttributeWithValue(radiobutton3_atk_object, "setsize", "5");
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkRelations) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.AddIntListAttribute(ax::mojom::IntListAttribute::kDetailsIds, {2});
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kStaticText;
-
- root.child_ids.push_back(2);
-
- AXNodeData child2;
- child2.id = 3;
- child2.role = ax::mojom::Role::kStaticText;
- std::vector<int32_t> labelledby_ids = {1, 4};
- child2.AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
- labelledby_ids);
-
- root.child_ids.push_back(3);
-
- AXNodeData child3;
- child3.id = 4;
- child3.role = ax::mojom::Role::kStaticText;
- child3.AddIntListAttribute(ax::mojom::IntListAttribute::kDetailsIds, {2});
- child3.AddIntAttribute(ax::mojom::IntAttribute::kMemberOfId, 1);
-
- root.child_ids.push_back(4);
-
- Init(root, child1, child2, child3);
-
- // We don't test relations that are too new for the runtime version of ATK.
- GEnumClass* enum_class =
- G_ENUM_CLASS(g_type_class_ref(atk_relation_type_get_type()));
- int max_relation_type = enum_class->maximum;
- g_type_class_unref(enum_class);
-
- auto assert_contains_relation = [&](AtkObject* object, AtkObject* target,
- AtkRelationType relation) {
- if (relation > max_relation_type)
- return;
-
- AtkRelationSet* relations = atk_object_ref_relation_set(object);
- ASSERT_TRUE(atk_relation_set_contains(relations, relation));
- ASSERT_TRUE(atk_relation_set_contains_target(relations, relation, target));
- g_object_unref(G_OBJECT(relations));
- };
-
- AtkObject* root_atk_object(GetRootAtkObject());
- EXPECT_TRUE(ATK_IS_OBJECT(root_atk_object));
- g_object_ref(root_atk_object);
-
- AtkObject* atk_child1(AtkObjectFromNode(GetRootAsAXNode()->children()[0]));
- AtkObject* atk_child2(AtkObjectFromNode(GetRootAsAXNode()->children()[1]));
- AtkObject* atk_child3(AtkObjectFromNode(GetRootAsAXNode()->children()[2]));
-
- assert_contains_relation(root_atk_object, atk_child1, ATK_RELATION_DETAILS);
- assert_contains_relation(atk_child1, root_atk_object,
- ATK_RELATION_DETAILS_FOR);
- assert_contains_relation(atk_child3, atk_child1, ATK_RELATION_DETAILS);
- assert_contains_relation(atk_child1, atk_child3, ATK_RELATION_DETAILS_FOR);
-
- assert_contains_relation(atk_child2, root_atk_object,
- ATK_RELATION_LABELLED_BY);
- assert_contains_relation(root_atk_object, atk_child2, ATK_RELATION_LABEL_FOR);
- assert_contains_relation(atk_child2, atk_child3, ATK_RELATION_LABELLED_BY);
- assert_contains_relation(atk_child3, atk_child2, ATK_RELATION_LABEL_FOR);
-
- assert_contains_relation(atk_child3, root_atk_object, ATK_RELATION_MEMBER_OF);
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAllReverseAtkRelations) {
- // We don't test relations that are too new for the runtime version of ATK.
- GEnumClass* enum_class =
- G_ENUM_CLASS(g_type_class_ref(atk_relation_type_get_type()));
- int max_relation_type = enum_class->maximum;
- g_type_class_unref(enum_class);
-
- auto test_relation = [&](auto attribute_setter,
- AtkRelationType expected_relation,
- AtkRelationType expected_reverse_relation) {
- if (expected_relation > max_relation_type ||
- expected_reverse_relation > max_relation_type)
- return;
-
- AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- attribute_setter(&root_data, 2);
-
- AXNodeData child_data;
- child_data.id = 2;
- child_data.role = ax::mojom::Role::kStaticText;
- root_data.child_ids.push_back(2);
- Init(root_data, child_data);
-
- AtkObject* source(GetRootAtkObject());
- AtkObject* target(AtkObjectFromNode(GetRootAsAXNode()->children()[0]));
-
- AtkRelationSet* relations = atk_object_ref_relation_set(source);
- ASSERT_TRUE(atk_relation_set_contains(relations, expected_relation));
- ASSERT_TRUE(
- atk_relation_set_contains_target(relations, expected_relation, target));
- g_object_unref(G_OBJECT(relations));
-
- relations = atk_object_ref_relation_set(target);
- ASSERT_TRUE(
- atk_relation_set_contains(relations, expected_reverse_relation));
- ASSERT_TRUE(atk_relation_set_contains_target(
- relations, expected_reverse_relation, source));
- g_object_unref(G_OBJECT(relations));
- };
-
- auto test_int_relation = [&](ax::mojom::IntAttribute relation,
- AtkRelationType expected_relation,
- AtkRelationType expected_reverse_relation) {
- auto setter = [&](AXNodeData* data, int target_id) {
- data->AddIntAttribute(relation, target_id);
- };
- test_relation(setter, expected_relation, expected_reverse_relation);
- };
-
- auto test_int_list_relation = [&](ax::mojom::IntListAttribute relation,
- AtkRelationType expected_relation,
- AtkRelationType expected_reverse_relation) {
- auto setter = [&](AXNodeData* data, int target_id) {
- std::vector<int32_t> ids = {target_id};
- data->AddIntListAttribute(relation, ids);
- };
- test_relation(setter, expected_relation, expected_reverse_relation);
- };
-
- test_int_list_relation(ax::mojom::IntListAttribute::kDetailsIds,
- ATK_RELATION_DETAILS, ATK_RELATION_DETAILS_FOR);
- test_int_relation(ax::mojom::IntAttribute::kErrormessageId,
- ATK_RELATION_ERROR_MESSAGE, ATK_RELATION_ERROR_FOR);
- test_int_list_relation(ax::mojom::IntListAttribute::kControlsIds,
- ATK_RELATION_CONTROLLER_FOR,
- ATK_RELATION_CONTROLLED_BY);
- test_int_list_relation(ax::mojom::IntListAttribute::kDescribedbyIds,
- ATK_RELATION_DESCRIBED_BY,
- ATK_RELATION_DESCRIPTION_FOR);
- test_int_list_relation(ax::mojom::IntListAttribute::kFlowtoIds,
- ATK_RELATION_FLOWS_TO, ATK_RELATION_FLOWS_FROM);
- test_int_list_relation(ax::mojom::IntListAttribute::kLabelledbyIds,
- ATK_RELATION_LABELLED_BY, ATK_RELATION_LABEL_FOR);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkRelationsTargetIndex) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
-
- AXNodeData label1;
- label1.id = 2;
- label1.role = ax::mojom::Role::kStaticText;
- root.child_ids.push_back(2);
-
- AXNodeData label2;
- label2.id = 3;
- label2.role = ax::mojom::Role::kList;
- root.child_ids.push_back(3);
-
- AXNodeData label3;
- label3.id = 4;
- label3.role = ax::mojom::Role::kTable;
- root.child_ids.push_back(4);
-
- AXNodeData button1;
- button1.id = 5;
- button1.role = ax::mojom::Role::kButton;
- button1.AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
- {2, 3, 4});
- root.child_ids.push_back(5);
-
- AXNodeData button2;
- button2.id = 6;
- button2.role = ax::mojom::Role::kButton;
- button2.AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
- {4, 3, 2});
- root.child_ids.push_back(6);
-
- AXNodeData button3;
- button3.id = 7;
- button3.role = ax::mojom::Role::kButton;
- button3.AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
- {4, 4, 2, 2, 3});
- root.child_ids.push_back(7);
-
- Init(root, label1, label2, label3, button1, button2, button3);
-
- auto test_index = [&](AtkObject* source, AtkObject* target,
- AtkRelationType relation_type, int index) {
- AtkRelationSet* relation_set = atk_object_ref_relation_set(source);
- ASSERT_TRUE(atk_relation_set_contains(relation_set, relation_type));
-
- AtkRelation* relation =
- atk_relation_set_get_relation_by_type(relation_set, relation_type);
- GPtrArray* targets = atk_relation_get_target(relation);
- ASSERT_TRUE(ATK_IS_OBJECT(g_ptr_array_index(targets, index)));
- ASSERT_TRUE(ATK_OBJECT(g_ptr_array_index(targets, index)) == target);
-
- g_object_unref(G_OBJECT(relation_set));
- };
-
- AtkObject* root_atk_object(GetRootAtkObject());
- EXPECT_TRUE(ATK_IS_OBJECT(root_atk_object));
- g_object_ref(root_atk_object);
-
- AtkObject* atk_label1(AtkObjectFromNode(GetRootAsAXNode()->children()[0]));
- AtkObject* atk_label2(AtkObjectFromNode(GetRootAsAXNode()->children()[1]));
- AtkObject* atk_label3(AtkObjectFromNode(GetRootAsAXNode()->children()[2]));
- AtkObject* atk_button1(AtkObjectFromNode(GetRootAsAXNode()->children()[3]));
- AtkObject* atk_button2(AtkObjectFromNode(GetRootAsAXNode()->children()[4]));
- AtkObject* atk_button3(AtkObjectFromNode(GetRootAsAXNode()->children()[5]));
-
- test_index(atk_button1, atk_label1, ATK_RELATION_LABELLED_BY, 0);
- test_index(atk_button1, atk_label2, ATK_RELATION_LABELLED_BY, 1);
- test_index(atk_button1, atk_label3, ATK_RELATION_LABELLED_BY, 2);
-
- test_index(atk_button2, atk_label3, ATK_RELATION_LABELLED_BY, 0);
- test_index(atk_button2, atk_label2, ATK_RELATION_LABELLED_BY, 1);
- test_index(atk_button2, atk_label1, ATK_RELATION_LABELLED_BY, 2);
-
- test_index(atk_button3, atk_label3, ATK_RELATION_LABELLED_BY, 0);
- test_index(atk_button3, atk_label1, ATK_RELATION_LABELLED_BY, 1);
- test_index(atk_button3, atk_label2, ATK_RELATION_LABELLED_BY, 2);
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextTextFieldGetNSelectionsZero) {
- Init(BuildTextField());
- AtkObject* root_atk_object(GetRootAtkObject());
- g_object_ref(root_atk_object);
-
- AtkText* atk_text = ATK_TEXT(root_atk_object);
- ASSERT_NE(nullptr, atk_text);
- EXPECT_EQ(0, atk_text_get_n_selections(atk_text));
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest,
- TestAtkTextContentEditableGetNSelectionsZero) {
- Init(BuildContentEditable());
- AtkObject* root_atk_object(GetRootAtkObject());
- g_object_ref(root_atk_object);
-
- AtkText* atk_text = ATK_TEXT(root_atk_object);
- ASSERT_NE(nullptr, atk_text);
- EXPECT_EQ(0, atk_text_get_n_selections(atk_text));
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextContentEditableGetNSelections) {
- Init(BuildContentEditableWithSelectionRange(1, 2));
- AtkObject* root_atk_object(GetRootAtkObject());
- g_object_ref(root_atk_object);
-
- AtkText* atk_text = ATK_TEXT(root_atk_object);
- ASSERT_NE(nullptr, atk_text);
- EXPECT_EQ(1, atk_text_get_n_selections(atk_text));
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextTextFieldSetSelection) {
- Init(BuildTextField());
- AtkObject* root_atk_object(GetRootAtkObject());
- g_object_ref(root_atk_object);
-
- AtkText* atk_text = ATK_TEXT(root_atk_object);
- ASSERT_NE(nullptr, atk_text);
-
- bool saw_selection_change = false;
- g_signal_connect(
- atk_text, "text-selection-changed",
- G_CALLBACK(+[](AtkObject* atkobject, bool* flag) { *flag = true; }),
- &saw_selection_change);
-
- int selection_start, selection_end;
-
- EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 0, 1));
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
- EXPECT_TRUE(saw_selection_change);
- g_free(atk_text_get_selection(atk_text, 0, &selection_start, &selection_end));
- EXPECT_EQ(selection_start, 0);
- EXPECT_EQ(selection_end, 1);
-
- // Reset position.
- EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 0, 0));
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
-
- saw_selection_change = false;
- EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 1, 0));
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
- EXPECT_TRUE(saw_selection_change);
- g_free(atk_text_get_selection(atk_text, 0, &selection_start, &selection_end));
- EXPECT_EQ(selection_start, 0);
- EXPECT_EQ(selection_end, 1);
-
- saw_selection_change = false;
- EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 2, 4));
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
- EXPECT_TRUE(saw_selection_change);
- g_free(atk_text_get_selection(atk_text, 0, &selection_start, &selection_end));
- EXPECT_EQ(selection_start, 2);
- EXPECT_EQ(selection_end, 4);
-
- saw_selection_change = false;
- EXPECT_FALSE(atk_text_set_selection(atk_text, 1, 0, 0));
- EXPECT_FALSE(saw_selection_change);
- g_free(atk_text_get_selection(atk_text, 0, &selection_start, &selection_end));
- EXPECT_EQ(selection_start, 2);
- EXPECT_EQ(selection_end, 4);
-
- saw_selection_change = false;
- EXPECT_FALSE(atk_text_set_selection(atk_text, 0, 0, 50));
-
- saw_selection_change = false;
- int n_characters = atk_text_get_character_count(atk_text);
- EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 0, -1));
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
- EXPECT_TRUE(saw_selection_change);
- g_free(atk_text_get_selection(atk_text, 0, &selection_start, &selection_end));
- EXPECT_EQ(selection_start, 0);
- EXPECT_EQ(selection_end, n_characters);
-
- saw_selection_change = false;
- EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 0, 1));
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
- EXPECT_EQ(1, atk_text_get_n_selections(atk_text));
- EXPECT_TRUE(atk_text_remove_selection(atk_text, 0));
- EXPECT_TRUE(saw_selection_change);
- EXPECT_EQ(0, atk_text_get_n_selections(atk_text));
-
- // Reset position.
- EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 0, 0));
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
-
- saw_selection_change = false;
- EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 0, 1));
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kTextSelectionChanged);
- EXPECT_EQ(1, atk_text_get_n_selections(atk_text));
- EXPECT_FALSE(atk_text_remove_selection(atk_text, 1));
- EXPECT_TRUE(saw_selection_change);
- EXPECT_EQ(1, atk_text_get_n_selections(atk_text));
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextTextFieldGetSelection) {
- Init(BuildTextField());
- AtkObject* root_atk_object(GetRootAtkObject());
- g_object_ref(root_atk_object);
-
- AtkText* atk_text = ATK_TEXT(root_atk_object);
- ASSERT_NE(nullptr, atk_text);
-
- int selection_start = 0, selection_end = 0;
- EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 0, 3));
- gchar* selected_text =
- atk_text_get_selection(atk_text, 0, &selection_start, &selection_end);
- EXPECT_STREQ("How", selected_text);
- EXPECT_EQ(selection_start, 0);
- EXPECT_EQ(selection_end, 3);
- g_free(selected_text);
-
- selection_start = 0;
- selection_end = 0;
-
- EXPECT_TRUE(atk_text_remove_selection(atk_text, 0));
- selected_text =
- atk_text_get_selection(atk_text, 0, &selection_start, &selection_end);
- EXPECT_EQ(nullptr, selected_text);
- EXPECT_EQ(selection_start, 0);
- EXPECT_EQ(selection_end, 0);
-
- EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 0, 3));
-
- selected_text =
- atk_text_get_selection(atk_text, 1, &selection_start, &selection_end);
- EXPECT_EQ(nullptr, selected_text);
- EXPECT_EQ(selection_start, 0);
- EXPECT_EQ(selection_end, 0);
-
- selected_text =
- atk_text_get_selection(atk_text, -1, &selection_start, &selection_end);
- EXPECT_EQ(nullptr, selected_text);
- EXPECT_EQ(selection_start, 0);
- EXPECT_EQ(selection_end, 0);
-
- g_object_unref(root_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectExpandRebuildsPlatformNode) {
- AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kUnknown;
-
- Init(root_data);
-
- AtkObject* original_atk_object = GetRootAtkObject();
- ASSERT_TRUE(ATK_IS_OBJECT(original_atk_object));
- ASSERT_FALSE(ATK_IS_SELECTION(original_atk_object));
- g_object_ref(original_atk_object);
-
- root_data = AXNodeData();
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kListBox;
- GetRootAsAXNode()->SetData(root_data);
-
- ASSERT_EQ(original_atk_object, GetRootAtkObject());
-
- GetRootPlatformNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kExpandedChanged);
-
- AtkObject* new_atk_object = GetRootAtkObject();
- ASSERT_NE(original_atk_object, new_atk_object);
- ASSERT_TRUE(ATK_IS_SELECTION(new_atk_object));
-
- g_object_unref(original_atk_object);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectParentChanged) {
- AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kListBox;
- root_data.child_ids.push_back(2);
-
- AXNodeData item_1_data;
- item_1_data.id = 2;
- item_1_data.role = ax::mojom::Role::kListBoxOption;
-
- Init(root_data, item_1_data);
-
- AXNode* item_1 = GetRootAsAXNode()->children()[0];
- AtkObject* atk_object = AtkObjectFromNode(item_1);
- AXPlatformNodeAuraLinux* node = GetPlatformNode(item_1);
-
- bool saw_parent_changed = false;
- g_signal_connect(
- atk_object, "property-change::accessible-parent",
- G_CALLBACK(+[](AtkObject*, void* property, bool* saw_parent_changed) {
- *saw_parent_changed = true;
- }),
- &saw_parent_changed);
-
- ASSERT_FALSE(saw_parent_changed);
- node->OnParentChanged();
- ASSERT_TRUE(saw_parent_changed);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestScrolledToAnchorEvent) {
- AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kListBox;
- root_data.child_ids.push_back(2);
-
- AXNodeData item_1_data;
- item_1_data.id = 2;
- item_1_data.role = ax::mojom::Role::kListBoxOption;
-
- Init(root_data, item_1_data);
-
- AXNode* item_1 = GetRootAsAXNode()->children()[0];
- AtkObject* atk_object = AtkObjectFromNode(item_1);
-
- bool saw_caret_moved = false;
- g_signal_connect(
- atk_object, "text-caret-moved",
- G_CALLBACK(+[](AtkObject*, int position, bool* saw_caret_moved) {
- *saw_caret_moved = true;
- }),
- &saw_caret_moved);
-
- GetPlatformNode(item_1)->OnScrolledToAnchor();
-
- ASSERT_TRUE(saw_caret_moved);
-}
-
-TEST_F(AXPlatformNodeAuraLinuxTest, TestDialogActiveWhenChildFocused) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kWindow;
- root.child_ids.push_back(2);
- root.child_ids.push_back(3);
-
- AXNodeData dialog;
- dialog.id = 2;
- dialog.role = ax::mojom::Role::kDialog;
- dialog.child_ids.push_back(4);
-
- AXNodeData node_outside_dialog;
- node_outside_dialog.id = 3;
- node_outside_dialog.role = ax::mojom::Role::kTextField;
-
- AXNodeData entry;
- entry.id = 4;
- entry.role = ax::mojom::Role::kTextField;
-
- Init(root, dialog, node_outside_dialog, entry);
-
- AtkObject* root_atk_object(GetRootAtkObject());
- EXPECT_TRUE(ATK_IS_OBJECT(root_atk_object));
-
- AXNode* dialog_node = GetRootAsAXNode()->children()[0];
- AtkObject* dialog_obj = AtkObjectFromNode(dialog_node);
- bool saw_active_state_change = false;
- g_signal_connect(dialog_obj, "state-change",
- G_CALLBACK(+[](AtkObject* atkobject, gchar* state_changed,
- gboolean new_value, bool* flag) {
- if (!g_strcmp0(state_changed, "active"))
- *flag = true;
- }),
- &saw_active_state_change);
-
- AXNode* entry_node = dialog_node->children()[0];
- GetPlatformNode(entry_node)
- ->NotifyAccessibilityEvent(ax::mojom::Event::kFocus);
- EXPECT_TRUE(saw_active_state_change);
- EXPECT_TRUE(AtkObjectHasState(dialog_obj, ATK_STATE_ACTIVE));
-
- saw_active_state_change = false;
-
- AXNode* outside_node = GetRootAsAXNode()->children()[1];
- GetPlatformNode(outside_node)
- ->NotifyAccessibilityEvent(ax::mojom::Event::kFocus);
- EXPECT_TRUE(saw_active_state_change);
- EXPECT_FALSE(AtkObjectHasState(dialog_obj, ATK_STATE_ACTIVE));
-}
-
-// Tests if kActiveDescendantChanged on unfocused node triggers a focused event.
-TEST_F(AXPlatformNodeAuraLinuxTest,
- TestActiveDescendantChangedOnUnfocusedNode) {
- AXNodeData menu;
- menu.id = 1;
- menu.role = ax::mojom::Role::kMenu;
- menu.AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId, 4);
- menu.child_ids = {2, 3};
-
- AXNodeData input;
- input.id = 2;
- input.role = ax::mojom::Role::kTextField;
- input.AddState(ax::mojom::State::kFocusable);
- input.AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId, 4);
-
- AXNodeData container;
- container.id = 3;
- container.role = ax::mojom::Role::kGenericContainer;
- container.child_ids = {4, 5};
-
- AXNodeData menu_item_1;
- menu_item_1.id = 4;
- menu_item_1.role = ax::mojom::Role::kMenuItemCheckBox;
-
- AXNodeData menu_item_2;
- menu_item_2.id = 5;
- menu_item_2.role = ax::mojom::Role::kMenuItemCheckBox;
-
- Init(menu, input, container, menu_item_1, menu_item_2);
- TestAXNodeWrapper::SetGlobalIsWebContent(true);
-
- // Creates TestAXNodeWrapper for the first menu item to keep the current
- // active descendant.
- AtkObjectFromNode(GetRootAsAXNode()->children()[1]->children()[0]);
-
- // Sets focus to the input node.
- AXNode* input_node = GetRootAsAXNode()->children()[0];
- GetPlatformNode(input_node)
- ->NotifyAccessibilityEvent(ax::mojom::Event::kFocus);
-
- bool saw_active_focus_state_change = false;
- AtkObject* menu_2_atk_object =
- AtkObjectFromNode(GetRootAsAXNode()->children()[1]->children()[1]);
- EXPECT_TRUE(ATK_IS_OBJECT(menu_2_atk_object));
- g_object_ref(menu_2_atk_object);
- // Registers callback to get focus event on |menu_2_atk_object|.
- g_signal_connect(menu_2_atk_object, "state-change",
- G_CALLBACK(+[](AtkObject* atkobject, gchar* state_changed,
- gboolean new_value, bool* flag) {
- if (!g_strcmp0(state_changed, "focused") && new_value)
- *flag = true;
- }),
- &saw_active_focus_state_change);
-
- // Updates the active descendant node from the node id 4 to the node id 5;
- AXNode* menu_node = GetRootAsAXNode();
- AXNodeData menu_new_data(menu);
- menu_new_data.AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
- 5);
- menu_node->SetData(menu_new_data);
-
- AXNodeData input_new_data(input);
- input_new_data.AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
- 5);
- input_node->SetData(input_new_data);
-
- // Notifies active descendant is changed.
- GetPlatformNode(menu_node)->NotifyAccessibilityEvent(
- ax::mojom::Event::kActiveDescendantChanged);
- // The current active descendant node, |menu_2_atk_object|, should get the
- // focused event.
- EXPECT_TRUE(saw_active_focus_state_change);
-
- TestAXNodeWrapper::SetGlobalIsWebContent(false);
- g_object_unref(menu_2_atk_object);
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_base.cc b/third_party/accessibility/ax/platform/ax_platform_node_base.cc
index 9d499d3..43a8202 100644
--- a/third_party/accessibility/ax/platform/ax_platform_node_base.cc
+++ b/third_party/accessibility/ax/platform/ax_platform_node_base.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/platform/ax_platform_node_base.h"
+#include "ax_platform_node_base.h"
#include <algorithm>
#include <iomanip>
@@ -14,28 +14,21 @@
#include <utility>
#include <vector>
-#include "base/no_destructor.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_tree_data.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-#include "ui/accessibility/platform/compute_attributes.h"
-#include "ui/gfx/geometry/rect_conversions.h"
+#include "ax/ax_action_data.h"
+#include "ax/ax_enums.h"
+#include "ax/ax_node_data.h"
+#include "ax/ax_role_properties.h"
+#include "ax/ax_tree_data.h"
+#include "ax_platform_node_delegate.h"
+#include "base/color_utils.h"
+#include "base/string_utils.h"
+#include "compute_attributes.h"
+#include "gfx/geometry/rect_conversions.h"
namespace ui {
namespace {
-// A function to call when focus changes, for testing only.
-base::LazyInstance<std::map<ax::mojom::Event, base::RepeatingClosure>>::
- DestructorAtExit g_on_notify_event_for_testing;
-
// Check for descendant comment, using limited depth first search.
bool FindDescendantRoleWithMaxDepth(AXPlatformNodeBase* node,
ax::mojom::Role descendant_role,
@@ -63,44 +56,21 @@
} // namespace
-const base::char16 AXPlatformNodeBase::kEmbeddedCharacter = L'\xfffc';
+const char16_t AXPlatformNodeBase::kEmbeddedCharacter = L'\xfffc';
// Map from each AXPlatformNode's unique id to its instance.
using UniqueIdMap = std::unordered_map<int32_t, AXPlatformNode*>;
-base::LazyInstance<UniqueIdMap>::Leaky g_unique_id_map =
- LAZY_INSTANCE_INITIALIZER;
-
-#if !BUILDFLAG_INTERNAL_HAS_NATIVE_ACCESSIBILITY()
-// static
-AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) {
- AXPlatformNodeBase* node = new AXPlatformNodeBase();
- node->Init(delegate);
- return node;
-}
-#endif
+UniqueIdMap g_unique_id_map;
// static
AXPlatformNode* AXPlatformNodeBase::GetFromUniqueId(int32_t unique_id) {
- UniqueIdMap* unique_ids = g_unique_id_map.Pointer();
- auto iter = unique_ids->find(unique_id);
- if (iter != unique_ids->end())
+ auto iter = g_unique_id_map.find(unique_id);
+ if (iter != g_unique_id_map.end())
return iter->second;
return nullptr;
}
-// static
-size_t AXPlatformNodeBase::GetInstanceCountForTesting() {
- return g_unique_id_map.Get().size();
-}
-
-// static
-void AXPlatformNodeBase::SetOnNotifyEventCallbackForTesting(
- ax::mojom::Event event_type,
- base::RepeatingClosure callback) {
- g_on_notify_event_for_testing.Get()[event_type] = std::move(callback);
-}
-
AXPlatformNodeBase::AXPlatformNodeBase() = default;
AXPlatformNodeBase::~AXPlatformNodeBase() = default;
@@ -109,7 +79,7 @@
delegate_ = delegate;
// This must be called after assigning our delegate.
- g_unique_id_map.Get()[GetUniqueId()] = this;
+ g_unique_id_map[GetUniqueId()] = this;
}
const AXNodeData& AXPlatformNodeBase::GetData() const {
@@ -149,23 +119,23 @@
return std::string();
}
-base::string16 AXPlatformNodeBase::GetNameAsString16() const {
+std::u16string AXPlatformNodeBase::GetNameAsString16() const {
std::string name = GetName();
if (name.empty())
- return base::string16();
+ return std::u16string();
return base::UTF8ToUTF16(name);
}
-base::Optional<int> AXPlatformNodeBase::GetIndexInParent() {
+std::optional<int> AXPlatformNodeBase::GetIndexInParent() {
AXPlatformNodeBase* parent = FromNativeViewAccessible(GetParent());
if (!parent)
- return base::nullopt;
+ return std::nullopt;
int child_count = parent->GetChildCount();
if (child_count == 0) {
// |child_count| could be 0 if the parent is IsLeaf.
- DCHECK(parent->IsLeaf());
- return base::nullopt;
+ BASE_DCHECK(parent->IsLeaf());
+ return std::nullopt;
}
// Ask the delegate for the index in parent, and return it if it's plausible.
@@ -187,15 +157,16 @@
// If the parent has a modal dialog, it doesn't count other children.
if (parent->delegate_ && parent->delegate_->HasModalDialog())
- return base::nullopt;
+ return std::nullopt;
- NOTREACHED()
+ BASE_LOG()
<< "Unable to find the child in the list of its parent's children.";
- return base::nullopt;
+ BASE_UNREACHABLE();
+ return std::nullopt;
}
-base::stack<gfx::NativeViewAccessible> AXPlatformNodeBase::GetAncestors() {
- base::stack<gfx::NativeViewAccessible> ancestors;
+std::stack<gfx::NativeViewAccessible> AXPlatformNodeBase::GetAncestors() {
+ std::stack<gfx::NativeViewAccessible> ancestors;
gfx::NativeViewAccessible current_node = GetNativeViewAccessible();
while (current_node) {
ancestors.push(current_node);
@@ -205,7 +176,7 @@
return ancestors;
}
-base::Optional<int> AXPlatformNodeBase::CompareTo(AXPlatformNodeBase& other) {
+std::optional<int> AXPlatformNodeBase::CompareTo(AXPlatformNodeBase& other) {
// We define two node's relative positions in the following way:
// 1. this->CompareTo(other) == 0:
// - |this| and |other| are the same node.
@@ -227,15 +198,15 @@
// be before (logically less) the node we visit later.
if (this == &other)
- return base::Optional<int>(0);
+ return std::optional<int>(0);
// Compute the ancestor stacks of both positions and traverse them from the
// top most ancestor down, so we can discover the first uncommon ancestors.
// The first uncommon ancestor is the immediate child of the lowest common
// ancestor.
gfx::NativeViewAccessible common_ancestor = nullptr;
- base::stack<gfx::NativeViewAccessible> our_ancestors = GetAncestors();
- base::stack<gfx::NativeViewAccessible> other_ancestors = other.GetAncestors();
+ std::stack<gfx::NativeViewAccessible> our_ancestors = GetAncestors();
+ std::stack<gfx::NativeViewAccessible> other_ancestors = other.GetAncestors();
// Start at the root and traverse down. Keep going until the |this|'s ancestor
// chain and |other|'s ancestor chain disagree. The last node before they
@@ -249,44 +220,47 @@
// Nodes do not have a common ancestor, they are not comparable.
if (!common_ancestor)
- return base::nullopt;
+ return std::nullopt;
// Compute the logical order when the common ancestor is |this| or |other|.
auto* common_ancestor_platform_node =
FromNativeViewAccessible(common_ancestor);
if (common_ancestor_platform_node == this)
- return base::Optional<int>(-1);
+ return std::optional<int>(-1);
if (common_ancestor_platform_node == &other)
- return base::Optional<int>(1);
+ return std::optional<int>(1);
// Compute the logical order of |this| and |other| by using their first
// uncommon ancestors.
if (!our_ancestors.empty() && !other_ancestors.empty()) {
- base::Optional<int> this_index_in_parent =
+ std::optional<int> this_index_in_parent =
FromNativeViewAccessible(our_ancestors.top())->GetIndexInParent();
- base::Optional<int> other_index_in_parent =
+ std::optional<int> other_index_in_parent =
FromNativeViewAccessible(other_ancestors.top())->GetIndexInParent();
if (!this_index_in_parent || !other_index_in_parent)
- return base::nullopt;
+ return std::nullopt;
int this_uncommon_ancestor_index = this_index_in_parent.value();
int other_uncommon_ancestor_index = other_index_in_parent.value();
- DCHECK_NE(this_uncommon_ancestor_index, other_uncommon_ancestor_index)
- << "Deepest uncommon ancestors should truly be uncommon, i.e. not "
- "the same.";
+ if (this_uncommon_ancestor_index == other_uncommon_ancestor_index) {
+ BASE_LOG()
+ << "Deepest uncommon ancestors should truly be uncommon, i.e. not "
+ "the same.";
+ BASE_UNREACHABLE();
+ }
- return base::Optional<int>(this_uncommon_ancestor_index -
- other_uncommon_ancestor_index);
+ return std::optional<int>(this_uncommon_ancestor_index -
+ other_uncommon_ancestor_index);
}
- return base::nullopt;
+ return std::nullopt;
}
// AXPlatformNode overrides.
void AXPlatformNodeBase::Destroy() {
- g_unique_id_map.Get().erase(GetUniqueId());
+ g_unique_id_map.erase(GetUniqueId());
AXPlatformNode::Destroy();
@@ -303,15 +277,10 @@
}
void AXPlatformNodeBase::NotifyAccessibilityEvent(ax::mojom::Event event_type) {
- if (g_on_notify_event_for_testing.Get().find(event_type) !=
- g_on_notify_event_for_testing.Get().end() &&
- g_on_notify_event_for_testing.Get()[event_type]) {
- g_on_notify_event_for_testing.Get()[event_type].Run();
- }
}
#if defined(OS_APPLE)
-void AXPlatformNodeBase::AnnounceText(const base::string16& text) {}
+void AXPlatformNodeBase::AnnounceText(const std::u16string& text) {}
#endif
AXPlatformNodeDelegate* AXPlatformNodeBase::GetDelegate() const {
@@ -466,16 +435,16 @@
return GetData().GetStringAttribute(attribute, value);
}
-base::string16 AXPlatformNodeBase::GetString16Attribute(
+std::u16string AXPlatformNodeBase::GetString16Attribute(
ax::mojom::StringAttribute attribute) const {
if (!delegate_)
- return base::string16();
+ return std::u16string();
return GetData().GetString16Attribute(attribute);
}
bool AXPlatformNodeBase::GetString16Attribute(
ax::mojom::StringAttribute attribute,
- base::string16* value) const {
+ std::u16string* value) const {
if (!delegate_)
return false;
return GetData().GetString16Attribute(attribute, value);
@@ -505,9 +474,8 @@
const AXPlatformNodeBase* current_node = this;
do {
- if (!current_node->delegate_) {
+ if (!current_node->delegate_)
return base::EmptyString();
- }
if (current_node->GetData().HasStringAttribute(attribute)) {
return current_node->GetData().GetStringAttribute(attribute);
@@ -519,7 +487,7 @@
return base::EmptyString();
}
-base::string16 AXPlatformNodeBase::GetInheritedString16Attribute(
+std::u16string AXPlatformNodeBase::GetInheritedString16Attribute(
ax::mojom::StringAttribute attribute) const {
return base::UTF8ToUTF16(GetInheritedStringAttribute(attribute));
}
@@ -546,7 +514,7 @@
bool AXPlatformNodeBase::GetInheritedString16Attribute(
ax::mojom::StringAttribute attribute,
- base::string16* value) const {
+ std::u16string* value) const {
std::string value_utf8;
if (!GetInheritedStringAttribute(attribute, &value_utf8))
return false;
@@ -655,9 +623,9 @@
return delegate_ && delegate_->IsText();
}
-base::string16 AXPlatformNodeBase::GetHypertext() const {
+std::u16string AXPlatformNodeBase::GetHypertext() const {
if (!delegate_)
- return base::string16();
+ return std::u16string();
// Hypertext of platform leaves, which internally are composite objects, are
// represented with the inner text of the internal composite object. These
@@ -670,15 +638,15 @@
return hypertext_.hypertext;
}
-base::string16 AXPlatformNodeBase::GetInnerText() const {
+std::u16string AXPlatformNodeBase::GetInnerText() const {
if (!delegate_)
- return base::string16();
+ return std::u16string();
return delegate_->GetInnerText();
}
-base::string16 AXPlatformNodeBase::GetRangeValueText() const {
+std::u16string AXPlatformNodeBase::GetRangeValueText() const {
float fval;
- base::string16 value =
+ std::u16string value =
GetString16Attribute(ax::mojom::StringAttribute::kValue);
if (value.empty() &&
@@ -688,7 +656,7 @@
return value;
}
-base::string16
+std::u16string
AXPlatformNodeBase::GetRoleDescriptionFromImageAnnotationStatusOrFromAttribute()
const {
if (GetData().role == ax::mojom::Role::kImage &&
@@ -702,8 +670,8 @@
return GetString16Attribute(ax::mojom::StringAttribute::kRoleDescription);
}
-base::string16 AXPlatformNodeBase::GetRoleDescription() const {
- base::string16 role_description =
+std::u16string AXPlatformNodeBase::GetRoleDescription() const {
+ std::u16string role_description =
GetRoleDescriptionFromImageAnnotationStatusOrFromAttribute();
if (!role_description.empty()) {
@@ -748,7 +716,7 @@
if (!table)
return nullptr;
- DCHECK(table->delegate_);
+ BASE_DCHECK(table->delegate_);
return static_cast<AXPlatformNodeBase*>(table->delegate_->GetTableCaption());
}
@@ -762,8 +730,8 @@
if (!table)
return nullptr;
- DCHECK(table->delegate_);
- base::Optional<int32_t> cell_id = table->delegate_->CellIndexToId(index);
+ BASE_DCHECK(table->delegate_);
+ std::optional<int32_t> cell_id = table->delegate_->CellIndexToId(index);
if (!cell_id)
return nullptr;
@@ -785,8 +753,8 @@
return nullptr;
}
- DCHECK(table->delegate_);
- base::Optional<int32_t> cell_id = table->delegate_->GetCellId(row, column);
+ BASE_DCHECK(table->delegate_);
+ std::optional<int32_t> cell_id = table->delegate_->GetCellId(row, column);
if (!cell_id)
return nullptr;
@@ -794,89 +762,89 @@
table->delegate_->GetFromNodeID(*cell_id));
}
-base::Optional<int> AXPlatformNodeBase::GetTableCellIndex() const {
+std::optional<int> AXPlatformNodeBase::GetTableCellIndex() const {
if (!delegate_)
- return base::nullopt;
+ return std::nullopt;
return delegate_->GetTableCellIndex();
}
-base::Optional<int> AXPlatformNodeBase::GetTableColumn() const {
+std::optional<int> AXPlatformNodeBase::GetTableColumn() const {
if (!delegate_)
- return base::nullopt;
+ return std::nullopt;
return delegate_->GetTableCellColIndex();
}
-base::Optional<int> AXPlatformNodeBase::GetTableColumnCount() const {
+std::optional<int> AXPlatformNodeBase::GetTableColumnCount() const {
if (!delegate_)
- return base::nullopt;
+ return std::nullopt;
AXPlatformNodeBase* table = GetTable();
if (!table)
- return base::nullopt;
+ return std::nullopt;
- DCHECK(table->delegate_);
+ BASE_DCHECK(table->delegate_);
return table->delegate_->GetTableColCount();
}
-base::Optional<int> AXPlatformNodeBase::GetTableAriaColumnCount() const {
+std::optional<int> AXPlatformNodeBase::GetTableAriaColumnCount() const {
if (!delegate_)
- return base::nullopt;
+ return std::nullopt;
AXPlatformNodeBase* table = GetTable();
if (!table)
- return base::nullopt;
+ return std::nullopt;
- DCHECK(table->delegate_);
+ BASE_DCHECK(table->delegate_);
return table->delegate_->GetTableAriaColCount();
}
-base::Optional<int> AXPlatformNodeBase::GetTableColumnSpan() const {
+std::optional<int> AXPlatformNodeBase::GetTableColumnSpan() const {
if (!delegate_)
- return base::nullopt;
+ return std::nullopt;
return delegate_->GetTableCellColSpan();
}
-base::Optional<int> AXPlatformNodeBase::GetTableRow() const {
+std::optional<int> AXPlatformNodeBase::GetTableRow() const {
if (!delegate_)
- return base::nullopt;
+ return std::nullopt;
if (delegate_->IsTableRow())
return delegate_->GetTableRowRowIndex();
if (delegate_->IsTableCellOrHeader())
return delegate_->GetTableCellRowIndex();
- return base::nullopt;
+ return std::nullopt;
}
-base::Optional<int> AXPlatformNodeBase::GetTableRowCount() const {
+std::optional<int> AXPlatformNodeBase::GetTableRowCount() const {
if (!delegate_)
- return base::nullopt;
+ return std::nullopt;
AXPlatformNodeBase* table = GetTable();
if (!table)
- return base::nullopt;
+ return std::nullopt;
- DCHECK(table->delegate_);
+ BASE_DCHECK(table->delegate_);
return table->delegate_->GetTableRowCount();
}
-base::Optional<int> AXPlatformNodeBase::GetTableAriaRowCount() const {
+std::optional<int> AXPlatformNodeBase::GetTableAriaRowCount() const {
if (!delegate_)
- return base::nullopt;
+ return std::nullopt;
AXPlatformNodeBase* table = GetTable();
if (!table)
- return base::nullopt;
+ return std::nullopt;
- DCHECK(table->delegate_);
+ BASE_DCHECK(table->delegate_);
return table->delegate_->GetTableAriaRowCount();
}
-base::Optional<int> AXPlatformNodeBase::GetTableRowSpan() const {
+std::optional<int> AXPlatformNodeBase::GetTableRowSpan() const {
if (!delegate_)
- return base::nullopt;
+ return std::nullopt;
return delegate_->GetTableCellRowSpan();
}
-base::Optional<float> AXPlatformNodeBase::GetFontSizeInPoints() const {
+std::optional<float> AXPlatformNodeBase::GetFontSizeInPoints() const {
float font_size;
// Attribute has no default value.
if (GetFloatAttribute(ax::mojom::FloatAttribute::kFontSize, &font_size)) {
@@ -890,7 +858,7 @@
points = std::round(points * 2.0) / 2.0;
return points;
}
- return base::nullopt;
+ return std::nullopt;
}
bool AXPlatformNodeBase::HasCaret(
@@ -942,26 +910,22 @@
}
bool AXPlatformNodeBase::IsHorizontallyScrollable() const {
- DCHECK_GE(GetIntAttribute(ax::mojom::IntAttribute::kScrollXMin), 0)
- << "Pixel sizes should be non-negative.";
- DCHECK_GE(GetIntAttribute(ax::mojom::IntAttribute::kScrollXMax), 0)
- << "Pixel sizes should be non-negative.";
+ BASE_DCHECK(GetIntAttribute(ax::mojom::IntAttribute::kScrollXMin) >= 0);
+ BASE_DCHECK(GetIntAttribute(ax::mojom::IntAttribute::kScrollXMax) >= 0);
return IsScrollable() &&
GetIntAttribute(ax::mojom::IntAttribute::kScrollXMin) <
GetIntAttribute(ax::mojom::IntAttribute::kScrollXMax);
}
bool AXPlatformNodeBase::IsVerticallyScrollable() const {
- DCHECK_GE(GetIntAttribute(ax::mojom::IntAttribute::kScrollYMin), 0)
- << "Pixel sizes should be non-negative.";
- DCHECK_GE(GetIntAttribute(ax::mojom::IntAttribute::kScrollYMax), 0)
- << "Pixel sizes should be non-negative.";
+ BASE_DCHECK(GetIntAttribute(ax::mojom::IntAttribute::kScrollYMin) >= 0);
+ BASE_DCHECK(GetIntAttribute(ax::mojom::IntAttribute::kScrollYMax) >= 0);
return IsScrollable() &&
GetIntAttribute(ax::mojom::IntAttribute::kScrollYMin) <
GetIntAttribute(ax::mojom::IntAttribute::kScrollYMax);
}
-base::string16 AXPlatformNodeBase::GetValue() const {
+std::u16string AXPlatformNodeBase::GetValue() const {
// Expose slider value.
if (GetData().IsRangeValueSupported())
return GetRangeValueText();
@@ -970,7 +934,7 @@
if (ui::IsDocument(GetData().role))
return base::UTF8ToUTF16(delegate_->GetTreeData().url);
- base::string16 value =
+ std::u16string value =
GetString16Attribute(ax::mojom::StringAttribute::kValue);
// Some screen readers like Jaws and VoiceOver require a
@@ -983,8 +947,7 @@
}
void AXPlatformNodeBase::ComputeAttributes(PlatformAttributeList* attributes) {
- DCHECK(delegate_) << "Many attributes need to be retrieved from our "
- "AXPlatformNodeDelegate.";
+ BASE_DCHECK(delegate_);
// Expose some HTML and ARIA attributes in the IAccessible2 attributes string
// "display", "tag", and "xml-roles" have somewhat unusual names for
// historical reasons. Aside from that virtually every ARIA attribute
@@ -1005,7 +968,7 @@
AddAttributeToList("autocomplete", "list", attributes);
}
- base::string16 role_description =
+ std::u16string role_description =
GetRoleDescriptionFromImageAnnotationStatusOrFromAttribute();
if (!role_description.empty() ||
HasStringAttribute(ax::mojom::StringAttribute::kRoleDescription)) {
@@ -1120,7 +1083,7 @@
// Expose table cell index.
if (IsCellOrTableHeader(GetData().role)) {
- base::Optional<int> index = delegate_->GetTableCellIndex();
+ std::optional<int> index = delegate_->GetTableCellIndex();
if (index) {
std::string str_index(base::NumberToString(*index));
AddAttributeToList("table-cell-index", str_index, attributes);
@@ -1290,15 +1253,6 @@
if (IsTextField())
AddAttributeToList("text-model", "a1", attributes);
- // Expose input-text type attribute.
- std::string type;
- std::string html_tag =
- GetStringAttribute(ax::mojom::StringAttribute::kHtmlTag);
- if (IsPlainTextField() && base::LowerCaseEqualsASCII(html_tag, "input") &&
- GetData().GetHtmlAttribute("type", &type)) {
- AddAttributeToList("text-input-type", type, attributes);
- }
-
std::string details_roles = ComputeDetailsRoles();
if (!details_roles.empty())
AddAttributeToList("details-roles", details_roles, attributes);
@@ -1308,7 +1262,7 @@
const ax::mojom::StringAttribute attribute,
const char* name,
PlatformAttributeList* attributes) {
- DCHECK(attributes);
+ BASE_DCHECK(attributes);
std::string value;
if (GetStringAttribute(attribute, &value)) {
AddAttributeToList(name, value, attributes);
@@ -1319,7 +1273,7 @@
const ax::mojom::BoolAttribute attribute,
const char* name,
PlatformAttributeList* attributes) {
- DCHECK(attributes);
+ BASE_DCHECK(attributes);
bool value;
if (GetBoolAttribute(attribute, &value)) {
AddAttributeToList(name, value ? "true" : "false", attributes);
@@ -1330,7 +1284,7 @@
const ax::mojom::IntAttribute attribute,
const char* name,
PlatformAttributeList* attributes) {
- DCHECK(attributes);
+ BASE_DCHECK(attributes);
auto maybe_value = ComputeAttribute(delegate_, attribute);
if (maybe_value.has_value()) {
@@ -1366,7 +1320,7 @@
// embedded object character for all the other children. Build up a map from
// the character index of each embedded object character to the id of the
// child object it points to.
- base::string16 hypertext;
+ std::u16string hypertext;
for (AXPlatformNodeChildIterator child_iter = AXPlatformNodeChildrenBegin();
child_iter != AXPlatformNodeChildrenEnd(); ++child_iter) {
// Similar to Firefox, we don't expose text-only objects in IA2 and ATK
@@ -1392,15 +1346,15 @@
PlatformAttributeList* attributes) {
}
-base::Optional<int> AXPlatformNodeBase::GetPosInSet() const {
+std::optional<int> AXPlatformNodeBase::GetPosInSet() const {
if (!delegate_)
- return base::nullopt;
+ return std::nullopt;
return delegate_->GetPosInSet();
}
-base::Optional<int> AXPlatformNodeBase::GetSetSize() const {
+std::optional<int> AXPlatformNodeBase::GetSetSize() const {
if (!delegate_)
- return base::nullopt;
+ return std::nullopt;
return delegate_->GetSetSize();
}
@@ -1449,7 +1403,7 @@
// static
void AXPlatformNodeBase::SanitizeStringAttribute(const std::string& input,
std::string* output) {
- DCHECK(output);
+ BASE_DCHECK(output);
// According to the IA2 spec and AT-SPI2, these characters need to be escaped
// with a backslash: backslash, colon, comma, equals and semicolon. Note
// that backslash must be replaced first.
@@ -1468,8 +1422,8 @@
return nullptr;
int32_t index = iterator->second;
- DCHECK_GE(index, 0);
- DCHECK_LT(index, static_cast<int32_t>(hypertext_.hyperlinks.size()));
+ BASE_DCHECK(index >= 0);
+ BASE_DCHECK(index < static_cast<int32_t>(hypertext_.hyperlinks.size()));
int32_t id = hypertext_.hyperlinks[index];
auto* hyperlink =
static_cast<AXPlatformNodeBase*>(AXPlatformNodeBase::GetFromUniqueId(id));
@@ -1502,7 +1456,7 @@
int32_t AXPlatformNodeBase::GetHypertextOffsetFromChild(
AXPlatformNodeBase* child) {
- // TODO(dougt) DCHECK(child.owner()->PlatformGetParent() == owner());
+ // TODO(dougt) BASE_DCHECK(child.owner()->PlatformGetParent() == owner());
if (IsLeaf())
return -1;
@@ -1569,12 +1523,12 @@
// IsDescendantOf includes the case when endpoint_object == this.
if (IsDescendantOf(endpoint_object)) {
if (endpoint_object->IsLeaf()) {
- DCHECK_EQ(endpoint_object, this) << "Text objects cannot have children.";
+ BASE_DCHECK(endpoint_object == this);
return endpoint_offset;
} else {
- DCHECK_GE(endpoint_offset, 0);
- DCHECK_LE(endpoint_offset,
- endpoint_object->GetDelegate()->GetChildCount());
+ BASE_DCHECK(endpoint_offset >= 0);
+ BASE_DCHECK(endpoint_offset <=
+ endpoint_object->GetDelegate()->GetChildCount());
// Adjust the |endpoint_offset| because the selection endpoint is a tree
// position, i.e. it represents a child index and not a text offset.
@@ -1583,14 +1537,14 @@
} else {
auto* child = static_cast<AXPlatformNodeBase*>(FromNativeViewAccessible(
endpoint_object->ChildAtIndex(endpoint_offset)));
- DCHECK(child);
+ BASE_DCHECK(child);
return endpoint_object->GetHypertextOffsetFromChild(child);
}
}
}
AXPlatformNodeBase* common_parent = this;
- base::Optional<int> index_in_common_parent = GetIndexInParent();
+ std::optional<int> index_in_common_parent = GetIndexInParent();
while (common_parent && !endpoint_object->IsDescendantOf(common_parent)) {
index_in_common_parent = common_parent->GetIndexInParent();
common_parent = static_cast<AXPlatformNodeBase*>(
@@ -1599,7 +1553,7 @@
if (!common_parent)
return -1;
- DCHECK(!(common_parent->IsText()));
+ BASE_DCHECK(!(common_parent->IsText()));
// Case 2. Is the selection endpoint inside a descendant of this object?
//
@@ -1626,7 +1580,7 @@
//
// We can safely assume that the endpoint is in another part of the tree or
// at common parent, and that this object is a descendant of common parent.
- base::Optional<int> endpoint_index_in_common_parent;
+ std::optional<int> endpoint_index_in_common_parent;
for (auto child_iter = common_parent->AXPlatformNodeChildrenBegin();
child_iter != common_parent->AXPlatformNodeChildrenEnd(); ++child_iter) {
if (endpoint_object->IsDescendantOf(child_iter.get())) {
@@ -1640,12 +1594,12 @@
if (endpoint_index_in_common_parent > index_in_common_parent)
return static_cast<int32_t>(GetHypertext().size());
- NOTREACHED();
+ BASE_UNREACHABLE();
return -1;
}
int AXPlatformNodeBase::GetSelectionAnchor(const AXTree::Selection* selection) {
- DCHECK(selection);
+ BASE_DCHECK(selection);
int32_t anchor_id = selection->anchor_object_id;
AXPlatformNodeBase* anchor_object =
static_cast<AXPlatformNodeBase*>(delegate_->GetFromNodeID(anchor_id));
@@ -1653,19 +1607,19 @@
if (!anchor_object)
return -1;
- int anchor_offset = int{selection->anchor_offset};
+ int anchor_offset = static_cast<int>(selection->anchor_offset);
return GetHypertextOffsetFromEndpoint(anchor_object, anchor_offset);
}
int AXPlatformNodeBase::GetSelectionFocus(const AXTree::Selection* selection) {
- DCHECK(selection);
+ BASE_DCHECK(selection);
int32_t focus_id = selection->focus_object_id;
AXPlatformNodeBase* focus_object =
static_cast<AXPlatformNodeBase*>(GetDelegate()->GetFromNodeID(focus_id));
if (!focus_object)
return -1;
- int focus_offset = int{selection->focus_offset};
+ int focus_offset = static_cast<int>(selection->focus_offset);
return GetHypertextOffsetFromEndpoint(focus_object, focus_offset);
}
@@ -1677,7 +1631,7 @@
void AXPlatformNodeBase::GetSelectionOffsets(const AXTree::Selection* selection,
int* selection_start,
int* selection_end) {
- DCHECK(selection_start && selection_end);
+ BASE_DCHECK(selection_start && selection_end);
if (IsPlainTextField() &&
GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart,
@@ -1692,7 +1646,7 @@
unignored_selection = delegate_->GetUnignoredSelection();
selection = &unignored_selection;
}
- DCHECK(selection);
+ BASE_DCHECK(selection);
GetSelectionOffsetsFromTree(selection, selection_start, selection_end);
}
@@ -1700,7 +1654,7 @@
const AXTree::Selection* selection,
int* selection_start,
int* selection_end) {
- DCHECK(selection_start && selection_end);
+ BASE_DCHECK(selection_start && selection_end);
*selection_start = GetSelectionAnchor(selection);
*selection_end = GetSelectionFocus(selection);
@@ -1758,8 +1712,8 @@
// For anything other than the "embedded character", we just compare the
// characters directly.
- base::char16 old_ch = old_hypertext.hypertext[old_char_index];
- base::char16 new_ch = hypertext_.hypertext[new_char_index];
+ char16_t old_ch = old_hypertext.hypertext[old_char_index];
+ char16_t new_ch = hypertext_.hypertext[new_char_index];
if (old_ch != new_ch)
return false;
if (new_ch != kEmbeddedCharacter)
@@ -1791,7 +1745,7 @@
}
// Return true if the index represents a text character.
-bool AXPlatformNodeBase::IsText(const base::string16& text,
+bool AXPlatformNodeBase::IsText(const std::u16string& text,
size_t index,
bool is_indexed_from_end) {
size_t text_len = text.size();
@@ -1805,88 +1759,6 @@
return delegate_ && GetData().HasCheckedState();
}
-void AXPlatformNodeBase::ComputeHypertextRemovedAndInserted(
- const AXHypertext& old_hypertext,
- size_t* start,
- size_t* old_len,
- size_t* new_len) {
- *start = 0;
- *old_len = 0;
- *new_len = 0;
-
- // Do not compute for text objects, otherwise redundant text change
- // announcements will occur in live regions, as the parent hypertext also
- // changes.
- if (IsText())
- return;
-
- const base::string16& old_text = old_hypertext.hypertext;
- const base::string16& new_text = hypertext_.hypertext;
-
- // TODO(accessibility) Plumb through which part of text changed so we don't
- // have to guess what changed based on character differences. This can be
- // wrong in some cases as follows:
- // -- EDITABLE --
- // If editable: when part of the text node changes, assume only that part
- // changed, and not the entire thing. For example, if "car" changes to
- // "cat", assume only 1 letter changed. This code compares common characters
- // to guess what has changed.
- // -- NOT EDITABLE --
- // When part of the text changes, assume the entire node's text changed. For
- // example, if "car" changes to "cat" then assume all 3 letters changed.
- // Note, it is possible (though rare) that CharacterData methods are used to
- // remove, insert, replace or append a substring.
- bool allow_partial_text_node_changes =
- GetData().HasState(ax::mojom::State::kEditable);
- size_t prefix_index = 0;
- size_t common_prefix = 0;
- while (prefix_index < old_text.size() && prefix_index < new_text.size() &&
- IsSameHypertextCharacter(old_hypertext, prefix_index, prefix_index)) {
- ++prefix_index;
- if (allow_partial_text_node_changes ||
- (!IsText(old_text, prefix_index) && !IsText(new_text, prefix_index))) {
- common_prefix = prefix_index;
- }
- }
-
- size_t suffix_index = 0;
- size_t common_suffix = 0;
- while (common_prefix + suffix_index < old_text.size() &&
- common_prefix + suffix_index < new_text.size() &&
- IsSameHypertextCharacter(old_hypertext,
- old_text.size() - suffix_index - 1,
- new_text.size() - suffix_index - 1)) {
- ++suffix_index;
- if (allow_partial_text_node_changes ||
- (!IsText(old_text, suffix_index, true) &&
- !IsText(new_text, suffix_index, true))) {
- common_suffix = suffix_index;
- }
- }
-
- *start = common_prefix;
- *old_len = old_text.size() - common_prefix - common_suffix;
- *new_len = new_text.size() - common_prefix - common_suffix;
-}
-
-int AXPlatformNodeBase::FindTextBoundary(
- ax::mojom::TextBoundary boundary,
- int offset,
- ax::mojom::MoveDirection direction,
- ax::mojom::TextAffinity affinity) const {
- if (boundary != ax::mojom::TextBoundary::kSentenceStart) {
- base::Optional<int> boundary_offset =
- GetDelegate()->FindTextBoundary(boundary, offset, direction, affinity);
- if (boundary_offset.has_value())
- return *boundary_offset;
- }
-
- std::vector<int32_t> unused_line_start_offsets;
- return static_cast<int>(
- FindAccessibleTextBoundary(GetHypertext(), unused_line_start_offsets,
- boundary, offset, direction, affinity));
-}
-
AXPlatformNodeBase* AXPlatformNodeBase::NearestLeafToPoint(
gfx::Point point) const {
// First, scope the search to the node that contains point.
@@ -2019,10 +1891,10 @@
int color;
if (GetIntAttribute(ax::mojom::IntAttribute::kBackgroundColor, &color)) {
- unsigned int alpha = SkColorGetA(color);
- unsigned int red = SkColorGetR(color);
- unsigned int green = SkColorGetG(color);
- unsigned int blue = SkColorGetB(color);
+ unsigned int alpha = ColorGetA(color);
+ unsigned int red = ColorGetR(color);
+ unsigned int green = ColorGetG(color);
+ unsigned int blue = ColorGetB(color);
// Don't expose default value of pure white.
if (alpha && (red != 255 || green != 255 || blue != 255)) {
std::string color_value = "rgb(" + base::NumberToString(red) + ',' +
@@ -2034,9 +1906,9 @@
}
if (GetIntAttribute(ax::mojom::IntAttribute::kColor, &color)) {
- unsigned int red = SkColorGetR(color);
- unsigned int green = SkColorGetG(color);
- unsigned int blue = SkColorGetB(color);
+ unsigned int red = ColorGetR(color);
+ unsigned int green = ColorGetG(color);
+ unsigned int blue = ColorGetB(color);
// Don't expose default value of black.
if (red || green || blue) {
std::string color_value = "rgb(" + base::NumberToString(red) + ',' +
@@ -2062,7 +1934,7 @@
attributes.push_back(std::make_pair("font-family", font_family));
}
- base::Optional<float> font_size_in_points = GetFontSizeInPoints();
+ std::optional<float> font_size_in_points = GetFontSizeInPoints();
// Attribute has no default value.
if (font_size_in_points) {
attributes.push_back(std::make_pair(
@@ -2147,7 +2019,7 @@
AXPlatformNodeBase* AXPlatformNodeBase::GetSelectedItem(
int selected_index) const {
- DCHECK_GE(selected_index, 0);
+ BASE_DCHECK(selected_index >= 0);
int max_items = GetMaxSelectableItems();
if (max_items == 0)
return nullptr;
@@ -2161,8 +2033,8 @@
if (returned_count <= selected_index)
return nullptr;
- DCHECK(!selected_children.empty());
- DCHECK_LT(selected_index, static_cast<int>(selected_children.size()));
+ BASE_DCHECK(!selected_children.empty());
+ BASE_DCHECK(selected_index < static_cast<int>(selected_children.size()));
return selected_children[selected_index];
}
@@ -2188,7 +2060,7 @@
void AXPlatformNodeBase::SanitizeTextAttributeValue(const std::string& input,
std::string* output) const {
- DCHECK(output);
+ BASE_DCHECK(output);
}
std::string AXPlatformNodeBase::ComputeDetailsRoles() const {
@@ -2228,7 +2100,7 @@
details_roles_set.insert("comment");
break;
}
- FALLTHROUGH;
+ // FALLTHROUGH;
}
default:
// Use * to indicate some other role.
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_base.h b/third_party/accessibility/ax/platform/ax_platform_node_base.h
index fb31b4e..a76af95 100644
--- a/third_party/accessibility/ax/platform/ax_platform_node_base.h
+++ b/third_party/accessibility/ax/platform/ax_platform_node_base.h
@@ -9,20 +9,15 @@
#include <string>
#include <vector>
+#include "ax/ax_enums.h"
+#include "ax/ax_node.h"
+#include "ax_build/build_config.h"
+#include "ax_platform_node.h"
+#include "ax_platform_node_delegate.h"
+#include "ax_platform_text_boundary.h"
#include "base/macros.h"
-#include "build/build_config.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/platform/ax_platform_node.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-#include "ui/accessibility/platform/ax_platform_text_boundary.h"
-#include "ui/base/buildflags.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/native_widget_types.h"
-
-#if BUILDFLAG(USE_ATK)
-#include <atk/atk.h>
-#endif
+#include "gfx/geometry/point.h"
+#include "gfx/native_widget_types.h"
namespace ui {
@@ -50,7 +45,7 @@
// Hypertext.
std::vector<int32_t> hyperlinks;
- base::string16 hypertext;
+ std::u16string hypertext;
};
class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode {
@@ -68,15 +63,15 @@
gfx::NativeViewAccessible ChildAtIndex(int index) const;
std::string GetName() const;
- base::string16 GetNameAsString16() const;
+ std::u16string GetNameAsString16() const;
// This returns nullopt if there's no parent, it's unable to find the child in
// the list of its parent's children, or its parent doesn't have children.
- virtual base::Optional<int> GetIndexInParent();
+ virtual std::optional<int> GetIndexInParent();
// Returns a stack of ancestors of this node. The node at the top of the stack
// is the top most ancestor.
- base::stack<gfx::NativeViewAccessible> GetAncestors();
+ std::stack<gfx::NativeViewAccessible> GetAncestors();
// Returns an optional integer indicating the logical order of this node
// compared to another node or returns an empty optional if the nodes
@@ -84,7 +79,7 @@
// 0: if this position is logically equivalent to the other node
// <0: if this position is logically less than (before) the other node
// >0: if this position is logically greater than (after) the other node
- base::Optional<int> CompareTo(AXPlatformNodeBase& other);
+ std::optional<int> CompareTo(AXPlatformNodeBase& other);
// AXPlatformNode.
void Destroy() override;
@@ -92,7 +87,7 @@
void NotifyAccessibilityEvent(ax::mojom::Event event_type) override;
#if defined(OS_APPLE)
- void AnnounceText(const base::string16& text) override;
+ void AnnounceText(const std::u16string& text) override;
#endif
AXPlatformNodeDelegate* GetDelegate() const override;
@@ -132,18 +127,18 @@
bool GetStringAttribute(ax::mojom::StringAttribute attribute,
std::string* value) const;
bool GetString16Attribute(ax::mojom::StringAttribute attribute,
- base::string16* value) const;
- base::string16 GetString16Attribute(
+ std::u16string* value) const;
+ std::u16string GetString16Attribute(
ax::mojom::StringAttribute attribute) const;
bool HasInheritedStringAttribute(ax::mojom::StringAttribute attribute) const;
const std::string& GetInheritedStringAttribute(
ax::mojom::StringAttribute attribute) const;
- base::string16 GetInheritedString16Attribute(
+ std::u16string GetInheritedString16Attribute(
ax::mojom::StringAttribute attribute) const;
bool GetInheritedStringAttribute(ax::mojom::StringAttribute attribute,
std::string* value) const;
bool GetInheritedString16Attribute(ax::mojom::StringAttribute attribute,
- base::string16* value) const;
+ std::u16string* value) const;
bool HasIntListAttribute(ax::mojom::IntListAttribute attribute) const;
const std::vector<int32_t>& GetIntListAttribute(
@@ -177,51 +172,51 @@
// If inside a table or ARIA grid, returns the zero-based index of the cell.
// Indices are in row major order and each cell is counted once regardless of
- // its span. Returns base::nullopt if not a cell or if not inside a table.
- base::Optional<int> GetTableCellIndex() const;
+ // its span. Returns std::nullopt if not a cell or if not inside a table.
+ std::optional<int> GetTableCellIndex() const;
// If inside a table or ARIA grid, returns the physical column number for the
// current cell. In contrast to logical columns, physical columns always start
// from 0 and have no gaps in their numbering. Logical columns can be set
- // using aria-colindex. Returns base::nullopt if not a cell or if not inside a
+ // using aria-colindex. Returns std::nullopt if not a cell or if not inside a
// table.
- base::Optional<int> GetTableColumn() const;
+ std::optional<int> GetTableColumn() const;
// If inside a table or ARIA grid, returns the number of physical columns.
- // Returns base::nullopt if not inside a table.
- base::Optional<int> GetTableColumnCount() const;
+ // Returns std::nullopt if not inside a table.
+ std::optional<int> GetTableColumnCount() const;
// If inside a table or ARIA grid, returns the number of ARIA columns.
- // Returns base::nullopt if not inside a table.
- base::Optional<int> GetTableAriaColumnCount() const;
+ // Returns std::nullopt if not inside a table.
+ std::optional<int> GetTableAriaColumnCount() const;
// If inside a table or ARIA grid, returns the number of physical columns that
- // this cell spans. Returns base::nullopt if not a cell or if not inside a
+ // this cell spans. Returns std::nullopt if not a cell or if not inside a
// table.
- base::Optional<int> GetTableColumnSpan() const;
+ std::optional<int> GetTableColumnSpan() const;
// If inside a table or ARIA grid, returns the physical row number for the
// current cell. In contrast to logical rows, physical rows always start from
// 0 and have no gaps in their numbering. Logical rows can be set using
- // aria-rowindex. Returns base::nullopt if not a cell or if not inside a
+ // aria-rowindex. Returns std::nullopt if not a cell or if not inside a
// table.
- base::Optional<int> GetTableRow() const;
+ std::optional<int> GetTableRow() const;
// If inside a table or ARIA grid, returns the number of physical rows.
- // Returns base::nullopt if not inside a table.
- base::Optional<int> GetTableRowCount() const;
+ // Returns std::nullopt if not inside a table.
+ std::optional<int> GetTableRowCount() const;
// If inside a table or ARIA grid, returns the number of ARIA rows.
- // Returns base::nullopt if not inside a table.
- base::Optional<int> GetTableAriaRowCount() const;
+ // Returns std::nullopt if not inside a table.
+ std::optional<int> GetTableAriaRowCount() const;
// If inside a table or ARIA grid, returns the number of physical rows that
- // this cell spans. Returns base::nullopt if not a cell or if not inside a
+ // this cell spans. Returns std::nullopt if not a cell or if not inside a
// table.
- base::Optional<int> GetTableRowSpan() const;
+ std::optional<int> GetTableRowSpan() const;
// Returns the font size converted to points, if available.
- base::Optional<float> GetFontSizeInPoints() const;
+ std::optional<float> GetFontSizeInPoints() const;
// Returns true if either a descendant has selection (sel_focus_object_id) or
// if this node is a simple text element and has text selection attributes.
@@ -273,7 +268,7 @@
// object character", and every leaf child node with its visible accessible
// name. This is how displayed text and embedded objects are represented in
// ATK and IA2 APIs.
- base::string16 GetHypertext() const;
+ std::u16string GetHypertext() const;
// Returns the text of this node and all descendant nodes; including text
// found in embedded objects.
@@ -281,15 +276,15 @@
// Only text displayed on screen is included. Text from ARIA and HTML
// attributes that is either not displayed on screen, or outside this node,
// e.g. aria-label and HTML title, is not returned.
- base::string16 GetInnerText() const;
+ std::u16string GetInnerText() const;
- virtual base::string16 GetValue() const;
+ virtual std::u16string GetValue() const;
// Represents a non-static text node in IAccessibleHypertext (and ATK in the
// future). This character is embedded in the response to
// IAccessibleText::get_text, indicating the position where a non-static text
// child object appears.
- static const base::char16 kEmbeddedCharacter;
+ static const char16_t kEmbeddedCharacter;
// Get a node given its unique id or null in the case that the id is unknown.
static AXPlatformNode* GetFromUniqueId(int32_t unique_id);
@@ -299,15 +294,7 @@
static void SetOnNotifyEventCallbackForTesting(
ax::mojom::Event event_type,
- base::RepeatingClosure callback);
-
- // This method finds text boundaries in the text used for platform text APIs.
- // Implementations may use side-channel data such as line or word indices to
- // produce appropriate results.
- virtual int FindTextBoundary(ax::mojom::TextBoundary boundary,
- int offset,
- ax::mojom::MoveDirection direction,
- ax::mojom::TextAffinity affinity) const;
+ std::function<void()> callback);
enum ScrollType {
TopLeft,
@@ -366,12 +353,12 @@
// Get the range value text, which might come from aria-valuetext or
// a floating-point value. This is different from the value string
// attribute used in input controls such as text boxes and combo boxes.
- base::string16 GetRangeValueText() const;
+ std::u16string GetRangeValueText() const;
// Get the role description from the node data or from the image annotation
// status.
- base::string16 GetRoleDescription() const;
- base::string16 GetRoleDescriptionFromImageAnnotationStatusOrFromAttribute()
+ std::u16string GetRoleDescription() const;
+ std::u16string GetRoleDescriptionFromImageAnnotationStatusOrFromAttribute()
const;
// Cast a gfx::NativeViewAccessible to an AXPlatformNodeBase if it is one,
@@ -384,11 +371,7 @@
// Sets the hypertext selection in this object if possible.
bool SetHypertextSelection(int start_offset, int end_offset);
-#if BUILDFLAG(USE_ATK)
- using PlatformAttributeList = AtkAttributeSet*;
-#else
- using PlatformAttributeList = std::vector<base::string16>;
-#endif
+ using PlatformAttributeList = std::vector<std::u16string>;
// Compute the attributes exposed via platform accessibility objects and put
// them into an attribute list, |attributes|. Currently only used by
@@ -485,13 +468,9 @@
bool IsSameHypertextCharacter(const AXHypertext& old_hypertext,
size_t old_char_index,
size_t new_char_index);
- void ComputeHypertextRemovedAndInserted(const AXHypertext& old_hypertext,
- size_t* start,
- size_t* old_len,
- size_t* new_len);
- base::Optional<int> GetPosInSet() const;
- base::Optional<int> GetSetSize() const;
+ std::optional<int> GetPosInSet() const;
+ std::optional<int> GetSetSize() const;
std::string GetInvalidValue() const;
@@ -504,14 +483,14 @@
private:
// Returns true if the index represents a text character.
- bool IsText(const base::string16& text,
+ bool IsText(const std::u16string& text,
size_t index,
bool is_indexed_from_end = false);
// Compute value for object attribute details-roles on aria-details nodes.
std::string ComputeDetailsRoles() const;
- DISALLOW_COPY_AND_ASSIGN(AXPlatformNodeBase);
+ BASE_DISALLOW_COPY_AND_ASSIGN(AXPlatformNodeBase);
};
} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_base_unittest.cc b/third_party/accessibility/ax/platform/ax_platform_node_base_unittest.cc
index 54991d0..15969e9 100644
--- a/third_party/accessibility/ax/platform/ax_platform_node_base_unittest.cc
+++ b/third_party/accessibility/ax/platform/ax_platform_node_base_unittest.cc
@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/platform/ax_platform_node_base.h"
-#include "base/strings/utf_string_conversions.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/platform/test_ax_node_wrapper.h"
+#include "ax_platform_node_base.h"
+
+#include "gtest/gtest.h"
+
+#include "base/string_utils.h"
+#include "test_ax_node_wrapper.h"
namespace ui {
namespace {
@@ -492,7 +494,7 @@
// Test for two nodes that do not share the same root. They should not be
// comparable.
AXPlatformNodeBase detached_node;
- EXPECT_EQ(base::nullopt, n1->CompareTo(detached_node));
+ EXPECT_EQ(std::nullopt, n1->CompareTo(detached_node));
// Create a test vector of all the tree nodes arranged in a pre-order
// traversal way. The node that has a smaller index in the vector should also
@@ -509,7 +511,7 @@
else if (lhs->GetData().id > rhs->GetData().id)
expected_result = 1;
- EXPECT_NE(base::nullopt, lhs->CompareTo(*rhs));
+ EXPECT_NE(std::nullopt, lhs->CompareTo(*rhs));
int actual_result = 0;
if (lhs->CompareTo(*rhs) < 0)
actual_result = -1;
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_delegate.h b/third_party/accessibility/ax/platform/ax_platform_node_delegate.h
index 6b9c27e..8f8aa036 100644
--- a/third_party/accessibility/ax/platform/ax_platform_node_delegate.h
+++ b/third_party/accessibility/ax/platform/ax_platform_node_delegate.h
@@ -16,26 +16,19 @@
#include <utility>
#include <vector>
-#include "base/optional.h"
-#include "ui/accessibility/ax_clipping_behavior.h"
-#include "ui/accessibility/ax_coordinate_system.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_node_position.h"
-#include "ui/accessibility/ax_offscreen_result.h"
-#include "ui/accessibility/ax_position.h"
-#include "ui/accessibility/ax_text_utils.h"
-#include "ui/accessibility/ax_tree.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/accessibility/platform/ax_unique_id.h"
-#include "ui/gfx/geometry/vector2d.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace gfx {
-
-class Rect;
-
-} // namespace gfx
+#include "ax/ax_clipping_behavior.h"
+#include "ax/ax_coordinate_system.h"
+#include "ax/ax_enums.h"
+#include "ax/ax_export.h"
+#include "ax/ax_node_position.h"
+#include "ax/ax_offscreen_result.h"
+#include "ax/ax_position.h"
+#include "ax/ax_tree.h"
+#include "ax/ax_tree_id.h"
+#include "ax_unique_id.h"
+#include "base/macros.h"
+#include "gfx/geometry/rect.h"
+#include "gfx/native_widget_types.h"
namespace ui {
@@ -84,7 +77,7 @@
// Only text displayed on screen is included. Text from ARIA and HTML
// attributes that is either not displayed on screen, or outside this node,
// e.g. aria-label and HTML title, is not returned.
- virtual base::string16 GetInnerText() const = 0;
+ virtual std::u16string GetInnerText() const = 0;
// Get the unignored selection from the tree
virtual const AXTree::Selection GetUnignoredSelection() const = 0;
@@ -180,7 +173,7 @@
// Returns the text of this node and represent the text of descendant nodes
// with a special character in place of every embedded object. This represents
// the concept of text in ATK and IA2 APIs.
- virtual base::string16 GetHypertext() const = 0;
+ virtual std::u16string GetHypertext() const = 0;
// Set the selection in the hypertext of this node. Depending on the
// implementation, this may mean the new selection will span multiple nodes.
@@ -307,7 +300,7 @@
// any instance of the application, regardless of locale. The author ID should
// be unique among sibling accessibility nodes and is best if unique across
// the application, however, not meeting this requirement is non-fatal.
- virtual base::string16 GetAuthorUniqueId() const = 0;
+ virtual std::u16string GetAuthorUniqueId() const = 0;
virtual const AXUniqueId& GetUniqueId() const = 0;
@@ -320,7 +313,7 @@
// that the delegate does not have all the information required to calculate
// this value and it is the responsibility of the AXPlatformNode itself to
// to calculate it.
- virtual base::Optional<int> FindTextBoundary(
+ virtual std::optional<int> FindTextBoundary(
ax::mojom::TextBoundary boundary,
int offset,
ax::mojom::MoveDirection direction,
@@ -347,12 +340,12 @@
// role, otherwise they return nullopt.
//
virtual bool IsTable() const = 0;
- virtual base::Optional<int> GetTableColCount() const = 0;
- virtual base::Optional<int> GetTableRowCount() const = 0;
- virtual base::Optional<int> GetTableAriaColCount() const = 0;
- virtual base::Optional<int> GetTableAriaRowCount() const = 0;
- virtual base::Optional<int> GetTableCellCount() const = 0;
- virtual base::Optional<bool> GetTableHasColumnOrRowHeaderNode() const = 0;
+ virtual std::optional<int> GetTableColCount() const = 0;
+ virtual std::optional<int> GetTableRowCount() const = 0;
+ virtual std::optional<int> GetTableAriaColCount() const = 0;
+ virtual std::optional<int> GetTableAriaRowCount() const = 0;
+ virtual std::optional<int> GetTableCellCount() const = 0;
+ virtual std::optional<bool> GetTableHasColumnOrRowHeaderNode() const = 0;
virtual std::vector<int32_t> GetColHeaderNodeIds() const = 0;
virtual std::vector<int32_t> GetColHeaderNodeIds(int col_index) const = 0;
virtual std::vector<int32_t> GetRowHeaderNodeIds() const = 0;
@@ -361,20 +354,20 @@
// Table row-like nodes.
virtual bool IsTableRow() const = 0;
- virtual base::Optional<int> GetTableRowRowIndex() const = 0;
+ virtual std::optional<int> GetTableRowRowIndex() const = 0;
// Table cell-like nodes.
virtual bool IsTableCellOrHeader() const = 0;
- virtual base::Optional<int> GetTableCellIndex() const = 0;
- virtual base::Optional<int> GetTableCellColIndex() const = 0;
- virtual base::Optional<int> GetTableCellRowIndex() const = 0;
- virtual base::Optional<int> GetTableCellColSpan() const = 0;
- virtual base::Optional<int> GetTableCellRowSpan() const = 0;
- virtual base::Optional<int> GetTableCellAriaColIndex() const = 0;
- virtual base::Optional<int> GetTableCellAriaRowIndex() const = 0;
- virtual base::Optional<int32_t> GetCellId(int row_index,
- int col_index) const = 0;
- virtual base::Optional<int32_t> CellIndexToId(int cell_index) const = 0;
+ virtual std::optional<int> GetTableCellIndex() const = 0;
+ virtual std::optional<int> GetTableCellColIndex() const = 0;
+ virtual std::optional<int> GetTableCellRowIndex() const = 0;
+ virtual std::optional<int> GetTableCellColSpan() const = 0;
+ virtual std::optional<int> GetTableCellRowSpan() const = 0;
+ virtual std::optional<int> GetTableCellAriaColIndex() const = 0;
+ virtual std::optional<int> GetTableCellAriaRowIndex() const = 0;
+ virtual std::optional<int32_t> GetCellId(int row_index,
+ int col_index) const = 0;
+ virtual std::optional<int32_t> CellIndexToId(int cell_index) const = 0;
// Helper methods to check if a cell is an ARIA-1.1+ 'cell' or 'gridcell'
virtual bool IsCellOrHeaderOfARIATable() const = 0;
@@ -383,8 +376,8 @@
// Ordered-set-like and item-like nodes.
virtual bool IsOrderedSetItem() const = 0;
virtual bool IsOrderedSet() const = 0;
- virtual base::Optional<int> GetPosInSet() const = 0;
- virtual base::Optional<int> GetSetSize() const = 0;
+ virtual std::optional<int> GetPosInSet() const = 0;
+ virtual std::optional<int> GetSetSize() const = 0;
//
// Events.
@@ -406,13 +399,13 @@
// Localized strings.
//
- virtual base::string16 GetLocalizedRoleDescriptionForUnlabeledImage()
+ virtual std::u16string GetLocalizedRoleDescriptionForUnlabeledImage()
const = 0;
- virtual base::string16 GetLocalizedStringForImageAnnotationStatus(
+ virtual std::u16string GetLocalizedStringForImageAnnotationStatus(
ax::mojom::ImageAnnotationStatus status) const = 0;
- virtual base::string16 GetLocalizedStringForLandmarkType() const = 0;
- virtual base::string16 GetLocalizedStringForRoleDescription() const = 0;
- virtual base::string16 GetStyleNameAttributeAsLocalizedString() const = 0;
+ virtual std::u16string GetLocalizedStringForLandmarkType() const = 0;
+ virtual std::u16string GetLocalizedStringForRoleDescription() const = 0;
+ virtual std::u16string GetStyleNameAttributeAsLocalizedString() const = 0;
//
// Testing.
@@ -442,7 +435,7 @@
virtual std::string SubtreeToStringHelper(size_t level) = 0;
private:
- DISALLOW_COPY_AND_ASSIGN(AXPlatformNodeDelegate);
+ BASE_DISALLOW_COPY_AND_ASSIGN(AXPlatformNodeDelegate);
};
} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.cc b/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.cc
index 21e347c..f91d493 100644
--- a/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.cc
+++ b/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.cc
@@ -2,18 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/platform/ax_platform_node_delegate_base.h"
+#include "ax_platform_node_delegate_base.h"
#include <vector>
+#include "ax/ax_action_data.h"
+#include "ax/ax_constants.h"
+#include "ax/ax_node_data.h"
+#include "ax/ax_role_properties.h"
+#include "ax/ax_tree_data.h"
#include "base/no_destructor.h"
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_constants.mojom.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_tree_data.h"
-#include "ui/accessibility/platform/ax_platform_node.h"
-#include "ui/accessibility/platform/ax_platform_node_base.h"
+
+#include "ax_platform_node.h"
+#include "ax_platform_node_base.h"
namespace ui {
@@ -31,14 +32,14 @@
return *empty_data;
}
-base::string16 AXPlatformNodeDelegateBase::GetInnerText() const {
+std::u16string AXPlatformNodeDelegateBase::GetInnerText() const {
// Unlike in web content The "kValue" attribute always takes precedence,
// because we assume that users of this base class, such as Views controls,
// are carefully crafted by hand, in contrast to HTML pages, where any content
// that might be present in the shadow DOM (AKA in the internal accessibility
// tree) is actually used by the renderer when assigning the "kValue"
// attribute, including any redundant white space.
- base::string16 value =
+ std::u16string value =
GetData().GetString16Attribute(ax::mojom::StringAttribute::kValue);
if (!value.empty())
return value;
@@ -50,7 +51,7 @@
if (IsLeaf() && !GetData().IsInvisibleOrIgnored())
return GetData().GetString16Attribute(ax::mojom::StringAttribute::kName);
- base::string16 inner_text;
+ std::u16string inner_text;
for (int i = 0; i < GetChildCount(); ++i) {
// TODO(nektar): Add const to all tree traversal methods and remove
// const_cast.
@@ -65,7 +66,7 @@
const AXTree::Selection AXPlatformNodeDelegateBase::GetUnignoredSelection()
const {
- return AXTree::Selection{-1, -1, -1, ax::mojom::TextAffinity::kDownstream};
+ return AXTree::Selection{false, -1, -1, ax::mojom::TextAffinity::kDownstream};
}
AXNodePosition::AXPositionInstance
@@ -162,14 +163,14 @@
AXPlatformNodeDelegateBase* parent,
int index)
: index_(index), parent_(parent) {
- DCHECK(parent);
- DCHECK(0 <= index && index <= parent->GetChildCount());
+ BASE_DCHECK(parent);
+ BASE_DCHECK(0 <= index && index <= parent->GetChildCount());
}
AXPlatformNodeDelegateBase::ChildIteratorBase::ChildIteratorBase(
const AXPlatformNodeDelegateBase::ChildIteratorBase& it)
: index_(it.index_), parent_(it.parent_) {
- DCHECK(parent_);
+ BASE_DCHECK(parent_);
}
bool AXPlatformNodeDelegateBase::ChildIteratorBase::operator==(
@@ -191,12 +192,12 @@
}
void AXPlatformNodeDelegateBase::ChildIteratorBase::operator--() {
- DCHECK_GT(index_, 0);
+ BASE_DCHECK(index_ > 0);
index_--;
}
void AXPlatformNodeDelegateBase::ChildIteratorBase::operator--(int) {
- DCHECK_GT(index_, 0);
+ BASE_DCHECK(index_ > 0);
index_--;
}
@@ -216,7 +217,7 @@
AXPlatformNodeDelegateBase::ChildIteratorBase::operator*() const {
AXPlatformNode* platform_node =
AXPlatformNode::FromNativeViewAccessible(GetNativeViewAccessible());
- DCHECK(platform_node && platform_node->GetDelegate());
+ BASE_DCHECK(platform_node && platform_node->GetDelegate());
return *(platform_node->GetDelegate());
}
@@ -241,8 +242,8 @@
return GetData().GetStringAttribute(ax::mojom::StringAttribute::kName);
}
-base::string16 AXPlatformNodeDelegateBase::GetHypertext() const {
- return base::string16();
+std::u16string AXPlatformNodeDelegateBase::GetHypertext() const {
+ return std::u16string();
}
bool AXPlatformNodeDelegateBase::SetHypertextSelection(int start_offset,
@@ -335,39 +336,39 @@
return ui::IsTableLike(GetData().role);
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableRowCount() const {
+std::optional<int> AXPlatformNodeDelegateBase::GetTableRowCount() const {
return GetData().GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount);
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableColCount() const {
+std::optional<int> AXPlatformNodeDelegateBase::GetTableColCount() const {
return GetData().GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount);
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableAriaColCount() const {
+std::optional<int> AXPlatformNodeDelegateBase::GetTableAriaColCount() const {
int aria_column_count;
if (!GetData().GetIntAttribute(ax::mojom::IntAttribute::kAriaColumnCount,
&aria_column_count)) {
- return base::nullopt;
+ return std::nullopt;
}
return aria_column_count;
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableAriaRowCount() const {
+std::optional<int> AXPlatformNodeDelegateBase::GetTableAriaRowCount() const {
int aria_row_count;
if (!GetData().GetIntAttribute(ax::mojom::IntAttribute::kAriaRowCount,
&aria_row_count)) {
- return base::nullopt;
+ return std::nullopt;
}
return aria_row_count;
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableCellCount() const {
- return base::nullopt;
+std::optional<int> AXPlatformNodeDelegateBase::GetTableCellCount() const {
+ return std::nullopt;
}
-base::Optional<bool>
+std::optional<bool>
AXPlatformNodeDelegateBase::GetTableHasColumnOrRowHeaderNode() const {
- return base::nullopt;
+ return std::nullopt;
}
std::vector<int32_t> AXPlatformNodeDelegateBase::GetColHeaderNodeIds() const {
@@ -396,7 +397,7 @@
return ui::IsTableRow(GetData().role);
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableRowRowIndex() const {
+std::optional<int> AXPlatformNodeDelegateBase::GetTableRowRowIndex() const {
return GetData().GetIntAttribute(ax::mojom::IntAttribute::kTableRowIndex);
}
@@ -404,48 +405,48 @@
return ui::IsCellOrTableHeader(GetData().role);
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableCellColIndex() const {
+std::optional<int> AXPlatformNodeDelegateBase::GetTableCellColIndex() const {
return GetData().GetIntAttribute(
ax::mojom::IntAttribute::kTableCellColumnIndex);
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableCellRowIndex() const {
+std::optional<int> AXPlatformNodeDelegateBase::GetTableCellRowIndex() const {
return GetData().GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex);
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableCellColSpan() const {
+std::optional<int> AXPlatformNodeDelegateBase::GetTableCellColSpan() const {
return GetData().GetIntAttribute(
ax::mojom::IntAttribute::kTableCellColumnSpan);
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableCellRowSpan() const {
+std::optional<int> AXPlatformNodeDelegateBase::GetTableCellRowSpan() const {
return GetData().GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowSpan);
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableCellAriaColIndex()
+std::optional<int> AXPlatformNodeDelegateBase::GetTableCellAriaColIndex()
const {
return GetData().GetIntAttribute(
ax::mojom::IntAttribute::kAriaCellColumnIndex);
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableCellAriaRowIndex()
+std::optional<int> AXPlatformNodeDelegateBase::GetTableCellAriaRowIndex()
const {
return GetData().GetIntAttribute(ax::mojom::IntAttribute::kAriaCellRowIndex);
}
-base::Optional<int32_t> AXPlatformNodeDelegateBase::GetCellId(
+std::optional<int32_t> AXPlatformNodeDelegateBase::GetCellId(
int row_index,
int col_index) const {
- return base::nullopt;
+ return std::nullopt;
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetTableCellIndex() const {
- return base::nullopt;
+std::optional<int> AXPlatformNodeDelegateBase::GetTableCellIndex() const {
+ return std::nullopt;
}
-base::Optional<int32_t> AXPlatformNodeDelegateBase::CellIndexToId(
+std::optional<int32_t> AXPlatformNodeDelegateBase::CellIndexToId(
int cell_index) const {
- return base::nullopt;
+ return std::nullopt;
}
bool AXPlatformNodeDelegateBase::IsCellOrHeaderOfARIATable() const {
@@ -464,12 +465,12 @@
return false;
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetPosInSet() const {
- return base::nullopt;
+std::optional<int> AXPlatformNodeDelegateBase::GetPosInSet() const {
+ return std::nullopt;
}
-base::Optional<int> AXPlatformNodeDelegateBase::GetSetSize() const {
- return base::nullopt;
+std::optional<int> AXPlatformNodeDelegateBase::GetSetSize() const {
+ return std::nullopt;
}
bool AXPlatformNodeDelegateBase::AccessibilityPerformAction(
@@ -477,31 +478,31 @@
return false;
}
-base::string16
+std::u16string
AXPlatformNodeDelegateBase::GetLocalizedStringForImageAnnotationStatus(
ax::mojom::ImageAnnotationStatus status) const {
- return base::string16();
+ return std::u16string();
}
-base::string16
+std::u16string
AXPlatformNodeDelegateBase::GetLocalizedRoleDescriptionForUnlabeledImage()
const {
- return base::string16();
+ return std::u16string();
}
-base::string16 AXPlatformNodeDelegateBase::GetLocalizedStringForLandmarkType()
+std::u16string AXPlatformNodeDelegateBase::GetLocalizedStringForLandmarkType()
const {
- return base::string16();
+ return std::u16string();
}
-base::string16
+std::u16string
AXPlatformNodeDelegateBase::GetLocalizedStringForRoleDescription() const {
- return base::string16();
+ return std::u16string();
}
-base::string16
+std::u16string
AXPlatformNodeDelegateBase::GetStyleNameAttributeAsLocalizedString() const {
- return base::string16();
+ return std::u16string();
}
TextAttributeMap AXPlatformNodeDelegateBase::ComputeTextAttributeMap(
@@ -543,7 +544,7 @@
AXPlatformNode* AXPlatformNodeDelegateBase::GetTargetNodeForRelation(
ax::mojom::IntAttribute attr) {
- DCHECK(IsNodeIdIntAttribute(attr));
+ BASE_DCHECK(IsNodeIdIntAttribute(attr));
int target_id;
if (!GetData().GetIntAttribute(attr, &target_id))
@@ -566,7 +567,7 @@
std::vector<AXPlatformNode*>
AXPlatformNodeDelegateBase::GetTargetNodesForRelation(
ax::mojom::IntListAttribute attr) {
- DCHECK(IsNodeIdIntListAttribute(attr));
+ BASE_DCHECK(IsNodeIdIntListAttribute(attr));
std::vector<int32_t> target_ids;
if (!GetData().GetIntListAttribute(attr, &target_ids))
return std::vector<AXPlatformNode*>();
@@ -601,8 +602,8 @@
return std::set<AXPlatformNode*>();
}
-base::string16 AXPlatformNodeDelegateBase::GetAuthorUniqueId() const {
- return base::string16();
+std::u16string AXPlatformNodeDelegateBase::GetAuthorUniqueId() const {
+ return std::u16string();
}
const AXUniqueId& AXPlatformNodeDelegateBase::GetUniqueId() const {
@@ -610,12 +611,12 @@
return *dummy_unique_id;
}
-base::Optional<int> AXPlatformNodeDelegateBase::FindTextBoundary(
+std::optional<int> AXPlatformNodeDelegateBase::FindTextBoundary(
ax::mojom::TextBoundary boundary,
int offset,
ax::mojom::MoveDirection direction,
ax::mojom::TextAffinity affinity) const {
- return base::nullopt;
+ return std::nullopt;
}
const std::vector<gfx::NativeViewAccessible>
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.h b/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.h
index 8158fe7..ea0fd5c 100644
--- a/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.h
+++ b/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.h
@@ -12,8 +12,7 @@
#include <string>
#include <vector>
-#include "base/optional.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
+#include "ax_platform_node_delegate.h"
namespace ui {
@@ -35,7 +34,7 @@
// Get the accessibility tree data for this node.
const AXTreeData& GetTreeData() const override;
- base::string16 GetInnerText() const override;
+ std::u16string GetInnerText() const override;
const AXTree::Selection GetUnignoredSelection() const override;
// Creates a text position rooted at this object.
@@ -101,7 +100,7 @@
std::unique_ptr<AXPlatformNodeDelegate::ChildIterator> ChildrenEnd() override;
std::string GetName() const override;
- base::string16 GetHypertext() const override;
+ std::u16string GetHypertext() const override;
bool SetHypertextSelection(int start_offset, int end_offset) override;
TextAttributeMap ComputeTextAttributeMap(
const TextAttributeList& default_attributes) const override;
@@ -196,11 +195,11 @@
std::set<AXPlatformNode*> GetReverseRelations(
ax::mojom::IntListAttribute attr) override;
- base::string16 GetAuthorUniqueId() const override;
+ std::u16string GetAuthorUniqueId() const override;
const AXUniqueId& GetUniqueId() const override;
- base::Optional<int> FindTextBoundary(
+ std::optional<int> FindTextBoundary(
ax::mojom::TextBoundary boundary,
int offset,
ax::mojom::MoveDirection direction,
@@ -216,12 +215,12 @@
// role, otherwise they return nullopt.
//
bool IsTable() const override;
- base::Optional<int> GetTableColCount() const override;
- base::Optional<int> GetTableRowCount() const override;
- base::Optional<int> GetTableAriaColCount() const override;
- base::Optional<int> GetTableAriaRowCount() const override;
- base::Optional<int> GetTableCellCount() const override;
- base::Optional<bool> GetTableHasColumnOrRowHeaderNode() const override;
+ std::optional<int> GetTableColCount() const override;
+ std::optional<int> GetTableRowCount() const override;
+ std::optional<int> GetTableAriaColCount() const override;
+ std::optional<int> GetTableAriaRowCount() const override;
+ std::optional<int> GetTableCellCount() const override;
+ std::optional<bool> GetTableHasColumnOrRowHeaderNode() const override;
std::vector<int32_t> GetColHeaderNodeIds() const override;
std::vector<int32_t> GetColHeaderNodeIds(int col_index) const override;
std::vector<int32_t> GetRowHeaderNodeIds() const override;
@@ -230,20 +229,19 @@
// Table row-like nodes.
bool IsTableRow() const override;
- base::Optional<int> GetTableRowRowIndex() const override;
+ std::optional<int> GetTableRowRowIndex() const override;
// Table cell-like nodes.
bool IsTableCellOrHeader() const override;
- base::Optional<int> GetTableCellIndex() const override;
- base::Optional<int> GetTableCellColIndex() const override;
- base::Optional<int> GetTableCellRowIndex() const override;
- base::Optional<int> GetTableCellColSpan() const override;
- base::Optional<int> GetTableCellRowSpan() const override;
- base::Optional<int> GetTableCellAriaColIndex() const override;
- base::Optional<int> GetTableCellAriaRowIndex() const override;
- base::Optional<int32_t> GetCellId(int row_index,
- int col_index) const override;
- base::Optional<int32_t> CellIndexToId(int cell_index) const override;
+ std::optional<int> GetTableCellIndex() const override;
+ std::optional<int> GetTableCellColIndex() const override;
+ std::optional<int> GetTableCellRowIndex() const override;
+ std::optional<int> GetTableCellColSpan() const override;
+ std::optional<int> GetTableCellRowSpan() const override;
+ std::optional<int> GetTableCellAriaColIndex() const override;
+ std::optional<int> GetTableCellAriaRowIndex() const override;
+ std::optional<int32_t> GetCellId(int row_index, int col_index) const override;
+ std::optional<int32_t> CellIndexToId(int cell_index) const override;
// Helper methods to check if a cell is an ARIA-1.1+ 'cell' or 'gridcell'
bool IsCellOrHeaderOfARIATable() const override;
@@ -252,8 +250,8 @@
// Ordered-set-like and item-like nodes.
bool IsOrderedSetItem() const override;
bool IsOrderedSet() const override;
- base::Optional<int> GetPosInSet() const override;
- base::Optional<int> GetSetSize() const override;
+ std::optional<int> GetPosInSet() const override;
+ std::optional<int> GetSetSize() const override;
//
// Events.
@@ -275,12 +273,12 @@
// Localized strings.
//
- base::string16 GetLocalizedStringForImageAnnotationStatus(
+ std::u16string GetLocalizedStringForImageAnnotationStatus(
ax::mojom::ImageAnnotationStatus status) const override;
- base::string16 GetLocalizedRoleDescriptionForUnlabeledImage() const override;
- base::string16 GetLocalizedStringForLandmarkType() const override;
- base::string16 GetLocalizedStringForRoleDescription() const override;
- base::string16 GetStyleNameAttributeAsLocalizedString() const override;
+ std::u16string GetLocalizedRoleDescriptionForUnlabeledImage() const override;
+ std::u16string GetLocalizedStringForLandmarkType() const override;
+ std::u16string GetLocalizedStringForRoleDescription() const override;
+ std::u16string GetStyleNameAttributeAsLocalizedString() const override;
//
// Testing.
@@ -303,7 +301,7 @@
AXPlatformNodeDelegate* GetParentDelegate();
private:
- DISALLOW_COPY_AND_ASSIGN(AXPlatformNodeDelegateBase);
+ BASE_DISALLOW_COPY_AND_ASSIGN(AXPlatformNodeDelegateBase);
};
} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_delegate_utils_win.cc b/third_party/accessibility/ax/platform/ax_platform_node_delegate_utils_win.cc
deleted file mode 100644
index e862610..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_delegate_utils_win.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_node_delegate_utils_win.h"
-
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/platform/ax_platform_node.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-
-namespace ui {
-
-bool IsValuePatternSupported(AXPlatformNodeDelegate* delegate) {
- // https://docs.microsoft.com/en-us/windows/desktop/winauto/uiauto-implementingvalue
- // The Value control pattern is used to support controls that have an
- // intrinsic value not spanning a range and that can be represented as
- // a string.
- //
- // IValueProvider must be implemented by controls such as the color picker
- // selection control [...]
-
- // https://www.w3.org/TR/html-aam-1.0/
- // The HTML AAM maps "href [a; area]" to UIA Value.Value
- return delegate->GetData().IsRangeValueSupported() ||
- IsReadOnlySupported(delegate->GetData().role) ||
- IsLink(delegate->GetData().role) ||
- delegate->GetData().role == ax::mojom::Role::kColorWell ||
- delegate->IsCellOrHeaderOfARIAGrid();
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_delegate_utils_win.h b/third_party/accessibility/ax/platform/ax_platform_node_delegate_utils_win.h
deleted file mode 100644
index 6f515d6..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_delegate_utils_win.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_DELEGATE_UTILS_WIN_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_DELEGATE_UTILS_WIN_H_
-
-#include "ui/accessibility/ax_export.h"
-
-namespace ui {
-
-class AXPlatformNodeDelegate;
-
-// Returns true if the value pattern is supported
-AX_EXPORT bool IsValuePatternSupported(AXPlatformNodeDelegate*);
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_DELEGATE_UTILS_WIN_H_
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_mac.h b/third_party/accessibility/ax/platform/ax_platform_node_mac.h
index 77b816d..1de7f4b 100644
--- a/third_party/accessibility/ax/platform/ax_platform_node_mac.h
+++ b/third_party/accessibility/ax/platform/ax_platform_node_mac.h
@@ -7,10 +7,12 @@
#import <Cocoa/Cocoa.h>
-#include "base/mac/scoped_nsobject.h"
#include "base/macros.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/platform/ax_platform_node_base.h"
+#include "base/platform/darwin/scoped_nsobject.h"
+
+#include "ax/ax_export.h"
+
+#include "ax_platform_node_base.h"
@class AXPlatformNodeCocoa;
@@ -23,7 +25,7 @@
// AXPlatformNode.
gfx::NativeViewAccessible GetNativeViewAccessible() override;
void NotifyAccessibilityEvent(ax::mojom::Event event_type) override;
- void AnnounceText(const base::string16& text) override;
+ void AnnounceText(const std::u16string& text) override;
// AXPlatformNodeBase.
void Destroy() override;
@@ -39,7 +41,7 @@
base::scoped_nsobject<AXPlatformNodeCocoa> native_node_;
- DISALLOW_COPY_AND_ASSIGN(AXPlatformNodeMac);
+ BASE_DISALLOW_COPY_AND_ASSIGN(AXPlatformNodeMac);
};
// Convenience function to determine whether an internal object role should
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_mac.mm b/third_party/accessibility/ax/platform/ax_platform_node_mac.mm
index 9b026d0..8cb1fb1 100644
--- a/third_party/accessibility/ax/platform/ax_platform_node_mac.mm
+++ b/third_party/accessibility/ax/platform/ax_platform_node_mac.mm
@@ -2,26 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#import "ui/accessibility/platform/ax_platform_node_mac.h"
+#import "ax_platform_node_mac.h"
#import <Cocoa/Cocoa.h>
#include <stddef.h>
-#include "base/mac/foundation_util.h"
-#include "base/macros.h"
+#include "ax/ax_action_data.h"
+#include "ax/ax_node_data.h"
+#include "ax/ax_role_properties.h"
#include "base/no_destructor.h"
-#include "base/strings/sys_string_conversions.h"
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/platform/ax_platform_node.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-#include "ui/base/l10n/l10n_util.h"
-#import "ui/gfx/mac/coordinate_conversion.h"
-#include "ui/strings/grit/ui_strings.h"
+#import "gfx/mac/coordinate_conversion.h"
+
+#include "ax_platform_node.h"
+#include "ax_platform_node_delegate.h"
namespace {
+NSString* const NSAccessibilityScrollToVisibleAction = @"AXScrollToVisible";
+
// Same length as web content/WebKit.
static int kLiveRegionDebounceMillis = 20;
@@ -295,7 +293,7 @@
const ActionList::value_type entries[] = {
// NSAccessibilityPressAction must come first in this list.
{ax::mojom::Action::kDoDefault, NSAccessibilityPressAction},
-
+ {ax::mojom::Action::kScrollToMakeVisible, NSAccessibilityScrollToVisibleAction},
{ax::mojom::Action::kDecrement, NSAccessibilityDecrementAction},
{ax::mojom::Action::kIncrement, NSAccessibilityIncrementAction},
{ax::mojom::Action::kShowContextMenu, NSAccessibilityShowMenuAction},
@@ -405,37 +403,39 @@
- (NSString*)getStringAttribute:(ax::mojom::StringAttribute)attribute {
std::string attributeValue;
if (_node->GetStringAttribute(attribute, &attributeValue))
- return base::SysUTF8ToNSString(attributeValue);
+ return @(attributeValue.data());
return nil;
}
- (NSString*)getAXValueAsString {
- id value = [self AXValue];
+ id value = [self AXValueInternal];
return [value isKindOfClass:[NSString class]] ? value : nil;
}
- (NSString*)getName {
- return base::SysUTF8ToNSString(_node->GetName());
+ return @(_node->GetName().data());
}
- (std::unique_ptr<AnnouncementSpec>)announcementForEvent:(ax::mojom::Event)eventType {
// Only alerts and live region changes should be announced.
- DCHECK(eventType == ax::mojom::Event::kAlert ||
- eventType == ax::mojom::Event::kLiveRegionChanged);
+ BASE_DCHECK(eventType == ax::mojom::Event::kAlert ||
+ eventType == ax::mojom::Event::kLiveRegionChanged);
std::string liveStatus = _node->GetStringAttribute(ax::mojom::StringAttribute::kLiveStatus);
// If live status is explicitly set to off, don't announce.
if (liveStatus == "off")
return nullptr;
NSString* name = [self getName];
- NSString* announcementText =
- [name length] > 0 ? name : base::SysUTF16ToNSString(_node->GetInnerText());
+ NSString* announcementText = name;
+ if ([announcementText length] <= 0) {
+ announcementText = @(base::UTF16ToUTF8(_node->GetInnerText()).data());
+ }
if ([announcementText length] == 0)
return nullptr;
auto announcement = std::make_unique<AnnouncementSpec>();
announcement->announcement = base::scoped_nsobject<NSString>([announcementText retain]);
- announcement->window = base::scoped_nsobject<NSWindow>([[self AXWindow] retain]);
+ announcement->window = base::scoped_nsobject<NSWindow>([[self AXWindowInternal] retain]);
announcement->is_polite = liveStatus != "assertive";
return announcement;
}
@@ -464,7 +464,7 @@
if (!_node)
return YES;
- return [[self AXRole] isEqualToString:NSAccessibilityUnknownRole] ||
+ return [[self AXRoleInternal] isEqualToString:NSAccessibilityUnknownRole] ||
_node->GetData().HasState(ax::mojom::State::kInvisible);
}
@@ -472,7 +472,7 @@
if (!NSPointInRect(point, [self boundsInScreen]))
return nil;
- for (id child in [[self AXChildren] reverseObjectEnumerator]) {
+ for (id child in [[self AXChildrenInternal] reverseObjectEnumerator]) {
if (!NSPointInRect(point, [child accessibilityFrame]))
continue;
if (id foundChild = [child accessibilityHitTest:point])
@@ -505,7 +505,7 @@
// VoiceOver expects the "press" action to be first. Note that some roles
// should be given a press action implicitly.
- DCHECK([action_list[0].second isEqualToString:NSAccessibilityPressAction]);
+ BASE_DCHECK([action_list[0].second isEqualToString:NSAccessibilityPressAction]);
for (const auto& item : action_list) {
if (data.HasAction(item.first) || HasImplicitAction(data, item.first))
[axActions addObject:item.second];
@@ -544,140 +544,32 @@
_node->GetDelegate()->AccessibilityPerformAction(data);
}
-// This method, while deprecated, is still called internally by AppKit.
-- (NSArray*)accessibilityAttributeNames {
- if (!_node)
- return @[];
- // These attributes are required on all accessibility objects.
- NSArray* const kAllRoleAttributes = @[
- NSAccessibilityChildrenAttribute,
- NSAccessibilityParentAttribute,
- NSAccessibilityPositionAttribute,
- NSAccessibilityRoleAttribute,
- NSAccessibilitySizeAttribute,
- NSAccessibilitySubroleAttribute,
- // Title is required for most elements. Cocoa asks for the value even if it
- // is omitted here, but won't present it to accessibility APIs without this.
- NSAccessibilityTitleAttribute,
- // Attributes which are not required, but are general to all roles.
- NSAccessibilityRoleDescriptionAttribute,
- NSAccessibilityEnabledAttribute,
- NSAccessibilityFocusedAttribute,
- NSAccessibilityHelpAttribute,
- NSAccessibilityTopLevelUIElementAttribute,
- NSAccessibilityWindowAttribute,
- ];
- // Attributes required for user-editable controls.
- NSArray* const kValueAttributes = @[ NSAccessibilityValueAttribute ];
- // Attributes required for unprotected textfields and labels.
- NSArray* const kUnprotectedTextAttributes = @[
- NSAccessibilityInsertionPointLineNumberAttribute,
- NSAccessibilityNumberOfCharactersAttribute,
- NSAccessibilitySelectedTextAttribute,
- NSAccessibilitySelectedTextRangeAttribute,
- NSAccessibilityVisibleCharacterRangeAttribute,
- ];
- // Required for all text, including protected textfields.
- NSString* const kTextAttributes = NSAccessibilityPlaceholderValueAttribute;
- base::scoped_nsobject<NSMutableArray> axAttributes([[NSMutableArray alloc] init]);
- [axAttributes addObjectsFromArray:kAllRoleAttributes];
- switch (_node->GetData().role) {
- case ax::mojom::Role::kTextField:
- case ax::mojom::Role::kTextFieldWithComboBox:
- case ax::mojom::Role::kStaticText:
- [axAttributes addObject:kTextAttributes];
- if (!_node->GetData().HasState(ax::mojom::State::kProtected))
- [axAttributes addObjectsFromArray:kUnprotectedTextAttributes];
- FALLTHROUGH;
- case ax::mojom::Role::kCheckBox:
- case ax::mojom::Role::kComboBoxMenuButton:
- case ax::mojom::Role::kMenuItemCheckBox:
- case ax::mojom::Role::kMenuItemRadio:
- case ax::mojom::Role::kRadioButton:
- case ax::mojom::Role::kSearchBox:
- case ax::mojom::Role::kSlider:
- case ax::mojom::Role::kSliderThumb:
- case ax::mojom::Role::kToggleButton:
- [axAttributes addObjectsFromArray:kValueAttributes];
- break;
- // TODO(tapted): Add additional attributes based on role.
- default:
- break;
- }
- if (_node->GetData().HasBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
- [axAttributes addObjectsFromArray:@[ NSAccessibilitySelectedAttribute ]];
- }
- if (ui::IsMenuItem(_node->GetData().role)) {
- [axAttributes addObjectsFromArray:@[ @"AXMenuItemMarkChar" ]];
- }
- return axAttributes.autorelease();
-}
-
-// Despite it being deprecated, AppKit internally calls this function sometimes
-// in unclear circumstances. It is implemented in terms of the new a11y API
-// here.
-- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute {
- if (!_node)
- return;
-
- if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
- [self setAccessibilityValue:value];
- } else if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
- [self setAccessibilitySelectedText:base::mac::ObjCCastStrict<NSString>(value)];
- } else if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
- [self setAccessibilitySelectedTextRange:base::mac::ObjCCastStrict<NSValue>(value).rangeValue];
- } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
- [self setAccessibilityFocused:base::mac::ObjCCastStrict<NSNumber>(value).boolValue];
- }
-}
-
-// This method, while deprecated, is still called internally by AppKit.
-- (id)accessibilityAttributeValue:(NSString*)attribute {
- if (!_node)
- return nil; // Return nil when detached. Even for ax::mojom::Role.
-
- SEL selector = NSSelectorFromString(attribute);
- if ([self respondsToSelector:selector])
- return [self performSelector:selector];
- return nil;
-}
-
-- (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter {
- if (!_node)
- return nil;
-
- SEL selector = NSSelectorFromString([attribute stringByAppendingString:@":"]);
- if ([self respondsToSelector:selector])
- return [self performSelector:selector withObject:parameter];
- return nil;
-}
-
-// NSAccessibility attributes. Order them according to
-// NSAccessibilityConstants.h, or see https://crbug.com/678898.
-
-- (NSString*)AXRole {
+- (NSString*)AXRoleInternal {
if (!_node)
return nil;
return [[self class] nativeRoleFromAXRole:_node->GetData().role];
}
-- (NSString*)AXRoleDescription {
+- (NSString*)AXRoleDescriptionInternal {
switch (_node->GetData().role) {
case ax::mojom::Role::kTab:
// There is no NSAccessibilityTabRole or similar (AXRadioButton is used
// instead). Do the same as NSTabView and put "tab" in the description.
- return [l10n_util::GetNSStringWithFixup(IDS_ACCNAME_TAB_ROLE_DESCRIPTION) lowercaseString];
+ // return [l10n_util::GetNSStringWithFixup(IDS_ACCNAME_TAB_ROLE_DESCRIPTION)
+ // lowercaseString];
+ return nil;
case ax::mojom::Role::kDisclosureTriangle:
- return [l10n_util::GetNSStringWithFixup(IDS_ACCNAME_DISCLOSURE_TRIANGLE_ROLE_DESCRIPTION)
- lowercaseString];
+ // return [l10n_util::GetNSStringWithFixup(
+ // IDS_ACCNAME_DISCLOSURE_TRIANGLE_ROLE_DESCRIPTION) lowercaseString];
+ return nil;
default:
break;
}
- return NSAccessibilityRoleDescription([self AXRole], [self AXSubrole]);
+ return NSAccessibilityRoleDescription([self AXRoleInternal], [self AXSubroleInternal]);
}
-- (NSString*)AXSubrole {
+- (NSString*)AXSubroleInternal {
ax::mojom::Role role = _node->GetData().role;
switch (role) {
case ax::mojom::Role::kTextField:
@@ -690,7 +582,7 @@
return [AXPlatformNodeCocoa nativeSubroleFromAXRole:role];
}
-- (NSString*)AXHelp {
+- (NSString*)AXHelpInternal {
// TODO(aleventhal) Key shortcuts attribute should eventually get
// its own field. Follow what WebKit does for aria-keyshortcuts, see
// https://bugs.webkit.org/show_bug.cgi?id=159215 (WebKit bug).
@@ -703,10 +595,10 @@
return [NSString stringWithFormat:@"%@ %@", desc, key];
}
-- (id)AXValue {
+- (id)AXValueInternal {
ax::mojom::Role role = _node->GetData().role;
if (role == ax::mojom::Role::kTab)
- return [self AXSelected];
+ return [self AXSelectedInternal];
if (ui::IsNameExposedInAXValueForRole(role))
return [self getName];
@@ -721,23 +613,23 @@
return [self getStringAttribute:ax::mojom::StringAttribute::kValue];
}
-- (NSNumber*)AXEnabled {
+- (NSNumber*)AXEnabledInternal {
return @(_node->GetData().GetRestriction() != ax::mojom::Restriction::kDisabled);
}
-- (NSNumber*)AXFocused {
+- (NSNumber*)AXFocusedInternal {
if (_node->GetData().HasState(ax::mojom::State::kFocusable))
return @(_node->GetDelegate()->GetFocus() == _node->GetNativeViewAccessible());
return @NO;
}
-- (id)AXParent {
+- (id)AXParentInternal {
if (!_node)
return nil;
return NSAccessibilityUnignoredAncestor(_node->GetParent());
}
-- (NSArray*)AXChildren {
+- (NSArray*)AXChildrenInternal {
if (!_node)
return @[];
@@ -750,36 +642,34 @@
return NSAccessibilityUnignoredChildren(children);
}
-- (id)AXWindow {
+- (id)AXWindowInternal {
return _node->GetDelegate()->GetNSWindow();
}
-- (id)AXTopLevelUIElement {
- return [self AXWindow];
+- (id)AXTopLevelUIElementInternal {
+ return [self AXWindowInternal];
}
-- (NSValue*)AXPosition {
+- (NSValue*)AXPositionInternal {
return [NSValue valueWithPoint:self.boundsInScreen.origin];
}
-- (NSValue*)AXSize {
+- (NSValue*)AXSizeInternal {
return [NSValue valueWithSize:self.boundsInScreen.size];
}
-- (NSString*)AXTitle {
+- (NSString*)AXTitleInternal {
if (ui::IsNameExposedInAXValueForRole(_node->GetData().role))
return @"";
return [self getName];
}
-// Misc attributes.
-
-- (NSNumber*)AXSelected {
+- (NSNumber*)AXSelectedInternal {
return @(_node->GetData().GetBoolAttribute(ax::mojom::BoolAttribute::kSelected));
}
-- (NSString*)AXPlaceholderValue {
+- (NSString*)AXPlaceholderValueInternal {
return [self getStringAttribute:ax::mojom::StringAttribute::kPlaceholder];
}
@@ -796,15 +686,13 @@
return @"";
}
-// Text-specific attributes.
-
-- (NSString*)AXSelectedText {
+- (NSString*)AXSelectedTextInternal {
NSRange selectedTextRange;
- [[self AXSelectedTextRange] getValue:&selectedTextRange];
+ [[self AXSelectedTextRangeInternal] getValue:&selectedTextRange];
return [[self getAXValueAsString] substringWithRange:selectedTextRange];
}
-- (NSValue*)AXSelectedTextRange {
+- (NSValue*)AXSelectedTextRangeInternal {
// Selection might not be supported. Return (NSRange){0,0} in that case.
int start = 0, end = 0;
if (_node->IsPlainTextField()) {
@@ -813,87 +701,28 @@
}
// NSRange cannot represent the direction the text was selected in.
- return [NSValue valueWithRange:{std::min(start, end), abs(end - start)}];
+ return [NSValue valueWithRange:{static_cast<NSUInteger>(std::min(start, end)),
+ static_cast<NSUInteger>(abs(end - start))}];
}
-- (NSNumber*)AXNumberOfCharacters {
+- (NSNumber*)AXNumberOfCharactersInternal {
return @([[self getAXValueAsString] length]);
}
-- (NSValue*)AXVisibleCharacterRange {
+- (NSValue*)AXVisibleCharacterRangeInternal {
return [NSValue valueWithRange:{0, [[self getAXValueAsString] length]}];
}
-- (NSNumber*)AXInsertionPointLineNumber {
+- (NSNumber*)AXInsertionPointLineNumberInternal {
// Multiline is not supported on views.
return @0;
}
-// Parameterized text-specific attributes.
-
-- (id)AXLineForIndex:(id)parameter {
- DCHECK([parameter isKindOfClass:[NSNumber class]]);
- // Multiline is not supported on views.
- return @0;
-}
-
-- (id)AXRangeForLine:(id)parameter {
- DCHECK([parameter isKindOfClass:[NSNumber class]]);
- DCHECK_EQ(0, [parameter intValue]);
- return [NSValue valueWithRange:{0, [[self getAXValueAsString] length]}];
-}
-
-- (id)AXStringForRange:(id)parameter {
- DCHECK([parameter isKindOfClass:[NSValue class]]);
- return [[self getAXValueAsString] substringWithRange:[parameter rangeValue]];
-}
-
-- (id)AXRangeForPosition:(id)parameter {
- DCHECK([parameter isKindOfClass:[NSValue class]]);
- // TODO(tapted): Hit-test [parameter pointValue] and return an NSRange.
- NOTIMPLEMENTED();
- return nil;
-}
-
-- (id)AXRangeForIndex:(id)parameter {
- DCHECK([parameter isKindOfClass:[NSNumber class]]);
- NOTIMPLEMENTED();
- return nil;
-}
-
-- (id)AXBoundsForRange:(id)parameter {
- DCHECK([parameter isKindOfClass:[NSValue class]]);
- // TODO(tapted): Provide an accessor on AXPlatformNodeDelegate to obtain this
- // from ui::TextInputClient::GetCompositionCharacterBounds().
- NOTIMPLEMENTED();
- return nil;
-}
-
-- (id)AXRTFForRange:(id)parameter {
- DCHECK([parameter isKindOfClass:[NSValue class]]);
- NOTIMPLEMENTED();
- return nil;
-}
-
-- (id)AXStyleRangeForIndex:(id)parameter {
- DCHECK([parameter isKindOfClass:[NSNumber class]]);
- NOTIMPLEMENTED();
- return nil;
-}
-
-- (id)AXAttributedStringForRange:(id)parameter {
- DCHECK([parameter isKindOfClass:[NSValue class]]);
- base::scoped_nsobject<NSAttributedString> attributedString(
- [[NSAttributedString alloc] initWithString:[self AXStringForRange:parameter]]);
- // TODO(tapted): views::WordLookupClient has a way to obtain the actual
- // decorations, and BridgedContentView has a conversion function that creates
- // an NSAttributedString. Refactor things so they can be used here.
- return attributedString.autorelease();
-}
+// Method based accessibility APIs.
- (NSString*)description {
- return [NSString
- stringWithFormat:@"%@ - %@ (%@)", [super description], [self AXTitle], [self AXRole]];
+ return [NSString stringWithFormat:@"%@ - %@ (%@)", [super description], [self AXTitleInternal],
+ [self AXRoleInternal]];
}
// The methods below implement the NSAccessibility protocol. These methods
@@ -906,21 +735,17 @@
// accessibilityPerformFoo methods, or are the stub implementations from
// NSAccessibilityElement sufficient?
- (NSArray*)accessibilityChildren {
- return [self AXChildren];
+ return [self AXChildrenInternal];
}
- (BOOL)isAccessibilityElement {
if (!_node)
return NO;
-
- return (![[self AXRole] isEqualToString:NSAccessibilityUnknownRole] &&
+ return (![[self AXRoleInternal] isEqualToString:NSAccessibilityUnknownRole] &&
!_node->GetData().HasState(ax::mojom::State::kInvisible));
}
- (BOOL)isAccessibilityEnabled {
- if (!_node)
- return NO;
-
- return _node->GetData().GetRestriction() != ax::mojom::Restriction::kDisabled;
+ return [[self AXEnabledInternal] boolValue];
}
- (NSRect)accessibilityFrame {
return [self boundsInScreen];
@@ -931,23 +756,47 @@
// and accessibilityTitle is "the title of the accessibility element"; at
// least in Chromium, the title usually is a short description of the element,
// so it also functions as a label.
- return [self AXTitle];
+ return [self AXTitleInternal];
}
- (NSString*)accessibilityTitle {
- return [self AXTitle];
+ return [self AXTitleInternal];
}
- (id)accessibilityValue {
- return [self AXValue];
+ return [self AXValueInternal];
}
- (NSAccessibilityRole)accessibilityRole {
- return [self AXRole];
+ return [self AXRoleInternal];
+}
+
+- (NSString*)accessibilityRoleDescription {
+ return [self AXRoleDescriptionInternal];
}
- (NSAccessibilitySubrole)accessibilitySubrole {
- return [self AXSubrole];
+ return [self AXSubroleInternal];
+}
+
+- (NSString*)accessibilityHelp {
+ return [self AXHelpInternal];
+}
+
+- (id)accessibilityParent {
+ return [self AXParentInternal];
+}
+
+- (id)accessibilityWindow {
+ return [self AXWindowInternal];
+}
+
+- (id)accessibilityTopLevelUIElement {
+ return [self AXTopLevelUIElementInternal];
+}
+
+- (BOOL)accessibilitySelected {
+ return [[self AXSelectedInternal] boolValue];
}
- (BOOL)isAccessibilitySelectorAllowed:(SEL)selector {
@@ -974,7 +823,8 @@
// accessibility clients from trying to set the selection range, which won't
// work because of 692362.
if (selector == @selector(setAccessibilitySelectedText:) ||
- selector == @selector(setAccessibilitySelectedTextRange:)) {
+ selector == @selector(setAccessibilitySelectedTextRange:) ||
+ selector == @selector(setAccessibilitySelectedTextMarkerRange:)) {
return restriction != ax::mojom::Restriction::kReadOnly;
}
@@ -993,7 +843,7 @@
data.action = _node->GetData().role == ax::mojom::Role::kTab ? ax::mojom::Action::kSetSelection
: ax::mojom::Action::kSetValue;
if ([value isKindOfClass:[NSString class]]) {
- data.value = base::SysNSStringToUTF8(value);
+ data.value = std::string([value UTF8String]);
} else if ([value isKindOfClass:[NSValue class]]) {
// TODO(https://crbug.com/386671): Is this case actually needed? The
// NSObject accessibility implementation supported this, but can it actually
@@ -1008,7 +858,6 @@
- (void)setAccessibilityFocused:(BOOL)isFocused {
if (!_node)
return;
-
ui::AXActionData data;
data.action = isFocused ? ax::mojom::Action::kFocus : ax::mojom::Action::kBlur;
_node->GetDelegate()->AccessibilityPerformAction(data);
@@ -1017,10 +866,9 @@
- (void)setAccessibilitySelectedText:(NSString*)text {
if (!_node)
return;
-
ui::AXActionData data;
data.action = ax::mojom::Action::kReplaceSelectedText;
- data.value = base::SysNSStringToUTF8(text);
+ data.value = std::string([text UTF8String]);
_node->GetDelegate()->AccessibilityPerformAction(data);
}
@@ -1028,7 +876,6 @@
- (void)setAccessibilitySelectedTextRange:(NSRange)range {
if (!_node)
return;
-
ui::AXActionData data;
data.action = ax::mojom::Action::kSetSelection;
data.anchor_offset = range.location;
@@ -1038,32 +885,31 @@
// "Configuring Text Elements" section of the NSAccessibility formal protocol.
// These are all "required" methods, although in practice the ones that are left
-// NOTIMPLEMENTED() seem to not be called anywhere (and were NOTIMPLEMENTED in
+// BASE_UNREACHABLE() seem to not be called anywhere (and were BASE_DCHECK false in
// the old API as well).
- (NSInteger)accessibilityInsertionPointLineNumber {
- return 0;
+ return [[self AXInsertionPointLineNumberInternal] integerValue];
}
- (NSInteger)accessibilityNumberOfCharacters {
if (!_node)
return 0;
-
- return [[self getAXValueAsString] length];
+ return [[self AXNumberOfCharactersInternal] integerValue];
}
- (NSString*)accessibilityPlaceholderValue {
if (!_node)
return nil;
- return [self AXPlaceholderValue];
+ return [self AXPlaceholderValueInternal];
}
- (NSString*)accessibilitySelectedText {
if (!_node)
return nil;
- return [self AXSelectedText];
+ return [self AXSelectedTextInternal];
}
- (NSRange)accessibilitySelectedTextRange {
@@ -1071,7 +917,7 @@
return NSMakeRange(0, 0);
NSRange r;
- [[self AXSelectedTextRange] getValue:&r];
+ [[self AXSelectedTextRangeInternal] getValue:&r];
return r;
}
@@ -1079,14 +925,30 @@
if (!_node)
return nil;
- return @[ [self AXSelectedTextRange] ];
+ return @[ [self AXSelectedTextRangeInternal] ];
+}
+
+- (NSRange)accessibilitySharedCharacterRange {
+ if (!_node)
+ return NSMakeRange(0, 0);
+
+ NSRange r;
+ [[self AXSelectedTextRangeInternal] getValue:&r];
+ return r;
+}
+
+- (NSArray*)accessibilitySharedTextUIElements {
+ if (!_node)
+ return nil;
+
+ return @[ self ];
}
- (NSRange)accessibilityVisibleCharacterRange {
if (!_node)
return NSMakeRange(0, 0);
- return NSMakeRange(0, [self accessibilityNumberOfCharacters]);
+ return [[self AXVisibleCharacterRangeInternal] rangeValue];
}
- (NSString*)accessibilityStringForRange:(NSRange)range {
@@ -1099,20 +961,27 @@
- (NSAttributedString*)accessibilityAttributedStringForRange:(NSRange)range {
if (!_node)
return nil;
-
// TODO(https://crbug.com/958811): Implement this for real.
base::scoped_nsobject<NSAttributedString> attributedString(
[[NSAttributedString alloc] initWithString:[self accessibilityStringForRange:range]]);
return attributedString.autorelease();
}
+- (NSData*)accessibilityRTFForRange:(NSRange)range {
+ return nil;
+}
+
+- (NSRect)accessibilityFrameForRange:(NSRange)range {
+ return NSZeroRect;
+}
+
- (NSInteger)accessibilityLineForIndex:(NSInteger)index {
// Views textfields are single-line.
return 0;
}
- (NSRange)accessibilityRangeForIndex:(NSInteger)index {
- NOTIMPLEMENTED();
+ BASE_UNREACHABLE();
return NSMakeRange(0, 0);
}
@@ -1128,16 +997,40 @@
if (!_node)
return NSMakeRange(0, 0);
- if (line != 0)
- NOTIMPLEMENTED() << "Views textfields are single-line.";
+ if (line != 0) {
+ BASE_LOG() << "Views textfields are single-line.";
+ BASE_UNREACHABLE();
+ }
return NSMakeRange(0, [self accessibilityNumberOfCharacters]);
}
- (NSRange)accessibilityRangeForPosition:(NSPoint)point {
- NOTIMPLEMENTED();
+ BASE_UNREACHABLE();
return NSMakeRange(0, 0);
}
+// "Setting the Focus" section of the NSAccessibility formal protocol.
+// These are all "required" methods.
+
+- (NSArray*)accessibilitySharedFocusElements {
+ if (![[self AXFocusedInternal] boolValue])
+ return nil;
+ return @[ self ];
+}
+- (id)accessibilityFocusedWindow {
+ if (![[self AXFocusedInternal] boolValue])
+ return nil;
+ return self;
+}
+- (id)accessibilityApplicationFocusedUIElement {
+ if (![[self AXFocusedInternal] boolValue])
+ return nil;
+ return self;
+}
+- (BOOL)isAccessibilityFocused {
+ return [[self AXFocusedInternal] boolValue];
+}
+
@end
namespace ui {
@@ -1220,8 +1113,9 @@
NotifyMacEvent(native_node_, event_type);
}
-void AXPlatformNodeMac::AnnounceText(const base::string16& text) {
- PostAnnouncementNotification(base::SysUTF16ToNSString(text), [native_node_ AXWindow], false);
+void AXPlatformNodeMac::AnnounceText(const std::u16string& text) {
+ PostAnnouncementNotification(@(base::UTF16ToUTF8(text).data()), [native_node_ AXWindowInternal],
+ false);
}
bool IsNameExposedInAXValueForRole(ax::mojom::Role role) {
@@ -1240,7 +1134,7 @@
void AXPlatformNodeMac::AddAttributeToList(const char* name,
const char* value,
PlatformAttributeList* attributes) {
- NOTREACHED();
+ BASE_UNREACHABLE();
}
} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_test_helper.cc b/third_party/accessibility/ax/platform/ax_platform_node_test_helper.cc
deleted file mode 100644
index 254594f..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_test_helper.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_node_test_helper.h"
-
-#include "ui/accessibility/ax_node_data.h"
-
-namespace ui {
-
-// static
-int AXPlatformNodeTestHelper::GetTreeSize(AXPlatformNode* ax_node) {
- if (!ax_node)
- return 0;
- int count = 1;
- AXPlatformNodeDelegate* delegate = ax_node->GetDelegate();
- for (int i = 0; i < delegate->GetChildCount(); ++i) {
- AXPlatformNode* child_node =
- AXPlatformNode::FromNativeViewAccessible(delegate->ChildAtIndex(i));
- count += GetTreeSize(child_node);
- }
- return count;
-}
-
-// static
-AXPlatformNode* AXPlatformNodeTestHelper::FindChildByName(
- AXPlatformNode* ax_node,
- const std::string& name) {
- if (!ax_node)
- return nullptr;
-
- AXPlatformNodeDelegate* delegate = ax_node->GetDelegate();
- if (delegate->GetName() == name)
- return ax_node;
-
- for (int i = 0; i < delegate->GetChildCount(); ++i) {
- AXPlatformNode* result_from_child = FindChildByName(
- AXPlatformNode::FromNativeViewAccessible(delegate->ChildAtIndex(i)),
- name);
- if (result_from_child)
- return result_from_child;
- }
- return nullptr;
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_test_helper.h b/third_party/accessibility/ax/platform/ax_platform_node_test_helper.h
deleted file mode 100644
index dd5ffb2..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_test_helper.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_TEST_HELPER_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_TEST_HELPER_H_
-
-#include <string>
-
-#include "ui/accessibility/platform/ax_platform_node.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-
-namespace ui {
-
-class AX_EXPORT AXPlatformNodeTestHelper {
- public:
- static int GetTreeSize(AXPlatformNode* ax_node);
- static AXPlatformNode* FindChildByName(AXPlatformNode* ax_node,
- const std::string& name);
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_TEST_HELPER_H_
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_textchildprovider_win.cc b/third_party/accessibility/ax/platform/ax_platform_node_textchildprovider_win.cc
deleted file mode 100644
index 42139b6..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_textchildprovider_win.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_node_textchildprovider_win.h"
-
-#include <UIAutomationClient.h>
-#include <UIAutomationCoreApi.h>
-
-#include "ui/accessibility/platform/ax_platform_node_textprovider_win.h"
-#include "ui/base/win/atl_module.h"
-
-#define UIA_VALIDATE_TEXTCHILDPROVIDER_CALL() \
- if (!owner()->GetDelegate()) \
- return UIA_E_ELEMENTNOTAVAILABLE;
-
-namespace ui {
-
-namespace {
-
-AXPlatformNodeWin* GetParentAXPlatformNodeWin(AXPlatformNodeWin* node) {
- gfx::NativeViewAccessible native_parent = node->GetParent();
-
- DCHECK(native_parent != node->GetNativeViewAccessible());
-
- return static_cast<AXPlatformNodeWin*>(
- AXPlatformNode::FromNativeViewAccessible(native_parent));
-}
-
-} // namespace
-
-AXPlatformNodeTextChildProviderWin::AXPlatformNodeTextChildProviderWin() {
- DVLOG(1) << __func__;
-}
-
-AXPlatformNodeTextChildProviderWin::~AXPlatformNodeTextChildProviderWin() {}
-
-// static
-AXPlatformNodeTextChildProviderWin* AXPlatformNodeTextChildProviderWin::Create(
- AXPlatformNodeWin* owner) {
- CComObject<AXPlatformNodeTextChildProviderWin>* text_child_provider = nullptr;
- if (SUCCEEDED(CComObject<AXPlatformNodeTextChildProviderWin>::CreateInstance(
- &text_child_provider))) {
- DCHECK(text_child_provider);
- text_child_provider->owner_ = owner;
- text_child_provider->AddRef();
- return text_child_provider;
- }
-
- return nullptr;
-}
-
-// static
-void AXPlatformNodeTextChildProviderWin::CreateIUnknown(
- AXPlatformNodeWin* owner,
- IUnknown** unknown) {
- Microsoft::WRL::ComPtr<AXPlatformNodeTextChildProviderWin>
- text_child_provider(Create(owner));
- if (text_child_provider)
- *unknown = text_child_provider.Detach();
-}
-
-HRESULT AXPlatformNodeTextChildProviderWin::get_TextContainer(
- IRawElementProviderSimple** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTCHILD_GET_TEXTCONTAINER);
- UIA_VALIDATE_TEXTCHILDPROVIDER_CALL();
-
- *result = nullptr;
-
- AXPlatformNodeWin* container = GetTextContainer(owner_.Get());
- if (container)
- container->QueryInterface(IID_PPV_ARGS(result));
-
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextChildProviderWin::get_TextRange(
- ITextRangeProvider** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTCHILD_GET_TEXTRANGE);
- UIA_VALIDATE_TEXTCHILDPROVIDER_CALL();
-
- *result = nullptr;
-
- AXPlatformNodeWin* container = GetTextContainer(owner_.Get());
- if (container && container->IsDescendant(owner())) {
- *result =
- AXPlatformNodeTextProviderWin::GetRangeFromChild(container, owner());
- }
-
- return S_OK;
-}
-
-AXPlatformNodeWin* AXPlatformNodeTextChildProviderWin::GetTextContainer(
- AXPlatformNodeWin* descendant) {
- for (AXPlatformNodeWin* parent = GetParentAXPlatformNodeWin(descendant);
- parent; parent = GetParentAXPlatformNodeWin(parent)) {
- if (parent->IsPatternProviderSupported(UIA_TextPatternId)) {
- return parent;
- }
- }
-
- return nullptr;
-}
-
-AXPlatformNodeWin* AXPlatformNodeTextChildProviderWin::owner() const {
- return owner_.Get();
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_textchildprovider_win.h b/third_party/accessibility/ax/platform/ax_platform_node_textchildprovider_win.h
deleted file mode 100644
index 75f0f51..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_textchildprovider_win.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_TEXTCHILDPROVIDER_WIN_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_TEXTCHILDPROVIDER_WIN_H_
-
-#include <wrl/client.h>
-
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/platform/ax_platform_node_win.h"
-
-namespace ui {
-class AX_EXPORT AXPlatformNodeTextChildProviderWin
- : public CComObjectRootEx<CComMultiThreadModel>,
- public ITextChildProvider {
- public:
- BEGIN_COM_MAP(AXPlatformNodeTextChildProviderWin)
- COM_INTERFACE_ENTRY(ITextChildProvider)
- END_COM_MAP()
-
- AXPlatformNodeTextChildProviderWin();
- ~AXPlatformNodeTextChildProviderWin();
-
- static AXPlatformNodeTextChildProviderWin* Create(
- ui::AXPlatformNodeWin* owner);
- static void CreateIUnknown(AXPlatformNodeWin* owner, IUnknown** unknown);
-
- // Retrieves this element's nearest ancestor provider that supports the Text
- // control pattern. If the element does not have an ancestor which supports
- // the Text control pattern, nullptr is returned. Note, an element which
- // supports the Text control pattern is not an ancestor of itself.
- IFACEMETHODIMP get_TextContainer(
- IRawElementProviderSimple** pRetVal) override;
-
- // Retrieves a text range that encloses this child element. If the element
- // does not have an ancestor which supports the Text control pattern, nullptr
- // is returned. Note, an element which supports the Text control pattern is
- // not an ancestor of itself.
- IFACEMETHODIMP get_TextRange(ITextRangeProvider** pRetVal) override;
-
- // Helper function to get_TextContainer().
- static AXPlatformNodeWin* GetTextContainer(AXPlatformNodeWin* descendant);
-
- private:
- AXPlatformNodeWin* owner() const;
-
- Microsoft::WRL::ComPtr<AXPlatformNodeWin> owner_;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_TEXTCHILDPROVIDER_WIN_H_
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_textchildprovider_win_unittest.cc b/third_party/accessibility/ax/platform/ax_platform_node_textchildprovider_win_unittest.cc
deleted file mode 100644
index ec5adb6..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_textchildprovider_win_unittest.cc
+++ /dev/null
@@ -1,381 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_node_win_unittest.h"
-
-#include "base/win/scoped_bstr.h"
-#include "ui/accessibility/platform/ax_fragment_root_win.h"
-#include "ui/accessibility/platform/ax_platform_node_textchildprovider_win.h"
-#include "ui/accessibility/platform/ax_platform_node_textprovider_win.h"
-#include "ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h"
-
-using Microsoft::WRL::ComPtr;
-
-namespace ui {
-
-class AXPlatformNodeTextChildProviderTest : public AXPlatformNodeWinTest {
- protected:
- // Construct an accessibility tree for testing ITextChildProvider resolution
- // from various positions in the tree. The following tree configuration
- // is constructed:
- //
- // root_________________________________________________
- // | |
- // nontext_child_of_root______ text_child_of_root
- // | | |
- // nontext_child_of_nontext text_child_of_nontext text_child_of_text
- //
- // nontext leaf elements are considered as embedded objects and expose a
- // character to allow the text pattern navigation to work with them too.
- // Because of that, a nontext leaf element is treated as a text element.
- void SetUp() override {
- ui::AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
-
- ui::AXNodeData nontext_child_of_root;
- nontext_child_of_root.id = 2;
- nontext_child_of_root.role = ax::mojom::Role::kGroup;
- nontext_child_of_root.SetName("non text child of root.");
- root.child_ids.push_back(nontext_child_of_root.id);
-
- ui::AXNodeData text_child_of_root;
- text_child_of_root.id = 3;
- text_child_of_root.role = ax::mojom::Role::kStaticText;
- text_child_of_root.SetName("text child of root.");
- root.child_ids.push_back(text_child_of_root.id);
-
- ui::AXNodeData nontext_child_of_nontext;
- nontext_child_of_nontext.id = 4;
- nontext_child_of_nontext.role = ax::mojom::Role::kGroup;
- nontext_child_of_nontext.SetName("nontext child of nontext.");
- nontext_child_of_root.child_ids.push_back(nontext_child_of_nontext.id);
-
- ui::AXNodeData text_child_of_nontext;
- text_child_of_nontext.id = 5;
- text_child_of_nontext.role = ax::mojom::Role::kStaticText;
- text_child_of_nontext.SetName("text child of nontext.");
- nontext_child_of_root.child_ids.push_back(text_child_of_nontext.id);
-
- ui::AXNodeData text_child_of_text;
- text_child_of_text.id = 6;
- text_child_of_text.role = ax::mojom::Role::kInlineTextBox;
- text_child_of_text.SetName("text child of text.");
- text_child_of_root.child_ids.push_back(text_child_of_text.id);
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root.id;
- update.nodes = {root,
- nontext_child_of_root,
- text_child_of_root,
- nontext_child_of_nontext,
- text_child_of_nontext,
- text_child_of_text};
-
- Init(update);
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* nontext_child_of_root_node = root_node->children()[0];
- AXNode* text_child_of_root_node = root_node->children()[1];
- AXNode* nontext_child_of_nontext_node =
- nontext_child_of_root_node->children()[0];
- AXNode* text_child_of_nontext_node =
- nontext_child_of_root_node->children()[1];
- AXNode* text_child_of_text_node = text_child_of_root_node->children()[0];
-
- InitITextChildProvider(root_node, root_provider_raw_,
- root_text_child_provider_);
- InitITextChildProvider(nontext_child_of_root_node,
- nontext_child_of_root_provider_raw_,
- nontext_child_of_root_text_child_provider_);
- InitITextChildProvider(text_child_of_root_node,
- text_child_of_root_text_provider_raw_,
- text_child_of_root_text_child_provider_);
- InitITextChildProvider(nontext_child_of_nontext_node,
- nontext_child_of_nontext_text_provider_raw_,
- nontext_child_of_nontext_text_child_provider_);
- InitITextChildProvider(text_child_of_nontext_node,
- text_child_of_nontext_text_provider_raw_,
- text_child_of_nontext_text_child_provider_);
- InitITextChildProvider(text_child_of_text_node,
- text_child_of_text_text_provider_raw_,
- text_child_of_text_text_child_provider_);
- }
-
- void InitITextChildProvider(
- AXNode* node,
- ComPtr<IRawElementProviderSimple>& raw_element_provider,
- ComPtr<ITextChildProvider>& text_child_provider) {
- raw_element_provider =
- QueryInterfaceFromNode<IRawElementProviderSimple>(node);
-
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider->GetPatternProvider(
- UIA_TextChildPatternId, &text_child_provider));
-
- // If the element does not support ITextChildProvider, create one anyways
- // for testing purposes.
- if (!text_child_provider) {
- ui::AXPlatformNodeWin* platform_node =
- (ui::AXPlatformNodeWin*)raw_element_provider.Get();
-
- ComPtr<ITextChildProvider> new_child_provider =
- ui::AXPlatformNodeTextChildProviderWin::Create(platform_node);
- new_child_provider->QueryInterface(IID_PPV_ARGS(&text_child_provider));
- }
- }
-
- ComPtr<IRawElementProviderSimple> root_provider_raw_;
- ComPtr<IRawElementProviderSimple> nontext_child_of_root_provider_raw_;
- ComPtr<IRawElementProviderSimple> text_child_of_root_text_provider_raw_;
- ComPtr<IRawElementProviderSimple> nontext_child_of_nontext_text_provider_raw_;
- ComPtr<IRawElementProviderSimple> text_child_of_nontext_text_provider_raw_;
- ComPtr<IRawElementProviderSimple> text_child_of_text_text_provider_raw_;
-
- ComPtr<ITextChildProvider> root_text_child_provider_;
- ComPtr<ITextChildProvider> nontext_child_of_root_text_child_provider_;
- ComPtr<ITextChildProvider> text_child_of_root_text_child_provider_;
- ComPtr<ITextChildProvider> nontext_child_of_nontext_text_child_provider_;
- ComPtr<ITextChildProvider> text_child_of_nontext_text_child_provider_;
- ComPtr<ITextChildProvider> text_child_of_text_text_child_provider_;
-};
-
-// ITextChildProvider::TextContainer Tests
-//
-// For each possible position in the tree verify:
-// 1) A text container can/cannot be retrieved if an ancestor does/doesn't
-// support the UIA Text control pattern.
-// 2) Any retrieved text container is the nearest ancestor text container.
-// 3) A Text control can in fact be retrieved from any retrieved text
-// container.
-
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderTextContainerFromRoot) {
- ComPtr<IRawElementProviderSimple> text_container;
- EXPECT_HRESULT_SUCCEEDED(
- root_text_child_provider_->get_TextContainer(&text_container));
- ASSERT_EQ(nullptr, text_container.Get());
-}
-
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderTextContainerFromNontextChildOfRoot) {
- ComPtr<IRawElementProviderSimple> text_container;
- EXPECT_HRESULT_SUCCEEDED(
- nontext_child_of_root_text_child_provider_->get_TextContainer(
- &text_container));
- ASSERT_NE(nullptr, text_container.Get());
-
- EXPECT_EQ(root_provider_raw_.Get(), text_container.Get());
-
- ComPtr<IUnknown> pattern_provider;
- ComPtr<ITextProvider> text_container_text_provider;
- text_container->GetPatternProvider(UIA_TextPatternId, &pattern_provider);
- ASSERT_NE(nullptr, pattern_provider.Get());
- EXPECT_HRESULT_SUCCEEDED(pattern_provider.As(&text_container_text_provider));
-}
-
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderTextContainerFromTextChildOfRoot) {
- ComPtr<IRawElementProviderSimple> text_container;
- EXPECT_HRESULT_SUCCEEDED(
- text_child_of_root_text_child_provider_->get_TextContainer(
- &text_container));
- ASSERT_NE(nullptr, text_container.Get());
-
- EXPECT_EQ(root_provider_raw_.Get(), text_container.Get());
-
- ComPtr<IUnknown> pattern_provider;
- ComPtr<ITextProvider> text_container_text_provider;
- text_container->GetPatternProvider(UIA_TextPatternId, &pattern_provider);
- ASSERT_NE(nullptr, pattern_provider.Get());
- EXPECT_HRESULT_SUCCEEDED(pattern_provider.As(&text_container_text_provider));
-}
-
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderTextContainerFromNontextChildOfNontext) {
- ComPtr<IRawElementProviderSimple> text_container;
- EXPECT_HRESULT_SUCCEEDED(
- nontext_child_of_nontext_text_child_provider_->get_TextContainer(
- &text_container));
- ASSERT_NE(nullptr, text_container.Get());
-
- EXPECT_EQ(root_provider_raw_.Get(), text_container.Get());
-
- ComPtr<IUnknown> pattern_provider;
- ComPtr<ITextProvider> text_container_text_provider;
- text_container->GetPatternProvider(UIA_TextPatternId, &pattern_provider);
- ASSERT_NE(nullptr, pattern_provider.Get());
- EXPECT_HRESULT_SUCCEEDED(pattern_provider.As(&text_container_text_provider));
-}
-
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderTextContainerFromTextChildOfNontext) {
- ComPtr<IRawElementProviderSimple> text_container;
- EXPECT_HRESULT_SUCCEEDED(
- text_child_of_nontext_text_child_provider_->get_TextContainer(
- &text_container));
- ASSERT_NE(nullptr, text_container.Get());
-
- EXPECT_EQ(root_provider_raw_.Get(), text_container.Get());
-
- ComPtr<IUnknown> pattern_provider;
- ComPtr<ITextProvider> text_container_text_provider;
- text_container->GetPatternProvider(UIA_TextPatternId, &pattern_provider);
- ASSERT_NE(nullptr, pattern_provider.Get());
- EXPECT_HRESULT_SUCCEEDED(pattern_provider.As(&text_container_text_provider));
-}
-
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderTextContainerFromTextChildOfText) {
- ComPtr<IRawElementProviderSimple> text_container;
- EXPECT_HRESULT_SUCCEEDED(
- text_child_of_text_text_child_provider_->get_TextContainer(
- &text_container));
- ASSERT_NE(nullptr, text_container.Get());
-
- EXPECT_EQ(text_child_of_root_text_provider_raw_.Get(), text_container.Get());
-
- ComPtr<IUnknown> pattern_provider;
- ComPtr<ITextProvider> text_container_text_provider;
- text_container->GetPatternProvider(UIA_TextPatternId, &pattern_provider);
- ASSERT_NE(nullptr, pattern_provider.Get());
- EXPECT_HRESULT_SUCCEEDED(pattern_provider.As(&text_container_text_provider));
-}
-
-// ITextChildProvider::TextRange Tests
-//
-// For each possible position in the tree verify:
-// 1) A text range can/cannot be retrieved if an ancestor does/doesn't
-// support the UIA Text control pattern.
-// 2) Any retrieved text range encloses the child element.
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderTextRangeFromRoot) {
- ComPtr<ITextRangeProvider> text_range_provider;
- EXPECT_HRESULT_SUCCEEDED(
- root_text_child_provider_->get_TextRange(&text_range_provider));
- EXPECT_EQ(nullptr, text_range_provider.Get());
-}
-
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderTextRangeFromNontextChildOfRoot) {
- ComPtr<ITextRangeProvider> text_range_provider;
- EXPECT_HRESULT_SUCCEEDED(
- nontext_child_of_root_text_child_provider_->get_TextRange(
- &text_range_provider));
- ASSERT_NE(nullptr, text_range_provider.Get());
-
- base::win::ScopedBstr text_content;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_EQ(
- 0,
- wcscmp(text_content.Get(),
- (kEmbeddedCharacterAsString + L"text child of nontext.").c_str()));
-
- ComPtr<IRawElementProviderSimple> enclosing_element;
- text_range_provider->GetEnclosingElement(&enclosing_element);
- EXPECT_EQ(nontext_child_of_root_provider_raw_.Get(), enclosing_element.Get());
-}
-
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderTextRangeFromTextChildOfRoot) {
- ComPtr<ITextRangeProvider> text_range_provider;
- EXPECT_HRESULT_SUCCEEDED(
- text_child_of_root_text_child_provider_->get_TextRange(
- &text_range_provider));
- ASSERT_NE(nullptr, text_range_provider.Get());
-
- base::win::ScopedBstr text_content;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_EQ(0, wcscmp(text_content.Get(), L"text child of text."));
-
- ComPtr<IRawElementProviderSimple> enclosing_element;
- text_range_provider->GetEnclosingElement(&enclosing_element);
- EXPECT_EQ(text_child_of_root_text_provider_raw_.Get(),
- enclosing_element.Get());
-}
-
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderTextRangeFromNontextChildOfNontext) {
- ComPtr<ITextRangeProvider> text_range_provider;
- EXPECT_HRESULT_SUCCEEDED(
- nontext_child_of_nontext_text_child_provider_->get_TextRange(
- &text_range_provider));
- ASSERT_NE(nullptr, text_range_provider.Get());
-
- base::win::ScopedBstr text_content;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_EQ(0, wcscmp(text_content.Get(), kEmbeddedCharacterAsString.c_str()));
-
- ComPtr<IRawElementProviderSimple> enclosing_element;
- text_range_provider->GetEnclosingElement(&enclosing_element);
- EXPECT_EQ(nontext_child_of_nontext_text_provider_raw_.Get(),
- enclosing_element.Get());
-}
-
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderTextRangeFromTextChildOfNontext) {
- ComPtr<ITextRangeProvider> text_range_provider;
- EXPECT_HRESULT_SUCCEEDED(
- text_child_of_nontext_text_child_provider_->get_TextRange(
- &text_range_provider));
- ASSERT_NE(nullptr, text_range_provider.Get());
-
- base::win::ScopedBstr text_content;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_EQ(0, wcscmp(text_content.Get(), L"text child of nontext."));
-
- ComPtr<IRawElementProviderSimple> enclosing_element;
- text_range_provider->GetEnclosingElement(&enclosing_element);
- EXPECT_EQ(text_child_of_nontext_text_provider_raw_.Get(),
- enclosing_element.Get());
-}
-
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderTextRangeFromTextChildOfText) {
- ComPtr<ITextRangeProvider> text_range_provider;
- EXPECT_HRESULT_SUCCEEDED(
- text_child_of_text_text_child_provider_->get_TextRange(
- &text_range_provider));
- ASSERT_NE(nullptr, text_range_provider.Get());
-
- base::win::ScopedBstr text_content;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_EQ(0, wcscmp(text_content.Get(), L"text child of text."));
-
- ComPtr<IRawElementProviderSimple> enclosing_element;
- text_range_provider->GetEnclosingElement(&enclosing_element);
- EXPECT_EQ(text_child_of_root_text_provider_raw_.Get(),
- enclosing_element.Get());
-}
-
-// ITextChildProvider Tests - Inactive AX Tree
-//
-// Test that both ITextChildProvider::GetTextContainer and
-// ITextChildProvider::GetTextContainer fail under an inactive AX tree.
-TEST_F(AXPlatformNodeTextChildProviderTest,
- ITextChildProviderInactiveAccessibilityTree) {
- DestroyTree();
-
- // Test that GetTextContainer fails under an inactive tree.
- ComPtr<IRawElementProviderSimple> text_container;
- HRESULT hr = nontext_child_of_root_text_child_provider_->get_TextContainer(
- &text_container);
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE), hr);
-
- // Test that GetTextRange fails under an inactive tree.
- ComPtr<ITextRangeProvider> text_range_provider;
- hr = nontext_child_of_root_text_child_provider_->get_TextRange(
- &text_range_provider);
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE), hr);
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_textprovider_win.cc b/third_party/accessibility/ax/platform/ax_platform_node_textprovider_win.cc
deleted file mode 100644
index 5baf0ab..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_textprovider_win.cc
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_node_textprovider_win.h"
-
-#include <utility>
-
-#include "base/win/scoped_safearray.h"
-#include "ui/accessibility/ax_node_position.h"
-#include "ui/accessibility/platform/ax_platform_node_base.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-#include "ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h"
-
-#define UIA_VALIDATE_TEXTPROVIDER_CALL() \
- if (!owner()->GetDelegate()) \
- return UIA_E_ELEMENTNOTAVAILABLE;
-#define UIA_VALIDATE_TEXTPROVIDER_CALL_1_ARG(arg) \
- if (!owner()->GetDelegate()) \
- return UIA_E_ELEMENTNOTAVAILABLE; \
- if (!arg) \
- return E_INVALIDARG;
-
-namespace ui {
-
-AXPlatformNodeTextProviderWin::AXPlatformNodeTextProviderWin() {
- DVLOG(1) << __func__;
-}
-
-AXPlatformNodeTextProviderWin::~AXPlatformNodeTextProviderWin() {}
-
-// static
-AXPlatformNodeTextProviderWin* AXPlatformNodeTextProviderWin::Create(
- AXPlatformNodeWin* owner) {
- CComObject<AXPlatformNodeTextProviderWin>* text_provider = nullptr;
- if (SUCCEEDED(CComObject<AXPlatformNodeTextProviderWin>::CreateInstance(
- &text_provider))) {
- DCHECK(text_provider);
- text_provider->owner_ = owner;
- text_provider->AddRef();
- return text_provider;
- }
-
- return nullptr;
-}
-
-// static
-void AXPlatformNodeTextProviderWin::CreateIUnknown(AXPlatformNodeWin* owner,
- IUnknown** unknown) {
- Microsoft::WRL::ComPtr<AXPlatformNodeTextProviderWin> text_provider(
- Create(owner));
- if (text_provider)
- *unknown = text_provider.Detach();
-}
-
-//
-// ITextProvider methods.
-//
-
-HRESULT AXPlatformNodeTextProviderWin::GetSelection(SAFEARRAY** selection) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXT_GETSELECTION);
- UIA_VALIDATE_TEXTPROVIDER_CALL();
-
- *selection = nullptr;
-
- AXPlatformNodeDelegate* delegate = owner()->GetDelegate();
- ui::AXTree::Selection unignored_selection = delegate->GetUnignoredSelection();
-
- AXPlatformNode* anchor_object =
- delegate->GetFromNodeID(unignored_selection.anchor_object_id);
- AXPlatformNode* focus_object =
- delegate->GetFromNodeID(unignored_selection.focus_object_id);
-
- // anchor_offset corresponds to the selection start index
- // and focus_offset is where the selection ends.
- auto start_offset = unignored_selection.anchor_offset;
- auto end_offset = unignored_selection.focus_offset;
-
- // If there's no selected object, return success and don't fill the SAFEARRAY.
- if (!anchor_object || !focus_object)
- return S_OK;
-
- AXNodePosition::AXPositionInstance start =
- anchor_object->GetDelegate()->CreateTextPositionAt(start_offset);
- AXNodePosition::AXPositionInstance end =
- focus_object->GetDelegate()->CreateTextPositionAt(end_offset);
-
- DCHECK(!start->IsNullPosition());
- DCHECK(!end->IsNullPosition());
-
- // Reverse start and end if the selection goes backwards
- if (*start > *end)
- std::swap(start, end);
-
- Microsoft::WRL::ComPtr<ITextRangeProvider> text_range_provider =
- AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
- owner_.Get(), std::move(start), std::move(end));
- if (&text_range_provider == nullptr)
- return E_OUTOFMEMORY;
-
- // Since we don't support disjoint text ranges, the SAFEARRAY returned
- // will always have one element
- base::win::ScopedSafearray selections_to_return(
- SafeArrayCreateVector(VT_UNKNOWN /* element type */, 0 /* lower bound */,
- 1 /* number of elements */));
-
- if (!selections_to_return.Get())
- return E_OUTOFMEMORY;
-
- LONG index = 0;
- HRESULT hr = SafeArrayPutElement(selections_to_return.Get(), &index,
- text_range_provider.Get());
- DCHECK(SUCCEEDED(hr));
-
- // Since DCHECK only happens in debug builds, return immediately to ensure
- // that we're not leaking the SAFEARRAY on release builds
- if (FAILED(hr))
- return E_FAIL;
-
- *selection = selections_to_return.Release();
-
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextProviderWin::GetVisibleRanges(
- SAFEARRAY** visible_ranges) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXT_GETVISIBLERANGES);
- UIA_VALIDATE_TEXTPROVIDER_CALL();
-
- const AXPlatformNodeDelegate* delegate = owner()->GetDelegate();
-
- // Get the Clipped Frame Bounds of the current node, not from the root,
- // so if this node is wrapped with overflow styles it will have the
- // correct bounds
- const gfx::Rect frame_rect = delegate->GetBoundsRect(
- AXCoordinateSystem::kFrame, AXClippingBehavior::kClipped);
-
- const auto start = delegate->CreateTextPositionAt(0);
- const auto end = start->CreatePositionAtEndOfAnchor();
- DCHECK(start->GetAnchor() == end->GetAnchor());
-
- // SAFEARRAYs are not dynamic, so fill the visible ranges in a vector
- // and then transfer to an appropriately-sized SAFEARRAY
- std::vector<Microsoft::WRL::ComPtr<ITextRangeProvider>> ranges;
-
- auto current_line_start = start->Clone();
- while (!current_line_start->IsNullPosition() && *current_line_start < *end) {
- auto current_line_end = current_line_start->CreateNextLineEndPosition(
- AXBoundaryBehavior::CrossBoundary);
- if (current_line_end->IsNullPosition() || *current_line_end > *end)
- current_line_end = end->Clone();
-
- gfx::Rect current_rect = delegate->GetInnerTextRangeBoundsRect(
- current_line_start->text_offset(), current_line_end->text_offset(),
- AXCoordinateSystem::kFrame, AXClippingBehavior::kUnclipped);
-
- if (frame_rect.Contains(current_rect)) {
- Microsoft::WRL::ComPtr<ITextRangeProvider> text_range_provider =
- AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
- owner_.Get(), current_line_start->Clone(),
- current_line_end->Clone());
-
- ranges.emplace_back(text_range_provider);
- }
-
- current_line_start = current_line_start->CreateNextLineStartPosition(
- AXBoundaryBehavior::CrossBoundary);
- }
-
- base::win::ScopedSafearray scoped_visible_ranges(
- SafeArrayCreateVector(VT_UNKNOWN /* element type */, 0 /* lower bound */,
- ranges.size() /* number of elements */));
-
- if (!scoped_visible_ranges.Get())
- return E_OUTOFMEMORY;
-
- LONG index = 0;
- for (Microsoft::WRL::ComPtr<ITextRangeProvider>& current_provider : ranges) {
- HRESULT hr = SafeArrayPutElement(scoped_visible_ranges.Get(), &index,
- current_provider.Get());
- DCHECK(SUCCEEDED(hr));
-
- // Since DCHECK only happens in debug builds, return immediately to ensure
- // that we're not leaking the SAFEARRAY on release builds
- if (FAILED(hr))
- return E_FAIL;
-
- ++index;
- }
-
- *visible_ranges = scoped_visible_ranges.Release();
-
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextProviderWin::RangeFromChild(
- IRawElementProviderSimple* child,
- ITextRangeProvider** range) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXT_RANGEFROMCHILD);
- UIA_VALIDATE_TEXTPROVIDER_CALL_1_ARG(child);
-
- *range = nullptr;
-
- Microsoft::WRL::ComPtr<ui::AXPlatformNodeWin> child_platform_node;
- if (!SUCCEEDED(child->QueryInterface(IID_PPV_ARGS(&child_platform_node))))
- return UIA_E_INVALIDOPERATION;
-
- if (!owner()->IsDescendant(child_platform_node.Get()))
- return E_INVALIDARG;
-
- *range = GetRangeFromChild(owner(), child_platform_node.Get());
-
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextProviderWin::RangeFromPoint(
- UiaPoint uia_point,
- ITextRangeProvider** range) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXT_RANGEFROMPOINT);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXT_RANGEFROMPOINT);
- UIA_VALIDATE_TEXTPROVIDER_CALL();
- *range = nullptr;
-
- gfx::Point point(uia_point.x, uia_point.y);
- // Retrieve the closest accessibility node. No coordinate unit conversion is
- // needed, hit testing input is also in screen coordinates.
-
- AXPlatformNodeWin* nearest_node =
- static_cast<AXPlatformNodeWin*>(owner()->NearestLeafToPoint(point));
- DCHECK(nearest_node);
- DCHECK(nearest_node->IsLeaf());
-
- AXNodePosition::AXPositionInstance start, end;
- start = nearest_node->GetDelegate()->CreateTextPositionAt(
- nearest_node->NearestTextIndexToPoint(point));
- DCHECK(!start->IsNullPosition());
- end = start->Clone();
-
- *range = AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
- nearest_node, std::move(start), std::move(end));
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextProviderWin::get_DocumentRange(
- ITextRangeProvider** range) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXT_GET_DOCUMENTRANGE);
- UIA_VALIDATE_TEXTPROVIDER_CALL();
-
- // Get range from child, where child is the current node. In other words,
- // getting the text range of the current owner AxPlatformNodeWin node.
- *range = GetRangeFromChild(owner(), owner());
-
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextProviderWin::get_SupportedTextSelection(
- enum SupportedTextSelection* text_selection) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXT_GET_SUPPORTEDTEXTSELECTION);
- UIA_VALIDATE_TEXTPROVIDER_CALL();
-
- *text_selection = SupportedTextSelection_Single;
- return S_OK;
-}
-
-//
-// ITextEditProvider methods.
-//
-
-HRESULT AXPlatformNodeTextProviderWin::GetActiveComposition(
- ITextRangeProvider** range) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTEDIT_GETACTIVECOMPOSITION);
- UIA_VALIDATE_TEXTPROVIDER_CALL();
-
- *range = nullptr;
- return GetTextRangeProviderFromActiveComposition(range);
-}
-
-HRESULT AXPlatformNodeTextProviderWin::GetConversionTarget(
- ITextRangeProvider** range) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTEDIT_GETCONVERSIONTARGET);
- UIA_VALIDATE_TEXTPROVIDER_CALL();
-
- *range = nullptr;
- return GetTextRangeProviderFromActiveComposition(range);
-}
-
-ITextRangeProvider* AXPlatformNodeTextProviderWin::GetRangeFromChild(
- ui::AXPlatformNodeWin* ancestor,
- ui::AXPlatformNodeWin* descendant) {
- DCHECK(ancestor);
- DCHECK(descendant);
- DCHECK(descendant->GetDelegate());
- DCHECK(ancestor->IsDescendant(descendant));
-
- // Start and end should be leaf text positions that span the beginning and end
- // of text content within a node. The start position should be the directly
- // first child and the end position should be the deepest last child node.
- AXNodePosition::AXPositionInstance start =
- descendant->GetDelegate()->CreateTextPositionAt(0)->AsLeafTextPosition();
-
- AXNodePosition::AXPositionInstance end;
- if (ui::IsDocument(descendant->GetData().role)) {
- // Fast path for getting the range of the web root.
- end = start->CreatePositionAtEndOfDocument();
- } else if (descendant->GetChildCount() == 0) {
- end = descendant->GetDelegate()
- ->CreateTextPositionAt(0)
- ->CreatePositionAtEndOfAnchor()
- ->AsLeafTextPosition();
- } else {
- AXPlatformNodeBase* deepest_last_child = descendant->GetLastChild();
- while (deepest_last_child && deepest_last_child->GetChildCount() > 0)
- deepest_last_child = deepest_last_child->GetLastChild();
-
- end = deepest_last_child->GetDelegate()
- ->CreateTextPositionAt(0)
- ->CreatePositionAtEndOfAnchor()
- ->AsLeafTextPosition();
- }
-
- return AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
- ancestor, std::move(start), std::move(end));
-}
-
-ui::AXPlatformNodeWin* AXPlatformNodeTextProviderWin::owner() const {
- return owner_.Get();
-}
-
-HRESULT
-AXPlatformNodeTextProviderWin::GetTextRangeProviderFromActiveComposition(
- ITextRangeProvider** range) {
- *range = nullptr;
- // We fetch the start and end offset of an active composition only if
- // this object has focus and TSF is in composition mode.
- // The offsets here refer to the character positions in a plain text
- // view of the DOM tree. Ex: if the active composition in an element
- // has "abc" then the range will be (0,3) in both TSF and accessibility
- if ((AXPlatformNode::FromNativeViewAccessible(
- owner()->GetDelegate()->GetFocus()) ==
- static_cast<AXPlatformNode*>(owner())) &&
- owner()->HasActiveComposition()) {
- gfx::Range active_composition_offset =
- owner()->GetActiveCompositionOffsets();
- AXNodePosition::AXPositionInstance start =
- owner()->GetDelegate()->CreateTextPositionAt(
- /*offset*/ active_composition_offset.start());
- AXNodePosition::AXPositionInstance end =
- owner()->GetDelegate()->CreateTextPositionAt(
- /*offset*/ active_composition_offset.end());
-
- *range = AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
- owner_.Get(), std::move(start), std::move(end));
- }
-
- return S_OK;
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_textprovider_win.h b/third_party/accessibility/ax/platform/ax_platform_node_textprovider_win.h
deleted file mode 100644
index 92af711..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_textprovider_win.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_TEXTPROVIDER_WIN_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_TEXTPROVIDER_WIN_H_
-
-#include <wrl/client.h>
-
-#include <string>
-
-#include "ui/accessibility/platform/ax_platform_node_win.h"
-
-namespace ui {
-class __declspec(uuid("3e1c192b-4348-45ac-8eb6-4b58eeb3dcca"))
- AXPlatformNodeTextProviderWin
- : public CComObjectRootEx<CComMultiThreadModel>,
- public ITextEditProvider {
- public:
- BEGIN_COM_MAP(AXPlatformNodeTextProviderWin)
- COM_INTERFACE_ENTRY(ITextProvider)
- COM_INTERFACE_ENTRY(ITextEditProvider)
- COM_INTERFACE_ENTRY(AXPlatformNodeTextProviderWin)
- END_COM_MAP()
-
- AXPlatformNodeTextProviderWin();
- ~AXPlatformNodeTextProviderWin();
-
- static AXPlatformNodeTextProviderWin* Create(AXPlatformNodeWin* owner);
- static void CreateIUnknown(AXPlatformNodeWin* owner, IUnknown** unknown);
-
- //
- // ITextProvider methods.
- //
-
- IFACEMETHODIMP GetSelection(SAFEARRAY** selection) override;
-
- IFACEMETHODIMP GetVisibleRanges(SAFEARRAY** visible_ranges) override;
-
- IFACEMETHODIMP RangeFromChild(IRawElementProviderSimple* child,
- ITextRangeProvider** range) override;
-
- IFACEMETHODIMP RangeFromPoint(UiaPoint point,
- ITextRangeProvider** range) override;
-
- IFACEMETHODIMP get_DocumentRange(ITextRangeProvider** range) override;
-
- IFACEMETHODIMP get_SupportedTextSelection(
- enum SupportedTextSelection* text_selection) override;
-
- //
- // ITextEditProvider methods.
- //
-
- IFACEMETHODIMP GetActiveComposition(ITextRangeProvider** range) override;
-
- IFACEMETHODIMP GetConversionTarget(ITextRangeProvider** range) override;
-
- // ITextProvider supporting methods.
-
- static ITextRangeProvider* GetRangeFromChild(
- ui::AXPlatformNodeWin* ancestor,
- ui::AXPlatformNodeWin* descendant);
-
- private:
- friend class AXPlatformNodeTextProviderTest;
- ui::AXPlatformNodeWin* owner() const;
- HRESULT GetTextRangeProviderFromActiveComposition(ITextRangeProvider** range);
-
- Microsoft::WRL::ComPtr<ui::AXPlatformNodeWin> owner_;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_TEXTPROVIDER_WIN_H_
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_textprovider_win_unittest.cc b/third_party/accessibility/ax/platform/ax_platform_node_textprovider_win_unittest.cc
deleted file mode 100644
index 17beb8f..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_textprovider_win_unittest.cc
+++ /dev/null
@@ -1,694 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_node_win_unittest.h"
-
-#include <UIAutomationClient.h>
-#include <UIAutomationCoreApi.h>
-
-#include <vector>
-
-#include "base/win/scoped_bstr.h"
-#include "base/win/scoped_safearray.h"
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/platform/ax_fragment_root_win.h"
-#include "ui/accessibility/platform/ax_platform_node_textprovider_win.h"
-#include "ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h"
-#include "ui/accessibility/platform/test_ax_node_wrapper.h"
-#include "ui/base/win/accessibility_misc_utils.h"
-
-using Microsoft::WRL::ComPtr;
-
-namespace ui {
-
-// Helper macros for UIAutomation HRESULT expectations
-#define EXPECT_UIA_INVALIDOPERATION(expr) \
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_INVALIDOPERATION), (expr))
-#define EXPECT_INVALIDARG(expr) \
- EXPECT_EQ(static_cast<HRESULT>(E_INVALIDARG), (expr))
-
-class AXPlatformNodeTextProviderTest : public AXPlatformNodeWinTest {
- public:
- AXPlatformNodeTextProviderTest() = default;
- ~AXPlatformNodeTextProviderTest() override = default;
- AXPlatformNodeTextProviderTest(const AXPlatformNodeTextProviderTest&) =
- delete;
- AXPlatformNodeTextProviderTest& operator=(
- const AXPlatformNodeTextProviderTest&) = delete;
-
- protected:
- ui::AXPlatformNodeWin* GetOwner(
- const AXPlatformNodeTextProviderWin* text_provider) {
- return text_provider->owner_.Get();
- }
- const AXNodePosition::AXPositionInstance& GetStart(
- const AXPlatformNodeTextRangeProviderWin* text_range) {
- return text_range->start_;
- }
- const AXNodePosition::AXPositionInstance& GetEnd(
- const AXPlatformNodeTextRangeProviderWin* text_range) {
- return text_range->end_;
- }
-};
-
-TEST_F(AXPlatformNodeTextProviderTest, ITextProviderRangeFromChild) {
- ui::AXNodeData text_data;
- text_data.id = 2;
- text_data.role = ax::mojom::Role::kStaticText;
- text_data.SetName("some text");
-
- ui::AXNodeData empty_text_data;
- empty_text_data.id = 3;
- empty_text_data.role = ax::mojom::Role::kStaticText;
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.SetName("Document");
- root_data.child_ids.push_back(2);
- root_data.child_ids.push_back(3);
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes.push_back(root_data);
- update.nodes.push_back(text_data);
- update.nodes.push_back(empty_text_data);
-
- Init(update);
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* text_node = root_node->children()[0];
- AXNode* empty_text_node = root_node->children()[1];
-
- ComPtr<IRawElementProviderSimple> root_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(root_node);
- ComPtr<IRawElementProviderSimple> text_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(text_node);
- ComPtr<IRawElementProviderSimple> empty_text_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(empty_text_node);
-
- // Call RangeFromChild on the root with the text child passed in.
- ComPtr<ITextProvider> text_provider;
- EXPECT_HRESULT_SUCCEEDED(
- root_node_raw->GetPatternProvider(UIA_TextPatternId, &text_provider));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->RangeFromChild(text_node_raw.Get(), &text_range_provider));
-
- base::win::ScopedBstr text_content;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_EQ(0, wcscmp(text_content.Get(), L"some text"));
-
- // Now test that the reverse relation doesn't return a valid
- // ITextRangeProvider, and instead returns E_INVALIDARG.
- EXPECT_HRESULT_SUCCEEDED(
- text_node_raw->GetPatternProvider(UIA_TextPatternId, &text_provider));
-
- EXPECT_INVALIDARG(
- text_provider->RangeFromChild(root_node_raw.Get(), &text_range_provider));
-
- // Now test that a child with no text returns a degenerate range.
- EXPECT_HRESULT_SUCCEEDED(
- root_node_raw->GetPatternProvider(UIA_TextPatternId, &text_provider));
-
- EXPECT_HRESULT_SUCCEEDED(text_provider->RangeFromChild(
- empty_text_node_raw.Get(), &text_range_provider));
-
- base::win::ScopedBstr empty_text_content;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, empty_text_content.Receive()));
- EXPECT_EQ(0, wcscmp(empty_text_content.Get(), L""));
-
- // Test that passing in an object from a different instance of
- // IRawElementProviderSimple than that of the valid text provider
- // returns UIA_E_INVALIDOPERATION.
- ComPtr<IRawElementProviderSimple> other_root_node_raw;
- MockIRawElementProviderSimple::CreateMockIRawElementProviderSimple(
- &other_root_node_raw);
-
- EXPECT_HRESULT_SUCCEEDED(
- root_node_raw->GetPatternProvider(UIA_TextPatternId, &text_provider));
-
- EXPECT_UIA_INVALIDOPERATION(text_provider->RangeFromChild(
- other_root_node_raw.Get(), &text_range_provider));
-}
-
-TEST_F(AXPlatformNodeTextProviderTest,
- ITextProviderRangeFromChildMultipleChildren) {
- const int ROOT_ID = 1;
- const int DIALOG_ID = 2;
- const int DIALOG_LABEL_ID = 3;
- const int DIALOG_DESCRIPTION_ID = 4;
- const int BUTTON_ID = 5;
- const int BUTTON_IMG_ID = 6;
- const int BUTTON_TEXT_ID = 7;
- const int DIALOG_DETAIL_ID = 8;
-
- ui::AXNodeData root;
- root.id = ROOT_ID;
- root.role = ax::mojom::Role::kRootWebArea;
- root.SetName("Document");
- root.child_ids = {DIALOG_ID};
-
- ui::AXNodeData dialog;
- dialog.id = DIALOG_ID;
- dialog.role = ax::mojom::Role::kDialog;
- dialog.child_ids = {DIALOG_LABEL_ID, DIALOG_DESCRIPTION_ID, BUTTON_ID,
- DIALOG_DETAIL_ID};
-
- ui::AXNodeData dialog_label;
- dialog_label.id = DIALOG_LABEL_ID;
- dialog_label.role = ax::mojom::Role::kStaticText;
- dialog_label.SetName("Dialog label.");
-
- ui::AXNodeData dialog_description;
- dialog_description.id = DIALOG_DESCRIPTION_ID;
- dialog_description.role = ax::mojom::Role::kStaticText;
- dialog_description.SetName("Dialog description.");
-
- ui::AXNodeData button;
- button.id = BUTTON_ID;
- button.role = ax::mojom::Role::kButton;
- button.child_ids = {BUTTON_IMG_ID, BUTTON_TEXT_ID};
-
- ui::AXNodeData button_img;
- button_img.id = BUTTON_IMG_ID;
- button_img.role = ax::mojom::Role::kImage;
-
- ui::AXNodeData button_text;
- button_text.id = BUTTON_TEXT_ID;
- button_text.role = ax::mojom::Role::kStaticText;
- button_text.SetName("ok.");
-
- ui::AXNodeData dialog_detail;
- dialog_detail.id = DIALOG_DETAIL_ID;
- dialog_detail.role = ax::mojom::Role::kStaticText;
- dialog_detail.SetName("Some more detail about dialog.");
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = ROOT_ID;
- update.nodes = {root, dialog, dialog_label, dialog_description,
- button, button_img, button_text, dialog_detail};
-
- Init(update);
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* dialog_node = root_node->children()[0];
-
- ComPtr<IRawElementProviderSimple> root_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(root_node);
- ComPtr<IRawElementProviderSimple> dialog_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(dialog_node);
-
- // Call RangeFromChild on the root with the dialog child passed in.
- ComPtr<ITextProvider> text_provider;
- EXPECT_HRESULT_SUCCEEDED(
- root_node_raw->GetPatternProvider(UIA_TextPatternId, &text_provider));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- EXPECT_HRESULT_SUCCEEDED(text_provider->RangeFromChild(dialog_node_raw.Get(),
- &text_range_provider));
-
- base::win::ScopedBstr text_content;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_EQ(0, wcscmp(text_content.Get(), (L"Dialog label.Dialog description." +
- kEmbeddedCharacterAsString +
- "ok.Some more detail "
- L"about dialog.")
- .c_str()));
-
- // Check the reverse relationship that GetEnclosingElement on the text range
- // gives back the dialog.
- ComPtr<IRawElementProviderSimple> enclosing_element;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetEnclosingElement(&enclosing_element));
- EXPECT_EQ(enclosing_element.Get(), dialog_node_raw.Get());
-}
-
-TEST_F(AXPlatformNodeTextProviderTest, NearestTextIndexToPoint) {
- ui::AXNodeData text_data;
- text_data.id = 2;
- text_data.role = ax::mojom::Role::kInlineTextBox;
- text_data.SetName("text");
- // spacing: "t-e-x---t-"
- text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kCharacterOffsets,
- {2, 4, 8, 10});
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.relative_bounds.bounds = gfx::RectF(1, 1, 2, 2);
- root_data.child_ids.push_back(2);
-
- Init(root_data, text_data);
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* text_node = root_node->children()[0];
-
- struct NearestTextIndexTestData {
- AXNode* node;
- struct point_offset_expected_index_pair {
- int point_offset_x;
- int expected_index;
- };
- std::vector<point_offset_expected_index_pair> test_data;
- };
- NearestTextIndexTestData nodes[] = {
- {text_node,
- {{0, 0}, {2, 0}, {3, 1}, {4, 1}, {5, 2}, {8, 2}, {9, 3}, {10, 3}}},
- {root_node,
- {{0, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {8, 0}, {9, 0}, {10, 0}}}};
- for (auto data : nodes) {
- ComPtr<IRawElementProviderSimple> element_provider =
- QueryInterfaceFromNode<IRawElementProviderSimple>(data.node);
- ComPtr<ITextProvider> text_provider;
- EXPECT_HRESULT_SUCCEEDED(element_provider->GetPatternProvider(
- UIA_TextPatternId, &text_provider));
- // get internal implementation to access helper for testing
- ComPtr<AXPlatformNodeTextProviderWin> platform_text_provider;
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->QueryInterface(IID_PPV_ARGS(&platform_text_provider)));
-
- ComPtr<AXPlatformNodeWin> platform_node;
- EXPECT_HRESULT_SUCCEEDED(
- element_provider->QueryInterface(IID_PPV_ARGS(&platform_node)));
-
- for (auto pair : data.test_data) {
- EXPECT_EQ(pair.expected_index, platform_node->NearestTextIndexToPoint(
- gfx::Point(pair.point_offset_x, 0)));
- }
- }
-}
-
-TEST_F(AXPlatformNodeTextProviderTest, ITextProviderDocumentRange) {
- ui::AXNodeData text_data;
- text_data.id = 2;
- text_data.role = ax::mojom::Role::kStaticText;
- text_data.SetName("some text");
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.SetName("Document");
- root_data.child_ids.push_back(2);
-
- Init(root_data, text_data);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
-
- ComPtr<ITextProvider> text_provider;
- EXPECT_HRESULT_SUCCEEDED(
- root_node->GetPatternProvider(UIA_TextPatternId, &text_provider));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-}
-
-TEST_F(AXPlatformNodeTextProviderTest, ITextProviderDocumentRangeNested) {
- ui::AXNodeData text_data;
- text_data.id = 3;
- text_data.role = ax::mojom::Role::kStaticText;
- text_data.SetName("some text");
-
- ui::AXNodeData paragraph_data;
- paragraph_data.id = 2;
- paragraph_data.role = ax::mojom::Role::kParagraph;
- paragraph_data.child_ids.push_back(3);
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.SetName("Document");
- root_data.child_ids.push_back(2);
-
- Init(root_data, paragraph_data, text_data);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
-
- ComPtr<ITextProvider> text_provider;
- EXPECT_HRESULT_SUCCEEDED(
- root_node->GetPatternProvider(UIA_TextPatternId, &text_provider));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-}
-
-TEST_F(AXPlatformNodeTextProviderTest, ITextProviderSupportedSelection) {
- ui::AXNodeData text_data;
- text_data.id = 2;
- text_data.role = ax::mojom::Role::kStaticText;
- text_data.SetName("some text");
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.SetName("Document");
- root_data.child_ids.push_back(2);
-
- Init(root_data, text_data);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
-
- ComPtr<ITextProvider> text_provider;
- EXPECT_HRESULT_SUCCEEDED(
- root_node->GetPatternProvider(UIA_TextPatternId, &text_provider));
-
- SupportedTextSelection text_selection_mode;
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_SupportedTextSelection(&text_selection_mode));
- EXPECT_EQ(text_selection_mode, SupportedTextSelection_Single);
-}
-
-TEST_F(AXPlatformNodeTextProviderTest, ITextProviderGetSelection) {
- ui::AXNodeData text_data;
- text_data.id = 2;
- text_data.role = ax::mojom::Role::kStaticText;
- text_data.SetName("some text");
-
- ui::AXNodeData textbox_data;
- textbox_data.id = 3;
- textbox_data.role = ax::mojom::Role::kInlineTextBox;
- textbox_data.SetName("textbox text");
- textbox_data.AddState(ax::mojom::State::kEditable);
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.SetName("Document");
- root_data.child_ids.push_back(2);
- root_data.child_ids.push_back(3);
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes.push_back(root_data);
- update.nodes.push_back(text_data);
- update.nodes.push_back(textbox_data);
- Init(update);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
-
- ComPtr<ITextProvider> root_text_provider;
- EXPECT_HRESULT_SUCCEEDED(
- root_node->GetPatternProvider(UIA_TextPatternId, &root_text_provider));
-
- base::win::ScopedSafearray selections;
- root_text_provider->GetSelection(selections.Receive());
- ASSERT_EQ(nullptr, selections.Get());
-
- ComPtr<AXPlatformNodeTextProviderWin> root_platform_node;
- root_text_provider->QueryInterface(IID_PPV_ARGS(&root_platform_node));
-
- AXPlatformNodeWin* owner = GetOwner(root_platform_node.Get());
- AXTreeData& selected_tree_data =
- const_cast<AXTreeData&>(owner->GetDelegate()->GetTreeData());
- selected_tree_data.sel_focus_object_id = 2;
- selected_tree_data.sel_anchor_object_id = 2;
- selected_tree_data.sel_anchor_offset = 0;
- selected_tree_data.sel_focus_offset = 4;
-
- root_text_provider->GetSelection(selections.Receive());
- ASSERT_NE(nullptr, selections.Get());
-
- LONG ubound;
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetUBound(selections.Get(), 1, &ubound));
- EXPECT_EQ(0, ubound);
- LONG lbound;
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetLBound(selections.Get(), 1, &lbound));
- EXPECT_EQ(0, lbound);
-
- LONG index = 0;
- ComPtr<ITextRangeProvider> text_range_provider;
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetElement(
- selections.Get(), &index, static_cast<void**>(&text_range_provider)));
-
- base::win::ScopedBstr text_content;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_EQ(0, wcscmp(text_content.Get(), L"some"));
- text_content.Reset();
- selections.Reset();
- text_range_provider.Reset();
-
- // Verify that start and end are appropriately swapped when sel_anchor_offset
- // is greater than sel_focus_offset
- selected_tree_data.sel_focus_object_id = 2;
- selected_tree_data.sel_anchor_object_id = 2;
- selected_tree_data.sel_anchor_offset = 4;
- selected_tree_data.sel_focus_offset = 0;
-
- root_text_provider->GetSelection(selections.Receive());
- ASSERT_NE(nullptr, selections.Get());
-
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetUBound(selections.Get(), 1, &ubound));
- EXPECT_EQ(0, ubound);
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetLBound(selections.Get(), 1, &lbound));
- EXPECT_EQ(0, lbound);
-
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetElement(
- selections.Get(), &index, static_cast<void**>(&text_range_provider)));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_EQ(0, wcscmp(text_content.Get(), L"some"));
- text_content.Reset();
- selections.Reset();
- text_range_provider.Reset();
-
- // Verify that text ranges at an insertion point returns a degenerate (empty)
- // text range via textbox with sel_anchor_offset equal to sel_focus_offset
- selected_tree_data.sel_focus_object_id = 3;
- selected_tree_data.sel_anchor_object_id = 3;
- selected_tree_data.sel_anchor_offset = 1;
- selected_tree_data.sel_focus_offset = 1;
-
- AXNode* text_edit_node = GetRootAsAXNode()->children()[1];
-
- ComPtr<IRawElementProviderSimple> text_edit_com =
- QueryInterfaceFromNode<IRawElementProviderSimple>(text_edit_node);
-
- ComPtr<ITextProvider> text_edit_provider;
- EXPECT_HRESULT_SUCCEEDED(text_edit_com->GetPatternProvider(
- UIA_TextPatternId, &text_edit_provider));
-
- selections.Reset();
- EXPECT_HRESULT_SUCCEEDED(
- text_edit_provider->GetSelection(selections.Receive()));
- EXPECT_NE(nullptr, selections.Get());
-
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetUBound(selections.Get(), 1, &ubound));
- EXPECT_EQ(0, ubound);
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetLBound(selections.Get(), 1, &lbound));
- EXPECT_EQ(0, lbound);
-
- ComPtr<ITextRangeProvider> text_edit_range_provider;
- EXPECT_HRESULT_SUCCEEDED(
- SafeArrayGetElement(selections.Get(), &index,
- static_cast<void**>(&text_edit_range_provider)));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_edit_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_EQ(0U, text_content.Length());
- text_content.Reset();
- selections.Reset();
- text_edit_range_provider.Reset();
-
- // Verify selections that span multiple nodes
- selected_tree_data.sel_focus_object_id = 2;
- selected_tree_data.sel_focus_offset = 0;
- selected_tree_data.sel_anchor_object_id = 3;
- selected_tree_data.sel_anchor_offset = 12;
-
- root_text_provider->GetSelection(selections.Receive());
- ASSERT_NE(nullptr, selections.Get());
-
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetUBound(selections.Get(), 1, &ubound));
- EXPECT_EQ(0, ubound);
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetLBound(selections.Get(), 1, &lbound));
- EXPECT_EQ(0, lbound);
-
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetElement(
- selections.Get(), &index, static_cast<void**>(&text_range_provider)));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_EQ(0, wcscmp(text_content.Get(), L"some texttextbox text"));
- text_content.Reset();
- selections.Reset();
- text_range_provider.Reset();
-
- // Verify SAFEARRAY value for degenerate selection.
- selected_tree_data.sel_focus_object_id = 2;
- selected_tree_data.sel_anchor_object_id = 2;
- selected_tree_data.sel_anchor_offset = 1;
- selected_tree_data.sel_focus_offset = 1;
-
- root_text_provider->GetSelection(selections.Receive());
- ASSERT_NE(nullptr, selections.Get());
-
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetUBound(selections.Get(), 1, &ubound));
- EXPECT_EQ(0, ubound);
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetLBound(selections.Get(), 1, &lbound));
- EXPECT_EQ(0, lbound);
-
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetElement(
- selections.Get(), &index, static_cast<void**>(&text_range_provider)));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_EQ(0, wcscmp(text_content.Get(), L""));
- text_content.Reset();
- selections.Reset();
- text_range_provider.Reset();
-
- // Now delete the tree (which will delete the associated elements) and verify
- // that UIA_E_ELEMENTNOTAVAILABLE is returned when calling GetSelection on
- // a dead element
- DestroyTree();
-
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- text_edit_provider->GetSelection(selections.Receive()));
-}
-
-TEST_F(AXPlatformNodeTextProviderTest, ITextProviderGetActiveComposition) {
- ui::AXNodeData text_data;
- text_data.id = 2;
- text_data.role = ax::mojom::Role::kStaticText;
- text_data.SetName("some text");
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.SetName("Document");
- root_data.child_ids.push_back(2);
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes.push_back(root_data);
- update.nodes.push_back(text_data);
- Init(update);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
-
- ComPtr<ITextProvider> root_text_provider;
- EXPECT_HRESULT_SUCCEEDED(
- root_node->GetPatternProvider(UIA_TextPatternId, &root_text_provider));
-
- ComPtr<ITextEditProvider> root_text_edit_provider;
- EXPECT_HRESULT_SUCCEEDED(root_node->GetPatternProvider(
- UIA_TextEditPatternId, &root_text_edit_provider));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- root_text_edit_provider->GetActiveComposition(&text_range_provider);
- ASSERT_EQ(nullptr, text_range_provider);
-
- ComPtr<AXPlatformNodeTextProviderWin> root_platform_node;
- root_text_provider->QueryInterface(IID_PPV_ARGS(&root_platform_node));
-
- ui::AXActionData action_data;
- action_data.action = ax::mojom::Action::kFocus;
- action_data.target_node_id = 1;
- AXPlatformNodeWin* owner = GetOwner(root_platform_node.Get());
- owner->GetDelegate()->AccessibilityPerformAction(action_data);
- const base::string16 active_composition_text = L"a";
- owner->OnActiveComposition(gfx::Range(0, 1), active_composition_text, false);
-
- root_text_edit_provider->GetActiveComposition(&text_range_provider);
- ASSERT_NE(nullptr, text_range_provider);
- ComPtr<AXPlatformNodeTextRangeProviderWin> actual_range;
- AXNodePosition::AXPositionInstance expected_start =
- owner->GetDelegate()->CreateTextPositionAt(0);
- AXNodePosition::AXPositionInstance expected_end =
- owner->GetDelegate()->CreateTextPositionAt(1);
- text_range_provider->QueryInterface(IID_PPV_ARGS(&actual_range));
- EXPECT_EQ(*GetStart(actual_range.Get()), *expected_start);
- EXPECT_EQ(*GetEnd(actual_range.Get()), *expected_end);
-}
-
-TEST_F(AXPlatformNodeTextProviderTest, ITextProviderGetConversionTarget) {
- ui::AXNodeData text_data;
- text_data.id = 2;
- text_data.role = ax::mojom::Role::kStaticText;
- text_data.SetName("some text");
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.SetName("Document");
- root_data.child_ids.push_back(2);
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes.push_back(root_data);
- update.nodes.push_back(text_data);
- Init(update);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
-
- ComPtr<ITextProvider> root_text_provider;
- EXPECT_HRESULT_SUCCEEDED(
- root_node->GetPatternProvider(UIA_TextPatternId, &root_text_provider));
-
- ComPtr<ITextEditProvider> root_text_edit_provider;
- EXPECT_HRESULT_SUCCEEDED(root_node->GetPatternProvider(
- UIA_TextEditPatternId, &root_text_edit_provider));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- root_text_edit_provider->GetConversionTarget(&text_range_provider);
- ASSERT_EQ(nullptr, text_range_provider);
-
- ComPtr<AXPlatformNodeTextProviderWin> root_platform_node;
- root_text_provider->QueryInterface(IID_PPV_ARGS(&root_platform_node));
-
- ui::AXActionData action_data;
- action_data.action = ax::mojom::Action::kFocus;
- action_data.target_node_id = 1;
- AXPlatformNodeWin* owner = GetOwner(root_platform_node.Get());
- owner->GetDelegate()->AccessibilityPerformAction(action_data);
- const base::string16 active_composition_text = L"a";
- owner->OnActiveComposition(gfx::Range(0, 1), active_composition_text, false);
-
- root_text_edit_provider->GetConversionTarget(&text_range_provider);
- ASSERT_NE(nullptr, text_range_provider);
- ComPtr<AXPlatformNodeTextRangeProviderWin> actual_range;
- AXNodePosition::AXPositionInstance expected_start =
- owner->GetDelegate()->CreateTextPositionAt(0);
- AXNodePosition::AXPositionInstance expected_end =
- owner->GetDelegate()->CreateTextPositionAt(1);
- text_range_provider->QueryInterface(IID_PPV_ARGS(&actual_range));
- EXPECT_EQ(*GetStart(actual_range.Get()), *expected_start);
- EXPECT_EQ(*GetEnd(actual_range.Get()), *expected_end);
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_textrangeprovider_win.cc b/third_party/accessibility/ax/platform/ax_platform_node_textrangeprovider_win.cc
deleted file mode 100644
index 287c6b0..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_textrangeprovider_win.cc
+++ /dev/null
@@ -1,1407 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h"
-
-#include <utility>
-#include <vector>
-
-#include "base/i18n/string_search.h"
-#include "base/win/scoped_safearray.h"
-#include "base/win/scoped_variant.h"
-#include "base/win/variant_vector.h"
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-
-#define UIA_VALIDATE_TEXTRANGEPROVIDER_CALL() \
- if (!owner() || !owner()->GetDelegate() || !start_ || \
- !start_->GetAnchor() || !end_ || !end_->GetAnchor()) \
- return UIA_E_ELEMENTNOTAVAILABLE; \
- start_ = start_->AsValidPosition(); \
- end_ = end_->AsValidPosition();
-#define UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_IN(in) \
- if (!owner() || !owner()->GetDelegate() || !start_ || \
- !start_->GetAnchor() || !end_ || !end_->GetAnchor()) \
- return UIA_E_ELEMENTNOTAVAILABLE; \
- if (!in) \
- return E_POINTER; \
- start_ = start_->AsValidPosition(); \
- end_ = end_->AsValidPosition();
-#define UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_OUT(out) \
- if (!owner() || !owner()->GetDelegate() || !start_ || \
- !start_->GetAnchor() || !end_ || !end_->GetAnchor()) \
- return UIA_E_ELEMENTNOTAVAILABLE; \
- if (!out) \
- return E_POINTER; \
- *out = {}; \
- start_ = start_->AsValidPosition(); \
- end_ = end_->AsValidPosition();
-#define UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_IN_1_OUT(in, out) \
- if (!owner() || !owner()->GetDelegate() || !start_ || \
- !start_->GetAnchor() || !end_ || !end_->GetAnchor()) \
- return UIA_E_ELEMENTNOTAVAILABLE; \
- if (!in || !out) \
- return E_POINTER; \
- *out = {}; \
- start_ = start_->AsValidPosition(); \
- end_ = end_->AsValidPosition();
-// Validate bounds calculated by AXPlatformNodeDelegate. Degenerate bounds
-// indicate the interface is not yet supported on the platform.
-#define UIA_VALIDATE_BOUNDS(bounds) \
- if (bounds.OffsetFromOrigin().IsZero() && bounds.IsEmpty()) \
- return UIA_E_NOTSUPPORTED;
-
-namespace ui {
-
-class AXRangePhysicalPixelRectDelegate : public AXRangeRectDelegate {
- public:
- AXRangePhysicalPixelRectDelegate(AXPlatformNodeTextRangeProviderWin* host)
- : host_(host) {}
-
- gfx::Rect GetInnerTextRangeBoundsRect(
- AXTreeID tree_id,
- AXNode::AXID node_id,
- int start_offset,
- int end_offset,
- AXOffscreenResult* offscreen_result) override {
- AXPlatformNodeDelegate* delegate = host_->GetDelegate(tree_id, node_id);
- DCHECK(delegate);
- return delegate->GetInnerTextRangeBoundsRect(
- start_offset, end_offset, ui::AXCoordinateSystem::kScreenPhysicalPixels,
- ui::AXClippingBehavior::kClipped, offscreen_result);
- }
-
- gfx::Rect GetBoundsRect(AXTreeID tree_id,
- AXNode::AXID node_id,
- AXOffscreenResult* offscreen_result) override {
- AXPlatformNodeDelegate* delegate = host_->GetDelegate(tree_id, node_id);
- DCHECK(delegate);
- return delegate->GetBoundsRect(
- ui::AXCoordinateSystem::kScreenPhysicalPixels,
- ui::AXClippingBehavior::kClipped, offscreen_result);
- }
-
- private:
- AXPlatformNodeTextRangeProviderWin* host_;
-};
-
-AXPlatformNodeTextRangeProviderWin::AXPlatformNodeTextRangeProviderWin() {
- DVLOG(1) << __func__;
-}
-
-AXPlatformNodeTextRangeProviderWin::~AXPlatformNodeTextRangeProviderWin() {}
-
-ITextRangeProvider* AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
- AXPlatformNodeWin* owner,
- AXPositionInstance start,
- AXPositionInstance end) {
- CComObject<AXPlatformNodeTextRangeProviderWin>* text_range_provider = nullptr;
- if (SUCCEEDED(CComObject<AXPlatformNodeTextRangeProviderWin>::CreateInstance(
- &text_range_provider))) {
- DCHECK(text_range_provider);
- text_range_provider->owner_ = owner;
- text_range_provider->start_ = std::move(start);
- text_range_provider->end_ = std::move(end);
- text_range_provider->AddRef();
- return text_range_provider;
- }
-
- return nullptr;
-}
-
-//
-// ITextRangeProvider methods.
-//
-HRESULT AXPlatformNodeTextRangeProviderWin::Clone(ITextRangeProvider** clone) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_CLONE);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_OUT(clone);
-
- *clone =
- CreateTextRangeProvider(owner_.Get(), start_->Clone(), end_->Clone());
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::Compare(ITextRangeProvider* other,
- BOOL* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_COMPARE);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_COMPARE);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_IN_1_OUT(other, result);
-
- Microsoft::WRL::ComPtr<AXPlatformNodeTextRangeProviderWin> other_provider;
- if (other->QueryInterface(IID_PPV_ARGS(&other_provider)) != S_OK)
- return UIA_E_INVALIDOPERATION;
-
- if (*start_ == *(other_provider->start_) &&
- *end_ == *(other_provider->end_)) {
- *result = TRUE;
- }
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::CompareEndpoints(
- TextPatternRangeEndpoint this_endpoint,
- ITextRangeProvider* other,
- TextPatternRangeEndpoint other_endpoint,
- int* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_COMPAREENDPOINTS);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_COMPAREENDPOINTS);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_IN_1_OUT(other, result);
-
- Microsoft::WRL::ComPtr<AXPlatformNodeTextRangeProviderWin> other_provider;
- if (other->QueryInterface(IID_PPV_ARGS(&other_provider)) != S_OK)
- return UIA_E_INVALIDOPERATION;
-
- const AXPositionInstance& this_provider_endpoint =
- (this_endpoint == TextPatternRangeEndpoint_Start) ? start_ : end_;
- const AXPositionInstance& other_provider_endpoint =
- (other_endpoint == TextPatternRangeEndpoint_Start)
- ? other_provider->start_
- : other_provider->end_;
-
- base::Optional<int> comparison =
- this_provider_endpoint->CompareTo(*other_provider_endpoint);
- if (!comparison)
- return UIA_E_INVALIDOPERATION;
-
- if (comparison.value() < 0)
- *result = -1;
- else if (comparison.value() > 0)
- *result = 1;
- else
- *result = 0;
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::ExpandToEnclosingUnit(
- TextUnit unit) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_EXPANDTOENCLOSINGUNIT);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_EXPANDTOENCLOSINGUNIT);
- return ExpandToEnclosingUnitImpl(unit);
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::ExpandToEnclosingUnitImpl(
- TextUnit unit) {
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL();
- NormalizeTextRange();
-
- // Determine if start is on a boundary of the specified TextUnit, if it is
- // not, move backwards until it is. Move the end forwards from start until it
- // is on the next TextUnit boundary, if one exists.
- switch (unit) {
- case TextUnit_Character: {
- // For characters, the start endpoint will always be on a TextUnit
- // boundary, thus we only need to move the end position.
- AXPositionInstance end_backup = end_->Clone();
- end_ = start_->CreateNextCharacterPosition(
- AXBoundaryBehavior::CrossBoundary);
-
- if (end_->IsNullPosition()) {
- // The previous could fail if the start is at the end of the last anchor
- // of the tree, try expanding to the previous character instead.
- AXPositionInstance start_backup = start_->Clone();
- start_ = start_->CreatePreviousCharacterPosition(
- AXBoundaryBehavior::CrossBoundary);
-
- if (start_->IsNullPosition()) {
- // Text representation is empty, undo everything and exit.
- start_ = std::move(start_backup);
- end_ = std::move(end_backup);
- return S_OK;
- }
- end_ = start_->CreateNextCharacterPosition(
- AXBoundaryBehavior::CrossBoundary);
- DCHECK(!end_->IsNullPosition());
- }
-
- NormalizeTextRange();
- break;
- }
- case TextUnit_Format:
- start_ = start_->CreatePreviousFormatStartPosition(
- AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- end_ = start_->CreateNextFormatEndPosition(
- AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- break;
- case TextUnit_Word: {
- AXPositionInstance start_backup = start_->Clone();
- start_ = start_->CreatePreviousWordStartPosition(
- AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- // Since we use AXBoundaryBehavior::StopIfAlreadyAtBoundary, the only case
- // possible where CreatePreviousWordStartPosition can return a
- // NullPosition is when it's called on a node before the first word
- // boundary. This can happen when the document starts with nodes that have
- // no word boundaries, like whitespaces and punctuation. When it happens,
- // move the position back to the start of the document.
- if (start_->IsNullPosition())
- start_ = start_backup->CreatePositionAtStartOfDocument();
-
- // Since start_ is already located at a word boundary, we need to cross it
- // in order to move to the next one. Because Windows ATs behave
- // undesirably when the start and end endpoints are not in the same anchor
- // (for character and word navigation), stop at anchor boundary.
- end_ = start_->CreateNextWordStartPosition(
- AXBoundaryBehavior::StopAtAnchorBoundary);
- break;
- }
- case TextUnit_Line:
- start_ = start_->CreateBoundaryStartPosition(
- AXBoundaryBehavior::StopIfAlreadyAtBoundary,
- ax::mojom::MoveDirection::kBackward,
- base::BindRepeating(&AtStartOfLinePredicate),
- base::BindRepeating(&AtEndOfLinePredicate));
- end_ = start_->CreateBoundaryEndPosition(
- AXBoundaryBehavior::StopIfAlreadyAtBoundary,
- ax::mojom::MoveDirection::kForward,
- base::BindRepeating(&AtStartOfLinePredicate),
- base::BindRepeating(&AtEndOfLinePredicate));
- break;
- case TextUnit_Paragraph:
- start_ = start_->CreatePreviousParagraphStartPosition(
- AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- end_ = start_->CreateNextParagraphEndPosition(
- AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- break;
- case TextUnit_Page: {
- // Per UIA spec, if the document containing the current range doesn't
- // support pagination, default to document navigation.
- const AXNode* common_anchor = start_->LowestCommonAnchor(*end_);
- if (common_anchor->tree()->HasPaginationSupport()) {
- start_ = start_->CreatePreviousPageStartPosition(
- ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- end_ = start_->CreateNextPageEndPosition(
- ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- break;
- }
- }
- FALLTHROUGH;
- case TextUnit_Document:
- start_ = start_->CreatePositionAtStartOfDocument()->AsLeafTextPosition();
- end_ = start_->CreatePositionAtEndOfDocument();
- break;
- default:
- return UIA_E_NOTSUPPORTED;
- }
- DCHECK(!start_->IsNullPosition());
- DCHECK(!end_->IsNullPosition());
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::FindAttribute(
- TEXTATTRIBUTEID text_attribute_id,
- VARIANT attribute_val,
- BOOL is_backward,
- ITextRangeProvider** result) {
- // Algorithm description:
- // Performs linear search. Expand forward or backward to fetch the first
- // instance of a sub text range that matches the attribute and its value.
- // |is_backward| determines the direction of our search.
- // |is_backward=true|, we search from the end of this text range to its
- // beginning.
- // |is_backward=false|, we search from the beginning of this text range to its
- // end.
- //
- // 1. Iterate through the vector of AXRanges in this text range in the
- // direction denoted by |is_backward|.
- // 2. The |matched_range| is initially denoted as null since no range
- // currently matches. We initialize |matched_range| to non-null value when
- // we encounter the first AXRange instance that matches in attribute and
- // value. We then set the |matched_range_start| to be the start (anchor) of
- // the current AXRange, and |matched_range_end| to be the end (focus) of
- // the current AXRange.
- // 3. If the current AXRange we are iterating on continues to match attribute
- // and value, we extend |matched_range| in one of the two following ways:
- // - If |is_backward=true|, we extend the |matched_range| by moving
- // |matched_range_start| backward. We do so by setting
- // |matched_range_start| to the start (anchor) of the current AXRange.
- // - If |is_backward=false|, we extend the |matched_range| by moving
- // |matched_range_end| forward. We do so by setting |matched_range_end|
- // to the end (focus) of the current AXRange.
- // 4. We found a match when the current AXRange we are iterating on does not
- // match the attribute and value and there is a previously matched range.
- // The previously matched range is the final match we found.
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_FINDATTRIBUTE);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_FINDATTRIBUTE);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_OUT(result);
- NormalizeTextRange();
-
- *result = nullptr;
- AXPositionInstance matched_range_start = nullptr;
- AXPositionInstance matched_range_end = nullptr;
-
- std::vector<AXNodeRange> anchors;
- AXNodeRange range(start_->Clone(), end_->Clone());
- for (AXNodeRange leaf_text_range : range)
- anchors.emplace_back(std::move(leaf_text_range));
-
- auto expand_match = [&matched_range_start, &matched_range_end, is_backward](
- auto& current_start, auto& current_end) {
- // The current AXRange has the attribute and its value that we are looking
- // for, we expand the matched text range if a previously matched exists,
- // otherwise initialize a newly matched text range.
- if (matched_range_start != nullptr && matched_range_end != nullptr) {
- // Continue expanding the matched text range forward/backward based on
- // the search direction.
- if (is_backward)
- matched_range_start = current_start->Clone();
- else
- matched_range_end = current_end->Clone();
- } else {
- // Initialize the matched text range. The first AXRange instance that
- // matches the attribute and its value encountered.
- matched_range_start = current_start->Clone();
- matched_range_end = current_end->Clone();
- }
- };
-
- HRESULT hr_result =
- is_backward
- ? FindAttributeRange(text_attribute_id, attribute_val,
- anchors.crbegin(), anchors.crend(), expand_match)
- : FindAttributeRange(text_attribute_id, attribute_val,
- anchors.cbegin(), anchors.cend(), expand_match);
- if (FAILED(hr_result))
- return E_FAIL;
-
- if (matched_range_start != nullptr && matched_range_end != nullptr)
- *result = CreateTextRangeProvider(owner(), std::move(matched_range_start),
- std::move(matched_range_end));
- return S_OK;
-}
-
-template <typename AnchorIterator, typename ExpandMatchLambda>
-HRESULT AXPlatformNodeTextRangeProviderWin::FindAttributeRange(
- const TEXTATTRIBUTEID text_attribute_id,
- VARIANT attribute_val,
- const AnchorIterator first,
- const AnchorIterator last,
- ExpandMatchLambda expand_match) {
- AXPlatformNodeWin* current_platform_node;
- bool is_match_found = false;
-
- for (auto it = first; it != last; ++it) {
- const auto& current_start = it->anchor();
- const auto& current_end = it->focus();
-
- DCHECK(current_start->GetAnchor() == current_end->GetAnchor());
-
- AXPlatformNodeDelegate* delegate = GetDelegate(current_start);
- DCHECK(delegate);
-
- current_platform_node = static_cast<AXPlatformNodeWin*>(
- delegate->GetFromNodeID(current_start->GetAnchor()->id()));
-
- base::win::VariantVector current_attribute_value;
- if (FAILED(current_platform_node->GetTextAttributeValue(
- text_attribute_id, current_start->text_offset(),
- current_end->text_offset(), ¤t_attribute_value))) {
- return E_FAIL;
- }
-
- if (!current_attribute_value.Compare(attribute_val)) {
- // When we encounter an AXRange instance that matches the attribute
- // and its value which we are looking for and no previously matched text
- // range exists, we expand or initialize the matched range.
- is_match_found = true;
- expand_match(current_start, current_end);
- } else if (is_match_found) {
- // When we encounter an AXRange instance that does not match the attribute
- // and its value which we are looking for and a previously matched text
- // range exists, the previously matched text range is the result we found.
- break;
- }
- }
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::FindText(
- BSTR string,
- BOOL backwards,
- BOOL ignore_case,
- ITextRangeProvider** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_FINDTEXT);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_FINDTEXT);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_IN_1_OUT(string, result);
-
- base::string16 search_string(string);
- if (search_string.length() <= 0)
- return E_INVALIDARG;
-
- size_t appended_newlines_count = 0;
- base::string16 text_range = GetString(-1, &appended_newlines_count);
- size_t find_start;
- size_t find_length;
- if (base::i18n::StringSearch(search_string, text_range, &find_start,
- &find_length, !ignore_case, !backwards) &&
- find_length > appended_newlines_count) {
- // TODO(https://crbug.com/1023599): There is a known issue here related to
- // text searches of a |string| starting and ending with a "\n", e.g.
- // "\nsometext" or "sometext\n" if the newline is computed from a line
- // breaking object. FindText() is rarely called, and when it is, it's not to
- // look for a string starting or ending with a newline. This may change
- // someday, and if so, we'll have to address this issue.
- const AXNode* common_anchor = start_->LowestCommonAnchor(*end_);
- AXPositionInstance start_ancestor_position =
- start_->CreateAncestorPosition(common_anchor);
- DCHECK(!start_ancestor_position->IsNullPosition());
- AXPositionInstance end_ancestor_position =
- end_->CreateAncestorPosition(common_anchor);
- DCHECK(!end_ancestor_position->IsNullPosition());
- AXTreeID tree_id = start_ancestor_position->tree_id();
- AXNode::AXID anchor_id = start_ancestor_position->anchor_id();
- const int start_offset =
- start_ancestor_position->text_offset() + find_start;
- const int end_offset = start_offset + find_length - appended_newlines_count;
- const int max_end_offset = end_ancestor_position->text_offset();
- DCHECK(start_offset <= end_offset && end_offset <= max_end_offset);
-
- AXPositionInstance start = ui::AXNodePosition::CreateTextPosition(
- tree_id, anchor_id, start_offset,
- ax::mojom::TextAffinity::kDownstream)
- ->AsLeafTextPosition();
- AXPositionInstance end = ui::AXNodePosition::CreateTextPosition(
- tree_id, anchor_id, end_offset,
- ax::mojom::TextAffinity::kDownstream)
- ->AsLeafTextPosition();
-
- *result =
- CreateTextRangeProvider(owner_.Get(), start->Clone(), end->Clone());
- }
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::GetAttributeValue(
- TEXTATTRIBUTEID attribute_id,
- VARIANT* value) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_GETATTRIBUTEVALUE);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_GETATTRIBUTEVALUE);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_OUT(value);
- NormalizeTextRange();
-
- base::win::VariantVector attribute_value;
-
- // The range is inclusive, so advance our endpoint to the next position
- const auto end_leaf_text_position = end_->AsLeafTextPosition();
- auto end = end_leaf_text_position->CreateNextAnchorPosition();
-
- // Iterate over anchor positions
- for (auto it = start_->AsLeafTextPosition();
- it->anchor_id() != end->anchor_id() || it->tree_id() != end->tree_id();
- it = it->CreateNextAnchorPosition()) {
- // If the iterator creates a null position, then it has likely overrun the
- // range, return failure. This is unexpected but may happen if the range
- // became inverted.
- DCHECK(!it->IsNullPosition());
- if (it->IsNullPosition())
- return E_FAIL;
-
- AXPlatformNodeDelegate* delegate = GetDelegate(it.get());
- DCHECK(it && delegate);
-
- AXPlatformNodeWin* platform_node = static_cast<AXPlatformNodeWin*>(
- delegate->GetFromNodeID(it->anchor_id()));
- DCHECK(platform_node);
-
- // Only get attributes for nodes in the tree
- if (platform_node->GetDelegate()->IsChildOfLeaf()) {
- platform_node = static_cast<AXPlatformNodeWin*>(
- AXPlatformNode::FromNativeViewAccessible(
- platform_node->GetDelegate()->GetClosestPlatformObject()));
- DCHECK(platform_node);
- }
-
- base::win::VariantVector current_value;
- const bool at_end_leaf_text_anchor =
- it->anchor_id() == end_leaf_text_position->anchor_id() &&
- it->tree_id() == end_leaf_text_position->tree_id();
- const base::Optional<int> start_offset =
- it->IsTextPosition() ? base::make_optional(it->text_offset())
- : base::nullopt;
- const base::Optional<int> end_offset =
- at_end_leaf_text_anchor
- ? base::make_optional(end_leaf_text_position->text_offset())
- : base::nullopt;
- HRESULT hr = platform_node->GetTextAttributeValue(
- attribute_id, start_offset, end_offset, ¤t_value);
- if (FAILED(hr))
- return E_FAIL;
-
- if (attribute_value.Type() == VT_EMPTY) {
- attribute_value = std::move(current_value);
- } else if (attribute_value != current_value) {
- V_VT(value) = VT_UNKNOWN;
- return ::UiaGetReservedMixedAttributeValue(&V_UNKNOWN(value));
- }
- }
-
- if (ShouldReleaseTextAttributeAsSafearray(attribute_id, attribute_value))
- *value = attribute_value.ReleaseAsSafearrayVariant();
- else
- *value = attribute_value.ReleaseAsScalarVariant();
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::GetBoundingRectangles(
- SAFEARRAY** screen_physical_pixel_rectangles) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_GETBOUNDINGRECTANGLES);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_GETBOUNDINGRECTANGLES);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_OUT(screen_physical_pixel_rectangles);
-
- *screen_physical_pixel_rectangles = nullptr;
- AXNodeRange range(start_->Clone(), end_->Clone());
- AXRangePhysicalPixelRectDelegate rect_delegate(this);
- std::vector<gfx::Rect> rects = range.GetRects(&rect_delegate);
-
- // 4 array items per rect: left, top, width, height
- SAFEARRAY* safe_array = SafeArrayCreateVector(
- VT_R8 /* element type */, 0 /* lower bound */, rects.size() * 4);
-
- if (!safe_array)
- return E_OUTOFMEMORY;
-
- if (rects.size() > 0) {
- double* double_array = nullptr;
- HRESULT hr = SafeArrayAccessData(safe_array,
- reinterpret_cast<void**>(&double_array));
-
- if (SUCCEEDED(hr)) {
- for (size_t rect_index = 0; rect_index < rects.size(); rect_index++) {
- const gfx::Rect& rect = rects[rect_index];
- double_array[rect_index * 4] = rect.x();
- double_array[rect_index * 4 + 1] = rect.y();
- double_array[rect_index * 4 + 2] = rect.width();
- double_array[rect_index * 4 + 3] = rect.height();
- }
- hr = SafeArrayUnaccessData(safe_array);
- }
-
- if (FAILED(hr)) {
- DCHECK(safe_array);
- SafeArrayDestroy(safe_array);
- return E_FAIL;
- }
- }
-
- *screen_physical_pixel_rectangles = safe_array;
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::GetEnclosingElement(
- IRawElementProviderSimple** element) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_GETENCLOSINGELEMENT);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_GETENCLOSINGELEMENT);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_OUT(element);
-
- AXPlatformNodeWin* enclosing_node = GetLowestAccessibleCommonPlatformNode();
- if (!enclosing_node)
- return UIA_E_ELEMENTNOTAVAILABLE;
-
- while (enclosing_node->GetData().IsIgnored() ||
- enclosing_node->GetData().role == ax::mojom::Role::kInlineTextBox ||
- enclosing_node->IsChildOfLeaf()) {
- AXPlatformNodeWin* parent = static_cast<AXPlatformNodeWin*>(
- AXPlatformNode::FromNativeViewAccessible(enclosing_node->GetParent()));
- DCHECK(parent);
- enclosing_node = parent;
- }
-
- enclosing_node->GetNativeViewAccessible()->QueryInterface(
- IID_PPV_ARGS(element));
-
- DCHECK(*element);
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::GetText(int max_count, BSTR* text) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_GETTEXT);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_GETTEXT);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_OUT(text);
-
- // -1 is a valid value that signifies that the caller wants complete text.
- // Any other negative value is an invalid argument.
- if (max_count < -1)
- return E_INVALIDARG;
-
- base::string16 full_text = GetString(max_count);
- if (!full_text.empty()) {
- size_t length = full_text.length();
-
- if (max_count != -1 && max_count < static_cast<int>(length))
- *text = SysAllocStringLen(full_text.c_str(), max_count);
- else
- *text = SysAllocStringLen(full_text.c_str(), length);
- } else {
- *text = SysAllocString(L"");
- }
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::Move(TextUnit unit,
- int count,
- int* units_moved) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_MOVE);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_MOVE);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_OUT(units_moved);
-
- // Per MSDN, move with zero count has no effect.
- if (count == 0)
- return S_OK;
-
- // Save a clone of start and end, in case one of the moves fails.
- auto start_backup = start_->Clone();
- auto end_backup = end_->Clone();
- bool is_degenerate_range = (*start_ == *end_);
-
- // Move the start of the text range forward or backward in the document by the
- // requested number of text unit boundaries.
- int start_units_moved = 0;
- HRESULT hr = MoveEndpointByUnitImpl(TextPatternRangeEndpoint_Start, unit,
- count, &start_units_moved);
-
- bool succeeded_move = SUCCEEDED(hr) && start_units_moved != 0;
- if (succeeded_move) {
- end_ = start_->Clone();
- if (!is_degenerate_range) {
- bool forwards = count > 0;
- if (forwards && start_->AtEndOfDocument()) {
- // The start is at the end of the document, so move the start backward
- // by one text unit to expand the text range from the degenerate range
- // state.
- int current_start_units_moved = 0;
- hr = MoveEndpointByUnitImpl(TextPatternRangeEndpoint_Start, unit, -1,
- ¤t_start_units_moved);
- start_units_moved -= 1;
- succeeded_move = SUCCEEDED(hr) && current_start_units_moved == -1 &&
- start_units_moved > 0;
- } else {
- // The start is not at the end of the document, so move the endpoint
- // forward by one text unit to expand the text range from the degenerate
- // state.
- int end_units_moved = 0;
- hr = MoveEndpointByUnitImpl(TextPatternRangeEndpoint_End, unit, 1,
- &end_units_moved);
- succeeded_move = SUCCEEDED(hr) && end_units_moved == 1;
- }
-
- // Because Windows ATs behave undesirably when the start and end endpoints
- // are not in the same anchor (for character and word navigation), make
- // sure to bring back the end endpoint to the end of the start's anchor.
- if (start_->anchor_id() != end_->anchor_id() &&
- (unit == TextUnit_Character || unit == TextUnit_Word)) {
- ExpandToEnclosingUnitImpl(unit);
- }
- }
- }
-
- if (!succeeded_move) {
- start_ = std::move(start_backup);
- end_ = std::move(end_backup);
- start_units_moved = 0;
- if (!SUCCEEDED(hr))
- return hr;
- }
-
- *units_moved = start_units_moved;
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::MoveEndpointByUnit(
- TextPatternRangeEndpoint endpoint,
- TextUnit unit,
- int count,
- int* units_moved) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_MOVEENDPOINTBYUNIT);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_MOVEENDPOINTBYUNIT);
- return MoveEndpointByUnitImpl(endpoint, unit, count, units_moved);
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::MoveEndpointByUnitImpl(
- TextPatternRangeEndpoint endpoint,
- TextUnit unit,
- int count,
- int* units_moved) {
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_OUT(units_moved);
-
- // Per MSDN, MoveEndpointByUnit with zero count has no effect.
- if (count == 0) {
- *units_moved = 0;
- return S_OK;
- }
-
- bool is_start_endpoint = endpoint == TextPatternRangeEndpoint_Start;
- AXPositionInstance& position_to_move = is_start_endpoint ? start_ : end_;
-
- AXPositionInstance new_position;
- switch (unit) {
- case TextUnit_Character:
- new_position =
- MoveEndpointByCharacter(position_to_move, count, units_moved);
- break;
- case TextUnit_Format:
- new_position = MoveEndpointByFormat(position_to_move, count, units_moved);
- break;
- case TextUnit_Word:
- new_position = MoveEndpointByWord(position_to_move, count, units_moved);
- break;
- case TextUnit_Line:
- new_position = MoveEndpointByLine(position_to_move, is_start_endpoint,
- count, units_moved);
- break;
- case TextUnit_Paragraph:
- new_position = MoveEndpointByParagraph(
- position_to_move, is_start_endpoint, count, units_moved);
- break;
- case TextUnit_Page:
- new_position = MoveEndpointByPage(position_to_move, is_start_endpoint,
- count, units_moved);
- break;
- case TextUnit_Document:
- new_position =
- MoveEndpointByDocument(position_to_move, count, units_moved);
- break;
- default:
- return UIA_E_NOTSUPPORTED;
- }
- position_to_move = std::move(new_position);
-
- // If the start was moved past the end, create a degenerate range with the end
- // equal to the start; do the equivalent if the end moved past the start.
- base::Optional<int> endpoint_comparison =
- AXNodeRange::CompareEndpoints(start_.get(), end_.get());
- DCHECK(endpoint_comparison.has_value());
-
- if (endpoint_comparison.value_or(0) > 0) {
- if (is_start_endpoint)
- end_ = start_->Clone();
- else
- start_ = end_->Clone();
- }
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::MoveEndpointByRange(
- TextPatternRangeEndpoint this_endpoint,
- ITextRangeProvider* other,
- TextPatternRangeEndpoint other_endpoint) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_MOVEENPOINTBYRANGE);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_MOVEENPOINTBYRANGE);
-
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_IN(other);
-
- Microsoft::WRL::ComPtr<AXPlatformNodeTextRangeProviderWin> other_provider;
- if (other->QueryInterface(IID_PPV_ARGS(&other_provider)) != S_OK)
- return UIA_E_INVALIDOPERATION;
-
- const AXPositionInstance& other_provider_endpoint =
- (other_endpoint == TextPatternRangeEndpoint_Start)
- ? other_provider->start_
- : other_provider->end_;
-
- if (this_endpoint == TextPatternRangeEndpoint_Start) {
- start_ = other_provider_endpoint->Clone();
- if (*start_ > *end_)
- end_ = start_->Clone();
- } else {
- end_ = other_provider_endpoint->Clone();
- if (*start_ > *end_)
- start_ = end_->Clone();
- }
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::Select() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_SELECT);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL();
-
- AXPositionInstance selection_start = start_->Clone();
- AXPositionInstance selection_end = end_->Clone();
-
- // Blink only supports selections within a single tree. So if start_ and end_
- // are in different trees, we can't directly pass them to the render process
- // for selection.
- if (selection_start->tree_id() != selection_end->tree_id()) {
- // Prioritize the end position's tree, as a selection's focus object is the
- // end of a selection.
- selection_start = selection_end->CreatePositionAtStartOfAXTree();
- }
-
- DCHECK(!selection_start->IsNullPosition());
- DCHECK(!selection_end->IsNullPosition());
- DCHECK_EQ(selection_start->tree_id(), selection_end->tree_id());
-
- // TODO(crbug.com/1124051): Blink does not support selection on the list
- // markers. So if |selection_start| or |selection_end| are in list markers, we
- // don't perform selection and return success. Remove this check once this bug
- // is fixed.
- if (selection_start->GetAnchor()->IsInListMarker() ||
- selection_end->GetAnchor()->IsInListMarker()) {
- return S_OK;
- }
-
- AXPlatformNodeDelegate* delegate =
- GetDelegate(selection_start->tree_id(), selection_start->anchor_id());
- DCHECK(delegate);
-
- AXNodeRange new_selection_range(std::move(selection_start),
- std::move(selection_end));
- RemoveFocusFromPreviousSelectionIfNeeded(new_selection_range);
-
- AXActionData action_data;
- action_data.anchor_node_id = new_selection_range.anchor()->anchor_id();
- action_data.anchor_offset = new_selection_range.anchor()->text_offset();
- action_data.focus_node_id = new_selection_range.focus()->anchor_id();
- action_data.focus_offset = new_selection_range.focus()->text_offset();
- action_data.action = ax::mojom::Action::kSetSelection;
-
- delegate->AccessibilityPerformAction(action_data);
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::AddToSelection() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_ADDTOSELECTION);
- // Blink does not support disjoint text selections.
- return UIA_E_INVALIDOPERATION;
-}
-
-HRESULT
-AXPlatformNodeTextRangeProviderWin::RemoveFromSelection() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_REMOVEFROMSELECTION);
- // Blink does not support disjoint text selections.
- return UIA_E_INVALIDOPERATION;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::ScrollIntoView(BOOL align_to_top) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_SCROLLINTOVIEW);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL();
-
- const AXPositionInstance start_common_ancestor =
- start_->LowestCommonAncestor(*end_);
- const AXPositionInstance end_common_ancestor =
- end_->LowestCommonAncestor(*start_);
- if (start_common_ancestor->IsNullPosition() ||
- end_common_ancestor->IsNullPosition())
- return E_INVALIDARG;
-
- const AXNode* common_ancestor_anchor = start_common_ancestor->GetAnchor();
- DCHECK(common_ancestor_anchor == end_common_ancestor->GetAnchor());
-
- const AXTreeID common_ancestor_tree_id = start_common_ancestor->tree_id();
- const AXPlatformNodeDelegate* root_delegate =
- GetRootDelegate(common_ancestor_tree_id);
- DCHECK(root_delegate);
- const gfx::Rect root_frame_bounds = root_delegate->GetBoundsRect(
- AXCoordinateSystem::kFrame, AXClippingBehavior::kUnclipped);
- UIA_VALIDATE_BOUNDS(root_frame_bounds);
-
- const AXPlatformNode* common_ancestor_platform_node =
- owner_->GetDelegate()->GetFromTreeIDAndNodeID(
- common_ancestor_tree_id, common_ancestor_anchor->id());
- DCHECK(common_ancestor_platform_node);
- AXPlatformNodeDelegate* common_ancestor_delegate =
- common_ancestor_platform_node->GetDelegate();
- DCHECK(common_ancestor_delegate);
- const gfx::Rect text_range_container_frame_bounds =
- common_ancestor_delegate->GetBoundsRect(AXCoordinateSystem::kFrame,
- AXClippingBehavior::kUnclipped);
- UIA_VALIDATE_BOUNDS(text_range_container_frame_bounds);
-
- gfx::Point target_point;
- if (align_to_top) {
- target_point = gfx::Point(root_frame_bounds.x(), root_frame_bounds.y());
- } else {
- target_point =
- gfx::Point(root_frame_bounds.x(),
- root_frame_bounds.y() + root_frame_bounds.height());
- }
-
- if ((align_to_top && start_->GetAnchor()->IsText()) ||
- (!align_to_top && end_->GetAnchor()->IsText())) {
- const gfx::Rect text_range_frame_bounds =
- common_ancestor_delegate->GetInnerTextRangeBoundsRect(
- start_common_ancestor->text_offset(),
- end_common_ancestor->text_offset(), AXCoordinateSystem::kFrame,
- AXClippingBehavior::kUnclipped);
- UIA_VALIDATE_BOUNDS(text_range_frame_bounds);
-
- if (align_to_top) {
- target_point.Offset(0, -(text_range_container_frame_bounds.height() -
- text_range_frame_bounds.height()));
- } else {
- target_point.Offset(0, -text_range_frame_bounds.height());
- }
- } else {
- if (!align_to_top)
- target_point.Offset(0, -text_range_container_frame_bounds.height());
- }
-
- const gfx::Rect root_screen_bounds = root_delegate->GetBoundsRect(
- AXCoordinateSystem::kScreenDIPs, AXClippingBehavior::kUnclipped);
- UIA_VALIDATE_BOUNDS(root_screen_bounds);
- target_point += root_screen_bounds.OffsetFromOrigin();
-
- AXActionData action_data;
- action_data.action = ax::mojom::Action::kScrollToPoint;
- action_data.target_node_id = common_ancestor_anchor->id();
- action_data.target_point = target_point;
- if (!common_ancestor_delegate->AccessibilityPerformAction(action_data))
- return E_FAIL;
- return S_OK;
-}
-
-HRESULT AXPlatformNodeTextRangeProviderWin::GetChildren(SAFEARRAY** children) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TEXTRANGE_GETCHILDREN);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_TEXTRANGE_GETCHILDREN);
- UIA_VALIDATE_TEXTRANGEPROVIDER_CALL_1_OUT(children);
-
- std::vector<gfx::NativeViewAccessible> descendants;
-
- const AXNode* common_anchor = start_->LowestCommonAnchor(*end_);
- const AXTreeID tree_id = common_anchor->tree()->GetAXTreeID();
- const AXNode::AXID node_id = common_anchor->id();
- AXPlatformNodeDelegate* delegate = GetDelegate(tree_id, node_id);
- DCHECK(delegate);
- while (delegate->GetData().IsIgnored()) {
- auto* node = static_cast<AXPlatformNodeWin*>(
- AXPlatformNode::FromNativeViewAccessible(delegate->GetParent()));
- DCHECK(node);
- delegate = node->GetDelegate();
- }
- if (delegate->GetChildCount())
- descendants = delegate->GetUIADescendants();
-
- SAFEARRAY* safe_array =
- SafeArrayCreateVector(VT_UNKNOWN, 0, descendants.size());
-
- if (!safe_array)
- return E_OUTOFMEMORY;
-
- if (safe_array->rgsabound->cElements != descendants.size()) {
- DCHECK(safe_array);
- SafeArrayDestroy(safe_array);
- return E_OUTOFMEMORY;
- }
-
- LONG i = 0;
- for (const gfx::NativeViewAccessible& descendant : descendants) {
- IRawElementProviderSimple* raw_provider;
- descendant->QueryInterface(IID_PPV_ARGS(&raw_provider));
- SafeArrayPutElement(safe_array, &i, raw_provider);
- ++i;
- }
-
- *children = safe_array;
- return S_OK;
-}
-
-// static
-bool AXPlatformNodeTextRangeProviderWin::AtStartOfLinePredicate(
- const AXPositionInstance& position) {
- return !position->IsIgnored() && position->AtStartOfAnchor() &&
- (position->AtStartOfLine() || position->AtStartOfInlineBlock());
-}
-
-// static
-bool AXPlatformNodeTextRangeProviderWin::AtEndOfLinePredicate(
- const AXPositionInstance& position) {
- return !position->IsIgnored() && position->AtEndOfAnchor() &&
- (position->AtEndOfLine() || position->AtStartOfInlineBlock());
-}
-
-// static
-AXPlatformNodeTextRangeProviderWin::AXPositionInstance
-AXPlatformNodeTextRangeProviderWin::GetNextTextBoundaryPosition(
- const AXPositionInstance& position,
- ax::mojom::TextBoundary boundary_type,
- AXBoundaryBehavior boundary_behavior,
- ax::mojom::MoveDirection boundary_direction) {
- // Override At[Start|End]OfLinePredicate for behavior specific to UIA.
- switch (boundary_type) {
- case ax::mojom::TextBoundary::kLineStart:
- return position->CreateBoundaryStartPosition(
- boundary_behavior, boundary_direction,
- base::BindRepeating(&AtStartOfLinePredicate),
- base::BindRepeating(&AtEndOfLinePredicate));
- case ax::mojom::TextBoundary::kLineEnd:
- return position->CreateBoundaryEndPosition(
- boundary_behavior, boundary_direction,
- base::BindRepeating(&AtStartOfLinePredicate),
- base::BindRepeating(&AtEndOfLinePredicate));
- default:
- return position->CreatePositionAtTextBoundary(
- boundary_type, boundary_direction, boundary_behavior);
- }
-}
-
-base::string16 AXPlatformNodeTextRangeProviderWin::GetString(
- int max_count,
- size_t* appended_newlines_count) {
- AXNodeRange range(start_->Clone(), end_->Clone());
- return range.GetText(AXTextConcatenationBehavior::kAsInnerText, max_count,
- false, appended_newlines_count);
-}
-
-AXPlatformNodeWin* AXPlatformNodeTextRangeProviderWin::owner() const {
- return owner_.Get();
-}
-
-AXPlatformNodeDelegate* AXPlatformNodeTextRangeProviderWin::GetDelegate(
- const AXPositionInstanceType* position) const {
- return GetDelegate(position->tree_id(), position->anchor_id());
-}
-
-AXPlatformNodeDelegate* AXPlatformNodeTextRangeProviderWin::GetDelegate(
- const AXTreeID tree_id,
- const AXNode::AXID node_id) const {
- AXPlatformNode* platform_node =
- owner_->GetDelegate()->GetFromTreeIDAndNodeID(tree_id, node_id);
- if (!platform_node)
- return nullptr;
-
- return platform_node->GetDelegate();
-}
-
-AXPlatformNodeTextRangeProviderWin::AXPositionInstance
-AXPlatformNodeTextRangeProviderWin::MoveEndpointByCharacter(
- const AXPositionInstance& endpoint,
- const int count,
- int* units_moved) {
- return MoveEndpointByUnitHelper(std::move(endpoint),
- ax::mojom::TextBoundary::kCharacter, count,
- units_moved);
-}
-
-AXPlatformNodeTextRangeProviderWin::AXPositionInstance
-AXPlatformNodeTextRangeProviderWin::MoveEndpointByWord(
- const AXPositionInstance& endpoint,
- const int count,
- int* units_moved) {
- return MoveEndpointByUnitHelper(std::move(endpoint),
- ax::mojom::TextBoundary::kWordStart, count,
- units_moved);
-}
-
-AXPlatformNodeTextRangeProviderWin::AXPositionInstance
-AXPlatformNodeTextRangeProviderWin::MoveEndpointByLine(
- const AXPositionInstance& endpoint,
- bool is_start_endpoint,
- const int count,
- int* units_moved) {
- return MoveEndpointByUnitHelper(std::move(endpoint),
- is_start_endpoint
- ? ax::mojom::TextBoundary::kLineStart
- : ax::mojom::TextBoundary::kLineEnd,
- count, units_moved);
-}
-
-AXPlatformNodeTextRangeProviderWin::AXPositionInstance
-AXPlatformNodeTextRangeProviderWin::MoveEndpointByFormat(
- const AXPositionInstance& endpoint,
- const int count,
- int* units_moved) {
- return MoveEndpointByUnitHelper(std::move(endpoint),
- ax::mojom::TextBoundary::kFormat, count,
- units_moved);
-}
-
-AXPlatformNodeTextRangeProviderWin::AXPositionInstance
-AXPlatformNodeTextRangeProviderWin::MoveEndpointByParagraph(
- const AXPositionInstance& endpoint,
- const bool is_start_endpoint,
- const int count,
- int* units_moved) {
- return MoveEndpointByUnitHelper(std::move(endpoint),
- is_start_endpoint
- ? ax::mojom::TextBoundary::kParagraphStart
- : ax::mojom::TextBoundary::kParagraphEnd,
- count, units_moved);
-}
-
-AXPlatformNodeTextRangeProviderWin::AXPositionInstance
-AXPlatformNodeTextRangeProviderWin::MoveEndpointByPage(
- const AXPositionInstance& endpoint,
- const bool is_start_endpoint,
- const int count,
- int* units_moved) {
- // Per UIA spec, if the document containing the current endpoint doesn't
- // support pagination, default to document navigation.
- AXPositionInstance common_ancestor = start_->LowestCommonAncestor(*end_);
- if (!common_ancestor->GetAnchor()->tree()->HasPaginationSupport())
- return MoveEndpointByDocument(std::move(endpoint), count, units_moved);
-
- return MoveEndpointByUnitHelper(std::move(endpoint),
- is_start_endpoint
- ? ax::mojom::TextBoundary::kPageStart
- : ax::mojom::TextBoundary::kPageEnd,
- count, units_moved);
-}
-
-AXPlatformNodeTextRangeProviderWin::AXPositionInstance
-AXPlatformNodeTextRangeProviderWin::MoveEndpointByDocument(
- const AXPositionInstance& endpoint,
- const int count,
- int* units_moved) {
- DCHECK_NE(count, 0);
-
- if (count < 0) {
- *units_moved = !endpoint->AtStartOfDocument() ? -1 : 0;
- return endpoint->CreatePositionAtStartOfDocument();
- }
- *units_moved = !endpoint->AtEndOfDocument() ? 1 : 0;
- return endpoint->CreatePositionAtEndOfDocument();
-}
-
-AXPlatformNodeTextRangeProviderWin::AXPositionInstance
-AXPlatformNodeTextRangeProviderWin::MoveEndpointByUnitHelper(
- const AXPositionInstance& endpoint,
- const ax::mojom::TextBoundary boundary_type,
- const int count,
- int* units_moved) {
- DCHECK_NE(count, 0);
- const ax::mojom::MoveDirection boundary_direction =
- (count > 0) ? ax::mojom::MoveDirection::kForward
- : ax::mojom::MoveDirection::kBackward;
-
- // Most of the methods used to create the next/previous position go back and
- // forth creating a leaf text position and rooting the result to the original
- // position's anchor; avoid this by normalizing to a leaf text position.
- AXPositionInstance current_endpoint = endpoint->AsLeafTextPosition();
-
- for (int iteration = 0; iteration < std::abs(count); ++iteration) {
- AXPositionInstance next_endpoint = GetNextTextBoundaryPosition(
- current_endpoint, boundary_type,
- AXBoundaryBehavior::StopAtLastAnchorBoundary, boundary_direction);
- DCHECK(next_endpoint->IsLeafTextPosition());
-
- // Since AXBoundaryBehavior::StopAtLastAnchorBoundary forces the next text
- // boundary position to be different than the input position, the only case
- // where these are equal is when they're already located at the last anchor
- // boundary. In such case, there is no next position to move to.
- if (next_endpoint->GetAnchor() == current_endpoint->GetAnchor() &&
- *next_endpoint == *current_endpoint) {
- *units_moved = (count > 0) ? iteration : -iteration;
- return current_endpoint;
- }
- current_endpoint = std::move(next_endpoint);
- }
-
- *units_moved = count;
- return current_endpoint;
-}
-
-void AXPlatformNodeTextRangeProviderWin::NormalizeTextRange() {
- if (!start_->IsValid() || !end_->IsValid())
- return;
-
- // If either endpoint is anchored to an ignored node,
- // first snap them both to be unignored positions.
- NormalizeAsUnignoredTextRange();
-
- // When carets are visible or selections are occurring, the precise state of
- // the TextPattern must be preserved so that the UIA client can handle
- // scenarios such as determining which characters were deleted. So
- // normalization must be bypassed.
- if (HasCaretOrSelectionInPlainTextField(start_) ||
- HasCaretOrSelectionInPlainTextField(end_)) {
- return;
- }
-
- AXPositionInstance normalized_start =
- start_->AsLeafTextPositionBeforeCharacter();
-
- // For a degenerate range, the |end_| will always be the same as the
- // normalized start, so there's no need to compute the normalized end.
- // However, a degenerate range might go undetected if there's an ignored node
- // (or many) between the two endpoints. For this reason, we need to
- // compare the |end_| with both the |start_| and the |normalized_start|.
- bool is_degenerate = *start_ == *end_ || *normalized_start == *end_;
- AXPositionInstance normalized_end =
- is_degenerate ? normalized_start->Clone()
- : end_->AsLeafTextPositionAfterCharacter();
-
- if (!normalized_start->IsNullPosition() &&
- !normalized_end->IsNullPosition()) {
- start_ = std::move(normalized_start);
- end_ = std::move(normalized_end);
- }
-
- DCHECK_LE(*start_, *end_);
-}
-
-void AXPlatformNodeTextRangeProviderWin::NormalizeAsUnignoredTextRange() {
- if (!start_->IsValid() || !end_->IsValid())
- return;
-
- if (!start_->IsIgnored() && !end_->IsIgnored())
- return;
-
- if (start_->IsIgnored()) {
- AXPositionInstance normalized_start =
- start_->AsUnignoredPosition(AXPositionAdjustmentBehavior::kMoveForward);
- if (normalized_start->IsNullPosition()) {
- normalized_start = start_->AsUnignoredPosition(
- AXPositionAdjustmentBehavior::kMoveBackward);
- }
- if (!normalized_start->IsNullPosition())
- start_ = std::move(normalized_start);
- }
-
- if (end_->IsIgnored()) {
- AXPositionInstance normalized_end =
- end_->AsUnignoredPosition(AXPositionAdjustmentBehavior::kMoveForward);
- if (normalized_end->IsNullPosition()) {
- normalized_end = end_->AsUnignoredPosition(
- AXPositionAdjustmentBehavior::kMoveBackward);
- }
- if (!normalized_end->IsNullPosition())
- end_ = std::move(normalized_end);
- }
-
- DCHECK_LE(*start_, *end_);
-}
-
-AXPlatformNodeDelegate* AXPlatformNodeTextRangeProviderWin::GetRootDelegate(
- const ui::AXTreeID tree_id) {
- const AXTreeManager* ax_tree_manager =
- AXTreeManagerMap::GetInstance().GetManager(tree_id);
- DCHECK(ax_tree_manager);
- AXNode* root_node = ax_tree_manager->GetRootAsAXNode();
- const AXPlatformNode* root_platform_node =
- owner_->GetDelegate()->GetFromTreeIDAndNodeID(tree_id, root_node->id());
- DCHECK(root_platform_node);
- return root_platform_node->GetDelegate();
-}
-
-AXNode* AXPlatformNodeTextRangeProviderWin::GetSelectionCommonAnchor() {
- AXPlatformNodeDelegate* delegate = owner()->GetDelegate();
- ui::AXTree::Selection unignored_selection = delegate->GetUnignoredSelection();
- AXPlatformNode* anchor_object =
- delegate->GetFromNodeID(unignored_selection.anchor_object_id);
- AXPlatformNode* focus_object =
- delegate->GetFromNodeID(unignored_selection.focus_object_id);
-
- if (!anchor_object || !focus_object)
- return nullptr;
-
- AXNodePosition::AXPositionInstance start =
- anchor_object->GetDelegate()->CreateTextPositionAt(
- unignored_selection.anchor_offset);
- AXNodePosition::AXPositionInstance end =
- focus_object->GetDelegate()->CreateTextPositionAt(
- unignored_selection.focus_offset);
-
- return start->LowestCommonAnchor(*end);
-}
-
-// When the current selection is inside a focusable element, the DOM focused
-// element will correspond to this element. When we update the selection to be
-// on a different element that is not focusable, the new selection won't be
-// applied unless we remove the DOM focused element. For example, with Narrator,
-// if we move by word from a text field (focusable) to a static text (not
-// focusable), the selection will stay on the text field because the DOM focused
-// element will still be the text field. To avoid that, we need to remove the
-// focus from this element. Since |ax::mojom::Action::kBlur| is not implemented,
-// we perform a |ax::mojom::Action::focus| action on the root node. The result
-// is the same.
-void AXPlatformNodeTextRangeProviderWin::
- RemoveFocusFromPreviousSelectionIfNeeded(const AXNodeRange& new_selection) {
- const AXNode* old_selection_node = GetSelectionCommonAnchor();
- const AXNode* new_selection_node =
- new_selection.anchor()->LowestCommonAnchor(*new_selection.focus());
-
- if (!old_selection_node)
- return;
-
- if (!new_selection_node ||
- (old_selection_node->data().HasState(ax::mojom::State::kFocusable) &&
- !new_selection_node->data().HasState(ax::mojom::State::kFocusable))) {
- AXPlatformNodeDelegate* root_delegate =
- GetRootDelegate(old_selection_node->tree()->GetAXTreeID());
- DCHECK(root_delegate);
-
- AXActionData focus_action;
- focus_action.action = ax::mojom::Action::kFocus;
- root_delegate->AccessibilityPerformAction(focus_action);
- }
-}
-
-AXPlatformNodeWin*
-AXPlatformNodeTextRangeProviderWin::GetLowestAccessibleCommonPlatformNode()
- const {
- AXNode* common_anchor = start_->LowestCommonAnchor(*end_);
- if (!common_anchor)
- return nullptr;
-
- const AXTreeID tree_id = common_anchor->tree()->GetAXTreeID();
- const AXNode::AXID node_id = common_anchor->id();
- AXPlatformNodeWin* platform_node =
- static_cast<AXPlatformNodeWin*>(AXPlatformNode::FromNativeViewAccessible(
- GetDelegate(tree_id, node_id)->GetNativeViewAccessible()));
- DCHECK(platform_node);
-
- return platform_node->GetLowestAccessibleElement();
-}
-
-bool AXPlatformNodeTextRangeProviderWin::HasCaretOrSelectionInPlainTextField(
- const AXPositionInstance& position) const {
- // This condition fixes issues when the caret is inside a plain text field,
- // but causes more issues when used inside of a rich text field. For this
- // reason, if we have a caret or a selection inside of an editable node,
- // restrict this to a plain text field as we gain nothing from using it in a
- // rich text field.
- AXPlatformNodeDelegate* delegate = GetDelegate(position.get());
- if (delegate && delegate->HasVisibleCaretOrSelection()) {
- if (!delegate->GetData().HasState(ax::mojom::State::kEditable) ||
- (delegate->GetData().IsPlainTextField() ||
- delegate->IsChildOfPlainTextField())) {
- return true;
- }
- }
- return false;
-}
-
-// static
-bool AXPlatformNodeTextRangeProviderWin::TextAttributeIsArrayType(
- TEXTATTRIBUTEID attribute_id) {
- // https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-textattribute-ids
- return attribute_id == UIA_AnnotationTypesAttributeId ||
- attribute_id == UIA_TabsAttributeId;
-}
-
-// static
-bool AXPlatformNodeTextRangeProviderWin::TextAttributeIsUiaReservedValue(
- const base::win::VariantVector& vector) {
- // Reserved values are always IUnknown.
- if (vector.Type() != VT_UNKNOWN)
- return false;
-
- base::win::ScopedVariant mixed_attribute_value_variant;
- {
- Microsoft::WRL::ComPtr<IUnknown> mixed_attribute_value;
- HRESULT hr = ::UiaGetReservedMixedAttributeValue(&mixed_attribute_value);
- DCHECK(SUCCEEDED(hr));
- mixed_attribute_value_variant.Set(mixed_attribute_value.Get());
- }
-
- base::win::ScopedVariant not_supported_value_variant;
- {
- Microsoft::WRL::ComPtr<IUnknown> not_supported_value;
- HRESULT hr = ::UiaGetReservedNotSupportedValue(¬_supported_value);
- DCHECK(SUCCEEDED(hr));
- not_supported_value_variant.Set(not_supported_value.Get());
- }
-
- return !vector.Compare(mixed_attribute_value_variant) ||
- !vector.Compare(not_supported_value_variant);
-}
-
-// static
-bool AXPlatformNodeTextRangeProviderWin::ShouldReleaseTextAttributeAsSafearray(
- TEXTATTRIBUTEID attribute_id,
- const base::win::VariantVector& attribute_value) {
- // |vector| may be pre-populated with a UIA reserved value. In such a case, we
- // must release as a scalar variant.
- return TextAttributeIsArrayType(attribute_id) &&
- !TextAttributeIsUiaReservedValue(attribute_value);
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_textrangeprovider_win.h b/third_party/accessibility/ax/platform/ax_platform_node_textrangeprovider_win.h
deleted file mode 100644
index 859c747..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_textrangeprovider_win.h
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_TEXTRANGEPROVIDER_WIN_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_TEXTRANGEPROVIDER_WIN_H_
-
-#include <wrl/client.h>
-
-#include <string>
-#include <tuple>
-#include <vector>
-
-#include "ui/accessibility/ax_node_position.h"
-#include "ui/accessibility/ax_position.h"
-#include "ui/accessibility/ax_range.h"
-#include "ui/accessibility/platform/ax_platform_node_win.h"
-
-namespace ui {
-class AX_EXPORT __declspec(uuid("3071e40d-a10d-45ff-a59f-6e8e1138e2c1"))
- AXPlatformNodeTextRangeProviderWin
- : public CComObjectRootEx<CComMultiThreadModel>,
- public ITextRangeProvider {
- public:
- BEGIN_COM_MAP(AXPlatformNodeTextRangeProviderWin)
- COM_INTERFACE_ENTRY(ITextRangeProvider)
- COM_INTERFACE_ENTRY(AXPlatformNodeTextRangeProviderWin)
- END_COM_MAP()
-
- AXPlatformNodeTextRangeProviderWin();
- ~AXPlatformNodeTextRangeProviderWin();
-
- // Creates an instance of the class.
- static ITextRangeProvider* CreateTextRangeProvider(
- AXPlatformNodeWin* owner,
- AXNodePosition::AXPositionInstance start,
- AXNodePosition::AXPositionInstance end);
-
- //
- // ITextRangeProvider methods.
- //
-
- IFACEMETHODIMP Clone(ITextRangeProvider** clone) override;
- IFACEMETHODIMP Compare(ITextRangeProvider* other, BOOL* result) override;
- IFACEMETHODIMP
- CompareEndpoints(TextPatternRangeEndpoint this_endpoint,
- ITextRangeProvider* other,
- TextPatternRangeEndpoint other_endpoint,
- int* result) override;
- IFACEMETHODIMP ExpandToEnclosingUnit(TextUnit unit) override;
- IFACEMETHODIMP
- FindAttribute(TEXTATTRIBUTEID attribute_id,
- VARIANT attribute_val,
- BOOL is_backward,
- ITextRangeProvider** result) override;
- IFACEMETHODIMP
- FindText(BSTR string,
- BOOL backwards,
- BOOL ignore_case,
- ITextRangeProvider** result) override;
- IFACEMETHODIMP GetAttributeValue(TEXTATTRIBUTEID attribute_id,
- VARIANT* value) override;
- IFACEMETHODIMP
- GetBoundingRectangles(SAFEARRAY** screen_physical_pixel_rectangles) override;
- IFACEMETHODIMP
- GetEnclosingElement(IRawElementProviderSimple** element) override;
- IFACEMETHODIMP GetText(int max_count, BSTR* text) override;
- IFACEMETHODIMP Move(TextUnit unit, int count, int* units_moved) override;
- IFACEMETHODIMP
- MoveEndpointByUnit(TextPatternRangeEndpoint endpoint,
- TextUnit unit,
- int count,
- int* units_moved) override;
- IFACEMETHODIMP
- MoveEndpointByRange(TextPatternRangeEndpoint this_endpoint,
- ITextRangeProvider* other,
- TextPatternRangeEndpoint other_endpoint) override;
- IFACEMETHODIMP Select() override;
- IFACEMETHODIMP AddToSelection() override;
- IFACEMETHODIMP RemoveFromSelection() override;
- IFACEMETHODIMP ScrollIntoView(BOOL align_to_top) override;
- IFACEMETHODIMP GetChildren(SAFEARRAY** children) override;
-
- private:
- using AXPositionInstance = AXNodePosition::AXPositionInstance;
- using AXPositionInstanceType = typename AXPositionInstance::element_type;
- using AXNodeRange = AXRange<AXPositionInstanceType>;
-
- friend class AXPlatformNodeTextRangeProviderTest;
- friend class AXPlatformNodeTextProviderTest;
- friend class AXRangePhysicalPixelRectDelegate;
-
- static bool AtStartOfLinePredicate(const AXPositionInstance& position);
- static bool AtEndOfLinePredicate(const AXPositionInstance& position);
-
- static AXPositionInstance GetNextTextBoundaryPosition(
- const AXPositionInstance& position,
- ax::mojom::TextBoundary boundary_type,
- AXBoundaryBehavior boundary_behavior,
- ax::mojom::MoveDirection boundary_direction);
-
- // Prefer these *Impl methods when functionality is needed internally. We
- // should avoid calling external APIs internally as it will cause the
- // histograms to become innaccurate.
- HRESULT MoveEndpointByUnitImpl(TextPatternRangeEndpoint endpoint,
- TextUnit unit,
- int count,
- int* units_moved);
-
- IFACEMETHODIMP ExpandToEnclosingUnitImpl(TextUnit unit);
-
- base::string16 GetString(int max_count,
- size_t* appended_newlines_count = nullptr);
- AXPlatformNodeWin* owner() const;
- AXPlatformNodeDelegate* GetDelegate(
- const AXPositionInstanceType* position) const;
- AXPlatformNodeDelegate* GetDelegate(const AXTreeID tree_id,
- const AXNode::AXID node_id) const;
-
- template <typename AnchorIterator, typename ExpandMatchLambda>
- HRESULT FindAttributeRange(const TEXTATTRIBUTEID text_attribute_id,
- VARIANT attribute_val,
- const AnchorIterator first,
- const AnchorIterator last,
- ExpandMatchLambda expand_match);
-
- AXPositionInstance MoveEndpointByCharacter(const AXPositionInstance& endpoint,
- const int count,
- int* units_moved);
- AXPositionInstance MoveEndpointByWord(const AXPositionInstance& endpoint,
- const int count,
- int* units_moved);
- AXPositionInstance MoveEndpointByLine(const AXPositionInstance& endpoint,
- bool is_start_endpoint,
- const int count,
- int* units_moved);
- AXPositionInstance MoveEndpointByParagraph(const AXPositionInstance& endpoint,
- const bool is_start_endpoint,
- const int count,
- int* units_moved);
- AXPositionInstance MoveEndpointByPage(const AXPositionInstance& endpoint,
- const bool is_start_endpoint,
- const int count,
- int* units_moved);
- AXPositionInstance MoveEndpointByFormat(const AXPositionInstance& endpoint,
- const int count,
- int* units_moved);
- AXPositionInstance MoveEndpointByDocument(const AXPositionInstance& endpoint,
- const int count,
- int* units_moved);
-
- AXPositionInstance MoveEndpointByUnitHelper(
- const AXPositionInstance& endpoint,
- const ax::mojom::TextBoundary boundary_type,
- const int count,
- int* units_moved);
-
- // A text range normalization is necessary to prevent a |start_| endpoint to
- // be positioned at the end of an anchor when it can be at the start of the
- // next anchor. After normalization, it is guaranteed that:
- // * both endpoints of a range are always positioned on unignored anchors;
- // * both endpoints of a range are never between a grapheme cluster;
- // * if the range is degenerate, both endpoints of a range are on the same
- // anchor.
- void NormalizeTextRange();
- void NormalizeAsUnignoredTextRange();
-
- AXPlatformNodeDelegate* GetRootDelegate(const ui::AXTreeID tree_id);
- AXNode* GetSelectionCommonAnchor();
- void RemoveFocusFromPreviousSelectionIfNeeded(
- const AXNodeRange& new_selection);
- AXPlatformNodeWin* GetLowestAccessibleCommonPlatformNode() const;
- bool HasCaretOrSelectionInPlainTextField(
- const AXPositionInstance& position) const;
-
- static bool TextAttributeIsArrayType(TEXTATTRIBUTEID attribute_id);
- static bool TextAttributeIsUiaReservedValue(
- const base::win::VariantVector& vector);
- static bool ShouldReleaseTextAttributeAsSafearray(
- TEXTATTRIBUTEID attribute_id,
- const base::win::VariantVector& vector);
-
- Microsoft::WRL::ComPtr<AXPlatformNodeWin> owner_;
- AXPositionInstance start_;
- AXPositionInstance end_;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_TEXTRANGEPROVIDER_WIN_H_
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_textrangeprovider_win_unittest.cc b/third_party/accessibility/ax/platform/ax_platform_node_textrangeprovider_win_unittest.cc
deleted file mode 100644
index d42dd13..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_textrangeprovider_win_unittest.cc
+++ /dev/null
@@ -1,5721 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_node_win_unittest.h"
-
-#include <UIAutomationClient.h>
-#include <UIAutomationCoreApi.h>
-
-#include <memory>
-#include <utility>
-
-#include "base/win/atl.h"
-#include "base/win/scoped_bstr.h"
-#include "base/win/scoped_safearray.h"
-#include "base/win/scoped_variant.h"
-#include "ui/accessibility/platform/ax_fragment_root_win.h"
-#include "ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h"
-using Microsoft::WRL::ComPtr;
-
-namespace ui {
-
-// Helper macros for UIAutomation HRESULT expectations
-#define EXPECT_UIA_ELEMENTNOTAVAILABLE(expr) \
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE), (expr))
-#define EXPECT_UIA_INVALIDOPERATION(expr) \
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_INVALIDOPERATION), (expr))
-#define EXPECT_UIA_ELEMENTNOTENABLED(expr) \
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTENABLED), (expr))
-#define EXPECT_UIA_NOTSUPPORTED(expr) \
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_NOTSUPPORTED), (expr))
-
-#define ASSERT_UIA_ELEMENTNOTAVAILABLE(expr) \
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE), (expr))
-#define ASSERT_UIA_INVALIDOPERATION(expr) \
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_INVALIDOPERATION), (expr))
-#define ASSERT_UIA_ELEMENTNOTENABLED(expr) \
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTENABLED), (expr))
-#define ASSERT_UIA_NOTSUPPORTED(expr) \
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_NOTSUPPORTED), (expr))
-
-#define EXPECT_UIA_SAFEARRAY_EQ(safearray, expected_property_values) \
- { \
- using T = typename decltype(expected_property_values)::value_type; \
- EXPECT_EQ(sizeof(T), ::SafeArrayGetElemsize(safearray)); \
- EXPECT_EQ(1u, SafeArrayGetDim(safearray)); \
- LONG array_lower_bound; \
- EXPECT_HRESULT_SUCCEEDED( \
- SafeArrayGetLBound(safearray, 1, &array_lower_bound)); \
- LONG array_upper_bound; \
- EXPECT_HRESULT_SUCCEEDED( \
- SafeArrayGetUBound(safearray, 1, &array_upper_bound)); \
- const size_t count = array_upper_bound - array_lower_bound + 1; \
- EXPECT_EQ(expected_property_values.size(), count); \
- if (sizeof(T) == ::SafeArrayGetElemsize(safearray) && \
- count == expected_property_values.size()) { \
- T* array_data; \
- EXPECT_HRESULT_SUCCEEDED(::SafeArrayAccessData( \
- safearray, reinterpret_cast<void**>(&array_data))); \
- for (size_t i = 0; i < count; ++i) { \
- EXPECT_EQ(array_data[i], expected_property_values[i]); \
- } \
- EXPECT_HRESULT_SUCCEEDED(::SafeArrayUnaccessData(safearray)); \
- } \
- }
-
-#define EXPECT_UIA_TEXTATTRIBUTE_EQ(provider, attribute, variant) \
- { \
- base::win::ScopedVariant scoped_variant; \
- EXPECT_HRESULT_SUCCEEDED( \
- provider->GetAttributeValue(attribute, scoped_variant.Receive())); \
- EXPECT_EQ(0, scoped_variant.Compare(variant)); \
- }
-
-#define EXPECT_UIA_TEXTATTRIBUTE_MIXED(provider, attribute) \
- { \
- ComPtr<IUnknown> expected_mixed; \
- EXPECT_HRESULT_SUCCEEDED( \
- ::UiaGetReservedMixedAttributeValue(&expected_mixed)); \
- base::win::ScopedVariant scoped_variant; \
- EXPECT_HRESULT_SUCCEEDED( \
- provider->GetAttributeValue(attribute, scoped_variant.Receive())); \
- EXPECT_EQ(VT_UNKNOWN, scoped_variant.type()); \
- EXPECT_EQ(expected_mixed.Get(), V_UNKNOWN(scoped_variant.ptr())); \
- }
-
-#define EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(provider, attribute) \
- { \
- ComPtr<IUnknown> expected_notsupported; \
- EXPECT_HRESULT_SUCCEEDED( \
- ::UiaGetReservedNotSupportedValue(&expected_notsupported)); \
- base::win::ScopedVariant scoped_variant; \
- EXPECT_HRESULT_SUCCEEDED( \
- provider->GetAttributeValue(attribute, scoped_variant.Receive())); \
- EXPECT_EQ(VT_UNKNOWN, scoped_variant.type()); \
- EXPECT_EQ(expected_notsupported.Get(), V_UNKNOWN(scoped_variant.ptr())); \
- }
-
-#define EXPECT_UIA_TEXTRANGE_EQ(provider, expected_content) \
- { \
- base::win::ScopedBstr provider_content; \
- EXPECT_HRESULT_SUCCEEDED( \
- provider->GetText(-1, provider_content.Receive())); \
- EXPECT_STREQ(expected_content, provider_content.Get()); \
- }
-
-#define EXPECT_UIA_FIND_TEXT(text_range_provider, search_term, ignore_case) \
- { \
- base::win::ScopedBstr find_string(search_term); \
- ComPtr<ITextRangeProvider> text_range_provider_found; \
- EXPECT_HRESULT_SUCCEEDED(text_range_provider->FindText( \
- find_string.Get(), false, ignore_case, &text_range_provider_found)); \
- base::win::ScopedBstr found_content; \
- EXPECT_HRESULT_SUCCEEDED( \
- text_range_provider_found->GetText(-1, found_content.Receive())); \
- if (ignore_case) \
- EXPECT_EQ(0, _wcsicmp(found_content.Get(), find_string.Get())); \
- else \
- EXPECT_EQ(0, wcscmp(found_content.Get(), find_string.Get())); \
- }
-
-#define EXPECT_UIA_FIND_TEXT_NO_MATCH(text_range_provider, search_term, \
- ignore_case) \
- { \
- base::win::ScopedBstr find_string(search_term); \
- ComPtr<ITextRangeProvider> text_range_provider_found; \
- EXPECT_HRESULT_SUCCEEDED(text_range_provider->FindText( \
- find_string.Get(), false, ignore_case, &text_range_provider_found)); \
- EXPECT_EQ(nullptr, text_range_provider_found); \
- }
-
-#define EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider, endpoint, unit, \
- count, expected_text, expected_count) \
- { \
- int result_count; \
- EXPECT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit( \
- endpoint, unit, count, &result_count)); \
- EXPECT_EQ(expected_count, result_count); \
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, expected_text); \
- }
-
-#define EXPECT_UIA_MOVE(text_range_provider, unit, count, expected_text, \
- expected_count) \
- { \
- int result_count; \
- EXPECT_HRESULT_SUCCEEDED( \
- text_range_provider->Move(unit, count, &result_count)); \
- EXPECT_EQ(expected_count, result_count); \
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, expected_text); \
- }
-
-#define EXPECT_ENCLOSING_ELEMENT(ax_node_given, ax_node_expected) \
- { \
- ComPtr<ITextRangeProvider> text_range_provider; \
- GetTextRangeProviderFromTextNode(text_range_provider, ax_node_given); \
- ComPtr<IRawElementProviderSimple> enclosing_element; \
- ASSERT_HRESULT_SUCCEEDED( \
- text_range_provider->GetEnclosingElement(&enclosing_element)); \
- ComPtr<IRawElementProviderSimple> expected_text_provider = \
- QueryInterfaceFromNode<IRawElementProviderSimple>(ax_node_expected); \
- EXPECT_EQ(expected_text_provider.Get(), enclosing_element.Get()); \
- }
-
-class AXPlatformNodeTextRangeProviderTest : public ui::AXPlatformNodeWinTest {
- public:
- const AXNodePosition::AXPositionInstance& GetStart(
- const AXPlatformNodeTextRangeProviderWin* text_range) {
- return text_range->start_;
- }
-
- const AXNodePosition::AXPositionInstance& GetEnd(
- const AXPlatformNodeTextRangeProviderWin* text_range) {
- return text_range->end_;
- }
-
- ui::AXPlatformNodeWin* GetOwner(
- const AXPlatformNodeTextRangeProviderWin* text_range) {
- return text_range->owner_.Get();
- }
-
- void NormalizeTextRange(AXPlatformNodeTextRangeProviderWin* text_range) {
- text_range->NormalizeTextRange();
- }
-
- ComPtr<AXPlatformNodeTextRangeProviderWin> CloneTextRangeProviderWin(
- AXPlatformNodeTextRangeProviderWin* text_range) {
- ComPtr<ITextRangeProvider> clone;
- text_range->Clone(&clone);
- ComPtr<AXPlatformNodeTextRangeProviderWin> clone_win;
- clone->QueryInterface(IID_PPV_ARGS(&clone_win));
- return clone_win;
- }
-
- void GetTextRangeProviderFromTextNode(
- ComPtr<ITextRangeProvider>& text_range_provider,
- ui::AXNode* text_node) {
- ComPtr<IRawElementProviderSimple> provider_simple =
- QueryInterfaceFromNode<IRawElementProviderSimple>(text_node);
- ASSERT_NE(nullptr, provider_simple.Get());
-
- ComPtr<ITextProvider> text_provider;
- EXPECT_HRESULT_SUCCEEDED(
- provider_simple->GetPatternProvider(UIA_TextPatternId, &text_provider));
- ASSERT_NE(nullptr, text_provider.Get());
-
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
- ASSERT_NE(nullptr, text_range_provider.Get());
- }
-
- void CreateTextRangeProviderWin(
- ComPtr<AXPlatformNodeTextRangeProviderWin>& text_range_provider_win,
- AXPlatformNodeWin* owner,
- AXTreeID tree_id,
- AXNode::AXID start_anchor_id,
- int start_offset,
- ax::mojom::TextAffinity start_affinity,
- AXNode::AXID end_anchor_id,
- int end_offset,
- ax::mojom::TextAffinity end_affinity) {
- AXNodePosition::AXPositionInstance range_start =
- AXNodePosition::CreateTextPosition(tree_id, start_anchor_id,
- start_offset, start_affinity);
- AXNodePosition::AXPositionInstance range_end =
- AXNodePosition::CreateTextPosition(tree_id, end_anchor_id, end_offset,
- end_affinity);
-
- ComPtr<ITextRangeProvider> text_range_provider =
- AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
- owner, std::move(range_start), std::move(range_end));
-
- text_range_provider->QueryInterface(IID_PPV_ARGS(&text_range_provider_win));
- }
-
- void ComputeWordBoundariesOffsets(const std::string& text,
- std::vector<int>& word_start_offsets,
- std::vector<int>& word_end_offsets) {
- char previous_char = ' ';
- word_start_offsets = std::vector<int>();
- for (size_t i = 0; i < text.size(); ++i) {
- if (previous_char == ' ' && text[i] != ' ')
- word_start_offsets.push_back(i);
- previous_char = text[i];
- }
-
- previous_char = ' ';
- word_end_offsets = std::vector<int>();
- for (size_t i = text.size(); i > 0; --i) {
- if (previous_char == ' ' && text[i - 1] != ' ')
- word_end_offsets.push_back(i);
- previous_char = text[i - 1];
- }
- std::reverse(word_end_offsets.begin(), word_end_offsets.end());
- }
-
- ui::AXTreeUpdate BuildTextDocument(
- const std::vector<std::string>& text_nodes_content,
- bool build_word_boundaries_offsets = false) {
- int current_id = 0;
- ui::AXNodeData root_data;
- root_data.id = ++current_id;
- root_data.role = ax::mojom::Role::kRootWebArea;
-
- ui::AXTreeUpdate update;
- update.tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.has_tree_data = true;
-
- for (const std::string& text_content : text_nodes_content) {
- ui::AXNodeData text_data;
- text_data.id = ++current_id;
- text_data.role = ax::mojom::Role::kStaticText;
- text_data.SetName(text_content);
-
- if (build_word_boundaries_offsets) {
- std::vector<int> word_end_offsets;
- std::vector<int> word_start_offsets;
- ComputeWordBoundariesOffsets(text_content, word_start_offsets,
- word_end_offsets);
- text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
- word_start_offsets);
- text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
- word_end_offsets);
- }
-
- root_data.child_ids.push_back(text_data.id);
- update.nodes.push_back(text_data);
- }
-
- update.nodes.insert(update.nodes.begin(), root_data);
- update.root_id = root_data.id;
- return update;
- }
-
- ui::AXTreeUpdate BuildAXTreeForBoundingRectangles() {
- // AXTree content:
- // <button>Button</button><input type="checkbox">Line 1<br>Line 2
- ui::AXNodeData root;
- ui::AXNodeData button;
- ui::AXNodeData check_box;
- ui::AXNodeData text_field;
- ui::AXNodeData static_text1;
- ui::AXNodeData line_break;
- ui::AXNodeData static_text2;
- ui::AXNodeData inline_box1;
- ui::AXNodeData inline_box2;
-
- const int ROOT_ID = 1;
- const int BUTTON_ID = 2;
- const int CHECK_BOX_ID = 3;
- const int TEXT_FIELD_ID = 4;
- const int STATIC_TEXT1_ID = 5;
- const int INLINE_BOX1_ID = 6;
- const int LINE_BREAK_ID = 7;
- const int STATIC_TEXT2_ID = 8;
- const int INLINE_BOX2_ID = 9;
-
- root.id = ROOT_ID;
- button.id = BUTTON_ID;
- check_box.id = CHECK_BOX_ID;
- text_field.id = TEXT_FIELD_ID;
- static_text1.id = STATIC_TEXT1_ID;
- inline_box1.id = INLINE_BOX1_ID;
- line_break.id = LINE_BREAK_ID;
- static_text2.id = STATIC_TEXT2_ID;
- inline_box2.id = INLINE_BOX2_ID;
-
- std::string LINE_1_TEXT = "Line 1";
- std::string LINE_2_TEXT = "Line 2";
- std::string LINE_BREAK_TEXT = "\n";
- std::string ALL_TEXT = LINE_1_TEXT + LINE_BREAK_TEXT + LINE_2_TEXT;
- std::string BUTTON_TEXT = "Button";
- std::string CHECKBOX_TEXT = "Check box";
-
- root.role = ax::mojom::Role::kRootWebArea;
-
- button.role = ax::mojom::Role::kButton;
- button.SetHasPopup(ax::mojom::HasPopup::kMenu);
- button.SetName(BUTTON_TEXT);
- button.SetValue(BUTTON_TEXT);
- button.relative_bounds.bounds = gfx::RectF(20, 20, 200, 30);
- button.AddIntAttribute(ax::mojom::IntAttribute::kNextOnLineId,
- check_box.id);
- root.child_ids.push_back(button.id);
-
- check_box.role = ax::mojom::Role::kCheckBox;
- check_box.SetCheckedState(ax::mojom::CheckedState::kTrue);
- check_box.SetName(CHECKBOX_TEXT);
- check_box.relative_bounds.bounds = gfx::RectF(20, 50, 200, 30);
- check_box.AddIntAttribute(ax::mojom::IntAttribute::kPreviousOnLineId,
- button.id);
- root.child_ids.push_back(check_box.id);
-
- text_field.role = ax::mojom::Role::kTextField;
- text_field.AddState(ax::mojom::State::kEditable);
- text_field.SetValue(ALL_TEXT);
- text_field.AddIntListAttribute(
- ax::mojom::IntListAttribute::kCachedLineStarts,
- std::vector<int32_t>{0, 7});
- text_field.child_ids.push_back(static_text1.id);
- text_field.child_ids.push_back(line_break.id);
- text_field.child_ids.push_back(static_text2.id);
- root.child_ids.push_back(text_field.id);
-
- static_text1.role = ax::mojom::Role::kStaticText;
- static_text1.AddState(ax::mojom::State::kEditable);
- static_text1.SetName(LINE_1_TEXT);
- static_text1.child_ids.push_back(inline_box1.id);
-
- inline_box1.role = ax::mojom::Role::kInlineTextBox;
- inline_box1.AddState(ax::mojom::State::kEditable);
- inline_box1.SetName(LINE_1_TEXT);
- inline_box1.relative_bounds.bounds = gfx::RectF(220, 20, 100, 30);
- std::vector<int32_t> character_offsets1;
- // The width of each character is 5px.
- character_offsets1.push_back(225); // "L" {220, 20, 5x30}
- character_offsets1.push_back(230); // "i" {225, 20, 5x30}
- character_offsets1.push_back(235); // "n" {230, 20, 5x30}
- character_offsets1.push_back(240); // "e" {235, 20, 5x30}
- character_offsets1.push_back(245); // " " {240, 20, 5x30}
- character_offsets1.push_back(250); // "1" {245, 20, 5x30}
- inline_box1.AddIntListAttribute(
- ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets1);
- inline_box1.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
- std::vector<int32_t>{0, 5});
- inline_box1.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
- std::vector<int32_t>{4, 6});
- inline_box1.AddIntAttribute(ax::mojom::IntAttribute::kNextOnLineId,
- line_break.id);
-
- line_break.role = ax::mojom::Role::kLineBreak;
- line_break.AddState(ax::mojom::State::kEditable);
- line_break.SetName(LINE_BREAK_TEXT);
- line_break.AddIntAttribute(ax::mojom::IntAttribute::kPreviousOnLineId,
- inline_box1.id);
-
- static_text2.role = ax::mojom::Role::kStaticText;
- static_text2.AddState(ax::mojom::State::kEditable);
- static_text2.SetName(LINE_2_TEXT);
- static_text2.child_ids.push_back(inline_box2.id);
-
- inline_box2.role = ax::mojom::Role::kInlineTextBox;
- inline_box2.AddState(ax::mojom::State::kEditable);
- inline_box2.SetName(LINE_2_TEXT);
- inline_box2.relative_bounds.bounds = gfx::RectF(220, 50, 100, 30);
- std::vector<int32_t> character_offsets2;
- // The width of each character is 7 px.
- character_offsets2.push_back(227); // "L" {220, 50, 7x30}
- character_offsets2.push_back(234); // "i" {227, 50, 7x30}
- character_offsets2.push_back(241); // "n" {234, 50, 7x30}
- character_offsets2.push_back(248); // "e" {241, 50, 7x30}
- character_offsets2.push_back(255); // " " {248, 50, 7x30}
- character_offsets2.push_back(262); // "2" {255, 50, 7x30}
- inline_box2.AddIntListAttribute(
- ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets2);
- inline_box2.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
- std::vector<int32_t>{0, 5});
- inline_box2.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
- std::vector<int32_t>{4, 6});
-
- AXTreeUpdate update;
- update.has_tree_data = true;
- update.root_id = ROOT_ID;
- update.nodes = {root, button, check_box,
- text_field, static_text1, inline_box1,
- line_break, static_text2, inline_box2};
- update.tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- return update;
- }
-
- const base::string16 tree_for_move_full_text =
- L"First line of text\nStandalone line\n"
- L"bold text\nParagraph 1\nParagraph 2";
-
- ui::AXTreeUpdate BuildAXTreeForMove() {
- ui::AXNodeData group1_data;
- group1_data.id = 2;
- group1_data.role = ax::mojom::Role::kGenericContainer;
- group1_data.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
-
- ui::AXNodeData text_data;
- text_data.id = 3;
- text_data.role = ax::mojom::Role::kStaticText;
- std::string text_content = "First line of text";
- text_data.SetName(text_content);
- std::vector<int> word_end_offsets;
- std::vector<int> word_start_offsets;
- ComputeWordBoundariesOffsets(text_content, word_start_offsets,
- word_end_offsets);
- text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
- word_start_offsets);
- text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
- word_end_offsets);
- group1_data.child_ids = {3};
-
- ui::AXNodeData group2_data;
- group2_data.id = 4;
- group2_data.role = ax::mojom::Role::kGenericContainer;
-
- ui::AXNodeData line_break1_data;
- line_break1_data.id = 5;
- line_break1_data.role = ax::mojom::Role::kLineBreak;
- line_break1_data.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
- line_break1_data.SetName("\n");
-
- ui::AXNodeData standalone_text_data;
- standalone_text_data.id = 6;
- standalone_text_data.role = ax::mojom::Role::kStaticText;
- text_content = "Standalone line";
- standalone_text_data.SetName(text_content);
- ComputeWordBoundariesOffsets(text_content, word_start_offsets,
- word_end_offsets);
- standalone_text_data.AddIntListAttribute(
- ax::mojom::IntListAttribute::kWordStarts, word_start_offsets);
- standalone_text_data.AddIntListAttribute(
- ax::mojom::IntListAttribute::kWordEnds, word_end_offsets);
-
- ui::AXNodeData line_break2_data;
- line_break2_data.id = 7;
- line_break2_data.role = ax::mojom::Role::kLineBreak;
- line_break2_data.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
- line_break2_data.SetName("\n");
-
- group2_data.child_ids = {5, 6, 7};
- standalone_text_data.AddIntAttribute(ax::mojom::IntAttribute::kNextOnLineId,
- line_break2_data.id);
- line_break2_data.AddIntAttribute(ax::mojom::IntAttribute::kPreviousOnLineId,
- standalone_text_data.id);
-
- ui::AXNodeData bold_text_data;
- bold_text_data.id = 8;
- bold_text_data.role = ax::mojom::Role::kStaticText;
- bold_text_data.AddIntAttribute(
- ax::mojom::IntAttribute::kTextStyle,
- static_cast<int32_t>(ax::mojom::TextStyle::kBold));
- text_content = "bold text";
- bold_text_data.SetName(text_content);
- ComputeWordBoundariesOffsets(text_content, word_start_offsets,
- word_end_offsets);
- bold_text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
- word_start_offsets);
- bold_text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
- word_end_offsets);
-
- ui::AXNodeData paragraph1_data;
- paragraph1_data.id = 9;
- paragraph1_data.role = ax::mojom::Role::kParagraph;
- paragraph1_data.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
-
- ui::AXNodeData paragraph1_text_data;
- paragraph1_text_data.id = 10;
- paragraph1_text_data.role = ax::mojom::Role::kStaticText;
- text_content = "Paragraph 1";
- paragraph1_text_data.SetName(text_content);
- ComputeWordBoundariesOffsets(text_content, word_start_offsets,
- word_end_offsets);
- paragraph1_text_data.AddIntListAttribute(
- ax::mojom::IntListAttribute::kWordStarts, word_start_offsets);
- paragraph1_text_data.AddIntListAttribute(
- ax::mojom::IntListAttribute::kWordEnds, word_end_offsets);
- paragraph1_data.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
-
- ui::AXNodeData ignored_text_data;
- ignored_text_data.id = 11;
- ignored_text_data.role = ax::mojom::Role::kStaticText;
- ignored_text_data.AddState(ax::mojom::State::kIgnored);
- text_content = "ignored text";
- ignored_text_data.SetName(text_content);
-
- paragraph1_data.child_ids = {10, 11};
-
- ui::AXNodeData paragraph2_data;
- paragraph2_data.id = 12;
- paragraph2_data.role = ax::mojom::Role::kParagraph;
- paragraph2_data.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
-
- ui::AXNodeData paragraph2_text_data;
- paragraph2_text_data.id = 13;
- paragraph2_text_data.role = ax::mojom::Role::kStaticText;
- text_content = "Paragraph 2";
- paragraph2_text_data.SetName(text_content);
- ComputeWordBoundariesOffsets(text_content, word_start_offsets,
- word_end_offsets);
- paragraph2_text_data.AddIntListAttribute(
- ax::mojom::IntListAttribute::kWordStarts, word_start_offsets);
- paragraph2_text_data.AddIntListAttribute(
- ax::mojom::IntListAttribute::kWordEnds, word_end_offsets);
- paragraph1_data.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
- paragraph2_data.child_ids = {13};
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.child_ids = {2, 4, 8, 9, 12};
-
- ui::AXTreeUpdate update;
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes = {root_data, group1_data,
- text_data, group2_data,
- line_break1_data, standalone_text_data,
- line_break2_data, bold_text_data,
- paragraph1_data, paragraph1_text_data,
- ignored_text_data, paragraph2_data,
- paragraph2_text_data};
- update.tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- return update;
- }
-
- ui::AXTreeUpdate BuildAXTreeForMoveByFormat() {
- // 1
- // |
- // -------------------------------------
- // | | | | | | |
- // 2 4 8 10 12 14 16
- // | | | | | | |
- // | --------- | | | | |
- // | | | | | | | | |
- // 3 5 6 7 9 11 13 15 17
-
- ui::AXNodeData group1_data;
- group1_data.id = 2;
- group1_data.role = ax::mojom::Role::kGenericContainer;
- group1_data.AddStringAttribute(ax::mojom::StringAttribute::kFontFamily,
- "test font");
-
- ui::AXNodeData text_data;
- text_data.id = 3;
- text_data.role = ax::mojom::Role::kStaticText;
- std::string text_content = "Text with formatting";
- text_data.SetName(text_content);
- group1_data.child_ids = {3};
-
- ui::AXNodeData group2_data;
- group2_data.id = 4;
- group2_data.role = ax::mojom::Role::kGenericContainer;
-
- ui::AXNodeData line_break1_data;
- line_break1_data.id = 5;
- line_break1_data.role = ax::mojom::Role::kLineBreak;
-
- ui::AXNodeData standalone_text_data;
- standalone_text_data.id = 6;
- standalone_text_data.role = ax::mojom::Role::kStaticText;
- text_content = "Standalone line with no formatting";
- standalone_text_data.SetName(text_content);
-
- ui::AXNodeData line_break2_data;
- line_break2_data.id = 7;
- line_break2_data.role = ax::mojom::Role::kLineBreak;
-
- group2_data.child_ids = {5, 6, 7};
-
- ui::AXNodeData group3_data;
- group3_data.id = 8;
- group3_data.role = ax::mojom::Role::kGenericContainer;
- group3_data.AddIntAttribute(
- ax::mojom::IntAttribute::kTextStyle,
- static_cast<int32_t>(ax::mojom::TextStyle::kBold));
-
- ui::AXNodeData bold_text_data;
- bold_text_data.id = 9;
- bold_text_data.role = ax::mojom::Role::kStaticText;
- text_content = "bold text";
- bold_text_data.SetName(text_content);
- group3_data.child_ids = {9};
-
- ui::AXNodeData paragraph1_data;
- paragraph1_data.id = 10;
- paragraph1_data.role = ax::mojom::Role::kParagraph;
- paragraph1_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 100);
-
- ui::AXNodeData paragraph1_text_data;
- paragraph1_text_data.id = 11;
- paragraph1_text_data.role = ax::mojom::Role::kStaticText;
- text_content = "Paragraph 1";
- paragraph1_text_data.SetName(text_content);
- paragraph1_data.child_ids = {11};
-
- ui::AXNodeData paragraph2_data;
- paragraph2_data.id = 12;
- paragraph2_data.role = ax::mojom::Role::kParagraph;
- paragraph2_data.AddFloatAttribute(ax::mojom::FloatAttribute::kFontSize,
- 1.0f);
-
- ui::AXNodeData paragraph2_text_data;
- paragraph2_text_data.id = 13;
- paragraph2_text_data.role = ax::mojom::Role::kStaticText;
- text_content = "Paragraph 2";
- paragraph2_text_data.SetName(text_content);
- paragraph2_data.child_ids = {13};
-
- ui::AXNodeData paragraph3_data;
- paragraph3_data.id = 14;
- paragraph3_data.role = ax::mojom::Role::kParagraph;
- paragraph3_data.AddFloatAttribute(ax::mojom::FloatAttribute::kFontSize,
- 1.0f);
-
- ui::AXNodeData paragraph3_text_data;
- paragraph3_text_data.id = 15;
- paragraph3_text_data.role = ax::mojom::Role::kStaticText;
- text_content = "Paragraph 3";
- paragraph3_text_data.SetName(text_content);
- paragraph3_data.child_ids = {15};
-
- ui::AXNodeData paragraph4_data;
- paragraph4_data.id = 16;
- paragraph4_data.role = ax::mojom::Role::kParagraph;
- paragraph4_data.AddFloatAttribute(ax::mojom::FloatAttribute::kFontSize,
- 2.0f);
-
- ui::AXNodeData paragraph4_text_data;
- paragraph4_text_data.id = 17;
- paragraph4_text_data.role = ax::mojom::Role::kStaticText;
- text_content = "Paragraph 4";
- paragraph4_text_data.SetName(text_content);
- paragraph4_data.child_ids = {17};
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.child_ids = {2, 4, 8, 10, 12, 14, 16};
-
- ui::AXTreeUpdate update;
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes = {root_data,
- group1_data,
- text_data,
- group2_data,
- group3_data,
- line_break1_data,
- standalone_text_data,
- line_break2_data,
- bold_text_data,
- paragraph1_data,
- paragraph1_text_data,
- paragraph2_data,
- paragraph2_text_data,
- paragraph3_data,
- paragraph3_text_data,
- paragraph4_data,
- paragraph4_text_data};
- update.tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- return update;
- }
-
- ui::AXTreeUpdate BuildAXTreeForMoveByPage() {
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kDocument;
-
- ui::AXNodeData page_1_data;
- page_1_data.id = 2;
- page_1_data.role = ax::mojom::Role::kRegion;
- page_1_data.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsPageBreakingObject, true);
-
- ui::AXNodeData page_1_text_data;
- page_1_text_data.id = 3;
- page_1_text_data.role = ax::mojom::Role::kStaticText;
- page_1_text_data.SetName("some text on page 1");
- page_1_text_data.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
- page_1_data.child_ids = {3};
-
- ui::AXNodeData page_2_data;
- page_2_data.id = 4;
- page_2_data.role = ax::mojom::Role::kRegion;
- page_2_data.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsPageBreakingObject, true);
-
- ui::AXNodeData page_2_text_data;
- page_2_text_data.id = 5;
- page_2_text_data.role = ax::mojom::Role::kStaticText;
- page_2_text_data.SetName("some text on page 2");
- page_2_text_data.AddIntAttribute(
- ax::mojom::IntAttribute::kTextStyle,
- static_cast<int32_t>(ax::mojom::TextStyle::kBold));
- page_2_data.child_ids = {5};
-
- ui::AXNodeData page_3_data;
- page_3_data.id = 6;
- page_3_data.role = ax::mojom::Role::kRegion;
- page_3_data.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsPageBreakingObject, true);
-
- ui::AXNodeData page_3_text_data;
- page_3_text_data.id = 7;
- page_3_text_data.role = ax::mojom::Role::kStaticText;
- page_3_text_data.SetName("some more text on page 3");
- page_3_data.child_ids = {7};
-
- root_data.child_ids = {2, 4, 6};
-
- ui::AXTreeUpdate update;
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes = {root_data, page_1_data, page_1_text_data,
- page_2_data, page_2_text_data, page_3_data,
- page_3_text_data};
- update.tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- return update;
- }
-};
-
-class MockAXPlatformNodeTextRangeProviderWin
- : public CComObjectRootEx<CComMultiThreadModel>,
- public ITextRangeProvider {
- public:
- BEGIN_COM_MAP(MockAXPlatformNodeTextRangeProviderWin)
- COM_INTERFACE_ENTRY(ITextRangeProvider)
- END_COM_MAP()
-
- MockAXPlatformNodeTextRangeProviderWin() {}
- ~MockAXPlatformNodeTextRangeProviderWin() {}
-
- static HRESULT CreateMockTextRangeProvider(ITextRangeProvider** provider) {
- CComObject<MockAXPlatformNodeTextRangeProviderWin>* text_range_provider =
- nullptr;
- HRESULT hr =
- CComObject<MockAXPlatformNodeTextRangeProviderWin>::CreateInstance(
- &text_range_provider);
- if (SUCCEEDED(hr)) {
- *provider = text_range_provider;
- }
-
- return hr;
- }
-
- //
- // ITextRangeProvider methods.
- //
- IFACEMETHODIMP Clone(ITextRangeProvider** clone) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP Compare(ITextRangeProvider* other, BOOL* result) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP CompareEndpoints(TextPatternRangeEndpoint this_endpoint,
- ITextRangeProvider* other,
- TextPatternRangeEndpoint other_endpoint,
- int* result) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP ExpandToEnclosingUnit(TextUnit unit) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP FindAttribute(TEXTATTRIBUTEID attribute_id,
- VARIANT val,
- BOOL backward,
- ITextRangeProvider** result) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP FindText(BSTR string,
- BOOL backwards,
- BOOL ignore_case,
- ITextRangeProvider** result) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP GetAttributeValue(TEXTATTRIBUTEID attribute_id,
- VARIANT* value) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP GetBoundingRectangles(SAFEARRAY** rectangles) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP GetEnclosingElement(
- IRawElementProviderSimple** element) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP GetText(int max_count, BSTR* text) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP Move(TextUnit unit, int count, int* units_moved) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP MoveEndpointByUnit(TextPatternRangeEndpoint endpoint,
- TextUnit unit,
- int count,
- int* units_moved) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP MoveEndpointByRange(
- TextPatternRangeEndpoint this_endpoint,
- ITextRangeProvider* other,
- TextPatternRangeEndpoint other_endpoint) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP Select() override { return E_NOTIMPL; }
-
- IFACEMETHODIMP AddToSelection() override { return E_NOTIMPL; }
-
- IFACEMETHODIMP RemoveFromSelection() override { return E_NOTIMPL; }
-
- IFACEMETHODIMP ScrollIntoView(BOOL align_to_top) override {
- return E_NOTIMPL;
- }
-
- IFACEMETHODIMP GetChildren(SAFEARRAY** children) override {
- return E_NOTIMPL;
- }
-};
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderClone) {
- Init(BuildTextDocument({"some text"}));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider,
- GetRootAsAXNode()->children()[0]);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"some text");
-
- ComPtr<ITextRangeProvider> text_range_provider_clone;
- text_range_provider->Clone(&text_range_provider_clone);
-
- ComPtr<AXPlatformNodeTextRangeProviderWin> original_range;
- ComPtr<AXPlatformNodeTextRangeProviderWin> clone_range;
-
- text_range_provider->QueryInterface(IID_PPV_ARGS(&original_range));
- text_range_provider_clone->QueryInterface(IID_PPV_ARGS(&clone_range));
-
- EXPECT_EQ(*GetStart(original_range.Get()), *GetStart(clone_range.Get()));
- EXPECT_EQ(*GetEnd(original_range.Get()), *GetEnd(clone_range.Get()));
- EXPECT_EQ(GetOwner(original_range.Get()), GetOwner(clone_range.Get()));
-
- // Clear original text range provider.
- text_range_provider.Reset();
- EXPECT_EQ(nullptr, text_range_provider.Get());
-
- // Ensure the clone still works correctly.
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider_clone, L"some text");
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderCompareEndpoints) {
- Init(BuildTextDocument({"some text", "more text"}));
-
- AXNode* root_node = GetRootAsAXNode();
-
- // Get the textRangeProvider for the document,
- // which contains text "some textmore text".
- ComPtr<ITextRangeProvider> document_text_range_provider;
- GetTextRangeProviderFromTextNode(document_text_range_provider, root_node);
-
- // Get the textRangeProvider for "some text".
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider,
- root_node->children()[0]);
-
- // Get the textRangeProvider for "more text".
- ComPtr<ITextRangeProvider> more_text_range_provider;
- GetTextRangeProviderFromTextNode(more_text_range_provider,
- root_node->children()[1]);
-
- // Compare the endpoints of the document which contains "some textmore text".
- int result;
- EXPECT_HRESULT_SUCCEEDED(document_text_range_provider->CompareEndpoints(
- TextPatternRangeEndpoint_Start, document_text_range_provider.Get(),
- TextPatternRangeEndpoint_Start, &result));
- EXPECT_EQ(0, result);
-
- EXPECT_HRESULT_SUCCEEDED(document_text_range_provider->CompareEndpoints(
- TextPatternRangeEndpoint_End, document_text_range_provider.Get(),
- TextPatternRangeEndpoint_End, &result));
- EXPECT_EQ(0, result);
-
- EXPECT_HRESULT_SUCCEEDED(document_text_range_provider->CompareEndpoints(
- TextPatternRangeEndpoint_Start, document_text_range_provider.Get(),
- TextPatternRangeEndpoint_End, &result));
- EXPECT_EQ(-1, result);
-
- EXPECT_HRESULT_SUCCEEDED(document_text_range_provider->CompareEndpoints(
- TextPatternRangeEndpoint_End, document_text_range_provider.Get(),
- TextPatternRangeEndpoint_Start, &result));
- EXPECT_EQ(1, result);
-
- // Compare the endpoints of "some text" and "more text". The position at the
- // end of "some text" is logically equivalent to the position at the start of
- // "more text".
- EXPECT_HRESULT_SUCCEEDED(text_range_provider->CompareEndpoints(
- TextPatternRangeEndpoint_Start, more_text_range_provider.Get(),
- TextPatternRangeEndpoint_Start, &result));
- EXPECT_EQ(-1, result);
-
- EXPECT_HRESULT_SUCCEEDED(text_range_provider->CompareEndpoints(
- TextPatternRangeEndpoint_End, more_text_range_provider.Get(),
- TextPatternRangeEndpoint_Start, &result));
- EXPECT_EQ(0, result);
-
- // Compare the endpoints of "some text" with those of the entire document. The
- // position at the start of "some text" is logically equivalent to the
- // position at the start of the document.
- EXPECT_HRESULT_SUCCEEDED(text_range_provider->CompareEndpoints(
- TextPatternRangeEndpoint_Start, document_text_range_provider.Get(),
- TextPatternRangeEndpoint_Start, &result));
- EXPECT_EQ(0, result);
-
- EXPECT_HRESULT_SUCCEEDED(text_range_provider->CompareEndpoints(
- TextPatternRangeEndpoint_End, document_text_range_provider.Get(),
- TextPatternRangeEndpoint_End, &result));
- EXPECT_EQ(-1, result);
-
- // Compare the endpoints of "more text" with those of the entire document.
- EXPECT_HRESULT_SUCCEEDED(more_text_range_provider->CompareEndpoints(
- TextPatternRangeEndpoint_Start, document_text_range_provider.Get(),
- TextPatternRangeEndpoint_Start, &result));
- EXPECT_EQ(1, result);
-
- EXPECT_HRESULT_SUCCEEDED(more_text_range_provider->CompareEndpoints(
- TextPatternRangeEndpoint_End, document_text_range_provider.Get(),
- TextPatternRangeEndpoint_End, &result));
- EXPECT_EQ(0, result);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderExpandToEnclosingCharacter) {
- ui::AXTreeUpdate update = BuildTextDocument({"some text", "more text"});
- Init(update);
- AXNode* root_node = GetRootAsAXNode();
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Character));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"s");
-
- int count;
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ 2, &count));
- ASSERT_EQ(2, count);
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 1, &count));
- ASSERT_EQ(1, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"om");
-
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Character));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"o");
-
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ 9, &count));
- ASSERT_EQ(9, count);
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 8, &count));
- ASSERT_EQ(8, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"mo");
-
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Character));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"m");
-
- // Move the start and end to the end of the document.
- // Expand to enclosing unit should never return a null position.
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ 9, &count));
- ASSERT_EQ(8, count);
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 9, &count));
- ASSERT_EQ(9, count);
-
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Character));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"t");
-
- // Move both endpoints to the position before the start of the "more text"
- // anchor. Then, force the start to be on the position after the end of
- // "some text" by moving one character backward and one forward.
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ -9, &count));
- ASSERT_EQ(-9, count);
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ -1,
- &count));
- ASSERT_EQ(-1, count);
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 1, &count));
- ASSERT_EQ(1, count);
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Character));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"m");
-
- // Check that the enclosing element of the range matches ATs expectations.
- ComPtr<IRawElementProviderSimple> more_text_provider =
- QueryInterfaceFromNode<IRawElementProviderSimple>(
- root_node->children()[1]);
- ComPtr<IRawElementProviderSimple> enclosing_element;
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->GetEnclosingElement(&enclosing_element));
- EXPECT_EQ(more_text_provider.Get(), enclosing_element.Get());
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderExpandToEnclosingWord) {
- Init(BuildTextDocument({"some text", "definitely not text"},
- /*build_word_boundaries_offsets*/ true));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider,
- GetRootAsAXNode()->children()[1]);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"definitely not text");
-
- // Start endpoint is already on a word's start boundary.
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Word));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"definitely ");
-
- // Start endpoint is between a word's start and end boundaries.
- int count;
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ -2,
- &count));
- ASSERT_EQ(-2, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"xtdefinitely ");
-
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ 4, &count));
- ASSERT_EQ(4, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"xtdefinitely not ");
-
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Word));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"text");
-
- // Start endpoint is on a word's end boundary.
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 18,
- &count));
- ASSERT_EQ(18, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"");
-
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ 1, &count));
- ASSERT_EQ(1, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L" ");
-
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Word));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"not ");
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderExpandToEnclosingLine) {
- Init(BuildTextDocument({"line #1", "maybe line #1?", "not line #1"}));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider,
- GetRootAsAXNode()->children()[0]);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"line #1");
-
- // Start endpoint is already on a line's start boundary.
- int count;
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ -11, &count));
- ASSERT_EQ(-7, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"");
-
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Line));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"line #1");
-
- // Start endpoint is between a line's start and end boundaries.
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 13,
- &count));
- ASSERT_EQ(13, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"");
-
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ 4, &count));
- ASSERT_EQ(4, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"line");
-
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Line));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"maybe line #1?");
-
- // Start endpoint is on a line's end boundary.
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 29,
- &count));
- ASSERT_EQ(25, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"");
-
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Line));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"not line #1");
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderExpandToEnclosingParagraph) {
- Init(BuildAXTreeForMove());
- AXNode* root_node = GetRootAsAXNode();
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
-
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider,
- /*expected_text*/ tree_for_move_full_text.data());
-
- // Start endpoint is already on a paragraph's start boundary.
- int count;
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Paragraph, /*count*/ -6, &count));
- EXPECT_EQ(-5, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"");
-
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Paragraph));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"First line of text\n");
-
- // Moving the start by two lines will create a degenerate range positioned
- // at the next paragraph (skipping the newline).
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Line, /*count*/ 2, &count));
- EXPECT_EQ(2, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"");
-
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Paragraph));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"Standalone line\n");
-
- // Move to the next paragraph via MoveEndpointByUnit (line), then move to
- // the middle of the paragraph via Move (word), then expand by paragraph.
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Line, /*count*/ 1, &count));
- EXPECT_EQ(1, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"");
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ 1,
- /*expected_text*/
- L"",
- /*expected_count*/ 1);
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Paragraph));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"bold text");
-
- // Create a degenerate range at the end of the document, then expand by
- // paragraph.
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Document, /*count*/ 1, &count));
- EXPECT_EQ(1, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"");
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Paragraph));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"Paragraph 2");
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderExpandToEnclosingFormat) {
- Init(BuildAXTreeForMoveByFormat());
- AXNode* root_node = GetRootAsAXNode();
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
-
- EXPECT_UIA_TEXTRANGE_EQ(
- text_range_provider,
- L"Text with formattingStandalone line with no formattingbold "
- L"textParagraph 1Paragraph 2Paragraph 3Paragraph 4");
-
- // https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-expandtoenclosingunit
- // Consider two consecutive text units A and B.
- // The documentation illustrates 9 cases, but cases 1 and 9 are equivalent.
- // In each case, the expected output is a range from start of A to end of A.
-
- // Create a range encompassing nodes 11-15 which will serve as text units A
- // and B for this test.
- ComPtr<ITextRangeProvider> units_a_b_provider;
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->Clone(&units_a_b_provider));
- int count;
- ASSERT_HRESULT_SUCCEEDED(units_a_b_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 63,
- &count));
- ASSERT_EQ(63, count);
- ASSERT_HRESULT_SUCCEEDED(units_a_b_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ -11, &count));
- ASSERT_EQ(-11, count);
- EXPECT_UIA_TEXTRANGE_EQ(units_a_b_provider,
- L"Paragraph 1Paragraph 2Paragraph 3");
-
- // Create a range encompassing node 11 which will serve as our expected
- // value of a range from start of A to end of A.
- ComPtr<ITextRangeProvider> unit_a_provider;
- ASSERT_HRESULT_SUCCEEDED(units_a_b_provider->Clone(&unit_a_provider));
- ASSERT_HRESULT_SUCCEEDED(unit_a_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ -22, &count));
- ASSERT_EQ(-22, count);
- EXPECT_UIA_TEXTRANGE_EQ(unit_a_provider, L"Paragraph 1");
-
- // Case 1: Degenerate range at start of A.
- {
- SCOPED_TRACE("Case 1: Degenerate range at start of A.");
- ComPtr<ITextRangeProvider> test_case_provider;
- ASSERT_HRESULT_SUCCEEDED(unit_a_provider->Clone(&test_case_provider));
- ASSERT_HRESULT_SUCCEEDED(test_case_provider->MoveEndpointByRange(
- TextPatternRangeEndpoint_End, test_case_provider.Get(),
- TextPatternRangeEndpoint_Start));
- EXPECT_UIA_TEXTRANGE_EQ(test_case_provider, L"");
-
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->ExpandToEnclosingUnit(TextUnit_Format));
- BOOL are_same;
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->Compare(unit_a_provider.Get(), &are_same));
- EXPECT_TRUE(are_same);
- }
-
- // Case 2: Range from start of A to middle of A.
- {
- SCOPED_TRACE("Case 2: Range from start of A to middle of A.");
- ComPtr<ITextRangeProvider> test_case_provider;
- ASSERT_HRESULT_SUCCEEDED(unit_a_provider->Clone(&test_case_provider));
- ASSERT_HRESULT_SUCCEEDED(test_case_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ -7,
- &count));
- ASSERT_EQ(-7, count);
- EXPECT_UIA_TEXTRANGE_EQ(test_case_provider, L"Para");
-
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->ExpandToEnclosingUnit(TextUnit_Format));
- BOOL are_same;
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->Compare(unit_a_provider.Get(), &are_same));
- EXPECT_TRUE(are_same);
- }
-
- // Case 3: Range from start of A to end of A.
- {
- SCOPED_TRACE("Case 3: Range from start of A to end of A.");
- ComPtr<ITextRangeProvider> test_case_provider;
- ASSERT_HRESULT_SUCCEEDED(unit_a_provider->Clone(&test_case_provider));
- EXPECT_UIA_TEXTRANGE_EQ(test_case_provider, L"Paragraph 1");
-
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->ExpandToEnclosingUnit(TextUnit_Format));
- BOOL are_same;
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->Compare(unit_a_provider.Get(), &are_same));
- EXPECT_TRUE(are_same);
- }
-
- // Case 4: Range from start of A to middle of B.
- {
- SCOPED_TRACE("Case 4: Range from start of A to middle of B.");
- ComPtr<ITextRangeProvider> test_case_provider;
- ASSERT_HRESULT_SUCCEEDED(unit_a_provider->Clone(&test_case_provider));
- ASSERT_HRESULT_SUCCEEDED(test_case_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ 4, &count));
- ASSERT_EQ(4, count);
- EXPECT_UIA_TEXTRANGE_EQ(test_case_provider, L"Paragraph 1Para");
-
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->ExpandToEnclosingUnit(TextUnit_Format));
- BOOL are_same;
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->Compare(unit_a_provider.Get(), &are_same));
- EXPECT_TRUE(are_same);
- }
-
- // Case 5: Degenerate range in middle of A.
- {
- SCOPED_TRACE("Case 5: Degenerate range in middle of A.");
- ComPtr<ITextRangeProvider> test_case_provider;
- ASSERT_HRESULT_SUCCEEDED(unit_a_provider->Clone(&test_case_provider));
- ASSERT_HRESULT_SUCCEEDED(test_case_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 4,
- &count));
- ASSERT_EQ(4, count);
- ASSERT_HRESULT_SUCCEEDED(test_case_provider->MoveEndpointByRange(
- TextPatternRangeEndpoint_End, test_case_provider.Get(),
- TextPatternRangeEndpoint_Start));
- EXPECT_UIA_TEXTRANGE_EQ(test_case_provider, L"");
-
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->ExpandToEnclosingUnit(TextUnit_Format));
- BOOL are_same;
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->Compare(unit_a_provider.Get(), &are_same));
- EXPECT_TRUE(are_same);
- }
-
- // Case 6: Range from middle of A to middle of A.
- {
- SCOPED_TRACE("Case 6: Range from middle of A to middle of A.");
- ComPtr<ITextRangeProvider> test_case_provider;
- ASSERT_HRESULT_SUCCEEDED(unit_a_provider->Clone(&test_case_provider));
- ASSERT_HRESULT_SUCCEEDED(test_case_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 4,
- &count));
- ASSERT_EQ(4, count);
- ASSERT_HRESULT_SUCCEEDED(test_case_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ -2,
- &count));
- ASSERT_EQ(-2, count);
- EXPECT_UIA_TEXTRANGE_EQ(test_case_provider, L"graph");
-
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->ExpandToEnclosingUnit(TextUnit_Format));
- BOOL are_same;
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->Compare(unit_a_provider.Get(), &are_same));
- EXPECT_TRUE(are_same);
- }
-
- // Case 7: Range from middle of A to end of A.
- {
- SCOPED_TRACE("Case 7: Range from middle of A to end of A.");
- ComPtr<ITextRangeProvider> test_case_provider;
- ASSERT_HRESULT_SUCCEEDED(unit_a_provider->Clone(&test_case_provider));
- ASSERT_HRESULT_SUCCEEDED(test_case_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 4,
- &count));
- ASSERT_EQ(4, count);
- EXPECT_UIA_TEXTRANGE_EQ(test_case_provider, L"graph 1");
-
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->ExpandToEnclosingUnit(TextUnit_Format));
- BOOL are_same;
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->Compare(unit_a_provider.Get(), &are_same));
- EXPECT_TRUE(are_same);
- }
-
- // Case 8: Range from middle of A to middle of B.
- {
- SCOPED_TRACE("Case 8: Range from middle of A to middle of B.");
- ComPtr<ITextRangeProvider> test_case_provider;
- ASSERT_HRESULT_SUCCEEDED(unit_a_provider->Clone(&test_case_provider));
- ASSERT_HRESULT_SUCCEEDED(test_case_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 4,
- &count));
- ASSERT_EQ(4, count);
- ASSERT_HRESULT_SUCCEEDED(test_case_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ 4, &count));
- ASSERT_EQ(4, count);
- EXPECT_UIA_TEXTRANGE_EQ(test_case_provider, L"graph 1Para");
-
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->ExpandToEnclosingUnit(TextUnit_Format));
- BOOL are_same;
- ASSERT_HRESULT_SUCCEEDED(
- test_case_provider->Compare(unit_a_provider.Get(), &are_same));
- EXPECT_TRUE(are_same);
- }
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderExpandToEnclosingFormatWithEmptyObjects) {
- // This test updates the tree structure to test a specific edge case.
- //
- // When using heading navigation, the empty objects (see
- // AXPosition::IsEmptyObjectReplacedByCharacter for information about empty
- // objects) sometimes cause a problem with
- // AXPlatformNodeTextRangeProviderWin::ExpandToEnlosingUnit.
- // With some specific AXTree (like the one used below), the empty object
- // causes ExpandToEnclosingUnit to move the range back on the heading that it
- // previously was instead of moving it forward/backward to the next heading.
- // To avoid this, empty objects are always marked as format boundaries.
- //
- // The issue normally occurs when a heading is directly followed by an ignored
- // empty object, itself followed by an unignored empty object.
- //
- // ++1 kRootWebArea
- // ++++2 kHeading
- // ++++++3 kStaticText
- // ++++++++4 kInlineTextBox
- // ++++5 kGenericContainer ignored
- // ++++6 kGenericContainer
- ui::AXNodeData root_1;
- ui::AXNodeData heading_2;
- ui::AXNodeData static_text_3;
- ui::AXNodeData inline_box_4;
- ui::AXNodeData generic_container_5;
- ui::AXNodeData generic_container_6;
-
- root_1.id = 1;
- heading_2.id = 2;
- static_text_3.id = 3;
- inline_box_4.id = 4;
- generic_container_5.id = 5;
- generic_container_6.id = 6;
-
- root_1.role = ax::mojom::Role::kRootWebArea;
- root_1.child_ids = {heading_2.id, generic_container_5.id,
- generic_container_6.id};
-
- heading_2.role = ax::mojom::Role::kHeading;
- heading_2.child_ids = {static_text_3.id};
-
- static_text_3.role = ax::mojom::Role::kStaticText;
- static_text_3.child_ids = {inline_box_4.id};
- static_text_3.SetName("3.14");
-
- inline_box_4.role = ax::mojom::Role::kInlineTextBox;
- inline_box_4.SetName("3.14");
-
- generic_container_5.role = ax::mojom::Role::kGenericContainer;
- generic_container_5.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
- generic_container_5.AddState(ax::mojom::State::kIgnored);
-
- generic_container_6.role = ax::mojom::Role::kGenericContainer;
- generic_container_6.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root_1.id;
- update.nodes.push_back(root_1);
- update.nodes.push_back(heading_2);
- update.nodes.push_back(static_text_3);
- update.nodes.push_back(inline_box_4);
- update.nodes.push_back(generic_container_5);
- update.nodes.push_back(generic_container_6);
-
- Init(update);
-
- AXNode* root_node = GetRootAsAXNode();
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
-
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"3.14\n\xFFFC");
-
- // Create a degenerate range positioned at the boundary between nodes 4 and 6,
- // e.g., "3.14<>" and "<\xFFFC>" (because node 5 is ignored).
- int count;
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_Start, TextUnit_Character, /*count*/ 5, &count));
- ASSERT_EQ(5, count);
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ -1, &count));
- ASSERT_EQ(-1, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"");
-
- // ExpandToEnclosingUnit should move the range to the next non-ignored empty
- // object (i.e, node 6), and not at the beginning of node 4.
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Format));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"\xFFFC");
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderExpandToEnclosingDocument) {
- Init(BuildTextDocument({"some text", "more text", "even more text"}));
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* text_node = root_node->children()[0];
- AXNode* more_text_node = root_node->children()[1];
- AXNode* even_more_text_node = root_node->children()[2];
-
- // Run the test twice, one for TextUnit_Document and once for TextUnit_Page,
- // since they should have identical behavior.
- const TextUnit textunit_types[] = {TextUnit_Document, TextUnit_Page};
- ComPtr<ITextRangeProvider> text_range_provider;
-
- for (auto& textunit : textunit_types) {
- GetTextRangeProviderFromTextNode(text_range_provider, text_node);
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(textunit));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider,
- L"some textmore texteven more text");
-
- GetTextRangeProviderFromTextNode(text_range_provider, more_text_node);
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(textunit));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider,
- L"some textmore texteven more text");
-
- GetTextRangeProviderFromTextNode(text_range_provider, even_more_text_node);
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(textunit));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider,
- L"some textmore texteven more text");
- }
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderInvalidCalls) {
- // Test for when a text range provider is invalid. Because no ax tree is
- // available, the anchor is invalid, so the text range provider fails the
- // validate call.
- {
- Init(BuildTextDocument({}));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, GetRootAsAXNode());
-
- DestroyTree();
- ComPtr<ITextRangeProvider> text_range_provider_clone;
- EXPECT_UIA_ELEMENTNOTAVAILABLE(
- text_range_provider->Clone(&text_range_provider_clone));
-
- BOOL compare_result;
- EXPECT_UIA_ELEMENTNOTAVAILABLE(text_range_provider->Compare(
- text_range_provider.Get(), &compare_result));
-
- int compare_endpoints_result;
- EXPECT_UIA_ELEMENTNOTAVAILABLE(text_range_provider->CompareEndpoints(
- TextPatternRangeEndpoint_Start, text_range_provider.Get(),
- TextPatternRangeEndpoint_Start, &compare_endpoints_result));
-
- VARIANT attr_val;
- V_VT(&attr_val) = VT_BOOL;
- V_BOOL(&attr_val) = VARIANT_TRUE;
- ComPtr<ITextRangeProvider> matched_range_provider;
- EXPECT_UIA_ELEMENTNOTAVAILABLE(text_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, attr_val, true, &matched_range_provider));
-
- EXPECT_UIA_ELEMENTNOTAVAILABLE(text_range_provider->MoveEndpointByRange(
- TextPatternRangeEndpoint_Start, text_range_provider.Get(),
- TextPatternRangeEndpoint_Start));
-
- EXPECT_UIA_ELEMENTNOTAVAILABLE(text_range_provider->Select());
- }
-
- // Test for when this provider is valid, but the other provider is not an
- // instance of AXPlatformNodeTextRangeProviderWin, so no operation can be
- // performed on the other provider.
- {
- Init(BuildTextDocument({}));
-
- ComPtr<ITextRangeProvider> this_provider;
- GetTextRangeProviderFromTextNode(this_provider, GetRootAsAXNode());
-
- ComPtr<ITextRangeProvider> other_provider_different_type;
- MockAXPlatformNodeTextRangeProviderWin::CreateMockTextRangeProvider(
- &other_provider_different_type);
-
- BOOL compare_result;
- EXPECT_UIA_INVALIDOPERATION(this_provider->Compare(
- other_provider_different_type.Get(), &compare_result));
-
- int compare_endpoints_result;
- EXPECT_UIA_INVALIDOPERATION(this_provider->CompareEndpoints(
- TextPatternRangeEndpoint_Start, other_provider_different_type.Get(),
- TextPatternRangeEndpoint_Start, &compare_endpoints_result));
-
- EXPECT_UIA_INVALIDOPERATION(this_provider->MoveEndpointByRange(
- TextPatternRangeEndpoint_Start, other_provider_different_type.Get(),
- TextPatternRangeEndpoint_Start));
- }
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderGetText) {
- Init(BuildTextDocument({"some text", "more text"}));
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* text_node = root_node->children()[0];
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, text_node);
-
- base::win::ScopedBstr text_content;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(-1, text_content.Receive()));
- EXPECT_STREQ(text_content.Get(), L"some text");
- text_content.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(4, text_content.Receive()));
- EXPECT_STREQ(text_content.Get(), L"some");
- text_content.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(0, text_content.Receive()));
- EXPECT_STREQ(text_content.Get(), L"");
- text_content.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(9, text_content.Receive()));
- EXPECT_STREQ(text_content.Get(), L"some text");
- text_content.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetText(10, text_content.Receive()));
- EXPECT_STREQ(text_content.Get(), L"some text");
- text_content.Reset();
-
- EXPECT_HRESULT_FAILED(text_range_provider->GetText(-1, nullptr));
-
- EXPECT_HRESULT_FAILED(
- text_range_provider->GetText(-2, text_content.Receive()));
- text_content.Reset();
-
- ComPtr<ITextRangeProvider> document_textrange;
- GetTextRangeProviderFromTextNode(document_textrange, root_node);
-
- EXPECT_HRESULT_SUCCEEDED(
- document_textrange->GetText(-1, text_content.Receive()));
- EXPECT_STREQ(text_content.Get(), L"some textmore text");
- text_content.Reset();
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderMoveCharacter) {
- Init(BuildAXTreeForMove());
- AXNode* root_node = GetRootAsAXNode();
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
-
- // Moving by 0 should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character, /*count*/ 0,
- /*expected_text*/ tree_for_move_full_text.data(),
- /*expected_count*/ 0);
-
- // Move forward.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/ L"i",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ 18,
- /*expected_text*/ L"S",
- /*expected_count*/ 18);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ 16,
- /*expected_text*/ L"b",
- /*expected_count*/ 16);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ 60,
- /*expected_text*/ L"2",
- /*expected_count*/ 30);
-
- // Trying to move past the last character should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/ L"2",
- /*expected_count*/ 0);
-
- // Move backward.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ -2,
- /*expected_text*/ L"h",
- /*expected_count*/ -2);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ -9,
- /*expected_text*/ L"1",
- /*expected_count*/ -9);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ -60,
- /*expected_text*/ L"F",
- /*expected_count*/ -54);
-
- // Moving backward by any number of characters at the start of document
- // should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ -1,
- /*expected_text*/
- L"F",
- /*expected_count*/ 0);
-
- // Degenerate range moves.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ -1,
- /*expected_text*/ L"",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ 4,
- /*expected_text*/ L"",
- /*expected_count*/ 4);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ 70,
- /*expected_text*/ L"",
- /*expected_count*/ 62);
-
- // Trying to move past the last character should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ 70,
- /*expected_text*/ L"",
- /*expected_count*/ 0);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
- /*count*/ -2,
- /*expected_text*/ L"",
- /*expected_count*/ -2);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMoveFormat) {
- Init(BuildAXTreeForMoveByFormat());
- AXNode* root_node = GetRootAsAXNode();
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
-
- // Moving by 0 should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ 0,
- /*expected_text*/
- L"Text with formattingStandalone line with no formattingbold "
- L"textParagraph 1Paragraph 2Paragraph 3Paragraph 4",
- /*expected_count*/ 0);
-
- // Move forward.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ 1,
- /*expected_text*/ L"Standalone line with no formatting",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ 2,
- /*expected_text*/ L"Paragraph 1",
- /*expected_count*/ 2);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ 1,
- /*expected_text*/ L"Paragraph 2Paragraph 3",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ 1,
- /*expected_text*/ L"Paragraph 4",
- /*expected_count*/ 1);
-
- // Trying to move past the last format should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ 1,
- /*expected_text*/ L"Paragraph 4",
- /*expected_count*/ 0);
-
- // Move backward.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ -3,
- /*expected_text*/ L"bold text",
- /*expected_count*/ -3);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ -1,
- /*expected_text*/ L"Standalone line with no formatting",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ -1,
- /*expected_text*/ L"Text with formatting",
- /*expected_count*/ -1);
-
- // Moving backward by any number of formats at the start of document
- // should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ -1,
- /*expected_text*/
- L"Text with formatting",
- /*expected_count*/ 0);
-
- // Test degenerate range creation at the beginning of the document.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
- /*count*/ -1,
- /*expected_text*/ L"",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
- /*count*/ 1,
- /*expected_text*/ L"Text with formatting",
- /*expected_count*/ 1);
-
- // Test degenerate range creation at the end of the document.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ 5,
- /*expected_text*/ L"Paragraph 4",
- /*expected_count*/ 5);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Format,
- /*count*/ 1,
- /*expected_text*/ L"",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Format,
- /*count*/ -1,
- /*expected_text*/ L"Paragraph 4",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Format,
- /*count*/ 1,
- /*expected_text*/ L"",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Format,
- /*count*/ -1,
- /*expected_text*/ L"Paragraph 4",
- /*expected_count*/ -1);
-
- // Degenerate range moves.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ -5,
- /*expected_text*/ L"Text with formatting",
- /*expected_count*/ -5);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
- /*count*/ -1,
- /*expected_text*/ L"",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ 3,
- /*expected_text*/ L"",
- /*expected_count*/ 3);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ 70,
- /*expected_text*/ L"",
- /*expected_count*/ 3);
-
- // Trying to move past the last format should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ 70,
- /*expected_text*/ L"",
- /*expected_count*/ 0);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
- /*count*/ -2,
- /*expected_text*/ L"",
- /*expected_count*/ -2);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMovePage) {
- Init(BuildAXTreeForMoveByPage());
- AXNode* root_node = GetRootAsAXNode();
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
-
- // Moving by 0 should have no effect.
- EXPECT_UIA_MOVE(
- text_range_provider, TextUnit_Page,
- /*count*/ 0,
- /*expected_text*/
- L"some text on page 1\nsome text on page 2some more text on page 3",
- /*expected_count*/ 0);
-
- // Backwards endpoint moves
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Page,
- /*count*/ -1,
- /*expected_text*/ L"some text on page 1\nsome text on page 2",
- /*expected_count*/ -1);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Page,
- /*count*/ -5,
- /*expected_text*/ L"",
- /*expected_count*/ -2);
-
- // Forwards endpoint move
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Page,
- /*count*/ 5,
- /*expected_text*/
- L"some text on page 1\nsome text on page 2some more text on page 3",
- /*expected_count*/ 3);
-
- // Range moves
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Page,
- /*count*/ 1,
- /*expected_text*/ L"some text on page 2",
- /*expected_count*/ 1);
-
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Page,
- /*count*/ 1,
- /*expected_text*/ L"some more text on page 3",
- /*expected_count*/ 1);
-
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Page,
- /*count*/ -1,
- /*expected_text*/ L"some text on page 2",
- /*expected_count*/ -1);
-
- // ExpandToEnclosingUnit - first move by character so it's not on a
- // page boundary before calling ExpandToEnclosingUnit
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ -2,
- /*expected_text*/ L"some text on page",
- /*expected_count*/ -2);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Character,
- /*count*/ 2,
- /*expected_text*/ L"me text on page",
- /*expected_count*/ 2);
-
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Page));
-
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Page,
- /*count*/ 0,
- /*expected_text*/
- L"some text on page 2",
- /*expected_count*/ 0);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMoveWord) {
- Init(BuildAXTreeForMove());
- AXNode* root_node = GetRootAsAXNode();
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
-
- // Moving by 0 should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word, /*count*/ 0,
- /*expected_text*/ tree_for_move_full_text.data(),
- /*expected_count*/ 0);
-
- // Move forward.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ 1,
- /*expected_text*/ L"line ",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ 2,
- /*expected_text*/ L"text",
- /*expected_count*/ 2);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ 2,
- /*expected_text*/ L"line",
- /*expected_count*/ 2);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ 3,
- /*expected_text*/ L"Paragraph ",
- /*expected_count*/ 3);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ 6,
- /*expected_text*/ L"2",
- /*expected_count*/ 3);
-
- // Trying to move past the last word should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ 1,
- /*expected_text*/ L"2",
- /*expected_count*/ 0);
-
- // Move backward.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ -3,
- /*expected_text*/ L"Paragraph ",
- /*expected_count*/ -3);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ -3,
- /*expected_text*/ L"line",
- /*expected_count*/ -3);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ -2,
- /*expected_text*/ L"text",
- /*expected_count*/ -2);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ -6,
- /*expected_text*/ L"First ",
- /*expected_count*/ -3);
-
- // Moving backward by any number of words at the start of document
- // should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ -20,
- /*expected_text*/ L"First ",
- /*expected_count*/ 0);
-
- // Degenerate range moves.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Word,
- /*count*/ -1,
- /*expected_text*/ L"",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ 4,
- /*expected_text*/ L"",
- /*expected_count*/ 4);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ 70,
- /*expected_text*/ L"",
- /*expected_count*/ 8);
-
- // Trying to move past the last word should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ 70,
- /*expected_text*/ L"",
- /*expected_count*/ 0);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Word,
- /*count*/ -2,
- /*expected_text*/ L"",
- /*expected_count*/ -2);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMoveLine) {
- Init(BuildAXTreeForMove());
- AXNode* root_node = GetRootAsAXNode();
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
-
- // Moving by 0 should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Line, /*count*/ 0,
- /*expected_text*/ tree_for_move_full_text.data(),
- /*expected_count*/ 0);
-
- // Move forward.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Line,
- /*count*/ 2,
- /*expected_text*/ L"Standalone line",
- /*expected_count*/ 2);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Line,
- /*count*/ 1,
- /*expected_text*/ L"bold text",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Line,
- /*count*/ 10,
- /*expected_text*/ L"Paragraph 2",
- /*expected_count*/ 2);
-
- // Trying to move past the last line should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Line,
- /*count*/ 1,
- /*expected_text*/ L"Paragraph 2",
- /*expected_count*/ 0);
-
- // Move backward.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Line,
- /*count*/ -1,
- /*expected_text*/ L"Paragraph 1",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Line,
- /*count*/ -5,
- /*expected_text*/ L"First line of text",
- /*expected_count*/ -4);
-
- // Moving backward by any number of lines at the start of document
- // should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Line,
- /*count*/ -20,
- /*expected_text*/ L"First line of text",
- /*expected_count*/ 0);
-
- // Degenerate range moves.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Line,
- /*count*/ -1,
- /*expected_text*/ L"",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Line,
- /*count*/ 4,
- /*expected_text*/ L"",
- /*expected_count*/ 4);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Line,
- /*count*/ 70,
- /*expected_text*/ L"",
- /*expected_count*/ 2);
-
- // Trying to move past the last line should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Line,
- /*count*/ 70,
- /*expected_text*/ L"",
- /*expected_count*/ 0);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Line,
- /*count*/ -2,
- /*expected_text*/ L"",
- /*expected_count*/ -2);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderMoveParagraph) {
- Init(BuildAXTreeForMove());
- AXNode* root_node = GetRootAsAXNode();
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
-
- // Moving by 0 should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph, /*count*/ 0,
- /*expected_text*/ tree_for_move_full_text.data(),
- /*expected_count*/ 0);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Paragraph,
- /*count*/ -4,
- /*expected_text*/ L"First line of text\n",
- /*expected_count*/ -4);
-
- // Move forward.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ 1,
- /*expected_text*/ L"Standalone line\n",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ 1,
- /*expected_text*/ L"bold text",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ 1,
- /*expected_text*/ L"Paragraph 1",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ 2,
- /*expected_text*/ L"Paragraph 2",
- /*expected_count*/ 1);
-
- // Trying to move past the last paragraph should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ 1,
- /*expected_text*/ L"Paragraph 2",
- /*expected_count*/ 0);
-
- // Move backward.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ -3,
- /*expected_text*/ L"Standalone line\n",
- /*expected_count*/ -3);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ -1,
- /*expected_text*/ L"First line of text\n",
- /*expected_count*/ -1);
-
- // Moving backward by any number of paragraphs at the start of document
- // should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ -1,
- /*expected_text*/
- L"First line of text\n",
- /*expected_count*/ 0);
-
- // Test degenerate range creation at the beginning of the document.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Paragraph,
- /*count*/ -1,
- /*expected_text*/ L"",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Paragraph,
- /*count*/ 1,
- /*expected_text*/ L"First line of text\n",
- /*expected_count*/ 1);
-
- // Test degenerate range creation at the end of the document.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ 6,
- /*expected_text*/ L"Paragraph 2",
- /*expected_count*/ 4);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Paragraph,
- /*count*/ 1,
- /*expected_text*/ L"",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Paragraph,
- /*count*/ -1,
- /*expected_text*/ L"Paragraph 2",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Paragraph,
- /*count*/ 1,
- /*expected_text*/ L"",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Paragraph,
- /*count*/ -1,
- /*expected_text*/ L"Paragraph 2",
- /*expected_count*/ -1);
-
- // Degenerate range moves.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ -7,
- /*expected_text*/ L"First line of text\n",
- /*expected_count*/ -4);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Paragraph,
- /*count*/ -1,
- /*expected_text*/ L"",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ 3,
- /*expected_text*/ L"",
- /*expected_count*/ 3);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ 70,
- /*expected_text*/ L"",
- /*expected_count*/ 2);
-
- // Trying to move past the last paragraph should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ 70,
- /*expected_text*/ L"",
- /*expected_count*/ 0);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Paragraph,
- /*count*/ -2,
- /*expected_text*/ L"",
- /*expected_count*/ -2);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderMoveDocument) {
- Init(BuildAXTreeForMove());
- AXNode* root_node = GetRootAsAXNode();
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
-
- // Moving by 0 should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Document, /*count*/ 0,
- /*expected_text*/ tree_for_move_full_text.data(),
- /*expected_count*/ 0);
-
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Document, /*count*/ -1,
- /*expected_text*/ tree_for_move_full_text.data(),
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Document, /*count*/ 2,
- /*expected_text*/ tree_for_move_full_text.data(),
- /*expected_count*/ 0);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Page, /*count*/ 1,
- /*expected_text*/ tree_for_move_full_text.data(),
- /*expected_count*/ 0);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Page, /*count*/ -1,
- /*expected_text*/ tree_for_move_full_text.data(),
- /*expected_count*/ 0);
-
- // Degenerate range moves.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Document,
- /*count*/ -2,
- /*expected_text*/ L"",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Page,
- /*count*/ 4,
- /*expected_text*/ L"",
- /*expected_count*/ 1);
-
- // Trying to move past the last character should have no effect.
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Document,
- /*count*/ 1,
- /*expected_text*/ L"",
- /*expected_count*/ 0);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Page,
- /*count*/ -2,
- /*expected_text*/ L"",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE(text_range_provider, TextUnit_Document,
- /*count*/ -1,
- /*expected_text*/ L"",
- /*expected_count*/ 0);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMove) {
- Init(BuildAXTreeForMove());
- AXNode* root_node = GetRootAsAXNode();
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
-
- // TODO(https://crbug.com/928948): test intermixed unit types
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderMoveEndpointByDocument) {
- Init(BuildTextDocument({"some text", "more text", "even more text"}));
- AXNode* text_node = GetRootAsAXNode()->children()[1];
-
- // Run the test twice, one for TextUnit_Document and once for TextUnit_Page,
- // since they should have identical behavior.
- const TextUnit textunit_types[] = {TextUnit_Document, TextUnit_Page};
- ComPtr<ITextRangeProvider> text_range_provider;
-
- for (auto& textunit : textunit_types) {
- GetTextRangeProviderFromTextNode(text_range_provider, text_node);
-
- // Verify MoveEndpointByUnit with zero count has no effect
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, textunit,
- /*count*/ 0,
- /*expected_text*/ L"more text",
- /*expected_count*/ 0);
-
- // Move the endpoint to the end of the document. Verify all text content.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, textunit,
- /*count*/ 1,
- /*expected_text*/ L"more texteven more text",
- /*expected_count*/ 1);
-
- // Verify no moves occur since the end is already at the end of the document
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, textunit,
- /*count*/ 5,
- /*expected_text*/ L"more texteven more text",
- /*expected_count*/ 0);
-
- // Move the end before the start
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, textunit,
- /*count*/ -4,
- /*expected_text*/ L"",
- /*expected_count*/ -1);
-
- // Move the end back to the end of the document. The text content
- // should now include the entire document since end was previously
- // moved before start.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, textunit,
- /*count*/ 1,
- /*expected_text*/ L"some textmore texteven more text",
- /*expected_count*/ 1);
-
- // Move the start point to the end
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_Start, textunit,
- /*count*/ 3,
- /*expected_text*/ L"",
- /*expected_count*/ 1);
-
- // Move the start point back to the beginning
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, textunit,
- /*count*/ -3,
- /*expected_text*/ L"some textmore texteven more text",
- /*expected_count*/ -1);
- }
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderMoveEndpointByCharacterMultilingual) {
- // The English string has three characters, each 8 bits in length.
- const std::string english = "hey";
-
- // The Hindi string has two characters, the first one 32 bits and the second
- // 64 bits in length. It is formatted in UTF16.
- const std::string hindi =
- base::UTF16ToUTF8(L"\x0939\x093F\x0928\x094D\x0926\x0940");
-
- // The Thai string has three characters, the first one 48, the second 32 and
- // the last one 16 bits in length. It is formatted in UTF16.
- const std::string thai =
- base::UTF16ToUTF8(L"\x0E23\x0E39\x0E49\x0E2A\x0E36\x0E01");
-
- Init(BuildTextDocument({english, hindi, thai}));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider,
- GetRootAsAXNode()->children()[0]);
-
- // Verify MoveEndpointByUnit with zero count has no effect
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"hey");
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Character,
- /*count*/ 0,
- /*expected_text*/ L"hey",
- /*expected_count*/ 0);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/ L"ey",
- /*expected_count*/ 1);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ -1,
- /*expected_text*/ L"e",
- /*expected_count*/ -1);
-
- // Move end into the adjacent node.
- //
- // The first character of the second node is 32 bits in length.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ 2,
- /*expected_text*/ L"ey\x0939\x093F",
- /*expected_count*/ 2);
-
- // The second character of the second node is 64 bits in length.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/ L"ey\x939\x93F\x928\x94D\x926\x940",
- /*expected_count*/ 1);
-
- // Move start into the adjacent node as well.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Character,
- /*count*/ 2,
- /*expected_text*/ L"\x939\x93F\x928\x94D\x926\x940",
- /*expected_count*/ 2);
-
- // Move end into the last node.
- //
- // The first character of the last node is 48 bits in length.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/ L"\x939\x93F\x928\x94D\x926\x940\xE23\xE39\xE49",
- /*expected_count*/ 1);
-
- // Move end back into the second node and then into the last node again.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ -2,
- /*expected_text*/ L"\x939\x93F",
- /*expected_count*/ -2);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ 3,
- /*expected_text*/
- L"\x939\x93F\x928\x94D\x926\x940\xE23\xE39\xE49\xE2A\xE36",
- /*expected_count*/ 3);
-
- // The last character of the last node is only 16 bits in length.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/
- L"\x939\x93F\x928\x94D\x926\x940\xE23\xE39\xE49\xE2A\xE36\xE01",
- /*expected_count*/ 1);
-
- // Move start into the last node.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Character,
- /*count*/ 3,
- /*expected_text*/ L"\x0E2A\x0E36\x0E01",
- /*expected_count*/ 3);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Character,
- /*count*/ -1,
- /*expected_text*/ L"\x0E23\x0E39\x0E49\x0E2A\x0E36\x0E01",
- /*expected_count*/ -1);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderMoveEndpointByWord) {
- Init(BuildTextDocument({"some text", "more text", "even more text"},
- /*build_word_boundaries_offsets*/ true));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider,
- GetRootAsAXNode()->children()[1]);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"more text");
-
- // Moving with zero count does not alter the range.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Word,
- /*count*/ 0,
- /*expected_text*/ L"more text",
- /*expected_count*/ 0);
-
- // Moving the start forward and backward.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Word,
- /*count*/ 1,
- /*expected_text*/ L"text",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Word,
- /*count*/ -1,
- /*expected_text*/ L"more text",
- /*expected_count*/ -1);
-
- // Moving the end backward and forward.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Word,
- /*count*/ -1,
- /*expected_text*/ L"more ",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Word,
- /*count*/ 1,
- /*expected_text*/ L"more text",
- /*expected_count*/ 1);
-
- // Moving the start past the end, then reverting.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Word,
- /*count*/ 3,
- /*expected_text*/ L"",
- /*expected_count*/ 3);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Word,
- /*count*/ -3,
- /*expected_text*/ L"more texteven ",
- /*expected_count*/ -3);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Word,
- /*count*/ -1,
- /*expected_text*/ L"more text",
- /*expected_count*/ -1);
-
- // Moving the end past the start, then reverting.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Word,
- /*count*/ -3,
- /*expected_text*/ L"",
- /*expected_count*/ -3);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Word,
- /*count*/ 3,
- /*expected_text*/ L"textmore text",
- /*expected_count*/ 3);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Word,
- /*count*/ 1,
- /*expected_text*/ L"more text",
- /*expected_count*/ 1);
-
- // Moving the endpoints further than both ends of the document.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Word,
- /*count*/ 5,
- /*expected_text*/ L"more texteven more text",
- /*expected_count*/ 3);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Word,
- /*count*/ 6,
- /*expected_text*/ L"",
- /*expected_count*/ 5);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Word,
- /*count*/ -8,
- /*expected_text*/ L"some textmore texteven more text",
- /*expected_count*/ -7);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Word,
- /*count*/ -8,
- /*expected_text*/ L"",
- /*expected_count*/ -7);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderMoveEndpointByLine) {
- Init(BuildTextDocument({"0", "1", "2", "3", "4", "5", "6"}));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider,
- GetRootAsAXNode()->children()[3]);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"3");
-
- // Moving with zero count does not alter the range.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Line,
- /*count*/ 0,
- /*expected_text*/ L"3",
- /*expected_count*/ 0);
-
- // Moving the start backward and forward.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Line,
- /*count*/ -2,
- /*expected_text*/ L"123",
- /*expected_count*/ -2);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Line,
- /*count*/ 1,
- /*expected_text*/ L"23",
- /*expected_count*/ 1);
-
- // Moving the end forward and backward.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Line,
- /*count*/ 3,
- /*expected_text*/ L"23456",
- /*expected_count*/ 3);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Line,
- /*count*/ -2,
- /*expected_text*/ L"234",
- /*expected_count*/ -2);
-
- // Moving the end past the start and vice versa.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Line,
- /*count*/ -4,
- /*expected_text*/ L"",
- /*expected_count*/ -4);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Line,
- /*count*/ -1,
- /*expected_text*/ L"0",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Line,
- /*count*/ 6,
- /*expected_text*/ L"",
- /*expected_count*/ 6);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Line,
- /*count*/ -6,
- /*expected_text*/ L"012345",
- /*expected_count*/ -6);
-
- // Moving the endpoints further than both ends of the document.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Line,
- /*count*/ -13,
- /*expected_text*/ L"",
- /*expected_count*/ -6);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider,
- TextPatternRangeEndpoint_End, TextUnit_Line,
- /*count*/ 11,
- /*expected_text*/ L"0123456",
- /*expected_count*/ 7);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Line,
- /*count*/ 9,
- /*expected_text*/ L"",
- /*expected_count*/ 7);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Line,
- /*count*/ -7,
- /*expected_text*/ L"0123456",
- /*expected_count*/ -7);
-}
-
-// Verify that the endpoint can move past an empty text field.
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderMoveEndpointByUnitTextField) {
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
-
- ui::AXNodeData group1_data;
- group1_data.id = 2;
- group1_data.role = ax::mojom::Role::kGenericContainer;
-
- ui::AXNodeData text_data;
- text_data.id = 3;
- text_data.role = ax::mojom::Role::kStaticText;
- std::string text_content = "some text";
- text_data.SetName(text_content);
- std::vector<int> word_start_offsets, word_end_offsets;
- ComputeWordBoundariesOffsets(text_content, word_start_offsets,
- word_end_offsets);
- text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
- word_start_offsets);
- text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
- word_end_offsets);
-
- ui::AXNodeData text_input_data;
- text_input_data.id = 4;
- text_input_data.role = ax::mojom::Role::kTextField;
-
- ui::AXNodeData group2_data;
- group2_data.id = 5;
- group2_data.role = ax::mojom::Role::kGenericContainer;
-
- ui::AXNodeData more_text_data;
- more_text_data.id = 6;
- more_text_data.role = ax::mojom::Role::kStaticText;
- text_content = "more text";
- more_text_data.SetName(text_content);
- ComputeWordBoundariesOffsets(text_content, word_start_offsets,
- word_end_offsets);
- more_text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
- word_start_offsets);
- more_text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
- word_end_offsets);
-
- ui::AXNodeData empty_text_data;
- empty_text_data.id = 7;
- empty_text_data.role = ax::mojom::Role::kStaticText;
- text_content = "";
- empty_text_data.SetName(text_content);
- ComputeWordBoundariesOffsets(text_content, word_start_offsets,
- word_end_offsets);
- empty_text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
- word_start_offsets);
- empty_text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
- word_end_offsets);
-
- root_data.child_ids = {group1_data.id, text_input_data.id, group2_data.id};
- group1_data.child_ids = {text_data.id};
- text_input_data.child_ids = {empty_text_data.id};
- group2_data.child_ids = {more_text_data.id};
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes = {root_data, group1_data, text_data, text_input_data,
- group2_data, more_text_data, empty_text_data};
-
- Init(update);
-
- // Set up variables from the tree for testing.
- AXNode* root_node = GetRootAsAXNode();
- AXNode* text_node = root_node->children()[0]->children()[0];
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, text_node);
-
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"some text");
-
- int count;
- // Tests for TextUnit_Character
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ 1, &count));
- ASSERT_EQ(1, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"some textm");
-
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ -1, &count));
- ASSERT_EQ(-1, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"some text");
-
- // Tests for TextUnit_Word
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Word, /*count*/ 1, &count));
- ASSERT_EQ(1, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"some textmore ");
-
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Word, /*count*/ -1, &count));
- ASSERT_EQ(-1, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"some text");
-
- // Tests for TextUnit_Line
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Line, /*count*/ 1, &count));
- ASSERT_EQ(1, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"some textmore text");
-
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Line, /*count*/ -1, &count));
- ASSERT_EQ(-1, count);
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"some text");
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderMoveEndpointByFormat) {
- Init(BuildAXTreeForMoveByFormat());
- AXNode* root_node = GetRootAsAXNode();
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, root_node);
-
- EXPECT_UIA_TEXTRANGE_EQ(
- text_range_provider,
- L"Text with formattingStandalone line with no formattingbold "
- L"textParagraph 1Paragraph 2Paragraph 3Paragraph 4");
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
- /*count*/ -2,
- /*expected_text*/
- L"Text with formattingStandalone line with no formattingbold "
- L"textParagraph 1",
- /*expected_count*/ -2);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
- /*count*/ -1,
- /*expected_text*/
- L"Text with formattingStandalone line with no formattingbold text",
-
- /*expected_count*/ -1);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
- /*count*/ -1,
- /*expected_text*/
- L"Text with formattingStandalone line with no formatting",
- /*expected_count*/ -1);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
- /*count*/ -1,
- /*expected_text*/ L"Text with formatting",
- /*expected_count*/ -1);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
- /*count*/ -1,
- /*expected_text*/ L"",
- /*expected_count*/ -1);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
- /*count*/ 7,
- /*expected_text*/
- L"Text with formattingStandalone line with no formattingbold "
- L"textParagraph 1Paragraph 2Paragraph 3Paragraph 4",
- /*expected_count*/ 6);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
- /*count*/ -8,
- /*expected_text*/ L"",
- /*expected_count*/ -6);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderCompare) {
- Init(BuildTextDocument({"some text", "some text"}));
- AXNode* root_node = GetRootAsAXNode();
-
- // Get the textRangeProvider for the document,
- // which contains text "some textsome text".
- ComPtr<ITextRangeProvider> document_text_range_provider;
- GetTextRangeProviderFromTextNode(document_text_range_provider, root_node);
-
- // Get the textRangeProvider for the first text node.
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider,
- root_node->children()[0]);
-
- // Get the textRangeProvider for the second text node.
- ComPtr<ITextRangeProvider> more_text_range_provider;
- GetTextRangeProviderFromTextNode(more_text_range_provider,
- root_node->children()[1]);
-
- // Compare text range of the entire document with itself, which should return
- // that they are equal.
- BOOL result;
- EXPECT_HRESULT_SUCCEEDED(document_text_range_provider->Compare(
- document_text_range_provider.Get(), &result));
- EXPECT_TRUE(result);
-
- // Compare the text range of the entire document with one of its child, which
- // should return that they are not equal.
- EXPECT_HRESULT_SUCCEEDED(document_text_range_provider->Compare(
- text_range_provider.Get(), &result));
- EXPECT_FALSE(result);
-
- // Compare the text range of text_node which contains "some text" with
- // text range of more_text_node which also contains "some text". Those two
- // text ranges should not equal, because their endpoints are different, even
- // though their contents are the same.
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->Compare(more_text_range_provider.Get(), &result));
- EXPECT_FALSE(result);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderSelection) {
- Init(BuildTextDocument({"some text"}));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, GetRootAsAXNode());
-
- ASSERT_UIA_INVALIDOPERATION(text_range_provider->AddToSelection());
- ASSERT_UIA_INVALIDOPERATION(text_range_provider->RemoveFromSelection());
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderGetBoundingRectangles) {
- ui::AXTreeUpdate update = BuildAXTreeForBoundingRectangles();
- Init(update);
- ComPtr<ITextRangeProvider> text_range_provider;
- base::win::ScopedSafearray rectangles;
- int count;
-
- // Expected bounding rects:
- // <button>Button</button><input type="checkbox">Line 1<br>Line 2
- // |---------------------||---------------------||----| |------|
- GetTextRangeProviderFromTextNode(text_range_provider, GetRootAsAXNode());
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetBoundingRectangles(rectangles.Receive()));
- std::vector<double> expected_values = {20, 20, 200, 30, /* button */
- 20, 50, 200, 30, /* check box */
- 220, 20, 30, 30, /* line 1 */
- 220, 50, 42, 30 /* line 2 */};
- EXPECT_UIA_SAFEARRAY_EQ(rectangles.Get(), expected_values);
- rectangles.Reset();
-
- // Move the text range end back by one character.
- // Expected bounding rects:
- // <button>Button</button><input type="checkbox">Line 1<br>Line 2
- // |---------------------||---------------------||----| |----|
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Character, /*count*/ -1, &count));
- ASSERT_EQ(-1, count);
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetBoundingRectangles(rectangles.Receive()));
- expected_values = {20, 20, 200, 30, /* button */
- 20, 50, 200, 30, /* check box */
- 220, 20, 30, 30, /* line 1 */
- 220, 50, 35, 30 /* line 2 */};
- EXPECT_UIA_SAFEARRAY_EQ(rectangles.Get(), expected_values);
- rectangles.Reset();
-
- // Move the text range end back by one line.
- // Expected bounding rects:
- // <button>Button</button><input type="checkbox">Line 1<br>Line 2
- // |---------------------||---------------------||-----|
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Line, /*count*/ -1, &count));
- ASSERT_EQ(-1, count);
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetBoundingRectangles(rectangles.Receive()));
- expected_values = {20, 20, 200, 30, /* button */
- 20, 50, 200, 30, /* check box */
- 220, 20, 30, 30 /* line 1 */};
- EXPECT_UIA_SAFEARRAY_EQ(rectangles.Get(), expected_values);
- rectangles.Reset();
-
- // Move the text range end back by one line.
- // Expected bounding rects:
- // <button>Button</button><input type="checkbox">Line 1<br>Line 2
- // |---------------------||---------------------|
- ASSERT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByUnit(
- TextPatternRangeEndpoint_End, TextUnit_Word, /*count*/ -2, &count));
- ASSERT_EQ(-2, count);
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetBoundingRectangles(rectangles.Receive()));
- expected_values = {20, 20, 200, 30, /* button */
- 20, 50, 200, 30 /* check box */};
- EXPECT_UIA_SAFEARRAY_EQ(rectangles.Get(), expected_values);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderGetEnclosingElement) {
- // Set up ax tree with the following structure:
- //
- // root
- // |
- // paragraph______________________________________________
- // | | | | |
- // static_text link link search input pdf_highlight
- // | | | | |
- // text_node static_text ul text_node static_text
- // | | |
- // text_node li text_node
- // |
- // static_text
- // |
- // text_node
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
-
- ui::AXNodeData paragraph_data;
- paragraph_data.id = 2;
- paragraph_data.role = ax::mojom::Role::kParagraph;
- root_data.child_ids.push_back(paragraph_data.id);
-
- ui::AXNodeData static_text_data1;
- static_text_data1.id = 3;
- static_text_data1.role = ax::mojom::Role::kStaticText;
- paragraph_data.child_ids.push_back(static_text_data1.id);
-
- ui::AXNodeData inline_text_data1;
- inline_text_data1.id = 4;
- inline_text_data1.role = ax::mojom::Role::kInlineTextBox;
- static_text_data1.child_ids.push_back(inline_text_data1.id);
-
- ui::AXNodeData link_data;
- link_data.id = 5;
- link_data.role = ax::mojom::Role::kLink;
- paragraph_data.child_ids.push_back(link_data.id);
-
- ui::AXNodeData static_text_data2;
- static_text_data2.id = 6;
- static_text_data2.role = ax::mojom::Role::kStaticText;
- link_data.child_ids.push_back(static_text_data2.id);
-
- ui::AXNodeData inline_text_data2;
- inline_text_data2.id = 7;
- inline_text_data2.role = ax::mojom::Role::kInlineTextBox;
- static_text_data2.child_ids.push_back(inline_text_data2.id);
-
- ui::AXNodeData link_data2;
- link_data2.id = 8;
- link_data2.role = ax::mojom::Role::kLink;
- paragraph_data.child_ids.push_back(link_data2.id);
-
- ui::AXNodeData list_data;
- list_data.id = 9;
- list_data.role = ax::mojom::Role::kList;
- link_data2.child_ids.push_back(list_data.id);
-
- ui::AXNodeData list_item_data;
- list_item_data.id = 10;
- list_item_data.role = ax::mojom::Role::kListItem;
- list_data.child_ids.push_back(list_item_data.id);
-
- ui::AXNodeData static_text_data3;
- static_text_data3.id = 11;
- static_text_data3.role = ax::mojom::Role::kStaticText;
- list_item_data.child_ids.push_back(static_text_data3.id);
-
- ui::AXNodeData inline_text_data3;
- inline_text_data3.id = 12;
- inline_text_data3.role = ax::mojom::Role::kInlineTextBox;
- static_text_data3.child_ids.push_back(inline_text_data3.id);
-
- ui::AXNodeData search_box;
- search_box.id = 13;
- search_box.role = ax::mojom::Role::kSearchBox;
- paragraph_data.child_ids.push_back(search_box.id);
-
- ui::AXNodeData search_text;
- search_text.id = 14;
- search_text.role = ax::mojom::Role::kStaticText;
- search_text.SetName("placeholder");
- search_box.child_ids.push_back(search_text.id);
-
- ui::AXNodeData pdf_highlight_data;
- pdf_highlight_data.id = 15;
- pdf_highlight_data.role = ax::mojom::Role::kPdfActionableHighlight;
- paragraph_data.child_ids.push_back(pdf_highlight_data.id);
-
- ui::AXNodeData static_text_data4;
- static_text_data4.id = 16;
- static_text_data4.role = ax::mojom::Role::kStaticText;
- pdf_highlight_data.child_ids.push_back(static_text_data4.id);
-
- ui::AXNodeData inline_text_data4;
- inline_text_data4.id = 17;
- inline_text_data4.role = ax::mojom::Role::kInlineTextBox;
- static_text_data4.child_ids.push_back(inline_text_data4.id);
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes = {root_data, paragraph_data, static_text_data1,
- inline_text_data1, link_data, static_text_data2,
- inline_text_data2, link_data2, list_data,
- list_item_data, static_text_data3, inline_text_data3,
- search_box, search_text, pdf_highlight_data,
- static_text_data4, inline_text_data4};
- Init(update);
-
- // Set up variables from the tree for testing.
- AXNode* paragraph_node = GetRootAsAXNode()->children()[0];
- AXNode* static_text_node1 = paragraph_node->children()[0];
- AXNode* link_node = paragraph_node->children()[1];
- AXNode* inline_text_node1 = static_text_node1->children()[0];
- AXNode* static_text_node2 = link_node->children()[0];
- AXNode* inline_text_node2 = static_text_node2->children()[0];
- AXNode* link_node2 = paragraph_node->children()[2];
- AXNode* list_node = link_node2->children()[0];
- AXNode* list_item_node = list_node->children()[0];
- AXNode* static_text_node3 = list_item_node->children()[0];
- AXNode* inline_text_node3 = static_text_node3->children()[0];
- AXNode* search_box_node = paragraph_node->children()[3];
- AXNode* search_text_node = search_box_node->children()[0];
- AXNode* pdf_highlight_node = paragraph_node->children()[4];
- AXNode* static_text_node4 = pdf_highlight_node->children()[0];
- AXNode* inline_text_node4 = static_text_node4->children()[0];
-
- ComPtr<IRawElementProviderSimple> link_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(link_node);
- ComPtr<IRawElementProviderSimple> static_text_node_raw1 =
- QueryInterfaceFromNode<IRawElementProviderSimple>(static_text_node1);
- ComPtr<IRawElementProviderSimple> static_text_node_raw2 =
- QueryInterfaceFromNode<IRawElementProviderSimple>(static_text_node2);
- ComPtr<IRawElementProviderSimple> static_text_node_raw3 =
- QueryInterfaceFromNode<IRawElementProviderSimple>(static_text_node3);
- ComPtr<IRawElementProviderSimple> inline_text_node_raw1 =
- QueryInterfaceFromNode<IRawElementProviderSimple>(inline_text_node1);
- ComPtr<IRawElementProviderSimple> inline_text_node_raw2 =
- QueryInterfaceFromNode<IRawElementProviderSimple>(inline_text_node2);
- ComPtr<IRawElementProviderSimple> inline_text_node_raw3 =
- QueryInterfaceFromNode<IRawElementProviderSimple>(inline_text_node3);
- ComPtr<IRawElementProviderSimple> search_box_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(search_box_node);
- ComPtr<IRawElementProviderSimple> search_text_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(search_text_node);
- ComPtr<IRawElementProviderSimple> pdf_highlight_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(pdf_highlight_node);
- ComPtr<IRawElementProviderSimple> inline_text_node_raw4 =
- QueryInterfaceFromNode<IRawElementProviderSimple>(inline_text_node4);
-
- // Test GetEnclosingElement for the two leaves text nodes. The enclosing
- // element of the first one should be its static text parent (because inline
- // text boxes shouldn't be exposed) and the enclosing element for the text
- // node that is grandchild of the link node should return the link node.
- // The text node in the link node with a complex subtree should behave
- // normally and return the static text parent.
- ComPtr<ITextProvider> text_provider;
- EXPECT_HRESULT_SUCCEEDED(inline_text_node_raw1->GetPatternProvider(
- UIA_TextPatternId, &text_provider));
-
- ComPtr<ITextRangeProvider> text_range_provider;
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-
- ComPtr<IRawElementProviderSimple> enclosing_element;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetEnclosingElement(&enclosing_element));
- EXPECT_EQ(static_text_node_raw1.Get(), enclosing_element.Get());
-
- EXPECT_HRESULT_SUCCEEDED(inline_text_node_raw2->GetPatternProvider(
- UIA_TextPatternId, &text_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetEnclosingElement(&enclosing_element));
- EXPECT_EQ(link_node_raw.Get(), enclosing_element.Get());
-
- EXPECT_HRESULT_SUCCEEDED(inline_text_node_raw3->GetPatternProvider(
- UIA_TextPatternId, &text_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetEnclosingElement(&enclosing_element));
- EXPECT_EQ(static_text_node_raw3.Get(), enclosing_element.Get());
-
- // The enclosing element of a text range in the search text should give the
- // search box
- EXPECT_HRESULT_SUCCEEDED(search_text_node_raw->GetPatternProvider(
- UIA_TextPatternId, &text_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Character));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetEnclosingElement(&enclosing_element));
- EXPECT_EQ(search_box_node_raw.Get(), enclosing_element.Get());
-
- // The enclosing element for the text node that is grandchild of the
- // pdf_highlight node should return the pdf_highlight node.
- EXPECT_HRESULT_SUCCEEDED(inline_text_node_raw4->GetPatternProvider(
- UIA_TextPatternId, &text_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetEnclosingElement(&enclosing_element));
- EXPECT_EQ(pdf_highlight_node_raw.Get(), enclosing_element.Get());
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderMoveEndpointByRange) {
- Init(BuildTextDocument({"some text", "more text"}));
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* text_node = root_node->children()[0];
- AXNode* more_text_node = root_node->children()[1];
-
- // Text range for the document, which contains text "some textmore text".
- ComPtr<IRawElementProviderSimple> root_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(root_node);
- ComPtr<ITextProvider> document_provider;
- EXPECT_HRESULT_SUCCEEDED(
- root_node_raw->GetPatternProvider(UIA_TextPatternId, &document_provider));
- ComPtr<ITextRangeProvider> document_text_range_provider;
- ComPtr<AXPlatformNodeTextRangeProviderWin> document_text_range;
-
- // Text range related to "some text".
- ComPtr<IRawElementProviderSimple> text_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(text_node);
- ComPtr<ITextProvider> text_provider;
- EXPECT_HRESULT_SUCCEEDED(
- text_node_raw->GetPatternProvider(UIA_TextPatternId, &text_provider));
- ComPtr<ITextRangeProvider> text_range_provider;
- ComPtr<AXPlatformNodeTextRangeProviderWin> text_range;
-
- // Text range related to "more text".
- ComPtr<IRawElementProviderSimple> more_text_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(more_text_node);
- ComPtr<ITextProvider> more_text_provider;
- EXPECT_HRESULT_SUCCEEDED(more_text_node_raw->GetPatternProvider(
- UIA_TextPatternId, &more_text_provider));
- ComPtr<ITextRangeProvider> more_text_range_provider;
- ComPtr<AXPlatformNodeTextRangeProviderWin> more_text_range;
-
- // Move the start of document text range "some textmore text" to the end of
- // itself.
- // The start of document text range "some textmore text" is at the end of
- // itself.
- //
- // Before:
- // |s e|
- // "some textmore text"
- // After:
- // |s
- // e|
- // "some textmore text"
-
- // Get the textRangeProvider for the document, which contains text
- // "some textmore text".
- EXPECT_HRESULT_SUCCEEDED(
- document_provider->get_DocumentRange(&document_text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(document_text_range_provider->MoveEndpointByRange(
- TextPatternRangeEndpoint_Start, document_text_range_provider.Get(),
- TextPatternRangeEndpoint_End));
-
- document_text_range_provider->QueryInterface(
- IID_PPV_ARGS(&document_text_range));
- EXPECT_EQ(*GetStart(document_text_range.Get()),
- *GetEnd(document_text_range.Get()));
-
- // Move the end of document text range "some textmore text" to the start of
- // itself.
- // The end of document text range "some textmore text" is at the start of
- // itself.
- //
- // Before:
- // |s e|
- // "some textmore text"
- // After:
- // |s
- // e|
- // "some textmore text"
-
- // Get the textRangeProvider for the document, which contains text
- // "some textmore text".
- EXPECT_HRESULT_SUCCEEDED(
- document_provider->get_DocumentRange(&document_text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(document_text_range_provider->MoveEndpointByRange(
- TextPatternRangeEndpoint_Start, document_text_range_provider.Get(),
- TextPatternRangeEndpoint_End));
-
- document_text_range_provider->QueryInterface(
- IID_PPV_ARGS(&document_text_range));
- EXPECT_EQ(*GetStart(document_text_range.Get()),
- *GetEnd(document_text_range.Get()));
-
- // Move the start of document text range "some textmore text" to the start
- // of text range "more text". The start of document text range "some
- // textmore text" is at the start of text range "more text". The end of
- // document range does not change.
- //
- // Before:
- // |s e|
- // "some textmore text"
- // After:
- // |s e|
- // "some textmore text"
-
- // Get the textRangeProvider for the document, which contains text
- // "some textmore text".
- EXPECT_HRESULT_SUCCEEDED(
- document_provider->get_DocumentRange(&document_text_range_provider));
- // Get the textRangeProvider for more_text_node which contains "more text".
- EXPECT_HRESULT_SUCCEEDED(
- more_text_provider->get_DocumentRange(&more_text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(document_text_range_provider->MoveEndpointByRange(
- TextPatternRangeEndpoint_Start, more_text_range_provider.Get(),
- TextPatternRangeEndpoint_Start));
-
- document_text_range_provider->QueryInterface(
- IID_PPV_ARGS(&document_text_range));
- more_text_range_provider->QueryInterface(IID_PPV_ARGS(&more_text_range));
- EXPECT_EQ(*GetStart(document_text_range.Get()),
- *GetStart(more_text_range.Get()));
-
- // Move the end of document text range "some textmore text" to the end of
- // text range "some text".
- // The end of document text range "some textmore text" is at the end of text
- // range "some text". The start of document range does not change.
- //
- // Before:
- // |s e|
- // "some textmore text"
- // After:
- // |s e|
- // "some textmore text"
-
- // Get the textRangeProvider for the document, which contains text
- // "some textmore text".
- EXPECT_HRESULT_SUCCEEDED(
- document_provider->get_DocumentRange(&document_text_range_provider));
- // Get the textRangeProvider for text_node which contains "some text".
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(document_text_range_provider->MoveEndpointByRange(
- TextPatternRangeEndpoint_End, text_range_provider.Get(),
- TextPatternRangeEndpoint_End));
-
- document_text_range_provider->QueryInterface(
- IID_PPV_ARGS(&document_text_range));
- text_range_provider->QueryInterface(IID_PPV_ARGS(&text_range));
- EXPECT_EQ(*GetEnd(document_text_range.Get()), *GetEnd(text_range.Get()));
-
- // Move the end of text range "more text" to the start of
- // text range "some text". Since the order of the endpoints being moved
- // (those of "more text") have to be ensured, both endpoints of "more text"
- // is at the start of "some text".
- //
- // Before:
- // |s e|
- // "some textmore text"
- // After:
- // e|
- // |s
- // "some textmore text"
-
- // Get the textRangeProvider for text_node which contains "some text".
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
- // Get the textRangeProvider for more_text_node which contains "more text".
- EXPECT_HRESULT_SUCCEEDED(
- more_text_provider->get_DocumentRange(&more_text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(more_text_range_provider->MoveEndpointByRange(
- TextPatternRangeEndpoint_End, text_range_provider.Get(),
- TextPatternRangeEndpoint_Start));
-
- text_range_provider->QueryInterface(IID_PPV_ARGS(&text_range));
- more_text_range_provider->QueryInterface(IID_PPV_ARGS(&more_text_range));
- EXPECT_EQ(*GetEnd(more_text_range.Get()), *GetStart(text_range.Get()));
- EXPECT_EQ(*GetStart(more_text_range.Get()), *GetStart(text_range.Get()));
-
- // Move the start of text range "some text" to the end of text range
- // "more text". Since the order of the endpoints being moved (those
- // of "some text") have to be ensured, both endpoints of "some text" is at
- // the end of "more text".
- //
- // Before:
- // |s e|
- // "some textmore text"
- // After:
- // |s
- // e|
- // "some textmore text"
-
- // Get the textRangeProvider for text_node which contains "some text".
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
- // Get the textRangeProvider for more_text_node which contains "more text".
- EXPECT_HRESULT_SUCCEEDED(
- more_text_provider->get_DocumentRange(&more_text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(text_range_provider->MoveEndpointByRange(
- TextPatternRangeEndpoint_Start, more_text_range_provider.Get(),
- TextPatternRangeEndpoint_End));
-
- text_range_provider->QueryInterface(IID_PPV_ARGS(&text_range));
- more_text_range_provider->QueryInterface(IID_PPV_ARGS(&more_text_range));
- EXPECT_EQ(*GetStart(text_range.Get()), *GetEnd(more_text_range.Get()));
- EXPECT_EQ(*GetEnd(text_range.Get()), *GetEnd(more_text_range.Get()));
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderGetChildren) {
- // Set up ax tree with the following structure:
- //
- // ++1 kRootWebArea
- // ++++2 kDocument ignored
- // ++++++3 kStaticText
- // ++++++++4 kInlineTextBox
- // ++++++++5 kInlineTextBox
- // ++++++6 kStaticText
- // ++++++7 kStaticText ignored
- // ++++++8 kButton
- // ++++++++9 kImage
- // ++++++++10 kStaticText
-
- AXNodeData root_1;
- AXNodeData document_2;
- AXNodeData static_text_3;
- AXNodeData inline_box_4;
- AXNodeData inline_box_5;
- AXNodeData static_text_6;
- AXNodeData static_text_7;
- AXNodeData button_8;
- AXNodeData image_9;
- AXNodeData static_text_10;
-
- root_1.id = 1;
- document_2.id = 2;
- static_text_3.id = 3;
- inline_box_4.id = 4;
- inline_box_5.id = 5;
- static_text_6.id = 6;
- static_text_7.id = 7;
- button_8.id = 8;
- image_9.id = 9;
- static_text_10.id = 10;
-
- root_1.role = ax::mojom::Role::kRootWebArea;
- root_1.child_ids = {document_2.id};
-
- document_2.role = ax::mojom::Role::kDocument;
- document_2.AddState(ax::mojom::State::kIgnored);
- document_2.child_ids = {static_text_3.id, static_text_6.id, static_text_7.id,
- button_8.id};
-
- static_text_3.role = ax::mojom::Role::kStaticText;
- static_text_3.child_ids = {inline_box_4.id, inline_box_5.id};
-
- inline_box_4.role = ax::mojom::Role::kInlineTextBox;
-
- inline_box_5.role = ax::mojom::Role::kInlineTextBox;
-
- static_text_6.role = ax::mojom::Role::kStaticText;
-
- static_text_7.role = ax::mojom::Role::kStaticText;
- static_text_7.AddState(ax::mojom::State::kIgnored);
-
- button_8.role = ax::mojom::Role::kButton;
- // Hack: This attribute is needed to be able to get a text range provider
- // located on this element (see AXPlatformNodeWin::GetPatternProvider).
- button_8.AddBoolAttribute(ax::mojom::BoolAttribute::kEditableRoot, true);
- button_8.child_ids = {image_9.id, static_text_10.id};
-
- image_9.role = ax::mojom::Role::kImage;
-
- static_text_10.role = ax::mojom::Role::kStaticText;
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root_1.id;
- update.nodes.push_back(root_1);
- update.nodes.push_back(document_2);
- update.nodes.push_back(static_text_3);
- update.nodes.push_back(inline_box_4);
- update.nodes.push_back(inline_box_5);
- update.nodes.push_back(static_text_6);
- update.nodes.push_back(static_text_7);
- update.nodes.push_back(button_8);
- update.nodes.push_back(image_9);
- update.nodes.push_back(static_text_10);
-
- Init(update);
-
- // Set up variables from the tree for testing.
- AXNode* document_2_node = GetRootAsAXNode()->children()[0];
- AXNode* static_text_3_node = document_2_node->children()[0];
- AXNode* inline_box_4_node = static_text_3_node->children()[0];
- AXNode* inline_box_5_node = static_text_3_node->children()[1];
- AXNode* static_text_6_node = document_2_node->children()[1];
- AXNode* button_8_node = document_2_node->children()[3];
-
- ComPtr<IRawElementProviderSimple> document_2_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(document_2_node);
- ComPtr<IRawElementProviderSimple> static_text_3_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(static_text_3_node);
- ComPtr<IRawElementProviderSimple> inline_box_4_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(inline_box_4_node);
- ComPtr<IRawElementProviderSimple> inline_box_5_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(inline_box_5_node);
- ComPtr<IRawElementProviderSimple> static_text_6_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(static_text_6_node);
- ComPtr<IRawElementProviderSimple> button_8_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(button_8_node);
-
- ComPtr<ITextProvider> text_provider;
- ComPtr<ITextRangeProvider> text_range_provider;
- base::win::ScopedSafearray children;
- std::vector<ComPtr<IRawElementProviderSimple>> expected_values = {};
-
- // Test inline_box_4 - a leaf node should have no children.
- {
- EXPECT_HRESULT_SUCCEEDED(inline_box_4_raw->GetPatternProvider(
- UIA_TextPatternId, &text_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetChildren(children.Receive()));
-
- expected_values = {};
-
- EXPECT_UIA_SAFEARRAY_EQ(children.Get(), expected_values);
- }
-
- // Test static_text_6 - a leaf node should have no children.
- {
- EXPECT_HRESULT_SUCCEEDED(static_text_6_raw->GetPatternProvider(
- UIA_TextPatternId, &text_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetChildren(children.Receive()));
-
- expected_values = {};
-
- EXPECT_UIA_SAFEARRAY_EQ(children.Get(), expected_values);
- }
-
- // Test static_text_3 - children should include inline_box_4 and inline_box_5.
- {
- EXPECT_HRESULT_SUCCEEDED(static_text_3_raw->GetPatternProvider(
- UIA_TextPatternId, &text_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetChildren(children.Receive()));
-
- expected_values = {inline_box_4_raw, inline_box_5_raw};
-
- EXPECT_UIA_SAFEARRAY_EQ(children.Get(), expected_values);
- }
-
- // Test button_8 - a button should never expose its children.
- {
- EXPECT_HRESULT_SUCCEEDED(
- button_8_raw->GetPatternProvider(UIA_TextPatternId, &text_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetChildren(children.Receive()));
-
- expected_values = {};
-
- EXPECT_UIA_SAFEARRAY_EQ(children.Get(), expected_values);
- }
-
- // Test document_2 - children should not include ignored nodes and nodes under
- // a node that should hide its children.
- {
- EXPECT_HRESULT_SUCCEEDED(
- document_2_raw->GetPatternProvider(UIA_TextPatternId, &text_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider->GetChildren(children.Receive()));
-
- expected_values = {
- static_text_3_raw, inline_box_4_raw, inline_box_5_raw,
- static_text_6_raw, button_8_raw,
- };
-
- EXPECT_UIA_SAFEARRAY_EQ(children.Get(), expected_values);
- }
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderGetAttributeValue) {
- ui::AXNodeData text_data;
- text_data.id = 2;
- text_data.role = ax::mojom::Role::kStaticText;
- text_data.AddStringAttribute(ax::mojom::StringAttribute::kFontFamily, "sans");
- text_data.AddFloatAttribute(ax::mojom::FloatAttribute::kFontSize, 16);
- text_data.AddFloatAttribute(ax::mojom::FloatAttribute::kFontWeight, 300);
- text_data.AddIntAttribute(ax::mojom::IntAttribute::kTextOverlineStyle, 1);
- text_data.AddIntAttribute(ax::mojom::IntAttribute::kTextStrikethroughStyle,
- 2);
- text_data.AddIntAttribute(ax::mojom::IntAttribute::kTextUnderlineStyle, 3);
- text_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- text_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU);
- text_data.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "fr-CA");
- text_data.SetTextDirection(ax::mojom::WritingDirection::kRtl);
- text_data.AddTextStyle(ax::mojom::TextStyle::kItalic);
- text_data.SetTextPosition(ax::mojom::TextPosition::kSubscript);
- text_data.SetRestriction(ax::mojom::Restriction::kReadOnly);
- text_data.SetTextAlign(ax::mojom::TextAlign::kCenter);
- text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kMarkerTypes,
- {(int)ax::mojom::MarkerType::kGrammar,
- (int)ax::mojom::MarkerType::kSpelling});
- text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kMarkerStarts,
- {0, 5});
- text_data.AddIntListAttribute(ax::mojom::IntListAttribute::kMarkerEnds,
- {9, 9});
- text_data.SetName("some text");
-
- ui::AXNodeData heading_data;
- heading_data.id = 3;
- heading_data.role = ax::mojom::Role::kHeading;
- heading_data.AddIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel, 6);
- heading_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- heading_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU);
- heading_data.SetTextDirection(ax::mojom::WritingDirection::kRtl);
- heading_data.SetTextPosition(ax::mojom::TextPosition::kSuperscript);
- heading_data.AddState(ax::mojom::State::kEditable);
- heading_data.child_ids = {4};
-
- ui::AXNodeData heading_text_data;
- heading_text_data.id = 4;
- heading_text_data.role = ax::mojom::Role::kStaticText;
- heading_text_data.AddState(ax::mojom::State::kInvisible);
- heading_text_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- heading_text_data.AddIntAttribute(ax::mojom::IntAttribute::kColor,
- 0xDEADC0DEU);
- heading_text_data.SetTextDirection(ax::mojom::WritingDirection::kRtl);
- heading_text_data.SetTextPosition(ax::mojom::TextPosition::kSuperscript);
- heading_text_data.AddState(ax::mojom::State::kEditable);
- heading_text_data.SetTextAlign(ax::mojom::TextAlign::kJustify);
- heading_text_data.AddIntListAttribute(
- ax::mojom::IntListAttribute::kMarkerTypes,
- {(int)ax::mojom::MarkerType::kSpelling});
- heading_text_data.AddIntListAttribute(
- ax::mojom::IntListAttribute::kMarkerStarts, {5});
- heading_text_data.AddIntListAttribute(
- ax::mojom::IntListAttribute::kMarkerEnds, {9});
- heading_text_data.SetName("more text");
-
- ui::AXNodeData mark_data;
- mark_data.id = 5;
- mark_data.role = ax::mojom::Role::kMark;
- mark_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- mark_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU);
- mark_data.SetTextDirection(ax::mojom::WritingDirection::kRtl);
- mark_data.child_ids = {6};
-
- ui::AXNodeData mark_text_data;
- mark_text_data.id = 6;
- mark_text_data.role = ax::mojom::Role::kStaticText;
- mark_text_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- mark_text_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU);
- mark_text_data.SetTextDirection(ax::mojom::WritingDirection::kRtl);
- mark_text_data.SetTextAlign(ax::mojom::TextAlign::kNone);
- mark_text_data.SetName("marked text");
-
- ui::AXNodeData list_data;
- list_data.id = 7;
- list_data.role = ax::mojom::Role::kList;
- list_data.child_ids = {8, 10};
- list_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- list_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU);
-
- ui::AXNodeData list_item_data;
- list_item_data.id = 8;
- list_item_data.role = ax::mojom::Role::kListItem;
- list_item_data.child_ids = {9};
- list_item_data.AddIntAttribute(
- ax::mojom::IntAttribute::kListStyle,
- static_cast<int>(ax::mojom::ListStyle::kOther));
- list_item_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- list_item_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU);
-
- ui::AXNodeData list_item_text_data;
- list_item_text_data.id = 9;
- list_item_text_data.role = ax::mojom::Role::kStaticText;
- list_item_text_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- list_item_text_data.AddIntAttribute(ax::mojom::IntAttribute::kColor,
- 0xDEADC0DEU);
- list_item_text_data.SetName("list item");
-
- ui::AXNodeData list_item2_data;
- list_item2_data.id = 10;
- list_item2_data.role = ax::mojom::Role::kListItem;
- list_item2_data.child_ids = {11};
- list_item2_data.AddIntAttribute(
- ax::mojom::IntAttribute::kListStyle,
- static_cast<int>(ax::mojom::ListStyle::kDisc));
- list_item2_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- list_item2_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU);
-
- ui::AXNodeData list_item2_text_data;
- list_item2_text_data.id = 11;
- list_item2_text_data.role = ax::mojom::Role::kStaticText;
- list_item2_text_data.AddIntAttribute(
- ax::mojom::IntAttribute::kBackgroundColor, 0xDEADBEEFU);
- list_item2_text_data.AddIntAttribute(ax::mojom::IntAttribute::kColor,
- 0xDEADC0DEU);
- list_item2_text_data.SetName("list item 2");
-
- ui::AXNodeData input_text_data;
- input_text_data.id = 12;
- input_text_data.role = ax::mojom::Role::kTextField;
- input_text_data.AddState(ax::mojom::State::kEditable);
- input_text_data.AddIntAttribute(
- ax::mojom::IntAttribute::kNameFrom,
- static_cast<int>(ax::mojom::NameFrom::kPlaceholder));
- input_text_data.AddStringAttribute(ax::mojom::StringAttribute::kPlaceholder,
- "placeholder2");
- input_text_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- input_text_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU);
- input_text_data.AddBoolAttribute(ax::mojom::BoolAttribute::kEditableRoot,
- true);
- input_text_data.SetName("placeholder");
- input_text_data.child_ids = {13};
-
- ui::AXNodeData placeholder_text_data;
- placeholder_text_data.id = 13;
- placeholder_text_data.role = ax::mojom::Role::kStaticText;
- placeholder_text_data.AddIntAttribute(
- ax::mojom::IntAttribute::kBackgroundColor, 0xDEADBEEFU);
- placeholder_text_data.AddIntAttribute(ax::mojom::IntAttribute::kColor,
- 0xDEADC0DEU);
- placeholder_text_data.SetName("placeholder");
-
- ui::AXNodeData input_text_data2;
- input_text_data2.id = 14;
- input_text_data2.role = ax::mojom::Role::kTextField;
- input_text_data2.AddState(ax::mojom::State::kEditable);
- input_text_data2.AddStringAttribute(ax::mojom::StringAttribute::kPlaceholder,
- "placeholder2");
- input_text_data2.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- input_text_data2.AddIntAttribute(ax::mojom::IntAttribute::kColor,
- 0xDEADC0DEU);
- input_text_data2.AddBoolAttribute(ax::mojom::BoolAttribute::kEditableRoot,
- true);
- input_text_data2.SetName("foo");
- input_text_data2.child_ids = {15};
-
- ui::AXNodeData placeholder_text_data2;
- placeholder_text_data2.id = 15;
- placeholder_text_data2.role = ax::mojom::Role::kStaticText;
- placeholder_text_data2.AddIntAttribute(
- ax::mojom::IntAttribute::kBackgroundColor, 0xDEADBEEFU);
- placeholder_text_data2.AddIntAttribute(ax::mojom::IntAttribute::kColor,
- 0xDEADC0DEU);
- placeholder_text_data2.SetName("placeholder2");
-
- ui::AXNodeData link_data;
- link_data.id = 16;
- link_data.role = ax::mojom::Role::kLink;
- link_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- link_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU);
-
- ui::AXNodeData link_text_data;
- link_text_data.id = 17;
- link_text_data.role = ax::mojom::Role::kStaticText;
- link_text_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor,
- 0xDEADBEEFU);
- link_text_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU);
- link_data.child_ids = {17};
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.child_ids = {2, 3, 5, 7, 12, 14, 16};
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes.push_back(root_data);
- update.nodes.push_back(text_data);
- update.nodes.push_back(heading_data);
- update.nodes.push_back(heading_text_data);
- update.nodes.push_back(mark_data);
- update.nodes.push_back(mark_text_data);
- update.nodes.push_back(list_data);
- update.nodes.push_back(list_item_data);
- update.nodes.push_back(list_item_text_data);
- update.nodes.push_back(list_item2_data);
- update.nodes.push_back(list_item2_text_data);
- update.nodes.push_back(input_text_data);
- update.nodes.push_back(placeholder_text_data);
- update.nodes.push_back(input_text_data2);
- update.nodes.push_back(placeholder_text_data2);
- update.nodes.push_back(link_data);
- update.nodes.push_back(link_text_data);
-
- Init(update);
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* text_node = root_node->children()[0];
- AXNode* heading_node = root_node->children()[1];
- AXNode* heading_text_node = heading_node->children()[0];
- AXNode* mark_node = root_node->children()[2];
- AXNode* mark_text_node = mark_node->children()[0];
- AXNode* list_node = root_node->children()[3];
- AXNode* list_item_node = list_node->children()[0];
- AXNode* list_item_text_node = list_item_node->children()[0];
- AXNode* list_item2_node = list_node->children()[1];
- AXNode* list_item2_text_node = list_item2_node->children()[0];
- AXNode* input_text_node = root_node->children()[4];
- AXNode* placeholder_text_node = input_text_node->children()[0];
- AXNode* input_text_node2 = root_node->children()[5];
- AXNode* placeholder_text_node2 = input_text_node2->children()[0];
- AXNode* link_node = root_node->children()[6];
- AXNode* link_text_node = link_node->children()[0];
-
- ComPtr<ITextRangeProvider> document_range_provider;
- GetTextRangeProviderFromTextNode(document_range_provider, root_node);
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider, text_node);
- ComPtr<ITextRangeProvider> heading_text_range_provider;
- GetTextRangeProviderFromTextNode(heading_text_range_provider,
- heading_text_node);
- ComPtr<ITextRangeProvider> mark_text_range_provider;
- GetTextRangeProviderFromTextNode(mark_text_range_provider, mark_text_node);
- ComPtr<ITextRangeProvider> list_item_text_range_provider;
- GetTextRangeProviderFromTextNode(list_item_text_range_provider,
- list_item_text_node);
- ComPtr<ITextRangeProvider> list_item2_text_range_provider;
- GetTextRangeProviderFromTextNode(list_item2_text_range_provider,
- list_item2_text_node);
-
- ComPtr<ITextRangeProvider> placeholder_text_range_provider;
- GetTextRangeProviderFromTextNode(placeholder_text_range_provider,
- placeholder_text_node);
-
- ComPtr<ITextRangeProvider> placeholder_text_range_provider2;
- GetTextRangeProviderFromTextNode(placeholder_text_range_provider2,
- placeholder_text_node2);
-
- ComPtr<ITextRangeProvider> link_text_range_provider;
- GetTextRangeProviderFromTextNode(link_text_range_provider, link_text_node);
-
- base::win::ScopedVariant expected_variant;
-
- // SkColor is ARGB, COLORREF is 0BGR
- expected_variant.Set(static_cast<int32_t>(0x00EFBEADU));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider,
- UIA_BackgroundColorAttributeId, expected_variant);
- // Important: all nodes need to have the kColor and kBackgroundColor attribute
- // set for this test, otherwise the following assert will fail.
- EXPECT_UIA_TEXTATTRIBUTE_EQ(document_range_provider,
- UIA_BackgroundColorAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(static_cast<int32_t>(BulletStyle::BulletStyle_None));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(list_item_text_range_provider,
- UIA_BulletStyleAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(
- static_cast<int32_t>(BulletStyle::BulletStyle_FilledRoundBullet));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(list_item2_text_range_provider,
- UIA_BulletStyleAttributeId, expected_variant);
- expected_variant.Reset();
-
- {
- base::win::ScopedVariant lang_variant;
- EXPECT_HRESULT_SUCCEEDED(text_range_provider->GetAttributeValue(
- UIA_CultureAttributeId, lang_variant.Receive()));
-
- EXPECT_EQ(lang_variant.type(), VT_I4);
- const LCID lcid = V_I4(lang_variant.ptr());
- EXPECT_EQ(LANG_FRENCH, PRIMARYLANGID(lcid));
- EXPECT_EQ(SUBLANG_FRENCH_CANADIAN, SUBLANGID(lcid));
- EXPECT_EQ(SORT_DEFAULT, SORTIDFROMLCID(lcid));
- }
-
- base::string16 font_name = base::UTF8ToUTF16("sans");
- expected_variant.Set(SysAllocString(font_name.c_str()));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_FontNameAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(12.0);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_FontSizeAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(300);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_FontWeightAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- // SkColor is ARGB, COLORREF is 0BGR
- expected_variant.Set(static_cast<int32_t>(0x00DEC0ADU));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider,
- UIA_ForegroundColorAttributeId, expected_variant);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(document_range_provider,
- UIA_ForegroundColorAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(false);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_IsHiddenAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- EXPECT_UIA_TEXTATTRIBUTE_MIXED(document_range_provider,
- UIA_IsHiddenAttributeId);
-
- expected_variant.Set(true);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_IsItalicAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(false);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(heading_text_range_provider,
- UIA_IsItalicAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(true);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_IsReadOnlyAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(false);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(heading_text_range_provider,
- UIA_IsReadOnlyAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(false);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(placeholder_text_range_provider,
- UIA_IsReadOnlyAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(false);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(placeholder_text_range_provider2,
- UIA_IsReadOnlyAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(true);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(link_text_range_provider,
- UIA_IsReadOnlyAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(HorizontalTextAlignment_Centered);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider,
- UIA_HorizontalTextAlignmentAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(HorizontalTextAlignment_Justified);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(heading_text_range_provider,
- UIA_HorizontalTextAlignmentAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(true);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_IsSubscriptAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(false);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(heading_text_range_provider,
- UIA_IsSubscriptAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(false);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_IsSuperscriptAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(true);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(heading_text_range_provider,
- UIA_IsSuperscriptAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(TextDecorationLineStyle::TextDecorationLineStyle_Dot);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_OverlineStyleAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(TextDecorationLineStyle::TextDecorationLineStyle_Dash);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(
- text_range_provider, UIA_StrikethroughStyleAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(TextDecorationLineStyle::TextDecorationLineStyle_Single);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider,
- UIA_UnderlineStyleAttributeId, expected_variant);
- expected_variant.Reset();
-
- base::string16 style_name = base::UTF8ToUTF16("");
- expected_variant.Set(SysAllocString(style_name.c_str()));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider, UIA_StyleNameAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(static_cast<int32_t>(StyleId_Heading6));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(heading_text_range_provider,
- UIA_StyleIdAttributeId, expected_variant);
- expected_variant.Reset();
-
- style_name = base::UTF8ToUTF16("mark");
- expected_variant.Set(SysAllocString(style_name.c_str()));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(mark_text_range_provider,
- UIA_StyleNameAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(static_cast<int32_t>(StyleId_NumberedList));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(list_item_text_range_provider,
- UIA_StyleIdAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(static_cast<int32_t>(StyleId_BulletedList));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(list_item2_text_range_provider,
- UIA_StyleIdAttributeId, expected_variant);
- expected_variant.Reset();
-
- expected_variant.Set(
- static_cast<int32_t>(FlowDirections::FlowDirections_RightToLeft));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(
- text_range_provider, UIA_TextFlowDirectionsAttributeId, expected_variant);
- EXPECT_UIA_TEXTATTRIBUTE_MIXED(document_range_provider,
- UIA_TextFlowDirectionsAttributeId);
- expected_variant.Reset();
-
- // Move the start endpoint back and forth one character to force such endpoint
- // to be located at the end of the previous anchor, this shouldn't cause
- // GetAttributeValue to include the previous anchor's attributes.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(mark_text_range_provider,
- TextPatternRangeEndpoint_Start,
- TextUnit_Character,
- /*count*/ -1,
- /*expected_text*/ L"tmarked text",
- /*expected_count*/ -1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(mark_text_range_provider,
- TextPatternRangeEndpoint_Start,
- TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/ L"marked text",
- /*expected_count*/ 1);
- expected_variant.Set(false);
- EXPECT_UIA_TEXTATTRIBUTE_EQ(mark_text_range_provider,
- UIA_IsSuperscriptAttributeId, expected_variant);
- expected_variant.Reset();
-
- // Same idea as above, but moving forth and back the end endpoint to force it
- // to be located at the start of the next anchor.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(mark_text_range_provider,
- TextPatternRangeEndpoint_End,
- TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/ L"marked textl",
- /*expected_count*/ 1);
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(mark_text_range_provider,
- TextPatternRangeEndpoint_End,
- TextUnit_Character,
- /*count*/ -1,
- /*expected_text*/ L"marked text",
- /*expected_count*/ -1);
- expected_variant.Set(
- static_cast<int32_t>(FlowDirections::FlowDirections_RightToLeft));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(mark_text_range_provider,
- UIA_TextFlowDirectionsAttributeId,
- expected_variant);
- expected_variant.Reset();
-
- {
- // |text_node| has a grammar error on the entire text, and a spelling error
- // for one word, so the range has mixed annotations.
- EXPECT_UIA_TEXTATTRIBUTE_MIXED(text_range_provider,
- UIA_AnnotationTypesAttributeId);
-
- // start: TextPosition, anchor_id=2, text_offset=5,
- // annotated_text=some <t>ext
- // end : TextPosition, anchor_id=2, text_offset=9,
- // annotated_text=some text<>
- AXPlatformNodeWin* owner =
- static_cast<AXPlatformNodeWin*>(AXPlatformNodeFromNode(text_node));
- ComPtr<AXPlatformNodeTextRangeProviderWin> range_with_annotations;
- CreateTextRangeProviderWin(
- range_with_annotations, owner, tree_data.tree_id,
- /*start_anchor_id=*/text_node->id(), /*start_offset=*/5,
- /*start_affinity*/ ax::mojom::TextAffinity::kDownstream,
- /*end_anchor_id=*/text_node->id(), /*end_offset=*/9,
- /*end_affinity*/ ax::mojom::TextAffinity::kDownstream);
-
- base::win::ScopedVariant annotation_types_variant;
- EXPECT_HRESULT_SUCCEEDED(range_with_annotations->GetAttributeValue(
- UIA_AnnotationTypesAttributeId, annotation_types_variant.Receive()));
-
- EXPECT_EQ(annotation_types_variant.type(), VT_ARRAY | VT_I4);
- std::vector<int> expected_annotations = {AnnotationType_SpellingError,
- AnnotationType_GrammarError};
- EXPECT_UIA_SAFEARRAY_EQ(V_ARRAY(annotation_types_variant.ptr()),
- expected_annotations);
- }
-
- {
- // |heading_text_node| has a a spelling error for one word, and no
- // annotations for the remaining text, so the range has mixed annotations.
- EXPECT_UIA_TEXTATTRIBUTE_MIXED(heading_text_range_provider,
- UIA_AnnotationTypesAttributeId);
-
- // start: TextPosition, anchor_id=4, text_offset=5,
- // annotated_text=more <t>ext
- // end : TextPosition, anchor_id=4, text_offset=9,
- // annotated_text=more text<>
- AXPlatformNodeWin* owner = static_cast<AXPlatformNodeWin*>(
- AXPlatformNodeFromNode(heading_text_node));
- ComPtr<AXPlatformNodeTextRangeProviderWin> range_with_annotations;
- CreateTextRangeProviderWin(
- range_with_annotations, owner, tree_data.tree_id,
- /*start_anchor_id=*/heading_text_node->id(), /*start_offset=*/5,
- /*start_affinity*/ ax::mojom::TextAffinity::kDownstream,
- /*end_anchor_id=*/heading_text_node->id(), /*end_offset=*/9,
- /*end_affinity*/ ax::mojom::TextAffinity::kDownstream);
-
- base::win::ScopedVariant annotation_types_variant;
- EXPECT_HRESULT_SUCCEEDED(range_with_annotations->GetAttributeValue(
- UIA_AnnotationTypesAttributeId, annotation_types_variant.Receive()));
-
- std::vector<int> expected_annotations = {AnnotationType_SpellingError};
- EXPECT_UIA_SAFEARRAY_EQ(V_ARRAY(annotation_types_variant.ptr()),
- expected_annotations);
- }
-
- {
- base::win::ScopedVariant empty_variant;
- EXPECT_UIA_TEXTATTRIBUTE_EQ(mark_text_range_provider,
- UIA_AnnotationTypesAttributeId, empty_variant);
- }
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderGetAttributeValueNotSupported) {
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
-
- ui::AXNodeData text_data_first;
- text_data_first.id = 2;
- text_data_first.role = ax::mojom::Role::kStaticText;
- text_data_first.SetName("first");
- root_data.child_ids.push_back(text_data_first.id);
-
- ui::AXNodeData text_data_second;
- text_data_second.id = 3;
- text_data_second.role = ax::mojom::Role::kStaticText;
- text_data_second.SetName("second");
- root_data.child_ids.push_back(text_data_second.id);
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes.push_back(root_data);
- update.nodes.push_back(text_data_first);
- update.nodes.push_back(text_data_second);
-
- Init(update);
-
- ComPtr<ITextRangeProvider> document_range_provider;
- GetTextRangeProviderFromTextNode(document_range_provider, GetRootAsAXNode());
-
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_AfterParagraphSpacingAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_AnimationStyleAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_AnnotationObjectsAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_BeforeParagraphSpacingAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_CapStyleAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_CaretBidiModeAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_CaretPositionAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_IndentationFirstLineAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_IndentationLeadingAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_IndentationTrailingAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_IsActiveAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_LineSpacingAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_LinkAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_MarginBottomAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_MarginLeadingAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_MarginTopAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_MarginTrailingAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_OutlineStylesAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_OverlineColorAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_SelectionActiveEndAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_StrikethroughColorAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_TabsAttributeId);
- EXPECT_UIA_TEXTATTRIBUTE_NOTSUPPORTED(document_range_provider,
- UIA_UnderlineColorAttributeId);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderGetAttributeValueWithAncestorTextPosition) {
- ui::AXTreeUpdate initial_state;
- ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
- initial_state.tree_data.tree_id = tree_id;
- initial_state.has_tree_data = true;
- initial_state.root_id = 1;
- initial_state.nodes.resize(5);
- initial_state.nodes[0].id = 1;
- initial_state.nodes[0].child_ids = {2};
- initial_state.nodes[0].role = ax::mojom::Role::kRootWebArea;
- initial_state.nodes[1].id = 2;
- initial_state.nodes[1].child_ids = {3};
- initial_state.nodes[1].role = ax::mojom::Role::kGenericContainer;
- initial_state.nodes[2].id = 3;
- initial_state.nodes[2].child_ids = {4, 5};
- initial_state.nodes[2].role = ax::mojom::Role::kGenericContainer;
- initial_state.nodes[3].id = 4;
- initial_state.nodes[3].role = ax::mojom::Role::kStaticText;
- initial_state.nodes[3].SetName("some text");
- initial_state.nodes[3].AddIntAttribute(
- ax::mojom::IntAttribute::kBackgroundColor, 0xDEADBEEFU);
- initial_state.nodes[4].id = 5;
- initial_state.nodes[4].role = ax::mojom::Role::kStaticText;
- initial_state.nodes[4].SetName("more text");
- initial_state.nodes[4].AddIntAttribute(
- ax::mojom::IntAttribute::kBackgroundColor, 0xDEADBEEFU);
-
- Init(initial_state);
-
- // Making |owner| AXID:2 so that |TestAXNodeWrapper::BuildAllWrappers|
- // will build the entire subtree, and not only AXID:3 for example.
- AXPlatformNodeWin* owner = static_cast<AXPlatformNodeWin*>(
- AXPlatformNodeFromNode(GetNodeFromTree(tree_id, 2)));
-
- // start: TextPosition, anchor_id=4, text_offset=0, annotated_text=<s>ome text
- // end : TextPosition, anchor_id=2, text_offset=17,
- // annotated_text=some textmore tex<t>
- ComPtr<AXPlatformNodeTextRangeProviderWin> text_range_provider_win;
- CreateTextRangeProviderWin(
- text_range_provider_win, owner, tree_id,
- /*start_anchor_id=*/4, /*start_offset=*/0,
- /*start_affinity*/ ax::mojom::TextAffinity::kDownstream,
- /*end_anchor_id=*/2, /*end_offset=*/17,
- /*end_affinity*/ ax::mojom::TextAffinity::kDownstream);
-
- ASSERT_TRUE(GetStart(text_range_provider_win.Get())->IsTextPosition());
- ASSERT_EQ(4, GetStart(text_range_provider_win.Get())->anchor_id());
- ASSERT_EQ(0, GetStart(text_range_provider_win.Get())->text_offset());
- ASSERT_TRUE(GetEnd(text_range_provider_win.Get())->IsTextPosition());
- ASSERT_EQ(2, GetEnd(text_range_provider_win.Get())->anchor_id());
- ASSERT_EQ(17, GetEnd(text_range_provider_win.Get())->text_offset());
-
- base::win::ScopedVariant expected_variant;
- // SkColor is ARGB, COLORREF is 0BGR
- expected_variant.Set(static_cast<int32_t>(0x00EFBEADU));
- EXPECT_UIA_TEXTATTRIBUTE_EQ(text_range_provider_win,
- UIA_BackgroundColorAttributeId, expected_variant);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderSelect) {
- Init(BuildTextDocument({"some text", "more text2"}));
- AXNode* root_node = GetRootAsAXNode();
-
- // Text range for the document, which contains text "some textmore text2".
- ComPtr<IRawElementProviderSimple> root_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(root_node);
- ComPtr<ITextProvider> document_provider;
- ComPtr<ITextRangeProvider> document_text_range_provider;
- ComPtr<AXPlatformNodeTextRangeProviderWin> document_text_range;
- EXPECT_HRESULT_SUCCEEDED(
- root_node_raw->GetPatternProvider(UIA_TextPatternId, &document_provider));
- EXPECT_HRESULT_SUCCEEDED(
- document_provider->get_DocumentRange(&document_text_range_provider));
- document_text_range_provider->QueryInterface(
- IID_PPV_ARGS(&document_text_range));
-
- // Text range related to "some text".
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider,
- root_node->children()[0]);
- ComPtr<AXPlatformNodeTextRangeProviderWin> text_range;
- text_range_provider->QueryInterface(IID_PPV_ARGS(&text_range));
-
- // Text range related to "more text2".
- ComPtr<ITextRangeProvider> more_text_range_provider;
- GetTextRangeProviderFromTextNode(more_text_range_provider,
- root_node->children()[1]);
- ComPtr<AXPlatformNodeTextRangeProviderWin> more_text_range;
- more_text_range_provider->QueryInterface(IID_PPV_ARGS(&more_text_range));
-
- AXPlatformNodeDelegate* delegate =
- GetOwner(document_text_range.Get())->GetDelegate();
-
- ComPtr<ITextRangeProvider> selected_text_range_provider;
- base::win::ScopedSafearray selection;
- LONG index = 0;
- LONG ubound;
- LONG lbound;
-
- // Text range "some text" performs select.
- {
- text_range_provider->Select();
-
- // Verify selection.
- AXTree::Selection unignored_selection = delegate->GetUnignoredSelection();
- EXPECT_EQ(2, unignored_selection.anchor_object_id);
- EXPECT_EQ(2, unignored_selection.focus_object_id);
- EXPECT_EQ(0, unignored_selection.anchor_offset);
- EXPECT_EQ(9, unignored_selection.focus_offset);
-
- // Verify the content of the selection.
- document_provider->GetSelection(selection.Receive());
- ASSERT_NE(nullptr, selection.Get());
-
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetUBound(selection.Get(), 1, &ubound));
- EXPECT_EQ(0, ubound);
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetLBound(selection.Get(), 1, &lbound));
- EXPECT_EQ(0, lbound);
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetElement(
- selection.Get(), &index,
- static_cast<void**>(&selected_text_range_provider)));
- EXPECT_UIA_TEXTRANGE_EQ(selected_text_range_provider, L"some text");
-
- selected_text_range_provider.Reset();
- selection.Reset();
- }
-
- // Text range "more text2" performs select.
- {
- more_text_range_provider->Select();
-
- // Verify selection
- AXTree::Selection unignored_selection = delegate->GetUnignoredSelection();
- EXPECT_EQ(3, unignored_selection.anchor_object_id);
- EXPECT_EQ(3, unignored_selection.focus_object_id);
- EXPECT_EQ(0, unignored_selection.anchor_offset);
- EXPECT_EQ(10, unignored_selection.focus_offset);
-
- // Verify the content of the selection.
- document_provider->GetSelection(selection.Receive());
- ASSERT_NE(nullptr, selection.Get());
-
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetUBound(selection.Get(), 1, &ubound));
- EXPECT_EQ(0, ubound);
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetLBound(selection.Get(), 1, &lbound));
- EXPECT_EQ(0, lbound);
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetElement(
- selection.Get(), &index,
- static_cast<void**>(&selected_text_range_provider)));
- EXPECT_UIA_TEXTRANGE_EQ(selected_text_range_provider, L"more text2");
-
- selected_text_range_provider.Reset();
- selection.Reset();
- }
-
- // Document text range "some textmore text2" performs select.
- {
- document_text_range_provider->Select();
-
- // Verify selection.
- AXTree::Selection unignored_selection = delegate->GetUnignoredSelection();
- EXPECT_EQ(2, unignored_selection.anchor_object_id);
- EXPECT_EQ(3, unignored_selection.focus_object_id);
- EXPECT_EQ(0, unignored_selection.anchor_offset);
- EXPECT_EQ(10, unignored_selection.focus_offset);
-
- // Verify the content of the selection.
- document_provider->GetSelection(selection.Receive());
- ASSERT_NE(nullptr, selection.Get());
-
- document_provider->GetSelection(selection.Receive());
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetUBound(selection.Get(), 1, &ubound));
- EXPECT_EQ(0, ubound);
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetLBound(selection.Get(), 1, &lbound));
- EXPECT_EQ(0, lbound);
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetElement(
- selection.Get(), &index,
- static_cast<void**>(&selected_text_range_provider)));
- EXPECT_UIA_TEXTRANGE_EQ(selected_text_range_provider,
- L"some textmore text2");
- }
-
- // A degenerate text range performs select.
- {
- // Move the endpoint of text range so it becomes degenerate, then select.
- text_range_provider->MoveEndpointByRange(TextPatternRangeEndpoint_Start,
- text_range_provider.Get(),
- TextPatternRangeEndpoint_End);
- text_range_provider->Select();
-
- // Verify selection.
- AXTree::Selection unignored_selection = delegate->GetUnignoredSelection();
- EXPECT_EQ(2, unignored_selection.anchor_object_id);
- EXPECT_EQ(2, unignored_selection.focus_object_id);
- EXPECT_EQ(9, unignored_selection.anchor_offset);
- EXPECT_EQ(9, unignored_selection.focus_offset);
-
- // Verify selection on degenerate range.
- document_provider->GetSelection(selection.Receive());
- ASSERT_NE(nullptr, selection.Get());
-
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetUBound(selection.Get(), 1, &ubound));
- EXPECT_EQ(0, ubound);
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetLBound(selection.Get(), 1, &lbound));
- EXPECT_EQ(0, lbound);
- EXPECT_HRESULT_SUCCEEDED(SafeArrayGetElement(
- selection.Get(), &index,
- static_cast<void**>(&selected_text_range_provider)));
- EXPECT_UIA_TEXTRANGE_EQ(selected_text_range_provider, L"");
-
- selected_text_range_provider.Reset();
- selection.Reset();
- }
-}
-
-// TODO(crbug.com/1124051): Remove this test once this crbug is fixed.
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderSelectListMarker) {
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
-
- ui::AXNodeData list_data;
- list_data.id = 2;
- list_data.role = ax::mojom::Role::kList;
- root_data.child_ids.push_back(list_data.id);
-
- ui::AXNodeData list_item_data;
- list_item_data.id = 3;
- list_item_data.role = ax::mojom::Role::kListItem;
- list_data.child_ids.push_back(list_item_data.id);
-
- ui::AXNodeData list_marker;
- list_marker.id = 4;
- list_marker.role = ax::mojom::Role::kListMarker;
- list_item_data.child_ids.push_back(list_marker.id);
-
- ui::AXNodeData static_text_data;
- static_text_data.id = 5;
- static_text_data.role = ax::mojom::Role::kStaticText;
- static_text_data.SetName("1. ");
- list_marker.child_ids.push_back(static_text_data.id);
-
- ui::AXNodeData list_item_text_data;
- list_item_text_data.id = 6;
- list_item_text_data.role = ax::mojom::Role::kStaticText;
- list_item_text_data.SetName("First Item");
- list_item_data.child_ids.push_back(list_item_text_data.id);
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes = {root_data, list_data, list_item_data,
- list_marker, static_text_data, list_item_text_data};
- Init(update);
- AXNode* root_node = GetRootAsAXNode();
-
- // Text range related to "1. ".
- AXNode* list_node = root_node->children()[0];
- AXNode* list_item_node = list_node->children()[0];
- AXNode* list_marker_node = list_item_node->children()[0];
- ComPtr<ITextRangeProvider> list_marker_text_range_provider;
- GetTextRangeProviderFromTextNode(list_marker_text_range_provider,
- list_marker_node->children()[0]);
-
- // A list marker text range performs select.
- EXPECT_HRESULT_SUCCEEDED(list_marker_text_range_provider->Select());
-
- // Verify selection was not performed on list marker range.
- base::win::ScopedSafearray selection;
- ComPtr<IRawElementProviderSimple> root_node_raw =
- QueryInterfaceFromNode<IRawElementProviderSimple>(root_node);
- ComPtr<ITextProvider> document_provider;
- EXPECT_HRESULT_SUCCEEDED(
- root_node_raw->GetPatternProvider(UIA_TextPatternId, &document_provider));
- EXPECT_HRESULT_SUCCEEDED(
- document_provider->GetSelection(selection.Receive()));
- ASSERT_EQ(nullptr, selection.Get());
- selection.Reset();
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderFindText) {
- Init(BuildTextDocument({"some text", "more text"}));
-
- AXNode* root_node = GetRootAsAXNode();
- ComPtr<ITextRangeProvider> range;
-
- // Test Leaf kStaticText search.
- GetTextRangeProviderFromTextNode(range, root_node->children()[0]);
- EXPECT_UIA_FIND_TEXT(range, L"some text", false);
- EXPECT_UIA_FIND_TEXT(range, L"SoMe TeXt", true);
- GetTextRangeProviderFromTextNode(range, root_node->children()[1]);
- EXPECT_UIA_FIND_TEXT(range, L"more", false);
- EXPECT_UIA_FIND_TEXT(range, L"MoRe", true);
-
- // Test searching for leaf content from ancestor.
- GetTextRangeProviderFromTextNode(range, root_node);
- EXPECT_UIA_FIND_TEXT(range, L"some text", false);
- EXPECT_UIA_FIND_TEXT(range, L"SoMe TeXt", true);
- EXPECT_UIA_FIND_TEXT(range, L"more text", false);
- EXPECT_UIA_FIND_TEXT(range, L"MoRe TeXt", true);
- EXPECT_UIA_FIND_TEXT(range, L"more", false);
- // Test finding text that crosses a node boundary.
- EXPECT_UIA_FIND_TEXT(range, L"textmore", false);
- // Test no match.
- EXPECT_UIA_FIND_TEXT_NO_MATCH(range, L"no match", false);
-
- // Test if range returned is in expected anchor node.
- GetTextRangeProviderFromTextNode(range, root_node->children()[1]);
- base::win::ScopedBstr find_string(L"more text");
- Microsoft::WRL::ComPtr<ITextRangeProvider> text_range_provider_found;
- EXPECT_HRESULT_SUCCEEDED(range->FindText(find_string.Get(), false, false,
- &text_range_provider_found));
- Microsoft::WRL::ComPtr<AXPlatformNodeTextRangeProviderWin>
- text_range_provider_win;
- text_range_provider_found->QueryInterface(
- IID_PPV_ARGS(&text_range_provider_win));
- ASSERT_TRUE(GetStart(text_range_provider_win.Get())->IsTextPosition());
- ASSERT_EQ(3, GetStart(text_range_provider_win.Get())->anchor_id());
- ASSERT_EQ(0, GetStart(text_range_provider_win.Get())->text_offset());
- ASSERT_TRUE(GetEnd(text_range_provider_win.Get())->IsTextPosition());
- ASSERT_EQ(3, GetEnd(text_range_provider_win.Get())->anchor_id());
- ASSERT_EQ(9, GetEnd(text_range_provider_win.Get())->text_offset());
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderFindTextBackwards) {
- Init(BuildTextDocument({"text", "some", "text"}));
- AXNode* root_node = GetRootAsAXNode();
-
- ComPtr<ITextRangeProvider> root_range_provider;
- GetTextRangeProviderFromTextNode(root_range_provider, root_node);
- ComPtr<ITextRangeProvider> text_node1_range;
- GetTextRangeProviderFromTextNode(text_node1_range, root_node->children()[0]);
- ComPtr<ITextRangeProvider> text_node3_range;
- GetTextRangeProviderFromTextNode(text_node3_range, root_node->children()[2]);
-
- ComPtr<ITextRangeProvider> text_range_provider_found;
- base::win::ScopedBstr find_string(L"text");
- BOOL range_equal;
-
- // Forward search finds the text_node1
- EXPECT_HRESULT_SUCCEEDED(root_range_provider->FindText(
- find_string.Get(), false, false, &text_range_provider_found));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider_found, find_string.Get());
-
- range_equal = false;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider_found->Compare(text_node1_range.Get(), &range_equal));
- EXPECT_TRUE(range_equal);
-
- // Backwards search finds the text_node3
- EXPECT_HRESULT_SUCCEEDED(root_range_provider->FindText(
- find_string.Get(), true, false, &text_range_provider_found));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider_found, find_string.Get());
-
- range_equal = false;
- EXPECT_HRESULT_SUCCEEDED(
- text_range_provider_found->Compare(text_node3_range.Get(), &range_equal));
- EXPECT_TRUE(range_equal);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderFindAttribute) {
- // document - visible
- // [empty]
- //
- // Search forward, look for IsHidden=true.
- // Expected: nullptr
- // Search forward, look for IsHidden=false.
- // Expected: ""
- // Note: returns "" rather than nullptr here because document root web area by
- // default set to visible. So the text range represents document matches
- // our searching criteria. And we return a degenerate range.
- //
- // Search backward, look for IsHidden=true.
- // Expected: nullptr
- // Search backward, look for IsHidden=false.
- // Expected: ""
- // Note: returns "" rather than nullptr here because document root web area by
- // default set to visible. So the text range represents document matches
- // our searching criteria. And we return a degenerate range.
- {
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
-
- ui::AXTreeUpdate update;
- update.tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes = {root_data};
-
- Init(update);
-
- bool is_search_backward;
- VARIANT is_hidden_attr_val;
- V_VT(&is_hidden_attr_val) = VT_BOOL;
- ComPtr<ITextRangeProvider> matched_range_provider;
- ComPtr<ITextRangeProvider> document_range_provider;
- GetTextRangeProviderFromTextNode(document_range_provider,
- GetRootAsAXNode());
-
- // Search forward, look for IsHidden=true.
- // Expected: nullptr
- V_BOOL(&is_hidden_attr_val) = VARIANT_TRUE;
- is_search_backward = false;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_EQ(nullptr, matched_range_provider.Get());
-
- // Search forward, look for IsHidden=false.
- // Expected: ""
- // Note: returns "" rather than nullptr here because document root web area
- // by default set to visible. So the text range represents document
- // matches our searching criteria. And we return a degenerate range.
- V_BOOL(&is_hidden_attr_val) = VARIANT_FALSE;
- is_search_backward = false;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"");
- matched_range_provider.Reset();
-
- // Search backward, look for IsHidden=true.
- // Expected: nullptr
- V_BOOL(&is_hidden_attr_val) = VARIANT_TRUE;
- is_search_backward = true;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_EQ(nullptr, matched_range_provider.Get());
-
- // Search backward, look for IsHidden=false.
- // Expected: ""
- // Note: returns "" rather than nullptr here because document root web area
- // by default set to visible. So the text range represents document
- // matches our searching criteria. And we return a degenerate range.
- V_BOOL(&is_hidden_attr_val) = VARIANT_FALSE;
- is_search_backward = true;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"");
- }
-
- // document - visible
- // text1 - invisible
- //
- // Search forward, look for IsHidden=true.
- // Expected: "text1"
- // Search forward, look for IsHidden=false.
- // Expected: nullptr
- // Search backward, look for IsHidden=true.
- // Expected: "text1"
- // Search backward, look for IsHidden=false.
- // Expected: nullptr
- {
- ui::AXNodeData text_data1;
- text_data1.id = 2;
- text_data1.role = ax::mojom::Role::kStaticText;
- text_data1.AddState(ax::mojom::State::kInvisible);
- text_data1.SetName("text1");
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.child_ids = {2};
-
- ui::AXTreeUpdate update;
- update.tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes = {root_data, text_data1};
-
- Init(update);
-
- bool is_search_backward;
- VARIANT is_hidden_attr_val;
- V_VT(&is_hidden_attr_val) = VT_BOOL;
- ComPtr<ITextRangeProvider> matched_range_provider;
- ComPtr<ITextRangeProvider> document_range_provider;
- GetTextRangeProviderFromTextNode(document_range_provider,
- GetRootAsAXNode());
-
- // Search forward, look for IsHidden=true.
- // Expected: "text1"
- V_BOOL(&is_hidden_attr_val) = VARIANT_TRUE;
- is_search_backward = false;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"text1");
- matched_range_provider.Reset();
-
- // Search forward, look for IsHidden=false.
- // Expected: nullptr
- V_BOOL(&is_hidden_attr_val) = VARIANT_FALSE;
- is_search_backward = false;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_EQ(nullptr, matched_range_provider.Get());
-
- // Search backward, look for IsHidden=true.
- // Expected: "text1"
- V_BOOL(&is_hidden_attr_val) = VARIANT_TRUE;
- is_search_backward = true;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"text1");
- matched_range_provider.Reset();
-
- // Search backward, look for IsHidden=false.
- // Expected: nullptr
- V_BOOL(&is_hidden_attr_val) = VARIANT_FALSE;
- is_search_backward = true;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_EQ(nullptr, matched_range_provider.Get());
- }
-
- // document - visible
- // text1 - visible
- // text2 - visible
- //
- // Search forward, look for IsHidden=true.
- // Expected: nullptr
- // Search forward, look for IsHidden=false.
- // Expected: "text1text2"
- // Search backward, look for IsHidden=true.
- // Expected: nullptr
- // Search backward, look for IsHidden=false.
- // Expected: "text1text2"
- {
- ui::AXNodeData text_data1;
- text_data1.id = 2;
- text_data1.role = ax::mojom::Role::kStaticText;
- text_data1.SetName("text1");
-
- ui::AXNodeData text_data2;
- text_data2.id = 3;
- text_data2.role = ax::mojom::Role::kStaticText;
- text_data2.SetName("text2");
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.child_ids = {2, 3};
-
- ui::AXTreeUpdate update;
- update.tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes = {root_data, text_data1, text_data2};
-
- Init(update);
-
- bool is_search_backward;
- VARIANT is_hidden_attr_val;
- V_VT(&is_hidden_attr_val) = VT_BOOL;
- ComPtr<ITextRangeProvider> matched_range_provider;
- ComPtr<ITextRangeProvider> document_range_provider;
- GetTextRangeProviderFromTextNode(document_range_provider,
- GetRootAsAXNode());
-
- // Search forward, look for IsHidden=true.
- // Expected: nullptr
- V_BOOL(&is_hidden_attr_val) = VARIANT_TRUE;
- is_search_backward = false;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_EQ(nullptr, matched_range_provider.Get());
-
- // Search forward, look for IsHidden=false.
- // Expected: "text1text2"
- V_BOOL(&is_hidden_attr_val) = VARIANT_FALSE;
- is_search_backward = false;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"text1text2");
- matched_range_provider.Reset();
-
- // Search backward, look for IsHidden=true.
- // Expected: nullptr
- V_BOOL(&is_hidden_attr_val) = VARIANT_TRUE;
- is_search_backward = true;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_EQ(nullptr, matched_range_provider.Get());
-
- // Search backward, look for IsHidden=false.
- // Expected: "text1text2"
- V_BOOL(&is_hidden_attr_val) = VARIANT_FALSE;
- is_search_backward = true;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"text1text2");
- }
-
- // document - visible
- // text1 - visible
- // text2 - invisible
- // text3 - invisible
- // text4 - visible
- // text5 - invisible
- //
- // Search forward, look for IsHidden=true.
- // Expected: "text2text3"
- // Search forward, look for IsHidden=false.
- // Expected: "text1"
- // Search backward, look for IsHidden=true.
- // Expected: "text5"
- // Search backward, look for IsHidden=false.
- // Expected: "text4"
- {
- ui::AXNodeData text_data1;
- text_data1.id = 2;
- text_data1.role = ax::mojom::Role::kStaticText;
- text_data1.SetName("text1");
-
- ui::AXNodeData text_data2;
- text_data2.id = 3;
- text_data2.role = ax::mojom::Role::kStaticText;
- text_data2.AddState(ax::mojom::State::kInvisible);
- text_data2.SetName("text2");
-
- ui::AXNodeData text_data3;
- text_data3.id = 4;
- text_data3.role = ax::mojom::Role::kStaticText;
- text_data3.AddState(ax::mojom::State::kInvisible);
- text_data3.SetName("text3");
-
- ui::AXNodeData text_data4;
- text_data4.id = 5;
- text_data4.role = ax::mojom::Role::kStaticText;
- text_data4.SetName("text4");
-
- ui::AXNodeData text_data5;
- text_data5.id = 6;
- text_data5.role = ax::mojom::Role::kStaticText;
- text_data5.AddState(ax::mojom::State::kInvisible);
- text_data5.SetName("text5");
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.child_ids = {2, 3, 4, 5, 6};
-
- ui::AXTreeUpdate update;
- update.tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes = {root_data, text_data1, text_data2,
- text_data3, text_data4, text_data5};
-
- Init(update);
-
- bool is_search_backward;
- VARIANT is_hidden_attr_val;
- V_VT(&is_hidden_attr_val) = VT_BOOL;
- ComPtr<ITextRangeProvider> matched_range_provider;
- ComPtr<ITextRangeProvider> document_range_provider;
- GetTextRangeProviderFromTextNode(document_range_provider,
- GetRootAsAXNode());
-
- // Search forward, look for IsHidden=true.
- // Expected: "text2text3"
- V_BOOL(&is_hidden_attr_val) = VARIANT_TRUE;
- is_search_backward = false;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"text2text3");
- matched_range_provider.Reset();
-
- // Search forward, look for IsHidden=false.
- // Expected: "text1"
- V_BOOL(&is_hidden_attr_val) = VARIANT_FALSE;
- is_search_backward = false;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"text1");
- matched_range_provider.Reset();
-
- // Search backward, look for IsHidden=true.
- // Expected: "text5"
- V_BOOL(&is_hidden_attr_val) = VARIANT_TRUE;
- is_search_backward = true;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"text5");
- matched_range_provider.Reset();
-
- // Search backward, look for IsHidden=false.
- // Expected: "text4"
- V_BOOL(&is_hidden_attr_val) = VARIANT_FALSE;
- is_search_backward = true;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"text4");
- }
-
- // document - visible
- // text1 - visible
- // text2 - invisible
- // text3 - invisible
- // text4 - invisible
- // text5 - visible
- //
- // Search forward, look for IsHidden=true.
- // Expected: "text2text3text4"
- // Search forward, look for IsHidden=false.
- // Expected: "text1"
- // Search backward, look for IsHidden=true.
- // Expected: "text2text3text4"
- // Search backward, look for IsHidden=false.
- // Expected: "text5"
- {
- ui::AXNodeData text_data1;
- text_data1.id = 2;
- text_data1.role = ax::mojom::Role::kStaticText;
- text_data1.SetName("text1");
-
- ui::AXNodeData text_data2;
- text_data2.id = 3;
- text_data2.role = ax::mojom::Role::kStaticText;
- text_data2.AddState(ax::mojom::State::kInvisible);
- text_data2.SetName("text2");
-
- ui::AXNodeData text_data3;
- text_data3.id = 4;
- text_data3.role = ax::mojom::Role::kStaticText;
- text_data3.AddState(ax::mojom::State::kInvisible);
- text_data3.SetName("text3");
-
- ui::AXNodeData text_data4;
- text_data4.id = 5;
- text_data4.role = ax::mojom::Role::kStaticText;
- text_data4.AddState(ax::mojom::State::kInvisible);
- text_data4.SetName("text4");
-
- ui::AXNodeData text_data5;
- text_data5.id = 6;
- text_data5.role = ax::mojom::Role::kStaticText;
- text_data5.SetName("text5");
-
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
- root_data.child_ids = {2, 3, 4, 5, 6};
-
- ui::AXTreeUpdate update;
- update.tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.has_tree_data = true;
- update.root_id = root_data.id;
- update.nodes = {root_data, text_data1, text_data2,
- text_data3, text_data4, text_data5};
-
- Init(update);
-
- bool is_search_backward;
- VARIANT is_hidden_attr_val;
- V_VT(&is_hidden_attr_val) = VT_BOOL;
- ComPtr<ITextRangeProvider> matched_range_provider;
- ComPtr<ITextRangeProvider> document_range_provider;
- GetTextRangeProviderFromTextNode(document_range_provider,
- GetRootAsAXNode());
-
- // Search forward, look for IsHidden=true.
- // Expected: "text2text3text4"
- V_BOOL(&is_hidden_attr_val) = VARIANT_TRUE;
- is_search_backward = false;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"text2text3text4");
- matched_range_provider.Reset();
-
- // Search forward, look for IsHidden=false.
- // Expected: "text1"
- V_BOOL(&is_hidden_attr_val) = VARIANT_FALSE;
- is_search_backward = false;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"text1");
- matched_range_provider.Reset();
-
- // Search backward, look for IsHidden=true.
- // Expected: "text2text3text4"
- V_BOOL(&is_hidden_attr_val) = VARIANT_TRUE;
- is_search_backward = true;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"text2text3text4");
- matched_range_provider.Reset();
-
- // Search backward, look for IsHidden=false.
- // Expected: "text5"
- V_BOOL(&is_hidden_attr_val) = VARIANT_FALSE;
- is_search_backward = true;
- document_range_provider->FindAttribute(
- UIA_IsHiddenAttributeId, is_hidden_attr_val, is_search_backward,
- &matched_range_provider);
- ASSERT_NE(nullptr, matched_range_provider.Get());
- EXPECT_UIA_TEXTRANGE_EQ(matched_range_provider, L"text5");
- }
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, ElementNotAvailable) {
- AXNodeData root_ax_node_data;
- root_ax_node_data.id = 1;
- root_ax_node_data.role = ax::mojom::Role::kRootWebArea;
-
- Init(root_ax_node_data);
-
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- QueryInterfaceFromNode<IRawElementProviderSimple>(GetRootAsAXNode());
- ASSERT_NE(nullptr, raw_element_provider_simple.Get());
-
- ComPtr<ITextProvider> text_provider;
- ASSERT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_TextPatternId, &text_provider));
- ASSERT_NE(nullptr, text_provider.Get());
-
- ComPtr<ITextRangeProvider> text_range_provider;
- ASSERT_HRESULT_SUCCEEDED(
- text_provider->get_DocumentRange(&text_range_provider));
- ASSERT_NE(nullptr, text_range_provider.Get());
-
- // An empty tree.
- SetTree(std::make_unique<AXTree>());
-
- BOOL bool_arg = FALSE;
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- text_range_provider->ScrollIntoView(bool_arg));
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestITextRangeProviderIgnoredNodes) {
- // Parent Tree
- // 1
- // |
- // 2(i)
- // |________________________________
- // | | | | | |
- // 3 4 5 6 7(i) 8(i)
- // | |________
- // | | |
- // 9(i) 10(i) 11
- // | |____
- // | | |
- // 12 13 14
-
- ui::AXTreeUpdate tree_update;
- ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
- tree_update.tree_data.tree_id = tree_id;
- tree_update.has_tree_data = true;
- tree_update.root_id = 1;
- tree_update.nodes.resize(14);
- tree_update.nodes[0].id = 1;
- tree_update.nodes[0].child_ids = {2};
- tree_update.nodes[0].role = ax::mojom::Role::kRootWebArea;
-
- tree_update.nodes[1].id = 2;
- tree_update.nodes[1].child_ids = {3, 4, 5, 6, 7, 8};
- tree_update.nodes[1].AddState(ax::mojom::State::kIgnored);
- tree_update.nodes[1].role = ax::mojom::Role::kDocument;
-
- tree_update.nodes[2].id = 3;
- tree_update.nodes[2].role = ax::mojom::Role::kStaticText;
- tree_update.nodes[2].SetName(".3.");
-
- tree_update.nodes[3].id = 4;
- tree_update.nodes[3].role = ax::mojom::Role::kStaticText;
- tree_update.nodes[3].SetName(".4.");
-
- tree_update.nodes[4].id = 5;
- tree_update.nodes[4].role = ax::mojom::Role::kStaticText;
- tree_update.nodes[4].SetName(".5.");
-
- tree_update.nodes[5].id = 6;
- tree_update.nodes[5].role = ax::mojom::Role::kGenericContainer;
- tree_update.nodes[5].child_ids = {9};
-
- tree_update.nodes[6].id = 7;
- tree_update.nodes[6].child_ids = {10, 11};
- tree_update.nodes[6].AddState(ax::mojom::State::kIgnored);
- tree_update.nodes[6].role = ax::mojom::Role::kGenericContainer;
-
- tree_update.nodes[7].id = 8;
- tree_update.nodes[7].AddState(ax::mojom::State::kIgnored);
- tree_update.nodes[7].role = ax::mojom::Role::kStaticText;
- tree_update.nodes[7].SetName(".8.");
-
- tree_update.nodes[8].id = 9;
- tree_update.nodes[8].child_ids = {12};
- tree_update.nodes[8].AddState(ax::mojom::State::kIgnored);
- tree_update.nodes[8].role = ax::mojom::Role::kGenericContainer;
-
- tree_update.nodes[9].id = 10;
- tree_update.nodes[9].child_ids = {13, 14};
- tree_update.nodes[9].AddState(ax::mojom::State::kIgnored);
- tree_update.nodes[8].role = ax::mojom::Role::kGenericContainer;
-
- tree_update.nodes[10].id = 11;
- tree_update.nodes[10].role = ax::mojom::Role::kStaticText;
- tree_update.nodes[10].SetName(".11.");
-
- tree_update.nodes[11].id = 12;
- tree_update.nodes[11].role = ax::mojom::Role::kStaticText;
- tree_update.nodes[11].AddState(ax::mojom::State::kIgnored);
- tree_update.nodes[11].SetName(".12.");
-
- tree_update.nodes[12].id = 13;
- tree_update.nodes[12].role = ax::mojom::Role::kStaticText;
- tree_update.nodes[12].SetName(".13.");
-
- tree_update.nodes[13].id = 14;
- tree_update.nodes[13].role = ax::mojom::Role::kStaticText;
- tree_update.nodes[13].SetName(".14.");
-
- Init(tree_update);
- EXPECT_ENCLOSING_ELEMENT(GetNodeFromTree(tree_id, 1),
- GetNodeFromTree(tree_id, 1));
- EXPECT_ENCLOSING_ELEMENT(GetNodeFromTree(tree_id, 2),
- GetNodeFromTree(tree_id, 1));
- EXPECT_ENCLOSING_ELEMENT(GetNodeFromTree(tree_id, 3),
- GetNodeFromTree(tree_id, 3));
- EXPECT_ENCLOSING_ELEMENT(GetNodeFromTree(tree_id, 4),
- GetNodeFromTree(tree_id, 4));
- EXPECT_ENCLOSING_ELEMENT(GetNodeFromTree(tree_id, 5),
- GetNodeFromTree(tree_id, 5));
- EXPECT_ENCLOSING_ELEMENT(GetNodeFromTree(tree_id, 8),
- GetNodeFromTree(tree_id, 1));
- EXPECT_ENCLOSING_ELEMENT(GetNodeFromTree(tree_id, 11),
- GetNodeFromTree(tree_id, 11));
- EXPECT_ENCLOSING_ELEMENT(GetNodeFromTree(tree_id, 13),
- GetNodeFromTree(tree_id, 13));
- EXPECT_ENCLOSING_ELEMENT(GetNodeFromTree(tree_id, 14),
- GetNodeFromTree(tree_id, 14));
-
- // Test movement and GetText()
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider,
- GetNodeFromTree(tree_id, 1));
-
- ASSERT_HRESULT_SUCCEEDED(
- text_range_provider->ExpandToEnclosingUnit(TextUnit_Character));
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L".");
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ 2,
- /*expected_text*/ L".3.",
- /*expected_count*/ 2);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ 6,
- /*expected_text*/ L".3..4..5.",
- /*expected_count*/ 6);
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ 13,
- /*expected_text*/ L".3..4..5.\xFFFC.13..14..11.",
- /*expected_count*/ 13);
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestNormalizeTextRangePastEndOfDocument) {
- ui::AXTreeUpdate initial_state;
- ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
- initial_state.tree_data.tree_id = tree_id;
- initial_state.has_tree_data = true;
- initial_state.root_id = 1;
- initial_state.nodes.resize(3);
- initial_state.nodes[0].id = 1;
- initial_state.nodes[0].child_ids = {2};
- initial_state.nodes[0].role = ax::mojom::Role::kRootWebArea;
- initial_state.nodes[1].id = 2;
- initial_state.nodes[1].child_ids = {3};
- initial_state.nodes[1].role = ax::mojom::Role::kStaticText;
- initial_state.nodes[1].SetName("aaa");
- initial_state.nodes[2].id = 3;
- initial_state.nodes[2].role = ax::mojom::Role::kInlineTextBox;
- initial_state.nodes[2].SetName("aaa");
-
- Init(initial_state);
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider,
- GetNodeFromTree(tree_id, 3));
-
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"aaa");
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Character,
- /*count*/ 2,
- /*expected_text*/ L"a",
- /*expected_count*/ 2);
-
- ComPtr<AXPlatformNodeTextRangeProviderWin> text_range_provider_win;
- text_range_provider->QueryInterface(IID_PPV_ARGS(&text_range_provider_win));
-
- const AXNodePosition::AXPositionInstance start_after_move =
- GetStart(text_range_provider_win.Get())->Clone();
- const AXNodePosition::AXPositionInstance end_after_move =
- GetEnd(text_range_provider_win.Get())->Clone();
- EXPECT_LT(*start_after_move, *end_after_move);
-
- AXTreeUpdate update;
- update.nodes.resize(2);
- update.nodes[0] = initial_state.nodes[1];
- update.nodes[0].SetName("aa");
- update.nodes[1] = initial_state.nodes[2];
- update.nodes[1].SetName("aa");
- ASSERT_TRUE(GetTree()->Unserialize(update));
-
- NormalizeTextRange(text_range_provider_win.Get());
- EXPECT_EQ(*start_after_move, *GetStart(text_range_provider_win.Get()));
- EXPECT_EQ(*end_after_move, *GetEnd(text_range_provider_win.Get()));
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestNormalizeTextRangePastEndOfDocumentWithIgnoredNodes) {
- ui::AXTreeUpdate initial_state;
- ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
- initial_state.tree_data.tree_id = tree_id;
- initial_state.has_tree_data = true;
- initial_state.root_id = 1;
- initial_state.nodes.resize(4);
- initial_state.nodes[0].id = 1;
- initial_state.nodes[0].child_ids = {2};
- initial_state.nodes[0].role = ax::mojom::Role::kRootWebArea;
- initial_state.nodes[1].id = 2;
- initial_state.nodes[1].child_ids = {3, 4};
- initial_state.nodes[1].role = ax::mojom::Role::kStaticText;
- initial_state.nodes[1].SetName("aaa");
- initial_state.nodes[2].id = 3;
- initial_state.nodes[2].role = ax::mojom::Role::kInlineTextBox;
- initial_state.nodes[2].SetName("aaa");
- initial_state.nodes[3].id = 4;
- initial_state.nodes[3].role = ax::mojom::Role::kInlineTextBox;
- initial_state.nodes[3].AddState(ax::mojom::State::kIgnored);
- initial_state.nodes[3].SetName("ignored");
-
- Init(initial_state);
-
- ComPtr<ITextRangeProvider> text_range_provider;
- GetTextRangeProviderFromTextNode(text_range_provider,
- GetNodeFromTree(tree_id, 3));
-
- EXPECT_UIA_TEXTRANGE_EQ(text_range_provider, L"aaa");
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Character,
- /*count*/ 2,
- /*expected_text*/ L"a",
- /*expected_count*/ 2);
-
- ComPtr<AXPlatformNodeTextRangeProviderWin> text_range_provider_win;
- text_range_provider->QueryInterface(IID_PPV_ARGS(&text_range_provider_win));
-
- const AXNodePosition::AXPositionInstance start_after_move =
- GetStart(text_range_provider_win.Get())->Clone();
- const AXNodePosition::AXPositionInstance end_after_move =
- GetEnd(text_range_provider_win.Get())->Clone();
- EXPECT_LT(*start_after_move, *end_after_move);
-
- AXTreeUpdate update;
- update.nodes.resize(2);
- update.nodes[0] = initial_state.nodes[1];
- update.nodes[0].SetName("aa");
- update.nodes[1] = initial_state.nodes[2];
- update.nodes[1].SetName("aa");
- ASSERT_TRUE(GetTree()->Unserialize(update));
-
- NormalizeTextRange(text_range_provider_win.Get());
- EXPECT_EQ(*start_after_move, *GetStart(text_range_provider_win.Get()));
- EXPECT_EQ(*end_after_move, *GetEnd(text_range_provider_win.Get()));
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestNormalizeTextRangeInsideIgnoredNodes) {
- ui::AXTreeUpdate initial_state;
- ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
- initial_state.tree_data.tree_id = tree_id;
- initial_state.has_tree_data = true;
- initial_state.root_id = 1;
- initial_state.nodes.resize(4);
- initial_state.nodes[0].id = 1;
- initial_state.nodes[0].child_ids = {2, 3, 4};
- initial_state.nodes[0].role = ax::mojom::Role::kRootWebArea;
- initial_state.nodes[1].id = 2;
- initial_state.nodes[1].role = ax::mojom::Role::kStaticText;
- initial_state.nodes[1].SetName("before");
- initial_state.nodes[2].id = 3;
- initial_state.nodes[2].role = ax::mojom::Role::kStaticText;
- initial_state.nodes[2].AddState(ax::mojom::State::kIgnored);
- initial_state.nodes[2].SetName("ignored");
- initial_state.nodes[3].id = 4;
- initial_state.nodes[3].role = ax::mojom::Role::kStaticText;
- initial_state.nodes[3].SetName("after");
-
- Init(initial_state);
-
- // Making |owner| AXID:1 so that |TestAXNodeWrapper::BuildAllWrappers|
- // will build the entire tree.
- AXPlatformNodeWin* owner = static_cast<AXPlatformNodeWin*>(
- AXPlatformNodeFromNode(GetNodeFromTree(tree_id, 1)));
-
- // start: TextPosition, anchor_id=3, text_offset=1, annotated_text=i<g>nored
- // end : TextPosition, anchor_id=3, text_offset=6, annotated_text=ignore<d>
- ComPtr<AXPlatformNodeTextRangeProviderWin> ignored_range_win;
- CreateTextRangeProviderWin(
- ignored_range_win, owner, tree_id,
- /*start_anchor_id=*/3, /*start_offset=*/1,
- /*start_affinity*/ ax::mojom::TextAffinity::kDownstream,
- /*end_anchor_id=*/3, /*end_offset=*/6,
- /*end_affinity*/ ax::mojom::TextAffinity::kDownstream);
-
- EXPECT_TRUE(GetStart(ignored_range_win.Get())->IsIgnored());
- EXPECT_TRUE(GetEnd(ignored_range_win.Get())->IsIgnored());
-
- ComPtr<AXPlatformNodeTextRangeProviderWin> normalized_range_win =
- CloneTextRangeProviderWin(ignored_range_win.Get());
- NormalizeTextRange(normalized_range_win.Get());
-
- EXPECT_FALSE(GetStart(normalized_range_win.Get())->IsIgnored());
- EXPECT_FALSE(GetEnd(normalized_range_win.Get())->IsIgnored());
- EXPECT_LE(*GetStart(ignored_range_win.Get()),
- *GetStart(normalized_range_win.Get()));
- EXPECT_LE(*GetEnd(ignored_range_win.Get()),
- *GetEnd(normalized_range_win.Get()));
- EXPECT_LE(*GetStart(normalized_range_win.Get()),
- *GetEnd(normalized_range_win.Get()));
-
- // Remove the last node, forcing |NormalizeTextRange| to normalize
- // using the opposite AdjustmentBehavior.
- AXTreeUpdate update;
- update.nodes.resize(1);
- update.nodes[0] = initial_state.nodes[0];
- update.nodes[0].child_ids = {2, 3};
- ASSERT_TRUE(GetTree()->Unserialize(update));
-
- normalized_range_win = CloneTextRangeProviderWin(ignored_range_win.Get());
- NormalizeTextRange(normalized_range_win.Get());
-
- EXPECT_FALSE(GetStart(normalized_range_win.Get())->IsIgnored());
- EXPECT_FALSE(GetEnd(normalized_range_win.Get())->IsIgnored());
- EXPECT_GE(*GetStart(ignored_range_win.Get()),
- *GetStart(normalized_range_win.Get()));
- EXPECT_GE(*GetEnd(ignored_range_win.Get()),
- *GetEnd(normalized_range_win.Get()));
- EXPECT_LE(*GetStart(normalized_range_win.Get()),
- *GetEnd(normalized_range_win.Get()));
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestNormalizeTextRangeSpanIgnoredNodes) {
- ui::AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
-
- ui::AXNodeData before_text;
- before_text.id = 2;
- before_text.role = ax::mojom::Role::kStaticText;
- before_text.SetName("before");
- root_data.child_ids.push_back(before_text.id);
-
- ui::AXNodeData ignored_text1;
- ignored_text1.id = 3;
- ignored_text1.role = ax::mojom::Role::kStaticText;
- ignored_text1.AddState(ax::mojom::State::kIgnored);
- ignored_text1.SetName("ignored1");
- root_data.child_ids.push_back(ignored_text1.id);
-
- ui::AXNodeData ignored_text2;
- ignored_text2.id = 4;
- ignored_text2.role = ax::mojom::Role::kStaticText;
- ignored_text2.AddState(ax::mojom::State::kIgnored);
- ignored_text2.SetName("ignored2");
- root_data.child_ids.push_back(ignored_text2.id);
-
- ui::AXNodeData after_text;
- after_text.id = 5;
- after_text.role = ax::mojom::Role::kStaticText;
- after_text.SetName("after");
- root_data.child_ids.push_back(after_text.id);
-
- ui::AXTreeUpdate update;
- ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.root_id = root_data.id;
- update.tree_data.tree_id = tree_id;
- update.has_tree_data = true;
- update.nodes = {root_data, before_text, ignored_text1, ignored_text2,
- after_text};
- Init(update);
-
- // Making |owner| AXID:1 so that |TestAXNodeWrapper::BuildAllWrappers|
- // will build the entire tree.
- AXPlatformNodeWin* owner = static_cast<AXPlatformNodeWin*>(
- AXPlatformNodeFromNode(GetNodeFromTree(tree_id, 1)));
-
- // Text range before NormalizeTextRange()
- // |before<>||ignored1||ignored2||<a>fter|
- // |-----------------------|
- // start: TextPosition, anchor_id=2, text_offset=6, annotated_text=before<>
- // end : TextPosition, anchor_id=5, text_offset=0, annotated_text=<a>fter
- ComPtr<AXPlatformNodeTextRangeProviderWin> range_span_ignored_nodes;
- CreateTextRangeProviderWin(
- range_span_ignored_nodes, owner, tree_id,
- /*start_anchor_id=*/2, /*start_offset=*/6,
- /*start_affinity*/ ax::mojom::TextAffinity::kDownstream,
- /*end_anchor_id=*/5, /*end_offset=*/0,
- /*end_affinity*/ ax::mojom::TextAffinity::kDownstream);
-
- // Text range after NormalizeTextRange()
- // |before||ignored1||ignored2||<a>fter|
- // |-|
- NormalizeTextRange(range_span_ignored_nodes.Get());
- EXPECT_EQ(*GetStart(range_span_ignored_nodes.Get()),
- *GetEnd(range_span_ignored_nodes.Get()));
-
- EXPECT_EQ(true, GetStart(range_span_ignored_nodes.Get())->IsTextPosition());
- EXPECT_EQ(true, GetStart(range_span_ignored_nodes.Get())->AtStartOfAnchor());
- EXPECT_EQ(5, GetStart(range_span_ignored_nodes.Get())->anchor_id());
- EXPECT_EQ(0, GetStart(range_span_ignored_nodes.Get())->text_offset());
-
- EXPECT_EQ(true, GetEnd(range_span_ignored_nodes.Get())->IsTextPosition());
- EXPECT_EQ(true, GetEnd(range_span_ignored_nodes.Get())->AtStartOfAnchor());
- EXPECT_EQ(5, GetEnd(range_span_ignored_nodes.Get())->anchor_id());
- EXPECT_EQ(0, GetEnd(range_span_ignored_nodes.Get())->text_offset());
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest,
- TestNormalizeTextRangeForceSameAnchorOnDegenerateRange) {
- // ++1 kRootWebArea
- // ++++2 kGenericContainer
- // ++++++3 kImage
- // ++++4 kTextField
- // ++++++5 kGenericContainer
- // ++++++++6 kStaticText
- // ++++++++++7 kInlineTextBox
- ui::AXNodeData root_1;
- ui::AXNodeData generic_container_2;
- ui::AXNodeData image_3;
- ui::AXNodeData text_field_4;
- ui::AXNodeData generic_container_5;
- ui::AXNodeData static_text_6;
- ui::AXNodeData inline_box_7;
-
- root_1.id = 1;
- generic_container_2.id = 2;
- image_3.id = 3;
- text_field_4.id = 4;
- generic_container_5.id = 5;
- static_text_6.id = 6;
- inline_box_7.id = 7;
-
- root_1.role = ax::mojom::Role::kRootWebArea;
- root_1.child_ids = {generic_container_2.id, text_field_4.id};
-
- generic_container_2.role = ax::mojom::Role::kGenericContainer;
- generic_container_2.AddBoolAttribute(
- ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
- generic_container_2.child_ids = {image_3.id};
-
- image_3.role = ax::mojom::Role::kImage;
-
- text_field_4.role = ax::mojom::Role::kTextField;
- text_field_4.child_ids = {generic_container_5.id};
- text_field_4.SetValue("3.14");
-
- generic_container_5.role = ax::mojom::Role::kGenericContainer;
- generic_container_5.child_ids = {static_text_6.id};
-
- static_text_6.role = ax::mojom::Role::kStaticText;
- static_text_6.child_ids = {inline_box_7.id};
- static_text_6.SetName("3.14");
-
- inline_box_7.role = ax::mojom::Role::kInlineTextBox;
- inline_box_7.SetName("3.14");
-
- ui::AXTreeUpdate update;
- ui::AXTreeData tree_data;
- tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data = tree_data;
- update.has_tree_data = true;
- update.root_id = root_1.id;
- update.nodes.push_back(root_1);
- update.nodes.push_back(generic_container_2);
- update.nodes.push_back(image_3);
- update.nodes.push_back(text_field_4);
- update.nodes.push_back(generic_container_5);
- update.nodes.push_back(static_text_6);
- update.nodes.push_back(inline_box_7);
-
- Init(update);
-
- AXPlatformNodeWin* owner = static_cast<AXPlatformNodeWin*>(
- AXPlatformNodeFromNode(GetNodeFromTree(tree_data.tree_id, 1)));
-
- // start: TextPosition, anchor_id=3, text_offset=1, annotated_text=/xFFFC<>
- // end : TextPosition, anchor_id=7, text_offset=0, annotated_text=<p>i
- ComPtr<AXPlatformNodeTextRangeProviderWin> range;
- CreateTextRangeProviderWin(
- range, owner, tree_data.tree_id,
- /*start_anchor_id=*/3, /*start_offset=*/1,
- /*start_affinity*/ ax::mojom::TextAffinity::kDownstream,
- /*end_anchor_id=*/7, /*end_offset=*/0,
- /*end_affinity*/ ax::mojom::TextAffinity::kDownstream);
-
- NormalizeTextRange(range.Get());
- EXPECT_EQ(*GetStart(range.Get()), *GetEnd(range.Get()));
-
- EXPECT_EQ(true, GetStart(range.Get())->AtStartOfAnchor());
- EXPECT_EQ(true, GetEnd(range.Get())->AtStartOfAnchor());
- EXPECT_EQ(7, GetStart(range.Get())->anchor_id());
- EXPECT_EQ(7, GetEnd(range.Get())->anchor_id());
-}
-
-TEST_F(AXPlatformNodeTextRangeProviderTest, TestValidateStartAndEnd) {
- // This test updates the tree structure to test a specific edge case -
- // CreatePositionAtFormatBoundary when text lies at the beginning and end
- // of the AX tree.
- AXNodeData root_data;
- root_data.id = 1;
- root_data.role = ax::mojom::Role::kRootWebArea;
-
- AXNodeData text_data;
- text_data.id = 2;
- text_data.role = ax::mojom::Role::kStaticText;
- text_data.SetName("some text");
-
- AXNodeData more_text_data;
- more_text_data.id = 3;
- more_text_data.role = ax::mojom::Role::kStaticText;
- more_text_data.SetName("more text");
-
- root_data.child_ids = {text_data.id, more_text_data.id};
-
- ui::AXTreeUpdate update;
- ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.root_id = root_data.id;
- update.tree_data.tree_id = tree_id;
- update.has_tree_data = true;
- update.nodes = {root_data, text_data, more_text_data};
- Init(update);
-
- // Create a position at MaxTextOffset
- // Making |owner| AXID:1 so that |TestAXNodeWrapper::BuildAllWrappers|
- // will build the entire tree.
- AXPlatformNodeWin* owner = static_cast<AXPlatformNodeWin*>(
- AXPlatformNodeFromNode(GetNodeFromTree(tree_id, 1)));
-
- // start: TextPosition, anchor_id=1, text_offset=0, annotated_text=<s>ome text
- // end : TextPosition, anchor_id=3, text_offset=9, annotated_text=more text<>
- ComPtr<AXPlatformNodeTextRangeProviderWin> text_range_provider;
- CreateTextRangeProviderWin(
- text_range_provider, owner, tree_id,
- /*start_anchor_id=*/1, /*start_offset=*/0,
- /*start_affinity*/ ax::mojom::TextAffinity::kDownstream,
- /*end_anchor_id=*/3, /*end_offset=*/9,
- /*end_affinity*/ ax::mojom::TextAffinity::kDownstream);
-
- // Since the end of the range is at MaxTextOffset, moving it by 1 character
- // should have an expected_count of 0.
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/ L"some textmore text",
- /*expected_count*/ 0);
-
- // Now make a change to shorten MaxTextOffset. Ensure that this position is
- // invalid, then call SnapToMaxTextOffsetIfBeyond and ensure that it is now
- // valid.
- more_text_data.SetName("ore tex");
- AXTreeUpdate test_update;
- test_update.nodes = {more_text_data};
- ASSERT_TRUE(GetTree()->Unserialize(test_update));
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/ L"some textore tex",
- /*expected_count*/ 0);
-
- // Now modify the tree so that start_ is pointing to a node that has been
- // removed from the tree.
- text_data.SetName("");
- AXTreeUpdate test_update2;
- test_update2.nodes = {text_data};
- ASSERT_TRUE(GetTree()->Unserialize(test_update2));
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/ L"re tex",
- /*expected_count*/ 1);
-
- // Now adjust a node that's not the final node in the tree to point past
- // MaxTextOffset. First move the range endpoints so that they're pointing to
- // MaxTextOffset on the first node.
- text_data.SetName("some text");
- AXTreeUpdate test_update3;
- test_update3.nodes = {text_data};
- ASSERT_TRUE(GetTree()->Unserialize(test_update3));
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Character,
- /*count*/ -10,
- /*expected_text*/ L"some textore tex",
- /*expected_count*/ -10);
-
- // Ensure that we're at MaxTextOffset on the first node by first
- // overshooting a negative move...
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ -8,
- /*expected_text*/ L"some tex",
- /*expected_count*/ -8);
-
- // ...followed by a positive move
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/ L"some text",
- /*expected_count*/ 1);
-
- // Now our range's start_ is pointing to offset 0 on the first node and end_
- // is pointing to MaxTextOffset on the first node. Now modify the tree so
- // that MaxTextOffset is invalid on the first node and ensure that we can
- // still move
- text_data.SetName("some tex");
- AXTreeUpdate test_update4;
- test_update4.nodes = {text_data};
- ASSERT_TRUE(GetTree()->Unserialize(test_update4));
-
- EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
- text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Character,
- /*count*/ 1,
- /*expected_text*/ L"ome tex",
- /*expected_count*/ 1);
-}
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_unittest.cc b/third_party/accessibility/ax/platform/ax_platform_node_unittest.cc
index 1cc881f..65ab692 100644
--- a/third_party/accessibility/ax/platform/ax_platform_node_unittest.cc
+++ b/third_party/accessibility/ax/platform/ax_platform_node_unittest.cc
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/platform/ax_platform_node_unittest.h"
+#include "ax_platform_node_unittest.h"
-#include "ui/accessibility/ax_constants.mojom.h"
-#include "ui/accessibility/platform/test_ax_node_wrapper.h"
+#include "ax/ax_constants.h"
+#include "test_ax_node_wrapper.h"
namespace ui {
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_unittest.h b/third_party/accessibility/ax/platform/ax_platform_node_unittest.h
index d004a05..abbd0db 100644
--- a/third_party/accessibility/ax/platform/ax_platform_node_unittest.h
+++ b/third_party/accessibility/ax/platform/ax_platform_node_unittest.h
@@ -5,13 +5,14 @@
#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_UNITTEST_H_
#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_UNITTEST_H_
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/accessibility/ax_tree_update.h"
-#include "ui/accessibility/test_ax_tree_manager.h"
+#include "gtest/gtest.h"
+
+#include "ax/ax_enums.h"
+#include "ax/ax_node.h"
+#include "ax/ax_node_data.h"
+#include "ax/ax_tree_id.h"
+#include "ax/ax_tree_update.h"
+#include "ax/test_ax_tree_manager.h"
namespace ui {
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_win.cc b/third_party/accessibility/ax/platform/ax_platform_node_win.cc
deleted file mode 100644
index 6d348bf..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_win.cc
+++ /dev/null
@@ -1,8105 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_node_win.h"
-
-#include <wrl/client.h>
-#include <wrl/implements.h>
-
-#include <algorithm>
-#include <map>
-#include <set>
-#include <string>
-#include <unordered_set>
-#include <utility>
-#include <vector>
-
-#include "base/json/json_writer.h"
-#include "base/lazy_instance.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/values.h"
-#include "base/win/enum_variant.h"
-#include "base/win/scoped_bstr.h"
-#include "base/win/scoped_safearray.h"
-#include "base/win/scoped_variant.h"
-#include "base/win/variant_vector.h"
-#include "skia/ext/skia_utils_win.h"
-#include "third_party/iaccessible2/ia2_api_all.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/accessibility/accessibility_features.h"
-#include "ui/accessibility/accessibility_switches.h"
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_active_popup.h"
-#include "ui/accessibility/ax_constants.mojom.h"
-#include "ui/accessibility/ax_enum_util.h"
-#include "ui/accessibility/ax_mode_observer.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_node_position.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_tree_data.h"
-#include "ui/accessibility/platform/ax_fragment_root_win.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate_utils_win.h"
-#include "ui/accessibility/platform/ax_platform_node_textchildprovider_win.h"
-#include "ui/accessibility/platform/ax_platform_node_textprovider_win.h"
-#include "ui/accessibility/platform/ax_platform_relation_win.h"
-#include "ui/accessibility/platform/uia_registrar_win.h"
-#include "ui/base/win/atl_module.h"
-#include "ui/display/win/screen_win.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-
-//
-// Macros to use at the top of any AXPlatformNodeWin function that implements
-// a non-UIA COM interface. Because COM objects are reference counted and
-// clients are completely untrusted, it's important to always first check that
-// our object is still valid, and then check that all pointer arguments are not
-// NULL.
-//
-#define COM_OBJECT_VALIDATE() \
- if (!GetDelegate()) \
- return E_FAIL;
-#define COM_OBJECT_VALIDATE_1_ARG(arg) \
- if (!GetDelegate()) \
- return E_FAIL; \
- if (!arg) \
- return E_INVALIDARG; \
- *arg = {};
-#define COM_OBJECT_VALIDATE_2_ARGS(arg1, arg2) \
- if (!GetDelegate()) \
- return E_FAIL; \
- if (!arg1) \
- return E_INVALIDARG; \
- *arg1 = {}; \
- if (!arg2) \
- return E_INVALIDARG; \
- *arg2 = {};
-#define COM_OBJECT_VALIDATE_3_ARGS(arg1, arg2, arg3) \
- if (!GetDelegate()) \
- return E_FAIL; \
- if (!arg1) \
- return E_INVALIDARG; \
- *arg1 = {}; \
- if (!arg2) \
- return E_INVALIDARG; \
- *arg2 = {}; \
- if (!arg3) \
- return E_INVALIDARG; \
- *arg3 = {};
-#define COM_OBJECT_VALIDATE_4_ARGS(arg1, arg2, arg3, arg4) \
- if (!GetDelegate()) \
- return E_FAIL; \
- if (!arg1) \
- return E_INVALIDARG; \
- *arg1 = {}; \
- if (!arg2) \
- return E_INVALIDARG; \
- *arg2 = {}; \
- if (!arg3) \
- return E_INVALIDARG; \
- *arg3 = {}; \
- if (!arg4) \
- return E_INVALIDARG; \
- *arg4 = {};
-#define COM_OBJECT_VALIDATE_5_ARGS(arg1, arg2, arg3, arg4, arg5) \
- if (!GetDelegate()) \
- return E_FAIL; \
- if (!arg1) \
- return E_INVALIDARG; \
- *arg1 = {}; \
- if (!arg2) \
- return E_INVALIDARG; \
- *arg2 = {}; \
- if (!arg3) \
- return E_INVALIDARG; \
- *arg3 = {}; \
- if (!arg4) \
- return E_INVALIDARG; \
- *arg4 = {}; \
- if (!arg5) \
- return E_INVALIDARG; \
- *arg5 = {};
-#define COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target) \
- if (!GetDelegate()) \
- return E_FAIL; \
- target = GetTargetFromChildID(var_id); \
- if (!target) \
- return E_INVALIDARG; \
- if (!target->GetDelegate()) \
- return E_INVALIDARG;
-#define COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, arg, target) \
- if (!GetDelegate()) \
- return E_FAIL; \
- if (!arg) \
- return E_INVALIDARG; \
- *arg = {}; \
- target = GetTargetFromChildID(var_id); \
- if (!target) \
- return E_INVALIDARG; \
- if (!target->GetDelegate()) \
- return E_INVALIDARG;
-#define COM_OBJECT_VALIDATE_VAR_ID_2_ARGS_AND_GET_TARGET(var_id, arg1, arg2, \
- target) \
- if (!GetDelegate()) \
- return E_FAIL; \
- if (!arg1) \
- return E_INVALIDARG; \
- *arg1 = {}; \
- if (!arg2) \
- return E_INVALIDARG; \
- *arg2 = {}; \
- target = GetTargetFromChildID(var_id); \
- if (!target) \
- return E_INVALIDARG; \
- if (!target->GetDelegate()) \
- return E_INVALIDARG;
-#define COM_OBJECT_VALIDATE_VAR_ID_3_ARGS_AND_GET_TARGET(var_id, arg1, arg2, \
- arg3, target) \
- if (!GetDelegate()) \
- return E_FAIL; \
- if (!arg1) \
- return E_INVALIDARG; \
- *arg1 = {}; \
- if (!arg2) \
- return E_INVALIDARG; \
- *arg2 = {}; \
- if (!arg3) \
- return E_INVALIDARG; \
- *arg3 = {}; \
- target = GetTargetFromChildID(var_id); \
- if (!target) \
- return E_INVALIDARG; \
- if (!target->GetDelegate()) \
- return E_INVALIDARG;
-#define COM_OBJECT_VALIDATE_VAR_ID_4_ARGS_AND_GET_TARGET(var_id, arg1, arg2, \
- arg3, arg4, target) \
- if (!GetDelegate()) \
- return E_FAIL; \
- if (!arg1) \
- return E_INVALIDARG; \
- *arg1 = {}; \
- if (!arg2) \
- return E_INVALIDARG; \
- *arg2 = {}; \
- if (!arg3) \
- return E_INVALIDARG; \
- *arg3 = {}; \
- if (!arg4) \
- return E_INVALIDARG; \
- *arg4 = {}; \
- target = GetTargetFromChildID(var_id); \
- if (!target) \
- return E_INVALIDARG; \
- if (!target->GetDelegate()) \
- return E_INVALIDARG;
-
-namespace ui {
-
-namespace {
-
-typedef std::unordered_set<AXPlatformNodeWin*> AXPlatformNodeWinSet;
-// Set of all AXPlatformNodeWin objects that were the target of an
-// alert event.
-base::LazyInstance<AXPlatformNodeWinSet>::Leaky g_alert_targets =
- LAZY_INSTANCE_INITIALIZER;
-
-base::LazyInstance<
- base::ObserverList<WinAccessibilityAPIUsageObserver>::Unchecked>::Leaky
- g_win_accessibility_api_usage_observer_list = LAZY_INSTANCE_INITIALIZER;
-
-// Sets the multiplier by which large changes to a RangeValueProvider are
-// greater than small changes.
-constexpr int kLargeChangeScaleFactor = 10;
-
-// The amount to scroll when UI Automation asks to scroll by a small increment.
-// Value is in device independent pixels and is the same used by Blink when
-// cursor keys are used to scroll a webpage.
-constexpr float kSmallScrollIncrement = 40.0f;
-
-void AppendTextToString(base::string16 extra_text, base::string16* string) {
- if (extra_text.empty())
- return;
-
- if (string->empty()) {
- *string = extra_text;
- return;
- }
-
- *string += base::string16(L". ") + extra_text;
-}
-
-// Helper function to GetPatternProviderFactoryMethod that, given a node,
-// will return a pattern interface through result based on the provided type T.
-template <typename T>
-void PatternProvider(AXPlatformNodeWin* node, IUnknown** result) {
- node->AddRef();
- *result = static_cast<T*>(node);
-}
-
-} // namespace
-
-void AXPlatformNodeWin::AddAttributeToList(const char* name,
- const char* value,
- PlatformAttributeList* attributes) {
- std::string str_value = value;
- SanitizeStringAttribute(str_value, &str_value);
- attributes->push_back(base::UTF8ToUTF16(name) + L":" +
- base::UTF8ToUTF16(str_value));
-}
-
-// There is no easy way to decouple |kScreenReader| and |kHTML| accessibility
-// modes when Windows screen readers are used. For example, certain roles use
-// the HTML tag name. Input fields require their type attribute to be exposed.
-const uint32_t kScreenReaderAndHTMLAccessibilityModes =
- AXMode::kScreenReader | AXMode::kHTML;
-
-//
-// WinAccessibilityAPIUsageObserver
-//
-
-WinAccessibilityAPIUsageObserver::WinAccessibilityAPIUsageObserver() {}
-
-WinAccessibilityAPIUsageObserver::~WinAccessibilityAPIUsageObserver() {}
-
-// static
-base::ObserverList<WinAccessibilityAPIUsageObserver>::Unchecked&
-GetWinAccessibilityAPIUsageObserverList() {
- return g_win_accessibility_api_usage_observer_list.Get();
-}
-
-//
-// AXPlatformNode::Create
-//
-
-// static
-AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) {
- // Make sure ATL is initialized in this module.
- win::CreateATLModuleIfNeeded();
-
- CComObject<AXPlatformNodeWin>* instance = nullptr;
- HRESULT hr = CComObject<AXPlatformNodeWin>::CreateInstance(&instance);
- DCHECK(SUCCEEDED(hr));
- instance->Init(delegate);
- instance->AddRef();
- return instance;
-}
-
-// static
-AXPlatformNode* AXPlatformNode::FromNativeViewAccessible(
- gfx::NativeViewAccessible accessible) {
- if (!accessible)
- return nullptr;
- Microsoft::WRL::ComPtr<AXPlatformNodeWin> ax_platform_node;
- accessible->QueryInterface(IID_PPV_ARGS(&ax_platform_node));
- return ax_platform_node.Get();
-}
-
-//
-// AXPlatformNodeWin
-//
-
-AXPlatformNodeWin::AXPlatformNodeWin() {}
-
-AXPlatformNodeWin::~AXPlatformNodeWin() {
- ClearOwnRelations();
-}
-
-void AXPlatformNodeWin::Init(AXPlatformNodeDelegate* delegate) {
- AXPlatformNodeBase::Init(delegate);
-}
-
-void AXPlatformNodeWin::ClearOwnRelations() {
- for (size_t i = 0; i < relations_.size(); ++i)
- relations_[i]->Invalidate();
- relations_.clear();
-}
-
-// Static
-void AXPlatformNodeWin::SanitizeStringAttributeForUIAAriaProperty(
- const base::string16& input,
- base::string16* output) {
- DCHECK(output);
- // According to the UIA Spec, these characters need to be escaped with a
- // backslash in an AriaProperties string: backslash, equals and semicolon.
- // Note that backslash must be replaced first.
- base::ReplaceChars(input, L"\\", L"\\\\", output);
- base::ReplaceChars(*output, L"=", L"\\=", output);
- base::ReplaceChars(*output, L";", L"\\;", output);
-}
-
-void AXPlatformNodeWin::StringAttributeToUIAAriaProperty(
- std::vector<base::string16>& properties,
- ax::mojom::StringAttribute attribute,
- const char* uia_aria_property) {
- base::string16 value;
- if (GetString16Attribute(attribute, &value)) {
- SanitizeStringAttributeForUIAAriaProperty(value, &value);
- properties.push_back(base::ASCIIToUTF16(uia_aria_property) + L"=" + value);
- }
-}
-
-void AXPlatformNodeWin::BoolAttributeToUIAAriaProperty(
- std::vector<base::string16>& properties,
- ax::mojom::BoolAttribute attribute,
- const char* uia_aria_property) {
- bool value;
- if (GetBoolAttribute(attribute, &value)) {
- properties.push_back((base::ASCIIToUTF16(uia_aria_property) + L"=") +
- (value ? L"true" : L"false"));
- }
-}
-
-void AXPlatformNodeWin::IntAttributeToUIAAriaProperty(
- std::vector<base::string16>& properties,
- ax::mojom::IntAttribute attribute,
- const char* uia_aria_property) {
- int value;
- if (GetIntAttribute(attribute, &value)) {
- properties.push_back(base::ASCIIToUTF16(uia_aria_property) + L"=" +
- base::NumberToString16(value));
- }
-}
-
-void AXPlatformNodeWin::FloatAttributeToUIAAriaProperty(
- std::vector<base::string16>& properties,
- ax::mojom::FloatAttribute attribute,
- const char* uia_aria_property) {
- float value;
- if (GetFloatAttribute(attribute, &value)) {
- properties.push_back(base::ASCIIToUTF16(uia_aria_property) + L"=" +
- base::NumberToString16(value));
- }
-}
-
-void AXPlatformNodeWin::StateToUIAAriaProperty(
- std::vector<base::string16>& properties,
- ax::mojom::State state,
- const char* uia_aria_property) {
- const AXNodeData& data = GetData();
- bool value = data.HasState(state);
- properties.push_back((base::ASCIIToUTF16(uia_aria_property) + L"=") +
- (value ? L"true" : L"false"));
-}
-
-void AXPlatformNodeWin::HtmlAttributeToUIAAriaProperty(
- std::vector<base::string16>& properties,
- const char* html_attribute_name,
- const char* uia_aria_property) {
- base::string16 html_attribute_value;
- if (GetData().GetHtmlAttribute(html_attribute_name, &html_attribute_value)) {
- SanitizeStringAttributeForUIAAriaProperty(html_attribute_value,
- &html_attribute_value);
- properties.push_back(base::ASCIIToUTF16(uia_aria_property) + L"=" +
- html_attribute_value);
- }
-}
-
-std::vector<AXPlatformNodeWin*>
-AXPlatformNodeWin::CreatePlatformNodeVectorFromRelationIdVector(
- std::vector<int32_t>& relation_id_list) {
- std::vector<AXPlatformNodeWin*> platform_node_list;
-
- for (int32_t id : relation_id_list) {
- AXPlatformNode* platform_node = GetDelegate()->GetFromNodeID(id);
- if (IsValidUiaRelationTarget(platform_node)) {
- platform_node_list.push_back(
- static_cast<AXPlatformNodeWin*>(platform_node));
- }
- }
-
- return platform_node_list;
-}
-
-SAFEARRAY* AXPlatformNodeWin::CreateUIAElementsSafeArray(
- std::vector<AXPlatformNodeWin*>& platform_node_list) {
- if (platform_node_list.empty())
- return nullptr;
-
- SAFEARRAY* uia_array =
- SafeArrayCreateVector(VT_UNKNOWN, 0, platform_node_list.size());
- LONG i = 0;
-
- for (AXPlatformNodeWin* platform_node : platform_node_list) {
- // All incoming ids should already be validated to have a valid relation
- // targets so that this function does not need to re-check before allocating
- // the SAFEARRAY.
- DCHECK(IsValidUiaRelationTarget(platform_node));
- SafeArrayPutElement(uia_array, &i,
- static_cast<IRawElementProviderSimple*>(platform_node));
- ++i;
- }
-
- return uia_array;
-}
-
-SAFEARRAY* AXPlatformNodeWin::CreateUIAControllerForArray() {
- std::vector<int32_t> relation_id_list =
- GetIntListAttribute(ax::mojom::IntListAttribute::kControlsIds);
-
- std::vector<AXPlatformNodeWin*> platform_node_list =
- CreatePlatformNodeVectorFromRelationIdVector(relation_id_list);
-
- if (GetActivePopupAxUniqueId() != base::nullopt) {
- AXPlatformNodeWin* view_popup_node_win = static_cast<AXPlatformNodeWin*>(
- GetFromUniqueId(GetActivePopupAxUniqueId().value()));
-
- if (IsValidUiaRelationTarget(view_popup_node_win))
- platform_node_list.push_back(view_popup_node_win);
- }
-
- return CreateUIAElementsSafeArray(platform_node_list);
-}
-
-SAFEARRAY* AXPlatformNodeWin::CreateUIAElementsArrayForRelation(
- const ax::mojom::IntListAttribute& attribute) {
- std::vector<int32_t> relation_id_list = GetIntListAttribute(attribute);
-
- std::vector<AXPlatformNodeWin*> platform_node_list =
- CreatePlatformNodeVectorFromRelationIdVector(relation_id_list);
-
- return CreateUIAElementsSafeArray(platform_node_list);
-}
-
-SAFEARRAY* AXPlatformNodeWin::CreateUIAElementsArrayForReverseRelation(
- const ax::mojom::IntListAttribute& attribute) {
- std::set<AXPlatformNode*> reverse_relations =
- GetDelegate()->GetReverseRelations(attribute);
-
- std::vector<int32_t> id_list;
- std::transform(
- reverse_relations.cbegin(), reverse_relations.cend(),
- std::back_inserter(id_list), [](AXPlatformNode* platform_node) {
- return static_cast<AXPlatformNodeWin*>(platform_node)->GetData().id;
- });
-
- std::vector<AXPlatformNodeWin*> platform_node_list =
- CreatePlatformNodeVectorFromRelationIdVector(id_list);
-
- return CreateUIAElementsSafeArray(platform_node_list);
-}
-
-SAFEARRAY* AXPlatformNodeWin::CreateClickablePointArray() {
- SAFEARRAY* clickable_point_array = SafeArrayCreateVector(VT_R8, 0, 2);
- gfx::Point center = GetDelegate()
- ->GetBoundsRect(AXCoordinateSystem::kScreenDIPs,
- AXClippingBehavior::kUnclipped)
- .CenterPoint();
-
- double* double_array;
- SafeArrayAccessData(clickable_point_array,
- reinterpret_cast<void**>(&double_array));
- double_array[0] = center.x();
- double_array[1] = center.y();
- SafeArrayUnaccessData(clickable_point_array);
-
- return clickable_point_array;
-}
-
-gfx::Vector2d AXPlatformNodeWin::CalculateUIAScrollPoint(
- const ScrollAmount horizontal_amount,
- const ScrollAmount vertical_amount) const {
- if (!GetDelegate() || !IsScrollable())
- return {};
-
- const gfx::Rect bounds = GetDelegate()->GetBoundsRect(
- AXCoordinateSystem::kScreenDIPs, AXClippingBehavior::kClipped);
- const int large_horizontal_change = bounds.width();
- const int large_vertical_change = bounds.height();
-
- const HWND hwnd = GetDelegate()->GetTargetForNativeAccessibilityEvent();
- DCHECK(hwnd);
- const float scale_factor =
- display::win::ScreenWin::GetScaleFactorForHWND(hwnd);
- const int small_change =
- base::ClampRound(kSmallScrollIncrement * scale_factor);
-
- const int x_min = GetIntAttribute(ax::mojom::IntAttribute::kScrollXMin);
- const int x_max = GetIntAttribute(ax::mojom::IntAttribute::kScrollXMax);
- const int y_min = GetIntAttribute(ax::mojom::IntAttribute::kScrollYMin);
- const int y_max = GetIntAttribute(ax::mojom::IntAttribute::kScrollYMax);
-
- int x = GetIntAttribute(ax::mojom::IntAttribute::kScrollX);
- int y = GetIntAttribute(ax::mojom::IntAttribute::kScrollY);
-
- switch (horizontal_amount) {
- case ScrollAmount_LargeDecrement:
- x -= large_horizontal_change;
- break;
- case ScrollAmount_LargeIncrement:
- x += large_horizontal_change;
- break;
- case ScrollAmount_NoAmount:
- break;
- case ScrollAmount_SmallDecrement:
- x -= small_change;
- break;
- case ScrollAmount_SmallIncrement:
- x += small_change;
- break;
- }
- x = std::min(x, x_max);
- x = std::max(x, x_min);
-
- switch (vertical_amount) {
- case ScrollAmount_LargeDecrement:
- y -= large_vertical_change;
- break;
- case ScrollAmount_LargeIncrement:
- y += large_vertical_change;
- break;
- case ScrollAmount_NoAmount:
- break;
- case ScrollAmount_SmallDecrement:
- y -= small_change;
- break;
- case ScrollAmount_SmallIncrement:
- y += small_change;
- break;
- }
- y = std::min(y, y_max);
- y = std::max(y, y_min);
-
- return {x, y};
-}
-
-//
-// AXPlatformNodeBase implementation.
-//
-
-void AXPlatformNodeWin::Dispose() {
- Release();
-}
-
-void AXPlatformNodeWin::Destroy() {
- RemoveAlertTarget();
-
- // This will end up calling Dispose() which may result in deleting this object
- // if there are no more outstanding references.
- AXPlatformNodeBase::Destroy();
-}
-
-//
-// AXPlatformNode implementation.
-//
-
-gfx::NativeViewAccessible AXPlatformNodeWin::GetNativeViewAccessible() {
- return this;
-}
-
-void AXPlatformNodeWin::NotifyAccessibilityEvent(ax::mojom::Event event_type) {
- AXPlatformNodeBase::NotifyAccessibilityEvent(event_type);
- // Menu items fire selection events but Windows screen readers work reliably
- // with focus events. Remap here.
- if (event_type == ax::mojom::Event::kSelection) {
- // A menu item could have something other than a role of
- // |ROLE_SYSTEM_MENUITEM|. Zoom modification controls for example have a
- // role of button.
- auto* parent =
- static_cast<AXPlatformNodeWin*>(FromNativeViewAccessible(GetParent()));
- int role = MSAARole();
- if (role == ROLE_SYSTEM_MENUITEM) {
- event_type = ax::mojom::Event::kFocus;
- } else if (role == ROLE_SYSTEM_LISTITEM) {
- if (AXPlatformNodeBase* container = GetSelectionContainer()) {
- const AXNodeData& data = container->GetData();
- if (data.role == ax::mojom::Role::kListBox &&
- !data.HasState(ax::mojom::State::kMultiselectable) &&
- GetDelegate()->GetFocus() == GetNativeViewAccessible()) {
- event_type = ax::mojom::Event::kFocus;
- }
- }
- } else if (parent) {
- int parent_role = parent->MSAARole();
- if (parent_role == ROLE_SYSTEM_MENUPOPUP ||
- parent_role == ROLE_SYSTEM_LIST) {
- event_type = ax::mojom::Event::kFocus;
- }
- }
- }
-
- if (event_type == ax::mojom::Event::kValueChanged) {
- // For the IAccessibleText interface to work on non-web content nodes, we
- // need to update the nodes' hypertext
- // when the value changes. Otherwise, for web and PDF content, this is
- // handled by "BrowserAccessibilityComWin".
- if (!GetDelegate()->IsWebContent())
- UpdateComputedHypertext();
- }
-
- if (base::Optional<DWORD> native_event = MojoEventToMSAAEvent(event_type)) {
- HWND hwnd = GetDelegate()->GetTargetForNativeAccessibilityEvent();
- if (!hwnd)
- return;
-
- ::NotifyWinEvent((*native_event), hwnd, OBJID_CLIENT, -GetUniqueId());
- }
-
- if (base::Optional<PROPERTYID> uia_property =
- MojoEventToUIAProperty(event_type)) {
- // For this event, we're not concerned with the old value.
- base::win::ScopedVariant old_value;
- ::VariantInit(old_value.Receive());
- base::win::ScopedVariant new_value;
- ::VariantInit(new_value.Receive());
- GetPropertyValueImpl((*uia_property), new_value.Receive());
- ::UiaRaiseAutomationPropertyChangedEvent(this, (*uia_property), old_value,
- new_value);
- }
-
- if (base::Optional<EVENTID> uia_event = MojoEventToUIAEvent(event_type))
- ::UiaRaiseAutomationEvent(this, (*uia_event));
-
- // Keep track of objects that are a target of an alert event.
- if (event_type == ax::mojom::Event::kAlert)
- AddAlertTarget();
-}
-
-bool AXPlatformNodeWin::HasActiveComposition() const {
- return active_composition_range_.end() > active_composition_range_.start();
-}
-
-gfx::Range AXPlatformNodeWin::GetActiveCompositionOffsets() const {
- return active_composition_range_;
-}
-
-void AXPlatformNodeWin::OnActiveComposition(
- const gfx::Range& range,
- const base::string16& active_composition_text,
- bool is_composition_committed) {
- // Cache the composition range that will be used when
- // GetActiveComposition and GetConversionTarget is called in
- // AXPlatformNodeTextProviderWin
- active_composition_range_ = range;
- // Fire the UiaTextEditTextChangedEvent
- FireUiaTextEditTextChangedEvent(range, active_composition_text,
- is_composition_committed);
-}
-
-void AXPlatformNodeWin::FireUiaTextEditTextChangedEvent(
- const gfx::Range& range,
- const base::string16& active_composition_text,
- bool is_composition_committed) {
- if (!::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) {
- return;
- }
-
- // This API is only supported from Win8.1 onwards
- // Check if the function pointer is valid or not
- using UiaRaiseTextEditTextChangedEventFunction = HRESULT(WINAPI*)(
- IRawElementProviderSimple*, TextEditChangeType, SAFEARRAY*);
- UiaRaiseTextEditTextChangedEventFunction text_edit_text_changed_func =
- reinterpret_cast<UiaRaiseTextEditTextChangedEventFunction>(
- ::GetProcAddress(GetModuleHandle(L"uiautomationcore.dll"),
- "UiaRaiseTextEditTextChangedEvent"));
- if (!text_edit_text_changed_func) {
- return;
- }
-
- TextEditChangeType text_edit_change_type =
- is_composition_committed ? TextEditChangeType_CompositionFinalized
- : TextEditChangeType_Composition;
- // Composition has been finalized by TSF
- base::win::ScopedBstr composition_text(active_composition_text.c_str());
- base::win::ScopedSafearray changed_data(
- SafeArrayCreateVector(VT_BSTR /* element type */, 0 /* lower bound */,
- 1 /* number of elements */));
- if (!changed_data.Get()) {
- return;
- }
-
- LONG index = 0;
- HRESULT hr =
- SafeArrayPutElement(changed_data.Get(), &index, composition_text.Get());
-
- if (FAILED(hr)) {
- return;
- } else {
- // Fire the UiaRaiseTextEditTextChangedEvent
- text_edit_text_changed_func(this, text_edit_change_type,
- changed_data.Release());
- }
-}
-
-bool AXPlatformNodeWin::IsValidUiaRelationTarget(
- AXPlatformNode* ax_platform_node) {
- if (!ax_platform_node)
- return false;
- if (!ax_platform_node->GetDelegate())
- return false;
-
- // This is needed for get_FragmentRoot.
- if (!ax_platform_node->GetDelegate()->GetTargetForNativeAccessibilityEvent())
- return false;
-
- return true;
-}
-
-//
-// IAccessible implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::accHitTest(LONG screen_physical_pixel_x,
- LONG screen_physical_pixel_y,
- VARIANT* child) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ACC_HIT_TEST);
- COM_OBJECT_VALIDATE_1_ARG(child);
-
- gfx::Point point(screen_physical_pixel_x, screen_physical_pixel_y);
- if (!GetDelegate()
- ->GetBoundsRect(AXCoordinateSystem::kScreenPhysicalPixels,
- AXClippingBehavior::kClipped)
- .Contains(point)) {
- // Return S_FALSE and VT_EMPTY when outside the object's boundaries.
- child->vt = VT_EMPTY;
- return S_FALSE;
- }
-
- AXPlatformNode* current_result = this;
- while (true) {
- gfx::NativeViewAccessible hit_child =
- current_result->GetDelegate()->HitTestSync(screen_physical_pixel_x,
- screen_physical_pixel_y);
- if (!hit_child) {
- child->vt = VT_EMPTY;
- return S_FALSE;
- }
-
- AXPlatformNode* hit_child_node =
- AXPlatformNode::FromNativeViewAccessible(hit_child);
- if (!hit_child_node)
- break;
-
- // If we get the same node, we're done.
- if (hit_child_node == current_result)
- break;
-
- // Prevent cycles / loops.
- //
- // This is a workaround for a bug where a hit test in web content might
- // return a node that's not a strict descendant. To catch that case
- // without disallowing other valid cases of hit testing, add the
- // following check:
- //
- // If the hit child comes from the same HWND, but it's not a descendant,
- // just ignore the result and stick with the current result. Note that
- // GetTargetForNativeAccessibilityEvent returns a node's owning HWND.
- //
- // Ideally this shouldn't happen - see http://crbug.com/1061323
- bool is_descendant = hit_child_node->IsDescendantOf(current_result);
- bool is_same_hwnd =
- hit_child_node->GetDelegate()->GetTargetForNativeAccessibilityEvent() ==
- current_result->GetDelegate()->GetTargetForNativeAccessibilityEvent();
- if (!is_descendant && is_same_hwnd)
- break;
-
- // Continue to check recursively. That's because HitTestSync may have
- // returned the best result within a particular accessibility tree,
- // but we might need to recurse further in a tree of a different type
- // (for example, from Views to Web).
- current_result = hit_child_node;
- }
-
- if (current_result == this) {
- // This object is the best match, so return CHILDID_SELF. It's tempting to
- // simplify the logic and use VT_DISPATCH everywhere, but the Windows
- // call AccessibleObjectFromPoint will keep calling accHitTest until some
- // object returns CHILDID_SELF.
- child->vt = VT_I4;
- child->lVal = CHILDID_SELF;
- return S_OK;
- }
-
- child->vt = VT_DISPATCH;
- child->pdispVal = static_cast<AXPlatformNodeWin*>(current_result);
- // Always increment ref when returning a reference to a COM object.
- child->pdispVal->AddRef();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::accDoDefaultAction(VARIANT var_id) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ACC_DO_DEFAULT_ACTION);
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target);
- AXActionData data;
- data.action = ax::mojom::Action::kDoDefault;
-
- if (target->GetDelegate()->AccessibilityPerformAction(data))
- return S_OK;
- return E_FAIL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::accLocation(LONG* physical_pixel_left,
- LONG* physical_pixel_top,
- LONG* width,
- LONG* height,
- VARIANT var_id) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ACC_LOCATION);
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_4_ARGS_AND_GET_TARGET(
- var_id, physical_pixel_left, physical_pixel_top, width, height, target);
-
- gfx::Rect bounds = target->GetDelegate()->GetBoundsRect(
- AXCoordinateSystem::kScreenPhysicalPixels,
- AXClippingBehavior::kUnclipped);
- *physical_pixel_left = bounds.x();
- *physical_pixel_top = bounds.y();
- *width = bounds.width();
- *height = bounds.height();
-
- if (bounds.IsEmpty())
- return S_FALSE;
-
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::accNavigate(LONG nav_dir,
- VARIANT start,
- VARIANT* end) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ACC_NAVIGATE);
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(start, end, target);
- end->vt = VT_EMPTY;
- if ((nav_dir == NAVDIR_FIRSTCHILD || nav_dir == NAVDIR_LASTCHILD) &&
- V_VT(&start) == VT_I4 && V_I4(&start) != CHILDID_SELF) {
- // MSAA states that navigating to first/last child can only be from self.
- return E_INVALIDARG;
- }
-
- IAccessible* result = nullptr;
- switch (nav_dir) {
- case NAVDIR_FIRSTCHILD:
- if (GetDelegate()->GetChildCount() > 0)
- result = GetDelegate()->GetFirstChild();
- break;
-
- case NAVDIR_LASTCHILD:
- if (GetDelegate()->GetChildCount() > 0)
- result = GetDelegate()->GetLastChild();
- break;
-
- case NAVDIR_NEXT: {
- AXPlatformNodeBase* next = target->GetNextSibling();
- if (next)
- result = next->GetNativeViewAccessible();
- break;
- }
-
- case NAVDIR_PREVIOUS: {
- AXPlatformNodeBase* previous = target->GetPreviousSibling();
- if (previous)
- result = previous->GetNativeViewAccessible();
- break;
- }
-
- case NAVDIR_DOWN: {
- // This direction is not implemented except in tables.
- if (!GetTableRow() || !GetTableRowSpan() || !GetTableColumn())
- return E_NOTIMPL;
-
- AXPlatformNodeBase* next = target->GetTableCell(
- *GetTableRow() + *GetTableRowSpan(), *GetTableColumn());
- if (!next)
- return S_OK;
-
- result = next->GetNativeViewAccessible();
- break;
- }
-
- case NAVDIR_UP: {
- // This direction is not implemented except in tables.
- if (!GetTableRow() || !GetTableColumn())
- return E_NOTIMPL;
-
- AXPlatformNodeBase* next =
- target->GetTableCell(*GetTableRow() - 1, *GetTableColumn());
- if (!next)
- return S_OK;
-
- result = next->GetNativeViewAccessible();
- break;
- }
-
- case NAVDIR_LEFT: {
- // This direction is not implemented except in tables.
- if (!GetTableRow() || !GetTableColumn())
- return E_NOTIMPL;
-
- AXPlatformNodeBase* next =
- target->GetTableCell(*GetTableRow(), *GetTableColumn() - 1);
- if (!next)
- return S_OK;
-
- result = next->GetNativeViewAccessible();
- break;
- }
-
- case NAVDIR_RIGHT: {
- // This direction is not implemented except in tables.
-
- if (!GetTableRow() || !GetTableColumn() || !GetTableColumnSpan())
- return E_NOTIMPL;
-
- AXPlatformNodeBase* next = target->GetTableCell(
- *GetTableRow(), *GetTableColumn() + *GetTableColumnSpan());
- if (!next)
- return S_OK;
-
- result = next->GetNativeViewAccessible();
- break;
- }
- }
-
- if (!result)
- return S_FALSE;
-
- end->vt = VT_DISPATCH;
- end->pdispVal = result;
- // Always increment ref when returning a reference to a COM object.
- end->pdispVal->AddRef();
-
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accChild(VARIANT var_child,
- IDispatch** disp_child) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_CHILD);
-
- *disp_child = nullptr;
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_child, target);
-
- *disp_child = target;
- (*disp_child)->AddRef();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accChildCount(LONG* child_count) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_CHILD_COUNT);
- COM_OBJECT_VALIDATE_1_ARG(child_count);
- *child_count = GetDelegate()->GetChildCount();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accDefaultAction(VARIANT var_id,
- BSTR* def_action) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_DEFAULT_ACTION);
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, def_action, target);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- int action;
- if (!target->GetIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb,
- &action)) {
- *def_action = nullptr;
- return S_FALSE;
- }
-
- base::string16 action_verb = base::UTF8ToUTF16(
- ui::ToLocalizedString(static_cast<ax::mojom::DefaultActionVerb>(action)));
- if (action_verb.empty()) {
- *def_action = nullptr;
- return S_FALSE;
- }
-
- *def_action = SysAllocString(action_verb.c_str());
- DCHECK(def_action);
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accDescription(VARIANT var_id,
- BSTR* desc) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_DESCRIPTION);
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, desc, target);
-
- return target->GetStringAttributeAsBstr(
- ax::mojom::StringAttribute::kDescription, desc);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accFocus(VARIANT* focus_child) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_FOCUS);
- COM_OBJECT_VALIDATE_1_ARG(focus_child);
- gfx::NativeViewAccessible focus_accessible = GetDelegate()->GetFocus();
- if (focus_accessible == this) {
- focus_child->vt = VT_I4;
- focus_child->lVal = CHILDID_SELF;
- } else if (focus_accessible) {
- Microsoft::WRL::ComPtr<IDispatch> focus_idispatch;
- if (FAILED(
- focus_accessible->QueryInterface(IID_PPV_ARGS(&focus_idispatch)))) {
- focus_child->vt = VT_EMPTY;
- return E_FAIL;
- }
-
- focus_child->vt = VT_DISPATCH;
- focus_child->pdispVal = focus_idispatch.Detach();
- } else {
- focus_child->vt = VT_EMPTY;
- }
-
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accKeyboardShortcut(VARIANT var_id,
- BSTR* acc_key) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_KEYBOARD_SHORTCUT);
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, acc_key, target);
-
- return target->GetStringAttributeAsBstr(
- ax::mojom::StringAttribute::kKeyShortcuts, acc_key);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accName(VARIANT var_id, BSTR* name_bstr) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_NAME);
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, name_bstr, target);
-
- for (WinAccessibilityAPIUsageObserver& observer :
- GetWinAccessibilityAPIUsageObserverList()) {
- observer.OnAccNameCalled();
- }
-
- if (!IsNameExposed())
- return S_FALSE;
-
- bool has_name = target->HasStringAttribute(ax::mojom::StringAttribute::kName);
- base::string16 name = target->GetNameAsString16();
- auto status = GetData().GetImageAnnotationStatus();
- switch (status) {
- case ax::mojom::ImageAnnotationStatus::kNone:
- case ax::mojom::ImageAnnotationStatus::kWillNotAnnotateDueToScheme:
- case ax::mojom::ImageAnnotationStatus::kIneligibleForAnnotation:
- case ax::mojom::ImageAnnotationStatus::kSilentlyEligibleForAnnotation:
- break;
-
- case ax::mojom::ImageAnnotationStatus::kEligibleForAnnotation:
- case ax::mojom::ImageAnnotationStatus::kAnnotationPending:
- case ax::mojom::ImageAnnotationStatus::kAnnotationEmpty:
- case ax::mojom::ImageAnnotationStatus::kAnnotationAdult:
- case ax::mojom::ImageAnnotationStatus::kAnnotationProcessFailed:
- AppendTextToString(
- GetDelegate()->GetLocalizedStringForImageAnnotationStatus(status),
- &name);
- break;
-
- case ax::mojom::ImageAnnotationStatus::kAnnotationSucceeded:
- AppendTextToString(
- GetString16Attribute(ax::mojom::StringAttribute::kImageAnnotation),
- &name);
- break;
- }
-
- if (name.empty() && !has_name)
- return S_FALSE;
-
- *name_bstr = SysAllocString(name.c_str());
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accParent(IDispatch** disp_parent) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_PARENT);
- COM_OBJECT_VALIDATE_1_ARG(disp_parent);
- *disp_parent = GetParent();
- if (*disp_parent) {
- (*disp_parent)->AddRef();
- return S_OK;
- }
-
- return S_FALSE;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accRole(VARIANT var_id, VARIANT* role) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_ROLE);
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, role, target);
-
- role->vt = VT_I4;
- role->lVal = target->MSAARole();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accState(VARIANT var_id, VARIANT* state) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_STATE);
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, state, target);
- state->vt = VT_I4;
- state->lVal = target->MSAAState();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accHelp(VARIANT var_id, BSTR* help) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_HELP);
- COM_OBJECT_VALIDATE_1_ARG(help);
- return S_FALSE;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_VALUE);
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, value, target);
- *value = GetValueAttributeAsBstr(target);
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::put_accValue(VARIANT var_id, BSTR new_value) {
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target);
- if (!new_value)
- return E_INVALIDARG;
-
- AXActionData data;
- data.action = ax::mojom::Action::kSetValue;
- data.value = base::WideToUTF8(new_value);
- if (target->GetDelegate()->AccessibilityPerformAction(data))
- return S_OK;
- return E_FAIL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accSelection(VARIANT* selected) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_SELECTION);
- COM_OBJECT_VALIDATE_1_ARG(selected);
- std::vector<Microsoft::WRL::ComPtr<IDispatch>> selected_nodes;
- for (int i = 0; i < GetDelegate()->GetChildCount(); ++i) {
- auto* node = static_cast<AXPlatformNodeWin*>(
- FromNativeViewAccessible(GetDelegate()->ChildAtIndex(i)));
- if (node &&
- node->GetData().GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
- Microsoft::WRL::ComPtr<IDispatch> node_idispatch;
- if (SUCCEEDED(node->QueryInterface(IID_PPV_ARGS(&node_idispatch))))
- selected_nodes.push_back(node_idispatch);
- }
- }
-
- if (selected_nodes.empty()) {
- selected->vt = VT_EMPTY;
- return S_OK;
- }
-
- if (selected_nodes.size() == 1) {
- selected->vt = VT_DISPATCH;
- selected->pdispVal = selected_nodes[0].Detach();
- return S_OK;
- }
-
- // Multiple items are selected.
- LONG selected_count = static_cast<LONG>(selected_nodes.size());
- Microsoft::WRL::ComPtr<base::win::EnumVariant> enum_variant =
- Microsoft::WRL::Make<base::win::EnumVariant>(selected_count);
- for (LONG i = 0; i < selected_count; ++i) {
- enum_variant->ItemAt(i)->vt = VT_DISPATCH;
- enum_variant->ItemAt(i)->pdispVal = selected_nodes[i].Detach();
- }
- selected->vt = VT_UNKNOWN;
- return enum_variant.CopyTo(IID_PPV_ARGS(&V_UNKNOWN(selected)));
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::accSelect(LONG flagsSelect, VARIANT var_id) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ACC_SELECT);
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target);
-
- if (flagsSelect & SELFLAG_TAKEFOCUS) {
- AXActionData action_data;
- action_data.action = ax::mojom::Action::kFocus;
- target->GetDelegate()->AccessibilityPerformAction(action_data);
- return S_OK;
- }
-
- return S_FALSE;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accHelpTopic(BSTR* help_file,
- VARIANT var_id,
- LONG* topic_id) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_HELP_TOPIC);
- AXPlatformNodeWin* target;
- COM_OBJECT_VALIDATE_VAR_ID_2_ARGS_AND_GET_TARGET(var_id, help_file, topic_id,
- target);
- if (help_file) {
- *help_file = nullptr;
- }
- if (topic_id) {
- *topic_id = static_cast<LONG>(-1);
- }
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::put_accName(VARIANT var_id, BSTR put_name) {
- // TODO(dougt): We may want to collect an API histogram here.
- // Deprecated.
- return E_NOTIMPL;
-}
-
-//
-// IAccessible2 implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::role(LONG* role) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ROLE);
- COM_OBJECT_VALIDATE_1_ARG(role);
-
- *role = ComputeIA2Role();
- // If we didn't explicitly set the IAccessible2 role, make it the same
- // as the MSAA role.
- if (!*role)
- *role = MSAARole();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_states(AccessibleStates* states) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_STATES);
- COM_OBJECT_VALIDATE_1_ARG(states);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- *states = ComputeIA2State();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_uniqueID(LONG* id) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_UNIQUE_ID);
- COM_OBJECT_VALIDATE_1_ARG(id);
- // We want to negate the unique id for it to be consistent across different
- // Windows accessiblity APIs. The negative unique id convention originated
- // from ::NotifyWinEvent() takes an hwnd and a child id. A 0 child id means
- // self, and a positive child id means child #n. In order to fire an event for
- // an arbitrary descendant of the window, Firefox started the practice of
- // using a negative unique id. We follow the same negative unique id
- // convention here and when we fire events via
- // ::NotifyWinEvent().
- *id = -GetUniqueId();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_windowHandle(HWND* window_handle) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_WINDOW_HANDLE);
- COM_OBJECT_VALIDATE_1_ARG(window_handle);
- *window_handle = GetDelegate()->GetTargetForNativeAccessibilityEvent();
- return *window_handle ? S_OK : S_FALSE;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_relationTargetsOfType(BSTR type_bstr,
- LONG max_targets,
- IUnknown*** targets,
- LONG* n_targets) {
- COM_OBJECT_VALIDATE_2_ARGS(targets, n_targets);
- if (!type_bstr)
- return E_INVALIDARG;
-
- *n_targets = 0;
- *targets = nullptr;
-
- // Special case for relations of type "alerts".
- base::string16 type(type_bstr);
- if (type == L"alerts") {
- // Collect all of the objects that have had an alert fired on them that
- // are a descendant of this object.
- std::vector<AXPlatformNodeWin*> alert_targets;
- for (auto iter = g_alert_targets.Get().begin();
- iter != g_alert_targets.Get().end(); ++iter) {
- AXPlatformNodeWin* target = *iter;
- if (IsDescendant(target))
- alert_targets.push_back(target);
- }
-
- LONG count = static_cast<LONG>(alert_targets.size());
- if (count == 0)
- return S_FALSE;
-
- // Don't return more targets than max_targets - but note that the caller
- // is allowed to specify max_targets=0 to mean no limit.
- if (max_targets > 0 && count > max_targets)
- count = max_targets;
-
- // Return the number of targets.
- *n_targets = count;
-
- // Allocate COM memory for the result array and populate it.
- *targets =
- static_cast<IUnknown**>(CoTaskMemAlloc(count * sizeof(IUnknown*)));
- for (LONG i = 0; i < count; ++i) {
- (*targets)[i] = static_cast<IAccessible*>(alert_targets[i]);
- (*targets)[i]->AddRef();
- }
- return S_OK;
- }
-
- base::string16 relation_type;
- std::set<AXPlatformNode*> enumerated_targets;
- int found = AXPlatformRelationWin::EnumerateRelationships(
- this, 0, type, &relation_type, &enumerated_targets);
- if (found == 0)
- return S_FALSE;
-
- // Don't return more targets than max_targets - but note that the caller
- // is allowed to specify max_targets=0 to mean no limit.
- int count = static_cast<int>(enumerated_targets.size());
- if (max_targets > 0 && count > max_targets)
- count = max_targets;
-
- // Allocate COM memory for the result array and populate it.
- *targets = static_cast<IUnknown**>(CoTaskMemAlloc(count * sizeof(IUnknown*)));
- int index = 0;
- for (AXPlatformNode* target : enumerated_targets) {
- if (target) {
- AXPlatformNodeWin* win_target = static_cast<AXPlatformNodeWin*>(target);
- (*targets)[index] = static_cast<IAccessible*>(win_target);
- (*targets)[index]->AddRef();
- if (++index > count)
- break;
- }
- }
- *n_targets = index;
- return index > 0 ? S_OK : S_FALSE;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_attributes(BSTR* attributes) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_IA2_GET_ATTRIBUTES);
- COM_OBJECT_VALIDATE_1_ARG(attributes);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
- *attributes = nullptr;
-
- base::string16 attributes_str;
- std::vector<base::string16> computed_attributes = ComputeIA2Attributes();
- for (const base::string16& attribute : computed_attributes)
- attributes_str += attribute + L';';
-
- if (attributes_str.empty())
- return S_FALSE;
-
- *attributes = SysAllocString(attributes_str.c_str());
- DCHECK(*attributes);
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_indexInParent(LONG* index_in_parent) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_INDEX_IN_PARENT);
- COM_OBJECT_VALIDATE_1_ARG(index_in_parent);
- base::Optional<int> index = GetIndexInParent();
- if (!index.has_value())
- return E_FAIL;
-
- *index_in_parent = index.value();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_nRelations(LONG* n_relations) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_RELATIONS);
- COM_OBJECT_VALIDATE_1_ARG(n_relations);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- int count = AXPlatformRelationWin::EnumerateRelationships(
- this, -1, base::string16(), nullptr, nullptr);
- *n_relations = count;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_relation(LONG relation_index,
- IAccessibleRelation** relation) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_RELATION);
- COM_OBJECT_VALIDATE_1_ARG(relation);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::string16 relation_type;
- std::set<AXPlatformNode*> targets;
- int found = AXPlatformRelationWin::EnumerateRelationships(
- this, relation_index, base::string16(), &relation_type, &targets);
- if (found == 0)
- return E_INVALIDARG;
-
- CComObject<AXPlatformRelationWin>* relation_obj;
- HRESULT hr = CComObject<AXPlatformRelationWin>::CreateInstance(&relation_obj);
- DCHECK(SUCCEEDED(hr));
- relation_obj->AddRef();
- relation_obj->Initialize(relation_type);
- for (AXPlatformNode* target : targets) {
- if (target)
- relation_obj->AddTarget(static_cast<AXPlatformNodeWin*>(target));
- }
-
- // Maintain references to all relations returned by this object.
- // Every time this object changes state, invalidate them.
- relations_.push_back(relation_obj);
- *relation = relation_obj;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_relations(LONG max_relations,
- IAccessibleRelation** relations,
- LONG* n_relations) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_RELATIONS);
- COM_OBJECT_VALIDATE_2_ARGS(relations, n_relations);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- LONG count;
- HRESULT hr = get_nRelations(&count);
- if (!SUCCEEDED(hr))
- return hr;
- count = std::min(count, max_relations);
- *n_relations = count;
- for (LONG i = 0; i < count; i++) {
- hr = get_relation(i, &relations[i]);
- if (!SUCCEEDED(hr))
- return hr;
- }
-
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_groupPosition(
- LONG* group_level,
- LONG* similar_items_in_group,
- LONG* position_in_group) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_GROUP_POSITION);
- COM_OBJECT_VALIDATE_3_ARGS(group_level, similar_items_in_group,
- position_in_group);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- *group_level = GetIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel);
- *similar_items_in_group = GetSetSize().value_or(0);
- *position_in_group = GetPosInSet().value_or(0);
-
- if (!*group_level && !*similar_items_in_group && !*position_in_group)
- return S_FALSE;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_localizedExtendedRole(
- BSTR* localized_extended_role) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_LOCALIZED_EXTENDED_ROLE);
- COM_OBJECT_VALIDATE_1_ARG(localized_extended_role);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::string16 role_description =
- GetRoleDescriptionFromImageAnnotationStatusOrFromAttribute();
- if (base::ContainsOnlyChars(role_description, base::kWhitespaceUTF16))
- return S_FALSE;
-
- *localized_extended_role = SysAllocString(role_description.c_str());
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_attribute(BSTR name, VARIANT* attribute) {
- COM_OBJECT_VALIDATE_1_ARG(attribute);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::string16 desired_attribute(name);
-
- // Each computed attribute from ComputeIA2Attributes is a string of
- // the form "key:value". Search for strings that start with the
- // attribute name plus a colon.
- base::string16 prefix = desired_attribute + L":";
-
- // Let's accept any case.
- const auto compare_case = base::CompareCase::INSENSITIVE_ASCII;
-
- const std::vector<base::string16> computed_attributes =
- ComputeIA2Attributes();
- for (const base::string16& computed_attribute : computed_attributes) {
- if (base::StartsWith(computed_attribute, prefix, compare_case)) {
- base::string16 value = computed_attribute.substr(prefix.size());
- attribute->vt = VT_BSTR;
- attribute->bstrVal = SysAllocString(value.c_str());
- return S_OK;
- }
- }
-
- return S_FALSE;
-}
-
-//
-// IAccessible2 methods not implemented.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::get_extendedRole(BSTR* extended_role) {
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::scrollTo(enum IA2ScrollType ia2_scroll_type) {
- COM_OBJECT_VALIDATE();
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_IA2_SCROLL_TO);
-
- switch (ia2_scroll_type) {
- case IA2_SCROLL_TYPE_TOP_LEFT:
- ScrollToNode(ScrollType::TopLeft);
- break;
- case IA2_SCROLL_TYPE_BOTTOM_RIGHT:
- ScrollToNode(ScrollType::BottomRight);
- break;
- case IA2_SCROLL_TYPE_TOP_EDGE:
- ScrollToNode(ScrollType::TopEdge);
- break;
- case IA2_SCROLL_TYPE_BOTTOM_EDGE:
- ScrollToNode(ScrollType::BottomEdge);
- break;
- case IA2_SCROLL_TYPE_LEFT_EDGE:
- ScrollToNode(ScrollType::LeftEdge);
- break;
- case IA2_SCROLL_TYPE_RIGHT_EDGE:
- ScrollToNode(ScrollType::RightEdge);
- break;
- case IA2_SCROLL_TYPE_ANYWHERE:
- ScrollToNode(ScrollType::Anywhere);
- break;
- }
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::scrollToPoint(
- enum IA2CoordinateType coordinate_type,
- LONG x,
- LONG y) {
- COM_OBJECT_VALIDATE();
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SCROLL_TO_POINT);
-
- // Convert to screen-relative coordinates if necessary.
- gfx::Point scroll_to(x, y);
- if (coordinate_type == IA2_COORDTYPE_PARENT_RELATIVE) {
- if (GetParent()) {
- AXPlatformNodeBase* base = FromNativeViewAccessible(GetParent());
- scroll_to += base->GetDelegate()
- ->GetBoundsRect(AXCoordinateSystem::kScreenDIPs,
- AXClippingBehavior::kUnclipped)
- .OffsetFromOrigin();
- }
- } else if (coordinate_type != IA2_COORDTYPE_SCREEN_RELATIVE) {
- return E_INVALIDARG;
- }
-
- AXActionData action_data;
- action_data.target_node_id = GetData().id;
- action_data.action = ax::mojom::Action::kScrollToPoint;
- action_data.target_point = scroll_to;
- GetDelegate()->AccessibilityPerformAction(action_data);
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_nExtendedStates(LONG* n_extended_states) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_EXTENDED_STATES);
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_extendedStates(LONG max_extended_states,
- BSTR** extended_states,
- LONG* n_extended_states) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_EXTENDED_STATES);
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_localizedExtendedStates(
- LONG max_localized_extended_states,
- BSTR** localized_extended_states,
- LONG* n_localized_extended_states) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_LOCALIZED_EXTENDED_STATES);
-
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_locale(IA2Locale* locale) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_LOCALE);
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accessibleWithCaret(IUnknown** accessible,
- LONG* caret_offset) {
- return E_NOTIMPL;
-}
-
-//
-// IAccessible2_3 implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::get_selectionRanges(IA2Range** ranges,
- LONG* nRanges) {
- COM_OBJECT_VALIDATE_2_ARGS(ranges, nRanges);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
- AXTree::Selection unignored_selection =
- GetDelegate()->GetUnignoredSelection();
- int32_t anchor_id = unignored_selection.anchor_object_id;
- auto* anchor_node =
- static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(anchor_id));
- if (!anchor_node)
- return E_FAIL;
- int anchor_offset = int{unignored_selection.anchor_offset};
-
- int32_t focus_id = unignored_selection.focus_object_id;
- auto* focus_node =
- static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(focus_id));
- if (!focus_node)
- return E_FAIL;
- int focus_offset = int{unignored_selection.focus_offset};
-
- if (!IsDescendant(anchor_node) || !IsDescendant(focus_node))
- return S_FALSE; // No selection within this subtree.
-
- *ranges = reinterpret_cast<IA2Range*>(CoTaskMemAlloc(sizeof(IA2Range)));
- anchor_node->AddRef();
- ranges[0]->anchor = static_cast<IAccessible*>(anchor_node);
- ranges[0]->anchorOffset = anchor_offset;
- focus_node->AddRef();
- ranges[0]->active = static_cast<IAccessible*>(focus_node);
- ranges[0]->activeOffset = focus_offset;
- *nRanges = 1;
- return S_OK;
-}
-
-//
-// IAccessible2_4 implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::setSelectionRanges(LONG nRanges,
- IA2Range* ranges) {
- COM_OBJECT_VALIDATE();
- // Blink supports only one selection range for now.
- if (nRanges != 1)
- return E_INVALIDARG;
- if (!ranges)
- return E_INVALIDARG;
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- if (!ranges->anchor)
- return E_INVALIDARG;
- if (!ranges->active)
- return E_INVALIDARG;
-
- Microsoft::WRL::ComPtr<IAccessible> anchor;
- if (FAILED(ranges->anchor->QueryInterface(IID_PPV_ARGS(&anchor))))
- return E_INVALIDARG;
-
- Microsoft::WRL::ComPtr<IAccessible> focus;
- if (FAILED(ranges->active->QueryInterface(IID_PPV_ARGS(&focus))))
- return E_INVALIDARG;
-
- const auto* anchor_node =
- static_cast<AXPlatformNodeWin*>(FromNativeViewAccessible(anchor.Get()));
- const auto* focus_node =
- static_cast<AXPlatformNodeWin*>(FromNativeViewAccessible(focus.Get()));
- if (!anchor_node || !focus_node)
- return E_INVALIDARG;
-
- // Blink only supports selections within a single tree.
- if (anchor_node->GetDelegate()->GetTreeData().tree_id !=
- focus_node->GetDelegate()->GetTreeData().tree_id) {
- return E_INVALIDARG;
- }
-
- if (ranges->anchorOffset < 0 || ranges->activeOffset < 0)
- return E_INVALIDARG;
-
- if (anchor_node->IsLeaf()) {
- if (size_t{ranges->anchorOffset} > anchor_node->GetHypertext().length()) {
- return E_INVALIDARG;
- }
- } else {
- if (ranges->anchorOffset > anchor_node->GetChildCount())
- return E_INVALIDARG;
- }
-
- if (focus_node->IsLeaf()) {
- if (size_t{ranges->activeOffset} > focus_node->GetHypertext().length())
- return E_INVALIDARG;
- } else {
- if (ranges->activeOffset > focus_node->GetChildCount())
- return E_INVALIDARG;
- }
-
- AXActionData action_data;
- action_data.action = ax::mojom::Action::kSetSelection;
- action_data.anchor_node_id = anchor_node->GetData().id;
- action_data.anchor_offset = int32_t{ranges->anchorOffset};
- action_data.focus_node_id = focus_node->GetData().id;
- action_data.focus_offset = int32_t{ranges->activeOffset};
- if (GetDelegate()->AccessibilityPerformAction(action_data))
- return S_OK;
- return S_FALSE;
-}
-
-//
-// IAccessibleEx implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::GetObjectForChild(LONG child_id,
- IAccessibleEx** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_OBJECT_FOR_CHILD);
- // No support for child IDs in this implementation.
- COM_OBJECT_VALIDATE_1_ARG(result);
- *result = nullptr;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::GetIAccessiblePair(IAccessible** accessible,
- LONG* child_id) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_IACCESSIBLE_PAIR);
- COM_OBJECT_VALIDATE_2_ARGS(accessible, child_id);
- *accessible = static_cast<IAccessible*>(this);
- (*accessible)->AddRef();
- *child_id = CHILDID_SELF;
- return S_OK;
-}
-
-//
-// IExpandCollapseProvider implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::Collapse() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_EXPANDCOLLAPSE_COLLAPSE);
- UIA_VALIDATE_CALL();
- if (GetData().GetRestriction() == ax::mojom::Restriction::kDisabled)
- return UIA_E_ELEMENTNOTAVAILABLE;
-
- if (GetData().HasState(ax::mojom::State::kCollapsed))
- return UIA_E_INVALIDOPERATION;
-
- AXActionData action_data;
- action_data.action = ax::mojom::Action::kDoDefault;
- if (GetDelegate()->AccessibilityPerformAction(action_data))
- return S_OK;
- return E_FAIL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::Expand() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_EXPANDCOLLAPSE_EXPAND);
- UIA_VALIDATE_CALL();
- if (GetData().GetRestriction() == ax::mojom::Restriction::kDisabled)
- return UIA_E_ELEMENTNOTAVAILABLE;
-
- if (GetData().HasState(ax::mojom::State::kExpanded))
- return UIA_E_INVALIDOPERATION;
-
- AXActionData action_data;
- action_data.action = ax::mojom::Action::kDoDefault;
- if (GetDelegate()->AccessibilityPerformAction(action_data))
- return S_OK;
- return E_FAIL;
-}
-
-ExpandCollapseState AXPlatformNodeWin::ComputeExpandCollapseState() const {
- const AXNodeData& data = GetData();
-
- // Since a menu button implies there is a popup and it is either expanded or
- // collapsed, and it should not support ExpandCollapseState_LeafNode.
- // According to the UIA spec, ExpandCollapseState_LeafNode indicates that the
- // element neither expands nor collapses.
- if (data.IsMenuButton()) {
- if (data.IsButtonPressed())
- return ExpandCollapseState_Expanded;
- return ExpandCollapseState_Collapsed;
- }
-
- if (data.HasState(ax::mojom::State::kExpanded)) {
- return ExpandCollapseState_Expanded;
- } else if (data.HasState(ax::mojom::State::kCollapsed)) {
- return ExpandCollapseState_Collapsed;
- } else {
- return ExpandCollapseState_LeafNode;
- }
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_ExpandCollapseState(
- ExpandCollapseState* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(
- UMA_API_EXPANDCOLLAPSE_GET_EXPANDCOLLAPSESTATE);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- *result = ComputeExpandCollapseState();
-
- return S_OK;
-}
-
-//
-// IGridItemProvider implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::get_Column(int* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GRIDITEM_GET_COLUMN);
- UIA_VALIDATE_CALL_1_ARG(result);
- base::Optional<int> column = GetTableColumn();
- if (!column)
- return E_FAIL;
- *result = *column;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_ColumnSpan(int* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GRIDITEM_GET_COLUMNSPAN);
- UIA_VALIDATE_CALL_1_ARG(result);
- base::Optional<int> column_span = GetTableColumnSpan();
- if (!column_span)
- return E_FAIL;
- *result = *column_span;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_ContainingGrid(
- IRawElementProviderSimple** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GRIDITEM_GET_CONTAININGGRID);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- AXPlatformNodeBase* table = GetTable();
- if (!table)
- return E_FAIL;
-
- auto* node_win = static_cast<AXPlatformNodeWin*>(table);
- node_win->AddRef();
- *result = static_cast<IRawElementProviderSimple*>(node_win);
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_Row(int* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GRIDITEM_GET_ROW);
- UIA_VALIDATE_CALL_1_ARG(result);
- base::Optional<int> row = GetTableRow();
- if (!row)
- return E_FAIL;
- *result = *row;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_RowSpan(int* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GRIDITEM_GET_ROWSPAN);
- UIA_VALIDATE_CALL_1_ARG(result);
- base::Optional<int> row_span = GetTableRowSpan();
- if (!row_span)
- return E_FAIL;
- *result = *row_span;
- return S_OK;
-}
-
-//
-// IGridProvider implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::GetItem(int row,
- int column,
- IRawElementProviderSimple** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GRID_GETITEM);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- AXPlatformNodeBase* cell = GetTableCell(row, column);
- if (!cell)
- return E_INVALIDARG;
-
- auto* node_win = static_cast<AXPlatformNodeWin*>(cell);
- node_win->AddRef();
- *result = static_cast<IRawElementProviderSimple*>(node_win);
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_RowCount(int* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GRID_GET_ROWCOUNT);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- base::Optional<int> row_count = GetTableAriaRowCount();
- if (!row_count)
- row_count = GetTableRowCount();
-
- if (!row_count || *row_count == ax::mojom::kUnknownAriaColumnOrRowCount)
- return E_UNEXPECTED;
- *result = *row_count;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_ColumnCount(int* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GRID_GET_COLUMNCOUNT);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- base::Optional<int> column_count = GetTableAriaColumnCount();
- if (!column_count)
- column_count = GetTableColumnCount();
-
- if (!column_count ||
- *column_count == ax::mojom::kUnknownAriaColumnOrRowCount) {
- return E_UNEXPECTED;
- }
- *result = *column_count;
- return S_OK;
-}
-
-//
-// IInvokeProvider implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::Invoke() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_INVOKE_INVOKE);
- UIA_VALIDATE_CALL();
-
- if (GetData().GetRestriction() == ax::mojom::Restriction::kDisabled)
- return UIA_E_ELEMENTNOTENABLED;
-
- AXActionData action_data;
- action_data.action = ax::mojom::Action::kDoDefault;
- GetDelegate()->AccessibilityPerformAction(action_data);
-
- return S_OK;
-}
-
-//
-// IScrollItemProvider implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::ScrollIntoView() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SCROLLITEM_SCROLLINTOVIEW);
- UIA_VALIDATE_CALL();
- gfx::Rect r = gfx::ToEnclosingRect(GetData().relative_bounds.bounds);
- r -= r.OffsetFromOrigin();
-
- AXActionData action_data;
- action_data.target_node_id = GetData().id;
- action_data.target_rect = r;
- action_data.horizontal_scroll_alignment =
- ax::mojom::ScrollAlignment::kScrollAlignmentCenter;
- action_data.vertical_scroll_alignment =
- ax::mojom::ScrollAlignment::kScrollAlignmentCenter;
- action_data.scroll_behavior =
- ax::mojom::ScrollBehavior::kDoNotScrollIfVisible;
- if (GetDelegate()->AccessibilityPerformAction(action_data))
- return S_OK;
- return E_FAIL;
-}
-
-//
-// IScrollProvider implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::Scroll(ScrollAmount horizontal_amount,
- ScrollAmount vertical_amount) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SCROLL_SCROLL);
- UIA_VALIDATE_CALL();
- if (!IsScrollable())
- return E_FAIL;
-
- AXActionData action_data;
- action_data.target_node_id = GetData().id;
- action_data.action = ax::mojom::Action::kSetScrollOffset;
- action_data.target_point = gfx::PointAtOffsetFromOrigin(
- CalculateUIAScrollPoint(horizontal_amount, vertical_amount));
- if (GetDelegate()->AccessibilityPerformAction(action_data))
- return S_OK;
- return E_FAIL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::SetScrollPercent(double horizontal_percent,
- double vertical_percent) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SCROLL_SETSCROLLPERCENT);
- UIA_VALIDATE_CALL();
- if (!IsScrollable())
- return E_FAIL;
-
- const double x_min = GetIntAttribute(ax::mojom::IntAttribute::kScrollXMin);
- const double x_max = GetIntAttribute(ax::mojom::IntAttribute::kScrollXMax);
- const double y_min = GetIntAttribute(ax::mojom::IntAttribute::kScrollYMin);
- const double y_max = GetIntAttribute(ax::mojom::IntAttribute::kScrollYMax);
- const int x =
- base::ClampRound(horizontal_percent / 100.0 * (x_max - x_min) + x_min);
- const int y =
- base::ClampRound(vertical_percent / 100.0 * (y_max - y_min) + y_min);
- const gfx::Point scroll_to(x, y);
-
- AXActionData action_data;
- action_data.target_node_id = GetData().id;
- action_data.action = ax::mojom::Action::kSetScrollOffset;
- action_data.target_point = scroll_to;
- if (GetDelegate()->AccessibilityPerformAction(action_data))
- return S_OK;
- return E_FAIL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_HorizontallyScrollable(BOOL* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SCROLL_GET_HORIZONTALLYSCROLLABLE);
- UIA_VALIDATE_CALL_1_ARG(result);
- *result = IsHorizontallyScrollable();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_HorizontalScrollPercent(double* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SCROLL_GET_HORIZONTALSCROLLPERCENT);
- UIA_VALIDATE_CALL_1_ARG(result);
- *result = GetHorizontalScrollPercent();
- return S_OK;
-}
-
-// Horizontal size of the viewable region as a percentage of the total content
-// area.
-IFACEMETHODIMP AXPlatformNodeWin::get_HorizontalViewSize(double* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SCROLL_GET_HORIZONTALVIEWSIZE);
- UIA_VALIDATE_CALL_1_ARG(result);
- if (!IsHorizontallyScrollable()) {
- *result = 100.;
- return S_OK;
- }
-
- gfx::RectF clipped_bounds(GetDelegate()->GetBoundsRect(
- AXCoordinateSystem::kScreenDIPs, AXClippingBehavior::kClipped));
- float x_min = GetIntAttribute(ax::mojom::IntAttribute::kScrollXMin);
- float x_max = GetIntAttribute(ax::mojom::IntAttribute::kScrollXMax);
- float total_width = clipped_bounds.width() + x_max - x_min;
- DCHECK_LE(clipped_bounds.width(), total_width);
- *result = 100.0 * clipped_bounds.width() / total_width;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_VerticallyScrollable(BOOL* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SCROLL_GET_VERTICALLYSCROLLABLE);
- UIA_VALIDATE_CALL_1_ARG(result);
- *result = IsVerticallyScrollable();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_VerticalScrollPercent(double* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SCROLL_GET_VERTICALSCROLLPERCENT);
- UIA_VALIDATE_CALL_1_ARG(result);
- *result = GetVerticalScrollPercent();
- return S_OK;
-}
-
-// Vertical size of the viewable region as a percentage of the total content
-// area.
-IFACEMETHODIMP AXPlatformNodeWin::get_VerticalViewSize(double* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SCROLL_GET_VERTICALVIEWSIZE);
- UIA_VALIDATE_CALL_1_ARG(result);
- if (!IsVerticallyScrollable()) {
- *result = 100.0;
- return S_OK;
- }
-
- gfx::RectF clipped_bounds(GetDelegate()->GetBoundsRect(
- AXCoordinateSystem::kScreenDIPs, AXClippingBehavior::kClipped));
- float y_min = GetIntAttribute(ax::mojom::IntAttribute::kScrollYMin);
- float y_max = GetIntAttribute(ax::mojom::IntAttribute::kScrollYMax);
- float total_height = clipped_bounds.height() + y_max - y_min;
- DCHECK_LE(clipped_bounds.height(), total_height);
- *result = 100.0 * clipped_bounds.height() / total_height;
- return S_OK;
-}
-
-//
-// ISelectionItemProvider implementation.
-//
-
-HRESULT AXPlatformNodeWin::ISelectionItemProviderSetSelected(
- bool selected) const {
- UIA_VALIDATE_CALL();
- if (GetData().GetRestriction() == ax::mojom::Restriction::kDisabled)
- return UIA_E_ELEMENTNOTENABLED;
-
- // The platform implements selection follows focus for single-selection
- // container elements. Focus action can change a node's accessibility selected
- // state, but does not cause the actual control to be selected.
- // https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_selection_follows_focus
- // https://www.w3.org/TR/core-aam-1.2/#mapping_events_selection
- //
- // We don't want to perform |Action::kDoDefault| for an ax node that has
- // |kSelected=true| and |kSelectedFromFocus=false|, because perform
- // |Action::kDoDefault| may cause the control to be unselected. However, if an
- // ax node is selected due to focus, i.e. |kSelectedFromFocus=true|, we need
- // to perform |Action::kDoDefault| on the ax node, since focus action only
- // changes an ax node's accessibility selected state to |kSelected=true| and
- // no |Action::kDoDefault| was performed on that node yet. So we need to
- // perform |Action::kDoDefault| on the ax node to cause its associated control
- // to be selected.
- if (selected == ISelectionItemProviderIsSelected() &&
- !GetBoolAttribute(ax::mojom::BoolAttribute::kSelectedFromFocus))
- return S_OK;
-
- AXActionData data;
- data.action = ax::mojom::Action::kDoDefault;
- if (GetDelegate()->AccessibilityPerformAction(data))
- return S_OK;
- return UIA_E_INVALIDOPERATION;
-}
-
-bool AXPlatformNodeWin::ISelectionItemProviderIsSelected() const {
- // https://www.w3.org/TR/core-aam-1.1/#mapping_state-property_table
- // SelectionItem.IsSelected is set according to the True or False value of
- // aria-checked for 'radio' and 'menuitemradio' roles.
- if (GetData().role == ax::mojom::Role::kRadioButton ||
- GetData().role == ax::mojom::Role::kMenuItemRadio)
- return GetData().GetCheckedState() == ax::mojom::CheckedState::kTrue;
-
- // https://www.w3.org/TR/wai-aria-1.1/#aria-selected
- // SelectionItem.IsSelected is set according to the True or False value of
- // aria-selected.
- return GetBoolAttribute(ax::mojom::BoolAttribute::kSelected);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::AddToSelection() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SELECTIONITEM_ADDTOSELECTION);
- return ISelectionItemProviderSetSelected(true);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::RemoveFromSelection() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SELECTIONITEM_REMOVEFROMSELECTION);
- return ISelectionItemProviderSetSelected(false);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::Select() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SELECTIONITEM_SELECT);
- return ISelectionItemProviderSetSelected(true);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_IsSelected(BOOL* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SELECTIONITEM_GET_ISSELECTED);
- UIA_VALIDATE_CALL_1_ARG(result);
- *result = ISelectionItemProviderIsSelected();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_SelectionContainer(
- IRawElementProviderSimple** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SELECTIONITEM_GET_SELECTIONCONTAINER);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- auto* node_win = static_cast<AXPlatformNodeWin*>(GetSelectionContainer());
- if (!node_win)
- return E_FAIL;
-
- node_win->AddRef();
- *result = static_cast<IRawElementProviderSimple*>(node_win);
- return S_OK;
-}
-
-//
-// ISelectionProvider implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::GetSelection(SAFEARRAY** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SELECTION_GETSELECTION);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- std::vector<AXPlatformNodeBase*> selected_children;
- int max_items = GetMaxSelectableItems();
- if (max_items)
- GetSelectedItems(max_items, &selected_children);
-
- LONG selected_children_count = selected_children.size();
- *result = SafeArrayCreateVector(VT_UNKNOWN, 0, selected_children_count);
- if (!*result)
- return E_OUTOFMEMORY;
-
- for (LONG i = 0; i < selected_children_count; ++i) {
- AXPlatformNodeWin* children =
- static_cast<AXPlatformNodeWin*>(selected_children[i]);
- HRESULT hr = SafeArrayPutElement(
- *result, &i, static_cast<IRawElementProviderSimple*>(children));
- if (FAILED(hr)) {
- SafeArrayDestroy(*result);
- *result = nullptr;
- return hr;
- }
- }
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_CanSelectMultiple(BOOL* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SELECTION_GET_CANSELECTMULTIPLE);
- UIA_VALIDATE_CALL_1_ARG(result);
- *result = GetData().HasState(ax::mojom::State::kMultiselectable);
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_IsSelectionRequired(BOOL* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SELECTION_GET_ISSELECTIONREQUIRED);
- UIA_VALIDATE_CALL_1_ARG(result);
- *result = GetData().HasState(ax::mojom::State::kRequired);
- return S_OK;
-}
-
-//
-// ITableItemProvider methods.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::GetColumnHeaderItems(SAFEARRAY** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TABLEITEM_GETCOLUMNHEADERITEMS);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- base::Optional<int> column = GetTableColumn();
- if (!column)
- return E_FAIL;
-
- std::vector<int32_t> column_header_ids =
- GetDelegate()->GetColHeaderNodeIds(*column);
-
- std::vector<AXPlatformNodeWin*> platform_node_list =
- CreatePlatformNodeVectorFromRelationIdVector(column_header_ids);
-
- *result = CreateUIAElementsSafeArray(platform_node_list);
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::GetRowHeaderItems(SAFEARRAY** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TABLEITEM_GETROWHEADERITEMS);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- base::Optional<int> row = GetTableRow();
- if (!row)
- return E_FAIL;
-
- std::vector<int32_t> row_header_ids =
- GetDelegate()->GetRowHeaderNodeIds(*row);
-
- std::vector<AXPlatformNodeWin*> platform_node_list =
- CreatePlatformNodeVectorFromRelationIdVector(row_header_ids);
-
- *result = CreateUIAElementsSafeArray(platform_node_list);
- return S_OK;
-}
-
-//
-// ITableProvider methods.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::GetColumnHeaders(SAFEARRAY** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TABLE_GETCOLUMNHEADERS);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- std::vector<int32_t> column_header_ids = GetDelegate()->GetColHeaderNodeIds();
-
- std::vector<AXPlatformNodeWin*> platform_node_list =
- CreatePlatformNodeVectorFromRelationIdVector(column_header_ids);
-
- *result = CreateUIAElementsSafeArray(platform_node_list);
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::GetRowHeaders(SAFEARRAY** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TABLE_GETROWHEADERS);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- std::vector<int32_t> row_header_ids = GetDelegate()->GetRowHeaderNodeIds();
-
- std::vector<AXPlatformNodeWin*> platform_node_list =
- CreatePlatformNodeVectorFromRelationIdVector(row_header_ids);
-
- *result = CreateUIAElementsSafeArray(platform_node_list);
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_RowOrColumnMajor(
- RowOrColumnMajor* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TABLE_GET_ROWORCOLUMNMAJOR);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- // Tables and ARIA grids are always in row major order
- // see AXPlatformNodeBase::GetTableCell
- *result = RowOrColumnMajor_RowMajor;
- return S_OK;
-}
-
-//
-// IToggleProvider implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::Toggle() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TOGGLE_TOGGLE);
- UIA_VALIDATE_CALL();
- AXActionData action_data;
- action_data.action = ax::mojom::Action::kDoDefault;
-
- if (GetDelegate()->AccessibilityPerformAction(action_data))
- return S_OK;
- return E_FAIL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_ToggleState(ToggleState* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_TOGGLE_GET_TOGGLESTATE);
- UIA_VALIDATE_CALL_1_ARG(result);
- const auto checked_state = GetData().GetCheckedState();
- if (checked_state == ax::mojom::CheckedState::kTrue) {
- *result = ToggleState_On;
- } else if (checked_state == ax::mojom::CheckedState::kMixed) {
- *result = ToggleState_Indeterminate;
- } else {
- *result = ToggleState_Off;
- }
- return S_OK;
-}
-
-//
-// IValueProvider implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::SetValue(LPCWSTR value) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_VALUE_SETVALUE);
- UIA_VALIDATE_CALL();
- if (!value)
- return E_INVALIDARG;
-
- if (GetData().IsReadOnlyOrDisabled())
- return UIA_E_ELEMENTNOTENABLED;
-
- AXActionData data;
- data.action = ax::mojom::Action::kSetValue;
- data.value = base::WideToUTF8(value);
- if (GetDelegate()->AccessibilityPerformAction(data))
- return S_OK;
- return E_FAIL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_IsReadOnly(BOOL* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_VALUE_GET_ISREADONLY);
- UIA_VALIDATE_CALL_1_ARG(result);
- *result = GetData().IsReadOnlyOrDisabled();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_Value(BSTR* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_VALUE_GET_VALUE);
- UIA_VALIDATE_CALL_1_ARG(result);
- *result = GetValueAttributeAsBstr(this);
- return S_OK;
-}
-
-//
-// IWindowProvider implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::SetVisualState(
- WindowVisualState window_visual_state) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_WINDOW_SETVISUALSTATE);
- UIA_VALIDATE_CALL();
- return UIA_E_NOTSUPPORTED;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::Close() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_WINDOW_CLOSE);
- UIA_VALIDATE_CALL();
- return UIA_E_NOTSUPPORTED;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::WaitForInputIdle(int milliseconds,
- BOOL* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_WINDOW_WAITFORINPUTIDLE);
- UIA_VALIDATE_CALL_1_ARG(result);
- return UIA_E_NOTSUPPORTED;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_CanMaximize(BOOL* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_WINDOW_GET_CANMAXIMIZE);
- UIA_VALIDATE_CALL_1_ARG(result);
- return UIA_E_NOTSUPPORTED;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_CanMinimize(BOOL* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_WINDOW_GET_CANMINIMIZE);
- UIA_VALIDATE_CALL_1_ARG(result);
- return UIA_E_NOTSUPPORTED;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_IsModal(BOOL* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_WINDOW_GET_ISMODAL);
- UIA_VALIDATE_CALL_1_ARG(result);
-
- *result = GetBoolAttribute(ax::mojom::BoolAttribute::kModal);
-
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_WindowVisualState(
- WindowVisualState* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_WINDOW_GET_WINDOWVISUALSTATE);
- UIA_VALIDATE_CALL_1_ARG(result);
- return UIA_E_NOTSUPPORTED;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_WindowInteractionState(
- WindowInteractionState* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_WINDOW_GET_WINDOWINTERACTIONSTATE);
- UIA_VALIDATE_CALL_1_ARG(result);
- return UIA_E_NOTSUPPORTED;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_IsTopmost(BOOL* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_WINDOW_GET_ISTOPMOST);
- UIA_VALIDATE_CALL_1_ARG(result);
- return UIA_E_NOTSUPPORTED;
-}
-
-//
-// IRangeValueProvider implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::SetValue(double value) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_RANGEVALUE_SETVALUE);
- UIA_VALIDATE_CALL();
- AXActionData data;
- data.action = ax::mojom::Action::kSetValue;
- data.value = base::NumberToString(value);
- if (GetDelegate()->AccessibilityPerformAction(data))
- return S_OK;
- return E_FAIL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_LargeChange(double* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_RANGEVALUE_GET_LARGECHANGE);
- UIA_VALIDATE_CALL_1_ARG(result);
- float attribute;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kStepValueForRange,
- &attribute)) {
- *result = attribute * kLargeChangeScaleFactor;
- return S_OK;
- }
- return E_FAIL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_Maximum(double* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_RANGEVALUE_GET_MAXIMUM);
- UIA_VALIDATE_CALL_1_ARG(result);
- float attribute;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange,
- &attribute)) {
- *result = attribute;
- return S_OK;
- }
- return E_FAIL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_Minimum(double* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_RANGEVALUE_GET_MINIMUM);
- UIA_VALIDATE_CALL_1_ARG(result);
- float attribute;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange,
- &attribute)) {
- *result = attribute;
- return S_OK;
- }
- return E_FAIL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_SmallChange(double* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_RANGEVALUE_GET_SMALLCHANGE);
- UIA_VALIDATE_CALL_1_ARG(result);
- float attribute;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kStepValueForRange,
- &attribute)) {
- *result = attribute;
- return S_OK;
- }
- return E_FAIL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_Value(double* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_RANGEVALUE_GET_VALUE);
- UIA_VALIDATE_CALL_1_ARG(result);
- float attribute;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange,
- &attribute)) {
- *result = attribute;
- return S_OK;
- }
- return E_FAIL;
-}
-
-// IAccessibleEx methods not implemented.
-IFACEMETHODIMP
-AXPlatformNodeWin::ConvertReturnedElement(IRawElementProviderSimple* element,
- IAccessibleEx** acc) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_CONVERT_RETURNED_ELEMENT);
- return E_NOTIMPL;
-}
-
-//
-// IAccessibleTable methods.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::get_accessibleAt(LONG row,
- LONG column,
- IUnknown** accessible) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACCESSIBLE_AT);
- COM_OBJECT_VALIDATE_1_ARG(accessible);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- AXPlatformNodeBase* cell = GetTableCell(int{row}, int{column});
- if (!cell)
- return E_INVALIDARG;
-
- auto* node_win = static_cast<AXPlatformNodeWin*>(cell);
- return node_win->QueryInterface(IID_PPV_ARGS(accessible));
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_caption(IUnknown** accessible) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_CAPTION);
- COM_OBJECT_VALIDATE_1_ARG(accessible);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- AXPlatformNodeBase* caption = GetTableCaption();
- if (!caption)
- return S_FALSE;
-
- auto* node_win = static_cast<AXPlatformNodeWin*>(caption);
- return node_win->QueryInterface(IID_PPV_ARGS(accessible));
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_childIndex(LONG row,
- LONG column,
- LONG* cell_index) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_CHILD_INDEX);
- COM_OBJECT_VALIDATE_1_ARG(cell_index);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- AXPlatformNodeBase* cell = GetTableCell(int{row}, int{column});
- if (!cell)
- return E_INVALIDARG;
-
- base::Optional<int> index = cell->GetTableCellIndex();
- if (!index)
- return E_FAIL;
-
- *cell_index = LONG{*index};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_columnDescription(LONG column,
- BSTR* description) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_COLUMN_DESCRIPTION);
- COM_OBJECT_VALIDATE_1_ARG(description);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> columns = GetTableColumnCount();
- if (!columns)
- return E_FAIL;
-
- if (column < 0 || column >= *columns)
- return E_INVALIDARG;
-
- std::vector<int32_t> column_header_ids =
- GetDelegate()->GetColHeaderNodeIds(int{column});
- for (int32_t node_id : column_header_ids) {
- AXPlatformNodeWin* cell =
- static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(node_id));
- if (!cell)
- continue;
-
- base::string16 cell_name = cell->GetNameAsString16();
- if (!cell_name.empty()) {
- *description = SysAllocString(cell_name.c_str());
- return S_OK;
- }
-
- cell_name =
- cell->GetString16Attribute(ax::mojom::StringAttribute::kDescription);
- if (!cell_name.empty()) {
- *description = SysAllocString(cell_name.c_str());
- return S_OK;
- }
- }
-
- return S_FALSE;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_columnExtentAt(LONG row,
- LONG column,
- LONG* n_columns_spanned) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_COLUMN_EXTENT_AT);
- COM_OBJECT_VALIDATE_1_ARG(n_columns_spanned);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- AXPlatformNodeBase* cell = GetTableCell(int{row}, int{column});
- if (!cell)
- return E_INVALIDARG;
-
- base::Optional<int> column_span = cell->GetTableColumnSpan();
- if (!column_span)
- return E_FAIL;
- *n_columns_spanned = LONG{*column_span};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_columnHeader(
- IAccessibleTable** accessible_table,
- LONG* starting_row_index) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_COLUMN_HEADER);
- COM_OBJECT_VALIDATE_2_ARGS(accessible_table, starting_row_index);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- // TODO(dmazzoni): implement
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_columnIndex(LONG cell_index,
- LONG* column_index) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_COLUMN_INDEX);
- COM_OBJECT_VALIDATE_1_ARG(column_index);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- AXPlatformNodeBase* cell = GetTableCell(cell_index);
- if (!cell)
- return E_INVALIDARG;
-
- base::Optional<int> cell_column = cell->GetTableColumn();
- if (!cell_column)
- return E_FAIL;
- *column_index = LONG{*cell_column};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_nColumns(LONG* column_count) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_COLUMNS);
- COM_OBJECT_VALIDATE_1_ARG(column_count);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
- base::Optional<int> columns = GetTableColumnCount();
- if (!columns)
- return E_FAIL;
- *column_count = LONG{*columns};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_nRows(LONG* row_count) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_ROWS);
- COM_OBJECT_VALIDATE_1_ARG(row_count);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
- base::Optional<int> rows = GetTableRowCount();
- if (!rows)
- return E_FAIL;
- *row_count = LONG{*rows};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_nSelectedChildren(LONG* cell_count) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_SELECTED_CHILDREN);
- COM_OBJECT_VALIDATE_1_ARG(cell_count);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> columns = GetTableColumnCount();
- base::Optional<int> rows = GetTableRowCount();
- if (!columns || !rows)
- return E_FAIL;
-
- LONG result = 0;
- for (int r = 0; r < *rows; ++r) {
- for (int c = 0; c < *columns; ++c) {
- AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (cell &&
- cell->GetData().GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
- ++result;
- }
- }
- *cell_count = result;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_nSelectedColumns(LONG* column_count) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_SELECTED_COLUMNS);
- COM_OBJECT_VALIDATE_1_ARG(column_count);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> columns = GetTableColumnCount();
- base::Optional<int> rows = GetTableRowCount();
- if (!columns || !rows)
- return E_FAIL;
-
- // If every cell in a column is selected, then that column is selected.
- LONG result = 0;
- for (int c = 0; c < *columns; ++c) {
- bool selected = true;
- for (int r = 0; r < *rows && selected == true; ++r) {
- const AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (!cell || !(cell->GetData().GetBoolAttribute(
- ax::mojom::BoolAttribute::kSelected)))
- selected = false;
- }
- if (selected)
- ++result;
- }
-
- *column_count = result;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_nSelectedRows(LONG* row_count) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_SELECTED_ROWS);
- COM_OBJECT_VALIDATE_1_ARG(row_count);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> columns = GetTableColumnCount();
- base::Optional<int> rows = GetTableRowCount();
- if (!columns || !rows)
- return E_FAIL;
-
- // If every cell in a row is selected, then that row is selected.
- LONG result = 0;
- for (int r = 0; r < *rows; ++r) {
- bool selected = true;
- for (int c = 0; c < *columns && selected == true; ++c) {
- const AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (!cell || !(cell->GetData().GetBoolAttribute(
- ax::mojom::BoolAttribute::kSelected)))
- selected = false;
- }
- if (selected)
- ++result;
- }
-
- *row_count = result;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_rowDescription(LONG row,
- BSTR* description) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ROW_DESCRIPTION);
- COM_OBJECT_VALIDATE_1_ARG(description);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> rows = GetTableRowCount();
- if (!rows)
- return E_FAIL;
-
- if (row < 0 || row >= *rows)
- return E_INVALIDARG;
-
- std::vector<int32_t> row_header_ids =
- GetDelegate()->GetRowHeaderNodeIds(int{row});
- for (int32_t node_id : row_header_ids) {
- AXPlatformNodeWin* cell =
- static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(node_id));
- if (!cell)
- continue;
-
- base::string16 cell_name = cell->GetNameAsString16();
- if (!cell_name.empty()) {
- *description = SysAllocString(cell_name.c_str());
- return S_OK;
- }
-
- cell_name =
- cell->GetString16Attribute(ax::mojom::StringAttribute::kDescription);
- if (!cell_name.empty()) {
- *description = SysAllocString(cell_name.c_str());
- return S_OK;
- }
- }
-
- return S_FALSE;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_rowExtentAt(LONG row,
- LONG column,
- LONG* n_rows_spanned) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ROW_EXTENT_AT);
- COM_OBJECT_VALIDATE_1_ARG(n_rows_spanned);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- const AXPlatformNodeBase* cell = GetTableCell(int{row}, int{column});
- if (!cell)
- return E_INVALIDARG;
-
- base::Optional<int> cell_row_span = cell->GetTableRowSpan();
- if (!cell_row_span)
- return E_FAIL;
- *n_rows_spanned = LONG{*cell_row_span};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_rowHeader(
- IAccessibleTable** accessible_table,
- LONG* starting_column_index) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ROW_HEADER);
- COM_OBJECT_VALIDATE_2_ARGS(accessible_table, starting_column_index);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- // TODO(dmazzoni): implement
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_rowIndex(LONG cell_index,
- LONG* row_index) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(row_index);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- const AXPlatformNodeBase* cell = GetTableCell(cell_index);
- if (!cell)
- return E_INVALIDARG;
-
- base::Optional<int> cell_row = cell->GetTableRow();
- if (!cell_row)
- return E_FAIL;
- *row_index = LONG{*cell_row};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_selectedChildren(LONG max_children,
- LONG** children,
- LONG* n_children) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_2_ARGS(children, n_children);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- if (max_children <= 0)
- return E_INVALIDARG;
-
- base::Optional<int> columns = GetTableColumnCount();
- base::Optional<int> rows = GetTableRowCount();
- if (!columns || !rows)
- return E_FAIL;
-
- std::vector<LONG> results;
- for (int r = 0; r < *rows; ++r) {
- for (int c = 0; c < *columns; ++c) {
- const AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (cell && cell->GetData().GetBoolAttribute(
- ax::mojom::BoolAttribute::kSelected)) {
- base::Optional<int> cell_index = cell->GetTableCellIndex();
- if (!cell_index)
- return E_FAIL;
-
- results.push_back(*cell_index);
- }
- }
- }
-
- return AllocateComArrayFromVector(results, max_children, children,
- n_children);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_selectedColumns(LONG max_columns,
- LONG** columns,
- LONG* n_columns) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_2_ARGS(columns, n_columns);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- if (max_columns <= 0)
- return E_INVALIDARG;
-
- base::Optional<int> column_count = GetTableColumnCount();
- base::Optional<int> row_count = GetTableRowCount();
- if (!column_count || !row_count)
- return E_FAIL;
-
- std::vector<LONG> results;
- for (int c = 0; c < *column_count; ++c) {
- bool selected = true;
- for (int r = 0; r < *row_count && selected == true; ++r) {
- const AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (!cell || !(cell->GetData().GetBoolAttribute(
- ax::mojom::BoolAttribute::kSelected)))
- selected = false;
- }
- if (selected)
- results.push_back(c);
- }
-
- return AllocateComArrayFromVector(results, max_columns, columns, n_columns);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_selectedRows(LONG max_rows,
- LONG** rows,
- LONG* n_rows) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_2_ARGS(rows, n_rows);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- if (max_rows <= 0)
- return E_INVALIDARG;
-
- base::Optional<int> column_count = GetTableColumnCount();
- base::Optional<int> row_count = GetTableRowCount();
- if (!column_count || !row_count)
- return E_FAIL;
-
- std::vector<LONG> results;
- for (int r = 0; r < *row_count; ++r) {
- bool selected = true;
- for (int c = 0; c < *column_count && selected == true; ++c) {
- const AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (!cell || !(cell->GetData().GetBoolAttribute(
- ax::mojom::BoolAttribute::kSelected)))
- selected = false;
- }
- if (selected)
- results.push_back(r);
- }
-
- return AllocateComArrayFromVector(results, max_rows, rows, n_rows);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_summary(IUnknown** accessible) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(accessible);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- // TODO(dmazzoni): implement.
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_isColumnSelected(LONG column,
- boolean* is_selected) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(is_selected);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> columns = GetTableColumnCount();
- base::Optional<int> rows = GetTableRowCount();
- if (!columns || !rows)
- return E_FAIL;
-
- if (column < 0 || column >= *columns)
- return E_INVALIDARG;
-
- for (int r = 0; r < *rows; ++r) {
- const AXPlatformNodeBase* cell = GetTableCell(r, column);
- if (!cell || !(cell->GetData().GetBoolAttribute(
- ax::mojom::BoolAttribute::kSelected)))
- return S_OK;
- }
-
- *is_selected = true;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_isRowSelected(LONG row,
- boolean* is_selected) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(is_selected);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> columns = GetTableColumnCount();
- base::Optional<int> rows = GetTableRowCount();
- if (!columns || !rows)
- return E_FAIL;
-
- if (row < 0 || row >= *rows)
- return E_INVALIDARG;
-
- for (int c = 0; c < *columns; ++c) {
- const AXPlatformNodeBase* cell = GetTableCell(row, c);
- if (!cell || !(cell->GetData().GetBoolAttribute(
- ax::mojom::BoolAttribute::kSelected)))
- return S_OK;
- }
-
- *is_selected = true;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_isSelected(LONG row,
- LONG column,
- boolean* is_selected) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(is_selected);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> columns = GetTableColumnCount();
- base::Optional<int> rows = GetTableRowCount();
- if (!columns || !rows)
- return E_FAIL;
-
- const AXPlatformNodeBase* cell = GetTableCell(int{row}, int{column});
- if (!cell)
- return E_INVALIDARG;
-
- if (cell->GetData().GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
- *is_selected = true;
-
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_rowColumnExtentsAtIndex(
- LONG index,
- LONG* row,
- LONG* column,
- LONG* row_extents,
- LONG* column_extents,
- boolean* is_selected) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_5_ARGS(row, column, row_extents, column_extents,
- is_selected);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- const AXPlatformNodeBase* cell = GetTableCell(index);
- if (!cell)
- return E_INVALIDARG;
-
- base::Optional<int> row_index = cell->GetTableRow();
- base::Optional<int> column_index = cell->GetTableColumn();
- base::Optional<int> row_span = cell->GetTableRowSpan();
- base::Optional<int> column_span = cell->GetTableColumnSpan();
- if (!row_index || !column_index || !row_span || !column_span)
- return E_FAIL;
-
- *row = LONG{*row_index};
- *column = LONG{*column_index};
- *row_extents = LONG{*row_span};
- *column_extents = LONG{*column_span};
- if (cell->GetData().GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
- *is_selected = true;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::selectRow(LONG row) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> rows = GetTableRowCount();
- if (!rows)
- return E_FAIL;
-
- if (row < 0 || row >= *rows)
- return E_INVALIDARG;
-
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::selectColumn(LONG column) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> columns = GetTableColumnCount();
- if (!columns)
- return E_FAIL;
-
- if (column < 0 || column >= *columns)
- return E_INVALIDARG;
-
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::unselectRow(LONG row) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> rows = GetTableRowCount();
- if (!rows)
- return E_FAIL;
-
- if (row < 0 || row >= *rows)
- return E_INVALIDARG;
-
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::unselectColumn(LONG column) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> columns = GetTableColumnCount();
- if (!columns)
- return E_FAIL;
-
- if (column < 0 || column >= *columns)
- return E_INVALIDARG;
-
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_modelChange(
- IA2TableModelChange* model_change) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(model_change);
- return E_NOTIMPL;
-}
-
-//
-// IAccessibleTable2 methods.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::get_cellAt(LONG row,
- LONG column,
- IUnknown** cell) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(cell);
- AXPlatformNode::NotifyAddAXModeFlags(AXMode::kScreenReader);
-
- AXPlatformNodeBase* table_cell = GetTableCell(int{row}, int{column});
- if (!table_cell)
- return E_INVALIDARG;
-
- auto* node_win = static_cast<AXPlatformNodeWin*>(table_cell);
- return node_win->QueryInterface(IID_PPV_ARGS(cell));
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_nSelectedCells(LONG* cell_count) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- // Note that this method does not need to set any ax mode since it
- // calls into get_nSelectedChildren() which does.
- return get_nSelectedChildren(cell_count);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_selectedCells(IUnknown*** cells,
- LONG* n_selected_cells) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_2_ARGS(cells, n_selected_cells);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> columns = GetTableColumnCount();
- base::Optional<int> rows = GetTableRowCount();
- if (!columns || !rows)
- return E_FAIL;
-
- std::vector<AXPlatformNodeBase*> selected;
- for (int r = 0; r < *rows; ++r) {
- for (int c = 0; c < *columns; ++c) {
- AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (cell &&
- cell->GetData().GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
- selected.push_back(cell);
- }
- }
-
- *n_selected_cells = static_cast<LONG>(selected.size());
- *cells = static_cast<IUnknown**>(
- CoTaskMemAlloc(selected.size() * sizeof(IUnknown*)));
-
- for (size_t i = 0; i < selected.size(); ++i) {
- auto* node_win = static_cast<AXPlatformNodeWin*>(selected[i]);
- node_win->QueryInterface(IID_PPV_ARGS(&(*cells)[i]));
- }
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_selectedColumns(LONG** columns,
- LONG* n_columns) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- return get_selectedColumns(INT_MAX, columns, n_columns);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_selectedRows(LONG** rows, LONG* n_rows) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- return get_selectedRows(INT_MAX, rows, n_rows);
-}
-
-//
-// IAccessibleTableCell methods.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::get_columnExtent(LONG* n_columns_spanned) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(n_columns_spanned);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> column_span = GetTableColumnSpan();
- if (!column_span)
- return E_FAIL;
- *n_columns_spanned = LONG{*column_span};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_columnHeaderCells(
- IUnknown*** cell_accessibles,
- LONG* n_column_header_cells) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_2_ARGS(cell_accessibles, n_column_header_cells);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> column = GetTableColumn();
- if (!column)
- return E_FAIL;
-
- std::vector<int32_t> column_header_ids =
- GetDelegate()->GetColHeaderNodeIds(*column);
- *cell_accessibles = static_cast<IUnknown**>(
- CoTaskMemAlloc(column_header_ids.size() * sizeof(IUnknown*)));
- int index = 0;
- for (int32_t node_id : column_header_ids) {
- AXPlatformNodeWin* node_win =
- static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(node_id));
- if (node_win) {
- node_win->QueryInterface(IID_PPV_ARGS(&(*cell_accessibles)[index]));
- ++index;
- }
- }
-
- *n_column_header_cells = LONG{column_header_ids.size()};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_columnIndex(LONG* column_index) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(column_index);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> column = GetTableColumn();
- if (!column)
- return E_FAIL;
- *column_index = LONG{*column};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_rowExtent(LONG* n_rows_spanned) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(n_rows_spanned);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> row_span = GetTableRowSpan();
- if (!row_span)
- return E_FAIL;
- *n_rows_spanned = LONG{*row_span};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_rowHeaderCells(
- IUnknown*** cell_accessibles,
- LONG* n_row_header_cells) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_2_ARGS(cell_accessibles, n_row_header_cells);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> row = GetTableRow();
- if (!row)
- return E_FAIL;
-
- std::vector<int32_t> row_header_ids =
- GetDelegate()->GetRowHeaderNodeIds(*row);
- *cell_accessibles = static_cast<IUnknown**>(
- CoTaskMemAlloc(row_header_ids.size() * sizeof(IUnknown*)));
- int index = 0;
- for (int32_t node_id : row_header_ids) {
- AXPlatformNodeWin* node_win =
- static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(node_id));
- if (node_win) {
- node_win->QueryInterface(IID_PPV_ARGS(&(*cell_accessibles)[index]));
- ++index;
- }
- }
-
- *n_row_header_cells = LONG{row_header_ids.size()};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_rowIndex(LONG* row_index) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(row_index);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> row = GetTableRow();
- if (!row)
- return E_FAIL;
- *row_index = LONG{*row};
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_isSelected(boolean* is_selected) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(is_selected);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- if (GetData().GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
- *is_selected = true;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_rowColumnExtents(LONG* row_index,
- LONG* column_index,
- LONG* row_extents,
- LONG* column_extents,
- boolean* is_selected) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_5_ARGS(row_index, column_index, row_extents,
- column_extents, is_selected);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- base::Optional<int> row = GetTableRow();
- base::Optional<int> column = GetTableColumn();
- base::Optional<int> row_span = GetTableRowSpan();
- base::Optional<int> column_span = GetTableColumnSpan();
- if (!row || !column || !row_span || !column_span)
- return E_FAIL;
-
- *row_index = LONG{*row};
- *column_index = LONG{*column};
- *row_extents = LONG{*row_span};
- *column_extents = LONG{*column_span};
- if (GetData().GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
- *is_selected = true;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_table(IUnknown** table) {
- // TODO(dougt) WIN_ACCESSIBILITY_API_HISTOGRAM?
- COM_OBJECT_VALIDATE_1_ARG(table);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- AXPlatformNodeBase* table_node = GetTable();
- if (!table_node)
- return E_FAIL;
-
- auto* node_win = static_cast<AXPlatformNodeWin*>(table_node);
- return node_win->QueryInterface(IID_PPV_ARGS(table));
-}
-
-//
-// IAccessibleText
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::get_nCharacters(LONG* n_characters) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_CHARACTERS);
- COM_OBJECT_VALIDATE_1_ARG(n_characters);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes |
- AXMode::kInlineTextBoxes);
-
- base::string16 text = GetHypertext();
- *n_characters = static_cast<LONG>(text.size());
-
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_caretOffset(LONG* offset) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_CARET_OFFSET);
- COM_OBJECT_VALIDATE_1_ARG(offset);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
- *offset = 0;
-
- if (!HasCaret())
- return S_FALSE;
-
- int selection_start, selection_end;
- GetSelectionOffsets(&selection_start, &selection_end);
- // The caret is always at the end of the selection.
- *offset = selection_end;
- if (*offset < 0)
- return S_FALSE;
-
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_nSelections(LONG* n_selections) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_SELECTIONS);
- COM_OBJECT_VALIDATE_1_ARG(n_selections);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- *n_selections = 0;
- int selection_start, selection_end;
- GetSelectionOffsets(&selection_start, &selection_end);
- if (selection_start >= 0 && selection_end >= 0 &&
- selection_start != selection_end) {
- *n_selections = 1;
- }
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_selection(LONG selection_index,
- LONG* start_offset,
- LONG* end_offset) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_SELECTION);
- COM_OBJECT_VALIDATE_2_ARGS(start_offset, end_offset);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- if (!start_offset || !end_offset || selection_index != 0)
- return E_INVALIDARG;
-
- *start_offset = 0;
- *end_offset = 0;
- int selection_start, selection_end;
- GetSelectionOffsets(&selection_start, &selection_end);
- if (selection_start >= 0 && selection_end >= 0 &&
- selection_start != selection_end) {
- // We should ignore the direction of the selection when exposing start and
- // end offsets. According to the IA2 Spec the end offset is always
- // increased by one past the end of the selection. This wouldn't make
- // sense if end < start.
- if (selection_end < selection_start)
- std::swap(selection_start, selection_end);
-
- *start_offset = selection_start;
- *end_offset = selection_end;
- return S_OK;
- }
-
- return E_INVALIDARG;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_text(LONG start_offset,
- LONG end_offset,
- BSTR* text) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_TEXT);
- COM_OBJECT_VALIDATE_1_ARG(text);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
- HandleSpecialTextOffset(&start_offset);
- HandleSpecialTextOffset(&end_offset);
-
- // The spec allows the arguments to be reversed.
- if (start_offset > end_offset)
- std::swap(start_offset, end_offset);
-
- const base::string16 str = GetHypertext();
- LONG str_len = static_cast<LONG>(str.length());
- if (start_offset < 0 || start_offset > str_len)
- return E_INVALIDARG;
- if (end_offset < 0 || end_offset > str_len)
- return E_INVALIDARG;
-
- base::string16 substr = str.substr(start_offset, end_offset - start_offset);
- if (substr.empty())
- return S_FALSE;
-
- *text = SysAllocString(substr.c_str());
- DCHECK(*text);
- return S_OK;
-}
-
-HRESULT AXPlatformNodeWin::IAccessibleTextGetTextForOffsetType(
- TextOffsetType text_offset_type,
- LONG offset,
- enum IA2TextBoundaryType boundary_type,
- LONG* start_offset,
- LONG* end_offset,
- BSTR* text) {
- COM_OBJECT_VALIDATE_3_ARGS(start_offset, end_offset, text);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes |
- AXMode::kInlineTextBoxes);
-
- // https://accessibility.linuxfoundation.org/a11yspecs/ia2/docs/html/_accessible_text_8idl.html
- // IA2_TEXT_BOUNDARY_SENTENCE is optional and we can let the screenreader
- // handle it, the rest of the boundary types must be supported.
- if (boundary_type == IA2_TEXT_BOUNDARY_SENTENCE)
- return S_FALSE;
-
- HandleSpecialTextOffset(&offset);
- if (offset < 0)
- return E_INVALIDARG;
-
- const base::string16& text_str = GetHypertext();
- LONG text_len = text_str.length();
-
- // https://accessibility.linuxfoundation.org/a11yspecs/ia2/docs/html/interface_i_accessible_text.html
- // All methods that operate on particular characters use character indices
- // (e.g. IAccessibleText::textAtOffset) from 0 to length-1.
- if (offset >= text_len) {
- // We aren't strictly following the spec here by allowing offset to be equal
- // to the text length for IA2_TEXT_BOUNDARY_LINE in case screen readers
- // expect this behavior which has existed since Feb. 2015,
- // commit: 6baff46f520e31ff92669890207be5708064d16e.
- const bool offset_for_line_text_len =
- offset == text_len && boundary_type == IA2_TEXT_BOUNDARY_LINE;
- if (!offset_for_line_text_len)
- return E_INVALIDARG;
- }
-
- LONG start, end;
-
- switch (text_offset_type) {
- case TextOffsetType::kAtOffset: {
- end = FindBoundary(boundary_type, offset,
- ax::mojom::MoveDirection::kForward);
- // Early return if the range will be degenerate containing no text.
- if (end <= 0)
- return S_FALSE;
- start = FindBoundary(boundary_type, offset,
- ax::mojom::MoveDirection::kBackward);
- break;
- }
- case TextOffsetType::kBeforeOffset: {
- // Find the start of the boundary at |offset| and assign to |end|,
- // then find the start of the preceding boundary and assign to |start|.
- end = FindBoundary(boundary_type, offset,
- ax::mojom::MoveDirection::kBackward);
- // Early return if the range will be degenerate containing no text,
- // or the range is after |offset|. Because the character at |offset| must
- // be excluded, |end| and |offset| may be equal.
- if (end <= 0 || end > offset)
- return S_FALSE;
- start = FindBoundary(boundary_type, end - 1,
- ax::mojom::MoveDirection::kBackward);
- break;
- }
- case TextOffsetType::kAfterOffset: {
- // Find the end of the boundary at |offset| and assign to |start|,
- // then find the end of the following boundary and assign to |end|.
- start = FindBoundary(boundary_type, offset,
- ax::mojom::MoveDirection::kForward);
- // Early return if the range will be degenerate containing no text,
- // or the range is before or includes|offset|. Because the character at
- // |offset| must be excluded, |start| and |offset| cannot be equal.
- if (start >= text_len || start <= offset)
- return S_FALSE;
- end = FindBoundary(boundary_type, start,
- ax::mojom::MoveDirection::kForward);
- break;
- }
- }
-
- DCHECK_LE(start, end);
- if (start >= end)
- return S_FALSE;
-
- *start_offset = start;
- *end_offset = end;
- return get_text(start, end, text);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_textAtOffset(
- LONG offset,
- enum IA2TextBoundaryType boundary_type,
- LONG* start_offset,
- LONG* end_offset,
- BSTR* text) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_TEXT_AT_OFFSET);
- return IAccessibleTextGetTextForOffsetType(TextOffsetType::kAtOffset, offset,
- boundary_type, start_offset,
- end_offset, text);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_textBeforeOffset(
- LONG offset,
- enum IA2TextBoundaryType boundary_type,
- LONG* start_offset,
- LONG* end_offset,
- BSTR* text) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_TEXT_BEFORE_OFFSET);
- return IAccessibleTextGetTextForOffsetType(TextOffsetType::kBeforeOffset,
- offset, boundary_type,
- start_offset, end_offset, text);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_textAfterOffset(
- LONG offset,
- enum IA2TextBoundaryType boundary_type,
- LONG* start_offset,
- LONG* end_offset,
- BSTR* text) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_TEXT_AFTER_OFFSET);
- return IAccessibleTextGetTextForOffsetType(TextOffsetType::kAfterOffset,
- offset, boundary_type,
- start_offset, end_offset, text);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_offsetAtPoint(
- LONG x,
- LONG y,
- enum IA2CoordinateType coord_type,
- LONG* offset) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_OFFSET_AT_POINT);
- COM_OBJECT_VALIDATE_1_ARG(offset);
-
- *offset = -1;
-
- if (coord_type == IA2CoordinateType::IA2_COORDTYPE_PARENT_RELATIVE) {
- // We don't support when the IA2 coordinate type is parent relative, but
- // we have to return something rather than E_NOTIMPL or screen readers
- // will complain.
- NOTIMPLEMENTED_LOG_ONCE() << "See http://crbug.com/1010726";
- return S_FALSE;
- }
-
- // We currently only handle IA2 screen relative coord type.
- DCHECK_EQ(coord_type, IA2_COORDTYPE_SCREEN_RELATIVE);
-
- const AXPlatformNodeWin* hit_child = static_cast<AXPlatformNodeWin*>(
- FromNativeViewAccessible(GetDelegate()->HitTestSync(x, y)));
-
- if (!hit_child || !hit_child->IsText()) {
- return S_FALSE;
- }
-
- for (int i = 0, text_length = hit_child->GetInnerText().length();
- i < text_length; ++i) {
- gfx::Rect char_bounds =
- hit_child->GetDelegate()->GetInnerTextRangeBoundsRect(
- i, i + 1, AXCoordinateSystem::kScreenDIPs,
- AXClippingBehavior::kUnclipped);
- if (char_bounds.Contains(x, y)) {
- *offset = i;
- break;
- }
- }
-
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::addSelection(LONG start_offset,
- LONG end_offset) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ADD_SELECTION);
- COM_OBJECT_VALIDATE();
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- // We only support one selection.
- return setSelection(0, start_offset, end_offset);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::removeSelection(LONG selection_index) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_REMOVE_SELECTION);
- COM_OBJECT_VALIDATE();
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- if (selection_index != 0)
- return E_INVALIDARG;
- // Simply collapse the selection to the position of the caret if a caret is
- // visible, otherwise set the selection to 0.
- return setCaretOffset(GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd));
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::setCaretOffset(LONG offset) {
- return setSelection(0, offset, offset);
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::setSelection(LONG selection_index,
- LONG start_offset,
- LONG end_offset) {
- if (selection_index != 0)
- return E_INVALIDARG;
-
- HandleSpecialTextOffset(&start_offset);
- HandleSpecialTextOffset(&end_offset);
- if (start_offset < 0 ||
- start_offset > static_cast<LONG>(GetHypertext().length())) {
- return E_INVALIDARG;
- }
- if (end_offset < 0 ||
- end_offset > static_cast<LONG>(GetHypertext().length())) {
- return E_INVALIDARG;
- }
-
- if (SetHypertextSelection(int{start_offset}, int{end_offset})) {
- return S_OK;
- }
- return E_FAIL;
-}
-
-//
-// IAccessibleHypertext methods not implemented.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::get_nHyperlinks(LONG* hyperlink_count) {
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_hyperlink(
- LONG index,
- IAccessibleHyperlink** hyperlink) {
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_hyperlinkIndex(LONG char_index,
- LONG* hyperlink_index) {
- return E_NOTIMPL;
-}
-
-//
-// IAccessibleText methods not implemented.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::get_newText(IA2TextSegment* new_text) {
- return E_NOTIMPL;
-}
-IFACEMETHODIMP AXPlatformNodeWin::get_oldText(IA2TextSegment* old_text) {
- return E_NOTIMPL;
-}
-IFACEMETHODIMP AXPlatformNodeWin::get_characterExtents(
- LONG offset,
- enum IA2CoordinateType coord_type,
- LONG* x,
- LONG* y,
- LONG* width,
- LONG* height) {
- return E_NOTIMPL;
-}
-IFACEMETHODIMP AXPlatformNodeWin::scrollSubstringTo(
- LONG start_index,
- LONG end_index,
- enum IA2ScrollType scroll_type) {
- return E_NOTIMPL;
-}
-IFACEMETHODIMP AXPlatformNodeWin::scrollSubstringToPoint(
- LONG start_index,
- LONG end_index,
- enum IA2CoordinateType coordinate_type,
- LONG x,
- LONG y) {
- return E_NOTIMPL;
-}
-IFACEMETHODIMP AXPlatformNodeWin::get_attributes(LONG offset,
- LONG* start_offset,
- LONG* end_offset,
- BSTR* text_attributes) {
- return E_NOTIMPL;
-}
-
-//
-// IAccessibleValue methods.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::get_currentValue(VARIANT* value) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_CURRENT_VALUE);
- COM_OBJECT_VALIDATE_1_ARG(value);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- float float_val;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange,
- &float_val)) {
- value->vt = VT_R8;
- value->dblVal = float_val;
- return S_OK;
- }
-
- value->vt = VT_EMPTY;
- return S_FALSE;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_minimumValue(VARIANT* value) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_MINIMUM_VALUE);
- COM_OBJECT_VALIDATE_1_ARG(value);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- float float_val;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange,
- &float_val)) {
- value->vt = VT_R8;
- value->dblVal = float_val;
- return S_OK;
- }
-
- value->vt = VT_EMPTY;
- return S_FALSE;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_maximumValue(VARIANT* value) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_MAXIMUM_VALUE);
- COM_OBJECT_VALIDATE_1_ARG(value);
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- float float_val;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange,
- &float_val)) {
- value->vt = VT_R8;
- value->dblVal = float_val;
- return S_OK;
- }
-
- value->vt = VT_EMPTY;
- return S_FALSE;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::setCurrentValue(VARIANT new_value) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SET_CURRENT_VALUE);
- COM_OBJECT_VALIDATE();
- AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-
- double double_value = 0.0;
- if (V_VT(&new_value) == VT_R8)
- double_value = V_R8(&new_value);
- else if (V_VT(&new_value) == VT_R4)
- double_value = V_R4(&new_value);
- else if (V_VT(&new_value) == VT_I4)
- double_value = V_I4(&new_value);
- else
- return E_INVALIDARG;
-
- AXActionData data;
- data.action = ax::mojom::Action::kSetValue;
- data.value = base::NumberToString(double_value);
- if (GetDelegate()->AccessibilityPerformAction(data))
- return S_OK;
- return E_FAIL;
-}
-
-//
-// IRawElementProviderFragment implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::Navigate(
- NavigateDirection direction,
- IRawElementProviderFragment** element_provider) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_NAVIGATE);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_NAVIGATE);
- UIA_VALIDATE_CALL_1_ARG(element_provider);
-
- *element_provider = nullptr;
-
- //
- // Navigation to a fragment root node:
- //
- // In order for the platform-neutral accessibility tree to support IA2 and UIA
- // simultaneously, we handle navigation to and from fragment roots in UIA
- // specific code. Consider the following platform-neutral tree:
- //
- // N1
- // _____/ \_____
- // / \
- // N2---N3---N4---N5
- // / \ / \
- // N6---N7 N8---N9
- //
- // N3 and N5 are nodes for which we need a fragment root. This will correspond
- // to the following tree in UIA:
- //
- // U1
- // _____/ \_____
- // / \
- // U2---R3---U4---R5
- // | |
- // U3 U5
- // / \ / \
- // U6---U7 U8---U9
- //
- // Ux is the platform node for Nx.
- // R3 and R5 are the fragment root nodes for U3 and U5 respectively.
- //
- // Navigation has the following behaviors:
- //
- // 1. Parent navigation: If source node Ux is the child of a fragment root,
- // return Rx. Otherwise, consult the platform-neutral tree.
- // 2. First/last child navigation: If target node Ux is the child of a
- // fragment root and the source node isn't Rx, return Rx. Otherwise, return
- // Ux.
- // 3. Next/previous sibling navigation:
- // a. If source node Ux is the child of a fragment root, return nullptr.
- // b. If target node Ux is the child of a fragment root, return Rx.
- // Otherwise, return Ux.
- //
- // Note that the condition in 3b is a special case of the condition in 2. In
- // 3b, the source node is never Rx. So in the code, we collapse them to a
- // common implementation.
- //
- // Navigation from an Rx node is set up by delegate APIs on AXFragmentRootWin.
- //
- gfx::NativeViewAccessible neighbor = nullptr;
- switch (direction) {
- case NavigateDirection_Parent: {
- // 1. If source node Ux is the child of a fragment root, return Rx.
- // Otherwise, consult the platform-neutral tree.
- AXFragmentRootWin* fragment_root =
- AXFragmentRootWin::GetFragmentRootParentOf(GetNativeViewAccessible());
- if (UNLIKELY(fragment_root)) {
- neighbor = fragment_root->GetNativeViewAccessible();
- } else {
- neighbor = GetParent();
- }
- } break;
-
- case NavigateDirection_FirstChild:
- if (GetChildCount() > 0)
- neighbor = GetFirstChild()->GetNativeViewAccessible();
- break;
-
- case NavigateDirection_LastChild:
- if (GetChildCount() > 0)
- neighbor = GetLastChild()->GetNativeViewAccessible();
- break;
-
- case NavigateDirection_NextSibling:
- // 3a. If source node Ux is the child of a fragment root, return nullptr.
- if (AXFragmentRootWin::GetFragmentRootParentOf(
- GetNativeViewAccessible()) == nullptr) {
- AXPlatformNodeBase* neighbor_node = GetNextSibling();
- if (neighbor_node)
- neighbor = neighbor_node->GetNativeViewAccessible();
- }
- break;
-
- case NavigateDirection_PreviousSibling:
- // 3a. If source node Ux is the child of a fragment root, return nullptr.
- if (AXFragmentRootWin::GetFragmentRootParentOf(
- GetNativeViewAccessible()) == nullptr) {
- AXPlatformNodeBase* neighbor_node = GetPreviousSibling();
- if (neighbor_node)
- neighbor = neighbor_node->GetNativeViewAccessible();
- }
- break;
-
- default:
- NOTREACHED();
- break;
- }
-
- if (neighbor) {
- if (direction != NavigateDirection_Parent) {
- // 2 / 3b. If target node Ux is the child of a fragment root and the
- // source node isn't Rx, return Rx.
- AXFragmentRootWin* fragment_root =
- AXFragmentRootWin::GetFragmentRootParentOf(neighbor);
- if (UNLIKELY(fragment_root && fragment_root != GetDelegate()))
- neighbor = fragment_root->GetNativeViewAccessible();
- }
- neighbor->QueryInterface(IID_PPV_ARGS(element_provider));
- }
-
- return S_OK;
-}
-
-void AXPlatformNodeWin::GetRuntimeIdArray(
- AXPlatformNodeWin::RuntimeIdArray& runtime_id) {
- runtime_id[0] = UiaAppendRuntimeId;
- runtime_id[1] = GetUniqueId();
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::GetRuntimeId(SAFEARRAY** runtime_id) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_RUNTIME_ID);
- UIA_VALIDATE_CALL_1_ARG(runtime_id);
-
- RuntimeIdArray id_array;
- GetRuntimeIdArray(id_array);
- *runtime_id = ::SafeArrayCreateVector(VT_I4, 0, id_array.size());
-
- int* array_data = nullptr;
- ::SafeArrayAccessData(*runtime_id, reinterpret_cast<void**>(&array_data));
-
- size_t runtime_id_byte_count = id_array.size() * sizeof(int);
- memcpy_s(array_data, runtime_id_byte_count, id_array.data(),
- runtime_id_byte_count);
-
- ::SafeArrayUnaccessData(*runtime_id);
-
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_BoundingRectangle(
- UiaRect* screen_physical_pixel_bounds) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_BOUNDINGRECTANGLE);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_GET_BOUNDINGRECTANGLE);
-
- UIA_VALIDATE_CALL_1_ARG(screen_physical_pixel_bounds);
-
- gfx::Rect bounds =
- delegate_->GetBoundsRect(AXCoordinateSystem::kScreenPhysicalPixels,
- AXClippingBehavior::kUnclipped);
- screen_physical_pixel_bounds->left = bounds.x();
- screen_physical_pixel_bounds->top = bounds.y();
- screen_physical_pixel_bounds->width = bounds.width();
- screen_physical_pixel_bounds->height = bounds.height();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::GetEmbeddedFragmentRoots(
- SAFEARRAY** embedded_fragment_roots) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GETEMBEDDEDFRAGMENTROOTS);
- UIA_VALIDATE_CALL_1_ARG(embedded_fragment_roots);
-
- *embedded_fragment_roots = nullptr;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::SetFocus() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SETFOCUS);
- UIA_VALIDATE_CALL();
-
- AXActionData action_data;
- action_data.action = ax::mojom::Action::kFocus;
- delegate_->AccessibilityPerformAction(action_data);
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_FragmentRoot(
- IRawElementProviderFragmentRoot** fragment_root) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_FRAGMENTROOT);
- UIA_VALIDATE_CALL_1_ARG(fragment_root);
-
- gfx::AcceleratedWidget widget =
- delegate_->GetTargetForNativeAccessibilityEvent();
- if (widget) {
- AXFragmentRootWin* root =
- AXFragmentRootWin::GetForAcceleratedWidget(widget);
- if (root != nullptr) {
- root->GetNativeViewAccessible()->QueryInterface(
- IID_PPV_ARGS(fragment_root));
- DCHECK(*fragment_root);
- return S_OK;
- }
- }
-
- *fragment_root = nullptr;
- return UIA_E_ELEMENTNOTAVAILABLE;
-}
-
-//
-// IRawElementProviderSimple implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::GetPatternProvider(PATTERNID pattern_id,
- IUnknown** result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PATTERN_PROVIDER);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_GET_PATTERN_PROVIDER);
- return GetPatternProviderImpl(pattern_id, result);
-}
-
-HRESULT AXPlatformNodeWin::GetPatternProviderImpl(PATTERNID pattern_id,
- IUnknown** result) {
- UIA_VALIDATE_CALL_1_ARG(result);
-
- *result = nullptr;
-
- PatternProviderFactoryMethod factory_method =
- GetPatternProviderFactoryMethod(pattern_id);
- if (factory_method)
- (*factory_method)(this, result);
-
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::GetPropertyValue(PROPERTYID property_id,
- VARIANT* result) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PROPERTY_VALUE);
- WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(UMA_API_GET_PROPERTY_VALUE);
-
- constexpr LONG kFirstKnownUiaPropertyId = UIA_RuntimeIdPropertyId;
- constexpr LONG kLastKnownUiaPropertyId = UIA_IsDialogPropertyId;
- if (property_id >= kFirstKnownUiaPropertyId &&
- property_id <= kLastKnownUiaPropertyId) {
- base::UmaHistogramSparse("Accessibility.WinAPIs.GetPropertyValue",
- property_id);
- } else {
- // Collapse all unknown property IDs into a single bucket.
- base::UmaHistogramSparse("Accessibility.WinAPIs.GetPropertyValue", 0);
- }
- return GetPropertyValueImpl(property_id, result);
-}
-
-HRESULT AXPlatformNodeWin::GetPropertyValueImpl(PROPERTYID property_id,
- VARIANT* result) {
- UIA_VALIDATE_CALL_1_ARG(result);
-
- result->vt = VT_EMPTY;
-
- int int_attribute;
- const AXNodeData& data = GetData();
-
- // Default UIA Property Ids.
- switch (property_id) {
- case UIA_AriaPropertiesPropertyId:
- result->vt = VT_BSTR;
- result->bstrVal = SysAllocString(ComputeUIAProperties().c_str());
- break;
-
- case UIA_AriaRolePropertyId:
- result->vt = VT_BSTR;
- result->bstrVal = SysAllocString(UIAAriaRole().c_str());
- break;
-
- case UIA_AutomationIdPropertyId:
- V_VT(result) = VT_BSTR;
- V_BSTR(result) =
- SysAllocString(GetDelegate()->GetAuthorUniqueId().c_str());
- break;
-
- case UIA_ClassNamePropertyId:
- result->vt = VT_BSTR;
- GetStringAttributeAsBstr(ax::mojom::StringAttribute::kClassName,
- &result->bstrVal);
- break;
-
- case UIA_ClickablePointPropertyId:
- result->vt = VT_ARRAY | VT_R8;
- result->parray = CreateClickablePointArray();
- break;
-
- case UIA_ControllerForPropertyId:
- result->vt = VT_ARRAY | VT_UNKNOWN;
- result->parray = CreateUIAControllerForArray();
- break;
-
- case UIA_ControlTypePropertyId:
- result->vt = VT_I4;
- result->lVal = ComputeUIAControlType();
- break;
-
- case UIA_CulturePropertyId: {
- base::Optional<LCID> lcid = GetCultureAttributeAsLCID();
- if (!lcid)
- return E_FAIL;
- result->vt = VT_I4;
- result->lVal = lcid.value();
- break;
- }
-
- case UIA_DescribedByPropertyId:
- result->vt = VT_ARRAY | VT_UNKNOWN;
- result->parray = CreateUIAElementsArrayForRelation(
- ax::mojom::IntListAttribute::kDescribedbyIds);
- break;
-
- case UIA_FlowsFromPropertyId:
- V_VT(result) = VT_ARRAY | VT_UNKNOWN;
- V_ARRAY(result) = CreateUIAElementsArrayForReverseRelation(
- ax::mojom::IntListAttribute::kFlowtoIds);
- break;
-
- case UIA_FlowsToPropertyId:
- result->vt = VT_ARRAY | VT_UNKNOWN;
- result->parray = CreateUIAElementsArrayForRelation(
- ax::mojom::IntListAttribute::kFlowtoIds);
- break;
-
- case UIA_FrameworkIdPropertyId:
- V_VT(result) = VT_BSTR;
- V_BSTR(result) = SysAllocString(FRAMEWORK_ID);
- break;
-
- case UIA_HasKeyboardFocusPropertyId:
- result->vt = VT_BOOL;
- result->boolVal = (delegate_->GetFocus() == GetNativeViewAccessible())
- ? VARIANT_TRUE
- : VARIANT_FALSE;
- break;
-
- case UIA_FullDescriptionPropertyId:
- result->vt = VT_BSTR;
- GetStringAttributeAsBstr(ax::mojom::StringAttribute::kDescription,
- &result->bstrVal);
- break;
-
- case UIA_HelpTextPropertyId:
- if (HasStringAttribute(ax::mojom::StringAttribute::kPlaceholder)) {
- V_VT(result) = VT_BSTR;
- GetStringAttributeAsBstr(ax::mojom::StringAttribute::kPlaceholder,
- &V_BSTR(result));
- } else if (data.GetNameFrom() == ax::mojom::NameFrom::kPlaceholder ||
- data.GetNameFrom() == ax::mojom::NameFrom::kTitle) {
- V_VT(result) = VT_BSTR;
- GetNameAsBstr(&V_BSTR(result));
- } else if (HasStringAttribute(ax::mojom::StringAttribute::kTooltip)) {
- V_VT(result) = VT_BSTR;
- GetStringAttributeAsBstr(ax::mojom::StringAttribute::kTooltip,
- &V_BSTR(result));
- }
- break;
-
- case UIA_IsContentElementPropertyId:
- case UIA_IsControlElementPropertyId:
- result->vt = VT_BOOL;
- result->boolVal = IsUIAControl() ? VARIANT_TRUE : VARIANT_FALSE;
- break;
-
- case UIA_IsDataValidForFormPropertyId:
- if (data.GetIntAttribute(ax::mojom::IntAttribute::kInvalidState,
- &int_attribute)) {
- result->vt = VT_BOOL;
- result->boolVal =
- (static_cast<int>(ax::mojom::InvalidState::kFalse) == int_attribute)
- ? VARIANT_TRUE
- : VARIANT_FALSE;
- }
- break;
-
- case UIA_IsDialogPropertyId:
- result->vt = VT_BOOL;
- result->boolVal = IsDialog(data.role) ? VARIANT_TRUE : VARIANT_FALSE;
- break;
-
- case UIA_IsKeyboardFocusablePropertyId:
- result->vt = VT_BOOL;
- result->boolVal =
- ShouldNodeHaveFocusableState(data) ? VARIANT_TRUE : VARIANT_FALSE;
- break;
-
- case UIA_IsOffscreenPropertyId:
- result->vt = VT_BOOL;
- result->boolVal =
- GetDelegate()->IsOffscreen() ? VARIANT_TRUE : VARIANT_FALSE;
- break;
-
- case UIA_IsRequiredForFormPropertyId:
- result->vt = VT_BOOL;
- if (data.HasState(ax::mojom::State::kRequired)) {
- result->boolVal = VARIANT_TRUE;
- } else {
- result->boolVal = VARIANT_FALSE;
- }
- break;
-
- case UIA_ItemStatusPropertyId: {
- // https://www.w3.org/TR/core-aam-1.1/#mapping_state-property_table
- // aria-sort='ascending|descending|other' is mapped for the
- // HeaderItem Control Type.
- int32_t sort_direction;
- if (IsTableHeader(data.role) &&
- GetIntAttribute(ax::mojom::IntAttribute::kSortDirection,
- &sort_direction)) {
- switch (static_cast<ax::mojom::SortDirection>(sort_direction)) {
- case ax::mojom::SortDirection::kNone:
- case ax::mojom::SortDirection::kUnsorted:
- break;
- case ax::mojom::SortDirection::kAscending:
- V_VT(result) = VT_BSTR;
- V_BSTR(result) = SysAllocString(L"ascending");
- break;
- case ax::mojom::SortDirection::kDescending:
- V_VT(result) = VT_BSTR;
- V_BSTR(result) = SysAllocString(L"descending");
- break;
- case ax::mojom::SortDirection::kOther:
- V_VT(result) = VT_BSTR;
- V_BSTR(result) = SysAllocString(L"other");
- break;
- }
- }
- break;
- }
-
- case UIA_LabeledByPropertyId:
- if (AXPlatformNodeWin* node = ComputeUIALabeledBy()) {
- result->vt = VT_UNKNOWN;
- result->punkVal = node->GetNativeViewAccessible();
- result->punkVal->AddRef();
- }
- break;
-
- case UIA_LocalizedControlTypePropertyId: {
- base::string16 localized_control_type = GetRoleDescription();
- if (!localized_control_type.empty()) {
- result->vt = VT_BSTR;
- result->bstrVal = SysAllocString(localized_control_type.c_str());
- }
- // If a role description has not been provided, leave as VT_EMPTY.
- // UIA core handles Localized Control type for some built-in types and
- // also has a mapping for ARIA roles. To get these defaults, we need to
- // have returned VT_EMPTY.
- } break;
-
- case UIA_NamePropertyId:
- if (IsNameExposed()) {
- result->vt = VT_BSTR;
- GetNameAsBstr(&result->bstrVal);
- }
- break;
-
- case UIA_OrientationPropertyId:
- if (SupportsOrientation(data.role)) {
- if (data.HasState(ax::mojom::State::kHorizontal) &&
- data.HasState(ax::mojom::State::kVertical)) {
- NOTREACHED() << "An accessibility object cannot have a horizontal "
- "and a vertical orientation at the same time.";
- }
- if (data.HasState(ax::mojom::State::kHorizontal)) {
- result->vt = VT_I4;
- result->intVal = OrientationType_Horizontal;
- }
- if (data.HasState(ax::mojom::State::kVertical)) {
- result->vt = VT_I4;
- result->intVal = OrientationType_Vertical;
- }
- } else {
- result->vt = VT_I4;
- result->intVal = OrientationType_None;
- }
- break;
-
- case UIA_IsEnabledPropertyId:
- V_VT(result) = VT_BOOL;
- switch (data.GetRestriction()) {
- case ax::mojom::Restriction::kDisabled:
- V_BOOL(result) = VARIANT_FALSE;
- break;
-
- case ax::mojom::Restriction::kNone:
- case ax::mojom::Restriction::kReadOnly:
- V_BOOL(result) = VARIANT_TRUE;
- break;
- }
- break;
-
- case UIA_IsPasswordPropertyId:
- result->vt = VT_BOOL;
- result->boolVal = data.HasState(ax::mojom::State::kProtected)
- ? VARIANT_TRUE
- : VARIANT_FALSE;
- break;
-
- case UIA_AcceleratorKeyPropertyId:
- if (data.HasStringAttribute(ax::mojom::StringAttribute::kKeyShortcuts)) {
- result->vt = VT_BSTR;
- GetStringAttributeAsBstr(ax::mojom::StringAttribute::kKeyShortcuts,
- &result->bstrVal);
- }
- break;
-
- case UIA_AccessKeyPropertyId:
- if (data.HasStringAttribute(ax::mojom::StringAttribute::kAccessKey)) {
- result->vt = VT_BSTR;
- GetStringAttributeAsBstr(ax::mojom::StringAttribute::kAccessKey,
- &result->bstrVal);
- }
- break;
-
- case UIA_IsPeripheralPropertyId:
- result->vt = VT_BOOL;
- result->boolVal = VARIANT_FALSE;
- break;
-
- case UIA_LevelPropertyId:
- if (data.GetIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel,
- &int_attribute)) {
- result->vt = VT_I4;
- result->intVal = int_attribute;
- }
- break;
-
- case UIA_LiveSettingPropertyId: {
- result->vt = VT_I4;
- result->intVal = LiveSetting::Off;
-
- std::string string_attribute;
- if (data.GetStringAttribute(ax::mojom::StringAttribute::kLiveStatus,
- &string_attribute)) {
- if (string_attribute == "polite")
- result->intVal = LiveSetting::Polite;
- else if (string_attribute == "assertive")
- result->intVal = LiveSetting::Assertive;
- }
- break;
- }
-
- case UIA_OptimizeForVisualContentPropertyId:
- result->vt = VT_BOOL;
- result->boolVal = VARIANT_FALSE;
- break;
-
- case UIA_PositionInSetPropertyId: {
- base::Optional<int> pos_in_set = GetPosInSet();
- if (pos_in_set) {
- result->vt = VT_I4;
- result->intVal = *pos_in_set;
- }
- } break;
-
- case UIA_ScrollHorizontalScrollPercentPropertyId: {
- V_VT(result) = VT_R8;
- V_R8(result) = GetHorizontalScrollPercent();
- break;
- }
-
- case UIA_ScrollVerticalScrollPercentPropertyId: {
- V_VT(result) = VT_R8;
- V_R8(result) = GetVerticalScrollPercent();
- break;
- }
-
- case UIA_SizeOfSetPropertyId: {
- base::Optional<int> set_size = GetSetSize();
- if (set_size) {
- result->vt = VT_I4;
- result->intVal = *set_size;
- }
- break;
- }
-
- case UIA_LandmarkTypePropertyId: {
- base::Optional<LONG> landmark_type = ComputeUIALandmarkType();
- if (landmark_type) {
- result->vt = VT_I4;
- result->intVal = landmark_type.value();
- }
- break;
- }
-
- case UIA_LocalizedLandmarkTypePropertyId: {
- base::string16 localized_landmark_type =
- GetDelegate()->GetLocalizedStringForLandmarkType();
- if (!localized_landmark_type.empty()) {
- result->vt = VT_BSTR;
- result->bstrVal = SysAllocString(localized_landmark_type.c_str());
- }
- break;
- }
-
- case UIA_ExpandCollapseExpandCollapseStatePropertyId:
- result->vt = VT_I4;
- result->intVal = static_cast<int>(ComputeExpandCollapseState());
- break;
-
- // Not currently implemented.
- case UIA_AnnotationObjectsPropertyId:
- case UIA_AnnotationTypesPropertyId:
- case UIA_CenterPointPropertyId:
- case UIA_FillColorPropertyId:
- case UIA_FillTypePropertyId:
- case UIA_HeadingLevelPropertyId:
- case UIA_ItemTypePropertyId:
- case UIA_OutlineColorPropertyId:
- case UIA_OutlineThicknessPropertyId:
- case UIA_RotationPropertyId:
- case UIA_SizePropertyId:
- case UIA_VisualEffectsPropertyId:
- break;
-
- // Provided by UIA Core; we should not implement.
- case UIA_BoundingRectanglePropertyId:
- case UIA_NativeWindowHandlePropertyId:
- case UIA_ProcessIdPropertyId:
- case UIA_ProviderDescriptionPropertyId:
- case UIA_RuntimeIdPropertyId:
- break;
- } // End of default UIA property ids.
-
- // Custom UIA Property Ids.
- if (property_id ==
- UiaRegistrarWin::GetInstance().GetUiaUniqueIdPropertyId()) {
- // We want to negate the unique id for it to be consistent across different
- // Windows accessiblity APIs. The negative unique id convention originated
- // from ::NotifyWinEvent() takes an hwnd and a child id. A 0 child id means
- // self, and a positive child id means child #n. In order to fire an event
- // for an arbitrary descendant of the window, Firefox started the practice
- // of using a negative unique id. We follow the same negative unique id
- // convention here and when we fire events via ::NotifyWinEvent().
- result->vt = VT_BSTR;
- result->bstrVal =
- SysAllocString(base::NumberToString16(-GetUniqueId()).c_str());
- }
-
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_ProviderOptions(ProviderOptions* ret) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PROVIDER_OPTIONS);
- UIA_VALIDATE_CALL_1_ARG(ret);
-
- *ret = ProviderOptions_ServerSideProvider | ProviderOptions_UseComThreading |
- ProviderOptions_RefuseNonClientSupport |
- ProviderOptions_HasNativeIAccessible;
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_HostRawElementProvider(
- IRawElementProviderSimple** provider) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_HOST_RAW_ELEMENT_PROVIDER);
- UIA_VALIDATE_CALL_1_ARG(provider);
-
- *provider = nullptr;
- return S_OK;
-}
-
-//
-// IRawElementProviderSimple2 implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::ShowContextMenu() {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SHOWCONTEXTMENU);
- UIA_VALIDATE_CALL();
-
- AXActionData action_data;
- action_data.action = ax::mojom::Action::kShowContextMenu;
- delegate_->AccessibilityPerformAction(action_data);
- return S_OK;
-}
-
-//
-// IChromeAccessible implementation.
-//
-
-void SendBulkFetchResponse(
- Microsoft::WRL::ComPtr<IChromeAccessibleDelegate> delegate,
- LONG request_id,
- std::string json_result) {
- base::string16 json_result_utf16 = base::UTF8ToUTF16(json_result);
- delegate->put_bulkFetchResult(request_id,
- SysAllocString(json_result_utf16.c_str()));
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_bulkFetch(
- BSTR input_json,
- LONG request_id,
- IChromeAccessibleDelegate* delegate) {
- COM_OBJECT_VALIDATE();
- if (!delegate)
- return E_INVALIDARG;
-
- // TODO(crbug.com/1083834): if parsing |input_json|, use
- // DataDecoder because the json is untrusted. For now, this is just
- // a stub that calls PostTask so that it's async, but it doesn't
- // actually parse the input.
-
- base::Value result(base::Value::Type::DICTIONARY);
- result.SetKey("role", base::Value(ui::ToString(GetData().role)));
-
- gfx::Rect bounds = GetDelegate()->GetBoundsRect(
- AXCoordinateSystem::kScreenDIPs, AXClippingBehavior::kUnclipped);
- result.SetKey("x", base::Value(bounds.x()));
- result.SetKey("y", base::Value(bounds.y()));
- result.SetKey("width", base::Value(bounds.width()));
- result.SetKey("height", base::Value(bounds.height()));
- std::string json_result;
- base::JSONWriter::Write(result, &json_result);
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(
- &SendBulkFetchResponse,
- Microsoft::WRL::ComPtr<IChromeAccessibleDelegate>(delegate),
- request_id, json_result));
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformNodeWin::get_hitTest(
- LONG screen_physical_pixel_x,
- LONG screen_physical_pixel_y,
- LONG request_id,
- IChromeAccessibleDelegate* delegate) {
- COM_OBJECT_VALIDATE();
-
- if (!delegate)
- return E_INVALIDARG;
-
- // TODO(crbug.com/1083834): Plumb through an actual async hit test.
- AXPlatformNodeWin* hit_child = static_cast<AXPlatformNodeWin*>(
- FromNativeViewAccessible(GetDelegate()->HitTestSync(
- screen_physical_pixel_x, screen_physical_pixel_y)));
-
- delegate->put_hitTestResult(request_id, static_cast<IAccessible*>(hit_child));
- return S_OK;
-}
-
-//
-// IServiceProvider implementation.
-//
-
-IFACEMETHODIMP AXPlatformNodeWin::QueryService(REFGUID guidService,
- REFIID riid,
- void** object) {
- COM_OBJECT_VALIDATE_1_ARG(object);
-
- if (riid == IID_IAccessible2) {
- for (WinAccessibilityAPIUsageObserver& observer :
- GetWinAccessibilityAPIUsageObserverList()) {
- observer.OnIAccessible2Used();
- }
- }
-
- if (guidService == IID_IAccessible || guidService == IID_IAccessible2 ||
- guidService == IID_IAccessible2_2 ||
- guidService == IID_IAccessibleTable ||
- guidService == IID_IAccessibleTable2 ||
- guidService == IID_IAccessibleTableCell ||
- guidService == IID_IAccessibleText ||
- guidService == IID_IAccessibleValue) {
- return QueryInterface(riid, object);
- }
-
- if (guidService == IID_IChromeAccessible) {
- if (features::IsIChromeAccessibleEnabled()) {
- return QueryInterface(riid, object);
- }
- }
-
- // TODO(suproteem): Include IAccessibleEx in the list, potentially checking
- // for version.
-
- *object = nullptr;
- return E_FAIL;
-}
-
-//
-// Methods used by the ATL COM map.
-//
-
-// static
-STDMETHODIMP AXPlatformNodeWin::InternalQueryInterface(
- void* this_ptr,
- const _ATL_INTMAP_ENTRY* entries,
- REFIID riid,
- void** object) {
- if (!object)
- return E_INVALIDARG;
- *object = nullptr;
- AXPlatformNodeWin* accessible =
- reinterpret_cast<AXPlatformNodeWin*>(this_ptr);
- DCHECK(accessible);
-
- if (riid == IID_IAccessibleTable || riid == IID_IAccessibleTable2) {
- if (!IsTableLike(accessible->GetData().role))
- return E_NOINTERFACE;
- } else if (riid == IID_IAccessibleTableCell) {
- if (!IsCellOrTableHeader(accessible->GetData().role))
- return E_NOINTERFACE;
- } else if (riid == IID_IAccessibleText || riid == IID_IAccessibleHypertext) {
- if (IsImageOrVideo(accessible->GetData().role)) {
- return E_NOINTERFACE;
- }
- } else if (riid == IID_IAccessibleValue) {
- if (!accessible->GetData().IsRangeValueSupported()) {
- return E_NOINTERFACE;
- }
- } else if (riid == IID_IChromeAccessible) {
- if (!features::IsIChromeAccessibleEnabled()) {
- return E_NOINTERFACE;
- }
- }
-
- return CComObjectRootBase::InternalQueryInterface(this_ptr, entries, riid,
- object);
-}
-
-HRESULT AXPlatformNodeWin::GetTextAttributeValue(
- TEXTATTRIBUTEID attribute_id,
- const base::Optional<int>& start_offset,
- const base::Optional<int>& end_offset,
- base::win::VariantVector* result) {
- DCHECK(!start_offset || start_offset.value() >= 0);
- DCHECK(!end_offset || end_offset.value() >= 0);
-
- switch (attribute_id) {
- case UIA_AnnotationTypesAttributeId:
- return GetAnnotationTypesAttribute(start_offset, end_offset, result);
- case UIA_BackgroundColorAttributeId:
- result->Insert<VT_I4>(
- GetIntAttributeAsCOLORREF(ax::mojom::IntAttribute::kBackgroundColor));
- break;
- case UIA_BulletStyleAttributeId:
- result->Insert<VT_I4>(ComputeUIABulletStyle());
- break;
- case UIA_CultureAttributeId: {
- base::Optional<LCID> lcid = GetCultureAttributeAsLCID();
- if (!lcid)
- return E_FAIL;
- result->Insert<VT_I4>(lcid.value());
- break;
- }
- case UIA_FontNameAttributeId:
- result->Insert<VT_BSTR>(GetFontNameAttributeAsBSTR());
- break;
- case UIA_FontSizeAttributeId: {
- base::Optional<float> font_size_in_points = GetFontSizeInPoints();
- if (font_size_in_points) {
- result->Insert<VT_R8>(*font_size_in_points);
- }
- break;
- }
- case UIA_FontWeightAttributeId:
- result->Insert<VT_I4>(
- GetFloatAttribute(ax::mojom::FloatAttribute::kFontWeight));
- break;
- case UIA_ForegroundColorAttributeId:
- result->Insert<VT_I4>(
- GetIntAttributeAsCOLORREF(ax::mojom::IntAttribute::kColor));
- break;
- case UIA_IsHiddenAttributeId:
- result->Insert<VT_BOOL>(IsInvisibleOrIgnored());
- break;
- case UIA_IsItalicAttributeId:
- result->Insert<VT_BOOL>(
- GetData().HasTextStyle(ax::mojom::TextStyle::kItalic));
- break;
- case UIA_IsReadOnlyAttributeId:
- // Placeholder text should return the enclosing element's read-only value.
- if (IsPlaceholderText()) {
- AXPlatformNodeWin* parent_platform_node =
- static_cast<AXPlatformNodeWin*>(
- FromNativeViewAccessible(GetParent()));
- return parent_platform_node->GetTextAttributeValue(
- attribute_id, start_offset, end_offset, result);
- }
- result->Insert<VT_BOOL>(GetData().IsReadOnlyOrDisabled());
- break;
- case UIA_IsSubscriptAttributeId:
- result->Insert<VT_BOOL>(GetData().GetTextPosition() ==
- ax::mojom::TextPosition::kSubscript);
- break;
- case UIA_IsSuperscriptAttributeId:
- result->Insert<VT_BOOL>(GetData().GetTextPosition() ==
- ax::mojom::TextPosition::kSuperscript);
- break;
- case UIA_OverlineStyleAttributeId:
- result->Insert<VT_I4>(GetUIATextDecorationStyle(
- ax::mojom::IntAttribute::kTextOverlineStyle));
- break;
- case UIA_StrikethroughStyleAttributeId:
- result->Insert<VT_I4>(GetUIATextDecorationStyle(
- ax::mojom::IntAttribute::kTextStrikethroughStyle));
- break;
- case UIA_StyleNameAttributeId:
- result->Insert<VT_BSTR>(GetStyleNameAttributeAsBSTR());
- break;
- case UIA_StyleIdAttributeId:
- result->Insert<VT_I4>(ComputeUIAStyleId());
- break;
- case UIA_HorizontalTextAlignmentAttributeId: {
- base::Optional<HorizontalTextAlignment> horizontal_text_alignment =
- AXTextAlignToUIAHorizontalTextAlignment(GetData().GetTextAlign());
- if (horizontal_text_alignment)
- result->Insert<VT_I4>(*horizontal_text_alignment);
- break;
- }
- case UIA_UnderlineStyleAttributeId:
- result->Insert<VT_I4>(GetUIATextDecorationStyle(
- ax::mojom::IntAttribute::kTextUnderlineStyle));
- break;
- case UIA_TextFlowDirectionsAttributeId:
- result->Insert<VT_I4>(
- TextDirectionToFlowDirections(GetData().GetTextDirection()));
- break;
- default: {
- Microsoft::WRL::ComPtr<IUnknown> not_supported_value;
- HRESULT hr = ::UiaGetReservedNotSupportedValue(¬_supported_value);
- if (SUCCEEDED(hr))
- result->Insert<VT_UNKNOWN>(not_supported_value.Get());
- return hr;
- } break;
- }
-
- return S_OK;
-}
-
-HRESULT AXPlatformNodeWin::GetAnnotationTypesAttribute(
- const base::Optional<int>& start_offset,
- const base::Optional<int>& end_offset,
- base::win::VariantVector* result) {
- base::win::VariantVector variant_vector;
-
- MarkerTypeRangeResult grammar_result = MarkerTypeRangeResult::kNone;
- MarkerTypeRangeResult spelling_result = MarkerTypeRangeResult::kNone;
-
- if (IsText() || IsPlainTextField()) {
- grammar_result = GetMarkerTypeFromRange(start_offset, end_offset,
- ax::mojom::MarkerType::kGrammar);
- spelling_result = GetMarkerTypeFromRange(start_offset, end_offset,
- ax::mojom::MarkerType::kSpelling);
- }
-
- if (grammar_result == MarkerTypeRangeResult::kMixed ||
- spelling_result == MarkerTypeRangeResult::kMixed) {
- Microsoft::WRL::ComPtr<IUnknown> mixed_attribute_value;
- HRESULT hr = ::UiaGetReservedMixedAttributeValue(&mixed_attribute_value);
- if (SUCCEEDED(hr))
- result->Insert<VT_UNKNOWN>(mixed_attribute_value.Get());
- return hr;
- }
-
- if (spelling_result == MarkerTypeRangeResult::kMatch)
- result->Insert<VT_I4>(AnnotationType_SpellingError);
- if (grammar_result == MarkerTypeRangeResult::kMatch)
- result->Insert<VT_I4>(AnnotationType_GrammarError);
-
- return S_OK;
-}
-
-base::Optional<LCID> AXPlatformNodeWin::GetCultureAttributeAsLCID() const {
- const base::string16 language =
- GetInheritedString16Attribute(ax::mojom::StringAttribute::kLanguage);
- const LCID lcid =
- LocaleNameToLCID(language.c_str(), LOCALE_ALLOW_NEUTRAL_NAMES);
- if (!lcid)
- return base::nullopt;
-
- return lcid;
-}
-
-COLORREF AXPlatformNodeWin::GetIntAttributeAsCOLORREF(
- ax::mojom::IntAttribute attribute) const {
- const SkColor color = GetIntAttribute(attribute);
- return skia::SkColorToCOLORREF(color);
-}
-
-BulletStyle AXPlatformNodeWin::ComputeUIABulletStyle() const {
- // UIA expects the list style of a non-list-item to be none however the
- // default list style cascaded is disc not none. Therefore we must ensure that
- // this node is contained within a list-item to distinguish non-list-items and
- // disc styled list items.
- const AXPlatformNodeBase* current_node = this;
- while (current_node &&
- current_node->GetData().role != ax::mojom::Role::kListItem) {
- current_node = FromNativeViewAccessible(current_node->GetParent());
- }
-
- const ax::mojom::ListStyle list_style =
- current_node ? current_node->GetData().GetListStyle()
- : ax::mojom::ListStyle::kNone;
-
- switch (list_style) {
- case ax::mojom::ListStyle::kNone:
- return BulletStyle::BulletStyle_None;
- case ax::mojom::ListStyle::kCircle:
- return BulletStyle::BulletStyle_HollowRoundBullet;
- case ax::mojom::ListStyle::kDisc:
- return BulletStyle::BulletStyle_FilledRoundBullet;
- case ax::mojom::ListStyle::kImage:
- return BulletStyle::BulletStyle_Other;
- case ax::mojom::ListStyle::kNumeric:
- case ax::mojom::ListStyle::kOther:
- return BulletStyle::BulletStyle_None;
- case ax::mojom::ListStyle::kSquare:
- return BulletStyle::BulletStyle_FilledSquareBullet;
- }
-}
-
-LONG AXPlatformNodeWin::ComputeUIAStyleId() const {
- const AXPlatformNodeBase* current_node = this;
- do {
- switch (current_node->GetData().role) {
- case ax::mojom::Role::kHeading:
- return AXHierarchicalLevelToUIAStyleId(current_node->GetIntAttribute(
- ax::mojom::IntAttribute::kHierarchicalLevel));
- case ax::mojom::Role::kListItem:
- return AXListStyleToUIAStyleId(current_node->GetData().GetListStyle());
- case ax::mojom::Role::kMark:
- return StyleId_Custom;
- case ax::mojom::Role::kBlockquote:
- return StyleId_Quote;
- default:
- break;
- }
- current_node = FromNativeViewAccessible(current_node->GetParent());
- } while (current_node);
-
- return StyleId_Normal;
-}
-
-// static
-base::Optional<HorizontalTextAlignment>
-AXPlatformNodeWin::AXTextAlignToUIAHorizontalTextAlignment(
- ax::mojom::TextAlign text_align) {
- switch (text_align) {
- case ax::mojom::TextAlign::kNone:
- return base::nullopt;
- case ax::mojom::TextAlign::kLeft:
- return HorizontalTextAlignment_Left;
- case ax::mojom::TextAlign::kRight:
- return HorizontalTextAlignment_Right;
- case ax::mojom::TextAlign::kCenter:
- return HorizontalTextAlignment_Centered;
- case ax::mojom::TextAlign::kJustify:
- return HorizontalTextAlignment_Justified;
- }
-}
-
-// static
-LONG AXPlatformNodeWin::AXHierarchicalLevelToUIAStyleId(
- int32_t hierarchical_level) {
- switch (hierarchical_level) {
- case 0:
- return StyleId_Normal;
- case 1:
- return StyleId_Heading1;
- case 2:
- return StyleId_Heading2;
- case 3:
- return StyleId_Heading3;
- case 4:
- return StyleId_Heading4;
- case 5:
- return StyleId_Heading5;
- case 6:
- return StyleId_Heading6;
- case 7:
- return StyleId_Heading7;
- case 8:
- return StyleId_Heading8;
- case 9:
- return StyleId_Heading9;
- default:
- return StyleId_Custom;
- }
-}
-
-// static
-LONG AXPlatformNodeWin::AXListStyleToUIAStyleId(
- ax::mojom::ListStyle list_style) {
- switch (list_style) {
- case ax::mojom::ListStyle::kNone:
- return StyleId_Normal;
- case ax::mojom::ListStyle::kCircle:
- case ax::mojom::ListStyle::kDisc:
- case ax::mojom::ListStyle::kImage:
- case ax::mojom::ListStyle::kSquare:
- return StyleId_BulletedList;
- case ax::mojom::ListStyle::kNumeric:
- case ax::mojom::ListStyle::kOther:
- return StyleId_NumberedList;
- }
-}
-
-// static
-FlowDirections AXPlatformNodeWin::TextDirectionToFlowDirections(
- ax::mojom::WritingDirection text_direction) {
- switch (text_direction) {
- case ax::mojom::WritingDirection::kNone:
- return FlowDirections::FlowDirections_Default;
- case ax::mojom::WritingDirection::kLtr:
- return FlowDirections::FlowDirections_Default;
- case ax::mojom::WritingDirection::kRtl:
- return FlowDirections::FlowDirections_RightToLeft;
- case ax::mojom::WritingDirection::kTtb:
- return FlowDirections::FlowDirections_Vertical;
- case ax::mojom::WritingDirection::kBtt:
- return FlowDirections::FlowDirections_BottomToTop;
- }
-}
-
-// static
-void AXPlatformNodeWin::AggregateRangesForMarkerType(
- AXPlatformNodeBase* node,
- ax::mojom::MarkerType marker_type,
- int offset_ranges_amount,
- std::vector<std::pair<int, int>>* ranges) {
- DCHECK(node->IsText());
- const std::vector<int32_t>& marker_types =
- node->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerTypes);
- const std::vector<int>& marker_starts =
- node->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerStarts);
- const std::vector<int>& marker_ends =
- node->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerEnds);
-
- for (size_t i = 0; i < marker_types.size(); ++i) {
- if (static_cast<ax::mojom::MarkerType>(marker_types[i]) != marker_type)
- continue;
-
- const int marker_start = marker_starts[i] + offset_ranges_amount;
- const int marker_end = marker_ends[i] + offset_ranges_amount;
- ranges->emplace_back(std::make_pair(marker_start, marker_end));
- }
-}
-
-AXPlatformNodeWin::MarkerTypeRangeResult
-AXPlatformNodeWin::GetMarkerTypeFromRange(
- const base::Optional<int>& start_offset,
- const base::Optional<int>& end_offset,
- ax::mojom::MarkerType marker_type) {
- DCHECK(IsText() || IsPlainTextField());
- std::vector<std::pair<int, int>> relevant_ranges;
-
- if (IsText()) {
- AggregateRangesForMarkerType(this, marker_type, /*offset_ranges_amount=*/0,
- &relevant_ranges);
- } else if (IsPlainTextField()) {
- int offset_ranges_amount = 0;
- for (AXPlatformNodeBase* static_text = GetFirstTextOnlyDescendant();
- static_text; static_text = static_text->GetNextSibling()) {
- const int child_offset_ranges_amount = offset_ranges_amount;
- if (start_offset || end_offset) {
- // Break if the current node is after the desired |end_offset|.
- if (end_offset && child_offset_ranges_amount > end_offset.value())
- break;
-
- // Skip over nodes preceding the desired |start_offset|.
- offset_ranges_amount += static_text->GetHypertext().length();
- if (start_offset && offset_ranges_amount < start_offset.value())
- continue;
- }
-
- AggregateRangesForMarkerType(static_text, marker_type,
- child_offset_ranges_amount,
- &relevant_ranges);
- }
- }
-
- // Sort the ranges by their start offset.
- const auto sort_ranges_by_start_offset = [](const std::pair<int, int>& a,
- const std::pair<int, int>& b) {
- return a.first < b.first;
- };
- std::sort(relevant_ranges.begin(), relevant_ranges.end(),
- sort_ranges_by_start_offset);
-
- // Validate that the desired range has a contiguous MarkerType.
- base::Optional<std::pair<int, int>> contiguous_range;
- for (const std::pair<int, int>& range : relevant_ranges) {
- if (end_offset && range.first > end_offset.value())
- break;
- if (start_offset && range.second < start_offset.value())
- continue;
-
- if (!contiguous_range) {
- contiguous_range = range;
- continue;
- }
-
- // If there is a gap, then the range must be mixed.
- if ((range.first - contiguous_range->second) > 1)
- return MarkerTypeRangeResult::kMixed;
-
- // Expand the range if possible.
- contiguous_range->second = std::max(contiguous_range->second, range.second);
- }
-
- // The desired range does not overlap with |marker_type|.
- if (!contiguous_range)
- return MarkerTypeRangeResult::kNone;
-
- // If there is a partial overlap, then the desired range must be mixed.
- // 1. The |start_offset| is not specified, treat it as offset 0.
- if (!start_offset && contiguous_range->first > 0)
- return MarkerTypeRangeResult::kMixed;
- // 2. The |end_offset| is not specified, treat it as max text offset.
- if (!end_offset && size_t{contiguous_range->second} < GetHypertext().length())
- return MarkerTypeRangeResult::kMixed;
- // 3. The |start_offset| is specified, but is before the first matching range.
- if (start_offset && start_offset.value() < contiguous_range->first)
- return MarkerTypeRangeResult::kMixed;
- // 4. The |end_offset| is specified, but is after the last matching range.
- if (end_offset && end_offset.value() > contiguous_range->second)
- return MarkerTypeRangeResult::kMixed;
-
- // The desired range is a complete match for |marker_type|.
- return MarkerTypeRangeResult::kMatch;
-}
-
-// IRawElementProviderSimple support methods.
-
-bool AXPlatformNodeWin::IsPatternProviderSupported(PATTERNID pattern_id) {
- return GetPatternProviderFactoryMethod(pattern_id);
-}
-
-//
-// Private member functions.
-//
-int AXPlatformNodeWin::MSAARole() {
- // If this is a web area for a presentational iframe, give it a role of
- // something other than DOCUMENT so that the fact that it's a separate doc
- // is not exposed to AT.
- if (IsWebAreaForPresentationalIframe())
- return ROLE_SYSTEM_GROUPING;
-
- switch (GetData().role) {
- case ax::mojom::Role::kAlert:
- return ROLE_SYSTEM_ALERT;
-
- case ax::mojom::Role::kAlertDialog:
- return ROLE_SYSTEM_DIALOG;
-
- case ax::mojom::Role::kAnchor:
- return ROLE_SYSTEM_LINK;
-
- case ax::mojom::Role::kComment:
- case ax::mojom::Role::kSuggestion:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kApplication:
- return ROLE_SYSTEM_APPLICATION;
-
- case ax::mojom::Role::kArticle:
- return ROLE_SYSTEM_DOCUMENT;
-
- case ax::mojom::Role::kAudio:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kBanner:
- case ax::mojom::Role::kHeader:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kBlockquote:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kButton:
- return ROLE_SYSTEM_PUSHBUTTON;
-
- case ax::mojom::Role::kCanvas:
- return ROLE_SYSTEM_GRAPHIC;
-
- case ax::mojom::Role::kCaption:
- return ROLE_SYSTEM_TEXT;
-
- case ax::mojom::Role::kCaret:
- return ROLE_SYSTEM_CARET;
-
- case ax::mojom::Role::kCell:
- return ROLE_SYSTEM_CELL;
-
- case ax::mojom::Role::kCheckBox:
- return ROLE_SYSTEM_CHECKBUTTON;
-
- case ax::mojom::Role::kClient:
- return ROLE_SYSTEM_PANE;
-
- case ax::mojom::Role::kColorWell:
- return ROLE_SYSTEM_TEXT;
-
- case ax::mojom::Role::kColumn:
- return ROLE_SYSTEM_COLUMN;
-
- case ax::mojom::Role::kColumnHeader:
- return ROLE_SYSTEM_COLUMNHEADER;
-
- case ax::mojom::Role::kComboBoxGrouping:
- case ax::mojom::Role::kComboBoxMenuButton:
- return ROLE_SYSTEM_COMBOBOX;
-
- case ax::mojom::Role::kComplementary:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kContentDeletion:
- case ax::mojom::Role::kContentInsertion:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kContentInfo:
- case ax::mojom::Role::kFooter:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kDate:
- case ax::mojom::Role::kDateTime:
- return ROLE_SYSTEM_DROPLIST;
-
- case ax::mojom::Role::kDefinition:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kDescriptionListDetail:
- return ROLE_SYSTEM_TEXT;
-
- case ax::mojom::Role::kDescriptionList:
- return ROLE_SYSTEM_LIST;
-
- case ax::mojom::Role::kDescriptionListTerm:
- return ROLE_SYSTEM_LISTITEM;
-
- case ax::mojom::Role::kDesktop:
- return ROLE_SYSTEM_PANE;
-
- case ax::mojom::Role::kDetails:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kDialog:
- return ROLE_SYSTEM_DIALOG;
-
- case ax::mojom::Role::kDisclosureTriangle:
- return ROLE_SYSTEM_PUSHBUTTON;
-
- case ax::mojom::Role::kDirectory:
- return ROLE_SYSTEM_LIST;
-
- case ax::mojom::Role::kDocCover:
- return ROLE_SYSTEM_GRAPHIC;
-
- case ax::mojom::Role::kDocBackLink:
- case ax::mojom::Role::kDocBiblioRef:
- case ax::mojom::Role::kDocGlossRef:
- case ax::mojom::Role::kDocNoteRef:
- return ROLE_SYSTEM_LINK;
-
- case ax::mojom::Role::kDocBiblioEntry:
- case ax::mojom::Role::kDocEndnote:
- case ax::mojom::Role::kDocFootnote:
- return ROLE_SYSTEM_LISTITEM;
-
- case ax::mojom::Role::kDocPageBreak:
- return ROLE_SYSTEM_SEPARATOR;
-
- case ax::mojom::Role::kDocAbstract:
- case ax::mojom::Role::kDocAcknowledgments:
- case ax::mojom::Role::kDocAfterword:
- case ax::mojom::Role::kDocAppendix:
- case ax::mojom::Role::kDocBibliography:
- case ax::mojom::Role::kDocChapter:
- case ax::mojom::Role::kDocColophon:
- case ax::mojom::Role::kDocConclusion:
- case ax::mojom::Role::kDocCredit:
- case ax::mojom::Role::kDocCredits:
- case ax::mojom::Role::kDocDedication:
- case ax::mojom::Role::kDocEndnotes:
- case ax::mojom::Role::kDocEpigraph:
- case ax::mojom::Role::kDocEpilogue:
- case ax::mojom::Role::kDocErrata:
- case ax::mojom::Role::kDocExample:
- case ax::mojom::Role::kDocForeword:
- case ax::mojom::Role::kDocGlossary:
- case ax::mojom::Role::kDocIndex:
- case ax::mojom::Role::kDocIntroduction:
- case ax::mojom::Role::kDocNotice:
- case ax::mojom::Role::kDocPageList:
- case ax::mojom::Role::kDocPart:
- case ax::mojom::Role::kDocPreface:
- case ax::mojom::Role::kDocPrologue:
- case ax::mojom::Role::kDocPullquote:
- case ax::mojom::Role::kDocQna:
- case ax::mojom::Role::kDocSubtitle:
- case ax::mojom::Role::kDocTip:
- case ax::mojom::Role::kDocToc:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kDocument:
- case ax::mojom::Role::kRootWebArea:
- case ax::mojom::Role::kWebArea:
- return ROLE_SYSTEM_DOCUMENT;
-
- case ax::mojom::Role::kEmbeddedObject:
- // Even though the HTML-AAM has ROLE_SYSTEM_CLIENT for <embed>, we are
- // forced to use ROLE_SYSTEM_GROUPING when the <embed> has children in the
- // accessibility tree.
- // https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings
- //
- // Screen readers Jaws and NVDA do not "see" any of the <embed>'s contents
- // if they are represented as its children in the accessibility tree. For
- // example, one of the places that would be negatively impacted is the
- // reading of PDFs.
- if (GetDelegate()->GetChildCount()) {
- return ROLE_SYSTEM_GROUPING;
- } else {
- return ROLE_SYSTEM_CLIENT;
- }
-
- case ax::mojom::Role::kFigcaption:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kFigure:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kFeed:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kFooterAsNonLandmark:
- case ax::mojom::Role::kHeaderAsNonLandmark:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kForm:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kGenericContainer:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kGraphicsDocument:
- return ROLE_SYSTEM_DOCUMENT;
-
- case ax::mojom::Role::kGraphicsObject:
- return ROLE_SYSTEM_PANE;
-
- case ax::mojom::Role::kGraphicsSymbol:
- return ROLE_SYSTEM_GRAPHIC;
-
- case ax::mojom::Role::kGrid:
- return ROLE_SYSTEM_TABLE;
-
- case ax::mojom::Role::kGroup:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kHeading:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kIframe:
- return ROLE_SYSTEM_DOCUMENT;
-
- case ax::mojom::Role::kIframePresentational:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kImage:
- case ax::mojom::Role::kImageMap:
- return ROLE_SYSTEM_GRAPHIC;
-
- case ax::mojom::Role::kInputTime:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kInlineTextBox:
- return ROLE_SYSTEM_STATICTEXT;
-
- case ax::mojom::Role::kLabelText:
- case ax::mojom::Role::kLegend:
- return ROLE_SYSTEM_TEXT;
-
- case ax::mojom::Role::kLayoutTable:
- return ROLE_SYSTEM_TABLE;
-
- case ax::mojom::Role::kLayoutTableCell:
- return ROLE_SYSTEM_CELL;
-
- case ax::mojom::Role::kLayoutTableRow:
- return ROLE_SYSTEM_ROW;
-
- case ax::mojom::Role::kLink:
- return ROLE_SYSTEM_LINK;
-
- case ax::mojom::Role::kList:
- return ROLE_SYSTEM_LIST;
-
- case ax::mojom::Role::kListBox:
- return ROLE_SYSTEM_LIST;
-
- case ax::mojom::Role::kListBoxOption:
- return ROLE_SYSTEM_LISTITEM;
-
- case ax::mojom::Role::kListGrid:
- return ROLE_SYSTEM_LIST;
-
- case ax::mojom::Role::kListItem:
- return ROLE_SYSTEM_LISTITEM;
-
- case ax::mojom::Role::kListMarker:
- if (!GetDelegate()->GetChildCount()) {
- // There's only a name attribute when using Legacy layout. With Legacy
- // layout, list markers have no child and are considered as StaticText.
- // We consider a list marker as a group in LayoutNG since it has
- // a text child node.
- return ROLE_SYSTEM_STATICTEXT;
- }
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kLog:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kMain:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kMark:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kMarquee:
- return ROLE_SYSTEM_ANIMATION;
-
- case ax::mojom::Role::kMath:
- return ROLE_SYSTEM_EQUATION;
-
- case ax::mojom::Role::kMenu:
- return ROLE_SYSTEM_MENUPOPUP;
-
- case ax::mojom::Role::kMenuBar:
- return ROLE_SYSTEM_MENUBAR;
-
- case ax::mojom::Role::kMenuItem:
- case ax::mojom::Role::kMenuItemCheckBox:
- case ax::mojom::Role::kMenuItemRadio:
- return ROLE_SYSTEM_MENUITEM;
-
- case ax::mojom::Role::kMenuListPopup:
- return ROLE_SYSTEM_LIST;
-
- case ax::mojom::Role::kMenuListOption:
- return ROLE_SYSTEM_LISTITEM;
-
- case ax::mojom::Role::kMeter:
- return ROLE_SYSTEM_PROGRESSBAR;
-
- case ax::mojom::Role::kNavigation:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kNote:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kParagraph:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kPdfActionableHighlight:
- return ROLE_SYSTEM_PUSHBUTTON;
-
- case ax::mojom::Role::kPluginObject:
- // See also case ax::mojom::Role::kEmbeddedObject.
- if (GetDelegate()->GetChildCount()) {
- return ROLE_SYSTEM_GROUPING;
- } else {
- return ROLE_SYSTEM_CLIENT;
- }
-
- case ax::mojom::Role::kPopUpButton: {
- std::string html_tag =
- GetData().GetStringAttribute(ax::mojom::StringAttribute::kHtmlTag);
- if (html_tag == "select")
- return ROLE_SYSTEM_COMBOBOX;
- return ROLE_SYSTEM_BUTTONMENU;
- }
-
- case ax::mojom::Role::kPortal:
- return ROLE_SYSTEM_PUSHBUTTON;
-
- case ax::mojom::Role::kPre:
- return ROLE_SYSTEM_TEXT;
-
- case ax::mojom::Role::kProgressIndicator:
- return ROLE_SYSTEM_PROGRESSBAR;
-
- case ax::mojom::Role::kRadioButton:
- return ROLE_SYSTEM_RADIOBUTTON;
-
- case ax::mojom::Role::kRadioGroup:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kRegion:
- return ROLE_SYSTEM_PANE;
-
- case ax::mojom::Role::kRow: {
- // Role changes depending on whether row is inside a treegrid
- // https://www.w3.org/TR/core-aam-1.1/#role-map-row
- return IsInTreeGrid() ? ROLE_SYSTEM_OUTLINEITEM : ROLE_SYSTEM_ROW;
- }
-
- case ax::mojom::Role::kRowGroup:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kRowHeader:
- return ROLE_SYSTEM_ROWHEADER;
-
- case ax::mojom::Role::kRuby:
- return ROLE_SYSTEM_TEXT;
-
- case ax::mojom::Role::kSection: {
- if (GetNameAsString16().empty()) {
- // Do not use ARIA mapping for nameless <section>.
- return ROLE_SYSTEM_GROUPING;
- }
- // Use ARIA mapping.
- return ROLE_SYSTEM_PANE;
- }
-
- case ax::mojom::Role::kScrollBar:
- return ROLE_SYSTEM_SCROLLBAR;
-
- case ax::mojom::Role::kScrollView:
- return ROLE_SYSTEM_PANE;
-
- case ax::mojom::Role::kSearch:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kSlider:
- return ROLE_SYSTEM_SLIDER;
-
- case ax::mojom::Role::kSliderThumb:
- return ROLE_SYSTEM_SLIDER;
-
- case ax::mojom::Role::kSpinButton:
- return ROLE_SYSTEM_SPINBUTTON;
-
- case ax::mojom::Role::kSwitch:
- return ROLE_SYSTEM_CHECKBUTTON;
-
- case ax::mojom::Role::kRubyAnnotation:
- case ax::mojom::Role::kStaticText:
- return ROLE_SYSTEM_STATICTEXT;
-
- case ax::mojom::Role::kStatus:
- return ROLE_SYSTEM_STATUSBAR;
-
- case ax::mojom::Role::kSplitter:
- return ROLE_SYSTEM_SEPARATOR;
-
- case ax::mojom::Role::kSvgRoot:
- return ROLE_SYSTEM_GRAPHIC;
-
- case ax::mojom::Role::kTab:
- return ROLE_SYSTEM_PAGETAB;
-
- case ax::mojom::Role::kTable:
- return ROLE_SYSTEM_TABLE;
-
- case ax::mojom::Role::kTableHeaderContainer:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kTabList:
- return ROLE_SYSTEM_PAGETABLIST;
-
- case ax::mojom::Role::kTabPanel:
- return ROLE_SYSTEM_PROPERTYPAGE;
-
- case ax::mojom::Role::kTerm:
- return ROLE_SYSTEM_LISTITEM;
-
- case ax::mojom::Role::kTitleBar:
- return ROLE_SYSTEM_TITLEBAR;
-
- case ax::mojom::Role::kToggleButton:
- return ROLE_SYSTEM_PUSHBUTTON;
-
- case ax::mojom::Role::kTextField:
- case ax::mojom::Role::kSearchBox:
- return ROLE_SYSTEM_TEXT;
-
- case ax::mojom::Role::kTextFieldWithComboBox:
- return ROLE_SYSTEM_COMBOBOX;
-
- case ax::mojom::Role::kAbbr:
- case ax::mojom::Role::kCode:
- case ax::mojom::Role::kEmphasis:
- case ax::mojom::Role::kStrong:
- case ax::mojom::Role::kTime:
- return ROLE_SYSTEM_TEXT;
-
- case ax::mojom::Role::kTimer:
- return ROLE_SYSTEM_CLOCK;
-
- case ax::mojom::Role::kToolbar:
- return ROLE_SYSTEM_TOOLBAR;
-
- case ax::mojom::Role::kTooltip:
- return ROLE_SYSTEM_TOOLTIP;
-
- case ax::mojom::Role::kTree:
- return ROLE_SYSTEM_OUTLINE;
-
- case ax::mojom::Role::kTreeGrid:
- return ROLE_SYSTEM_OUTLINE;
-
- case ax::mojom::Role::kTreeItem:
- return ROLE_SYSTEM_OUTLINEITEM;
-
- case ax::mojom::Role::kLineBreak:
- return ROLE_SYSTEM_WHITESPACE;
-
- case ax::mojom::Role::kVideo:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kWebView:
- return ROLE_SYSTEM_CLIENT;
-
- case ax::mojom::Role::kPane:
- case ax::mojom::Role::kWindow:
- // Do not return ROLE_SYSTEM_WINDOW as that is a special MSAA system
- // role used to indicate a real native window object. It is
- // automatically created by oleacc.dll as a parent of the root of our
- // hierarchy, matching the HWND.
- return ROLE_SYSTEM_PANE;
-
- case ax::mojom::Role::kImeCandidate:
- case ax::mojom::Role::kIgnored:
- case ax::mojom::Role::kKeyboard:
- case ax::mojom::Role::kNone:
- case ax::mojom::Role::kPresentational:
- case ax::mojom::Role::kUnknown:
- return ROLE_SYSTEM_PANE;
- }
-
- NOTREACHED();
- return ROLE_SYSTEM_GROUPING;
-}
-
-bool AXPlatformNodeWin::IsWebAreaForPresentationalIframe() {
- if (GetData().role != ax::mojom::Role::kWebArea &&
- GetData().role != ax::mojom::Role::kRootWebArea) {
- return false;
- }
-
- AXPlatformNodeBase* parent = FromNativeViewAccessible(GetParent());
- if (!parent)
- return false;
-
- return parent->GetData().role == ax::mojom::Role::kIframePresentational;
-}
-
-int32_t AXPlatformNodeWin::ComputeIA2State() {
- const AXNodeData& data = GetData();
- int32_t ia2_state = IA2_STATE_OPAQUE;
-
- if (IsPlatformCheckable())
- ia2_state |= IA2_STATE_CHECKABLE;
-
- if (HasIntAttribute(ax::mojom::IntAttribute::kInvalidState) &&
- GetIntAttribute(ax::mojom::IntAttribute::kInvalidState) !=
- static_cast<int32_t>(ax::mojom::InvalidState::kFalse))
- ia2_state |= IA2_STATE_INVALID_ENTRY;
- if (data.HasState(ax::mojom::State::kRequired))
- ia2_state |= IA2_STATE_REQUIRED;
- if (data.HasState(ax::mojom::State::kVertical))
- ia2_state |= IA2_STATE_VERTICAL;
- if (data.HasState(ax::mojom::State::kHorizontal))
- ia2_state |= IA2_STATE_HORIZONTAL;
-
- if (data.HasState(ax::mojom::State::kEditable))
- ia2_state |= IA2_STATE_EDITABLE;
-
- if (IsTextField()) {
- if (data.HasState(ax::mojom::State::kMultiline)) {
- ia2_state |= IA2_STATE_MULTI_LINE;
- } else {
- ia2_state |= IA2_STATE_SINGLE_LINE;
- }
- if (!IsInvisibleOrIgnored())
- ia2_state |= IA2_STATE_SELECTABLE_TEXT;
- }
-
- if (!GetStringAttribute(ax::mojom::StringAttribute::kAutoComplete).empty() ||
- data.HasState(ax::mojom::State::kAutofillAvailable)) {
- ia2_state |= IA2_STATE_SUPPORTS_AUTOCOMPLETION;
- }
-
- if (GetBoolAttribute(ax::mojom::BoolAttribute::kModal))
- ia2_state |= IA2_STATE_MODAL;
-
- // Clear editable state on some widgets.
- switch (data.role) {
- case ax::mojom::Role::kTreeItem:
- case ax::mojom::Role::kListBoxOption:
- // Clear editable state if text selection changes should not be spoken.
- // Subwidgets in a contenteditable such as tree items will clear
- // IA2_STATE_EDITABLE when used with aria-activedescendant.
- // HACK: look to remove in 2022 or later, once Google Slides no longer
- // needs this to avoid NVDA double speaking in slides thumb view.
- // Normally, NVDA will speak both a text selection and activedescendant
- // changes in an editor, but clearing IA2_STATE_EDITABLE prevents that.
- // This helps with user interfaces like Google slides that have a tree or
- // listbox widget inside an editor, which they currently do in order to
- // enable paste operations. Eventually this need should go away once IE11
- // support is no longer needed and Slides instead relies on paste events.
- if (!data.HasState(ax::mojom::State::kFocusable) ||
- GetBoolAttribute(ax::mojom::BoolAttribute::kEditableRoot))
- break; // Not used with activedescendant, so preserve editable state.
- FALLTHROUGH; // Will clear editable state.
- case ax::mojom::Role::kMenuListPopup:
- case ax::mojom::Role::kMenuListOption:
- ia2_state &= ~(IA2_STATE_EDITABLE);
- break;
- default:
- break;
- }
-
- return ia2_state;
-}
-
-// ComputeIA2Role() only returns a role if the MSAA role doesn't suffice,
-// otherwise this method returns 0. See AXPlatformNodeWin::role().
-int32_t AXPlatformNodeWin::ComputeIA2Role() {
- // If this is a web area for a presentational iframe, give it a role of
- // something other than DOCUMENT so that the fact that it's a separate doc
- // is not exposed to AT.
- if (IsWebAreaForPresentationalIframe()) {
- return ROLE_SYSTEM_GROUPING;
- }
-
- int32_t ia2_role = 0;
-
- switch (GetData().role) {
- case ax::mojom::Role::kComment:
- return IA2_ROLE_COMMENT;
- case ax::mojom::Role::kSuggestion:
- return IA2_ROLE_SUGGESTION;
- case ax::mojom::Role::kBanner:
- case ax::mojom::Role::kHeader:
- // CORE-AAM recommends LANDMARK instead of HEADER.
- ia2_role = IA2_ROLE_LANDMARK;
- break;
- case ax::mojom::Role::kBlockquote:
- ia2_role = IA2_ROLE_SECTION;
- break;
- case ax::mojom::Role::kCanvas:
- if (GetBoolAttribute(ax::mojom::BoolAttribute::kCanvasHasFallback)) {
- ia2_role = IA2_ROLE_CANVAS;
- }
- break;
- case ax::mojom::Role::kCaption:
- ia2_role = IA2_ROLE_CAPTION;
- break;
- case ax::mojom::Role::kColorWell:
- ia2_role = IA2_ROLE_COLOR_CHOOSER;
- break;
- case ax::mojom::Role::kComplementary:
- // CORE-AAM recommends LANDMARK instead of COMPLEMENTARY_CONTENT.
- ia2_role = IA2_ROLE_LANDMARK;
- break;
- case ax::mojom::Role::kContentDeletion:
- ia2_role = IA2_ROLE_CONTENT_DELETION;
- break;
- case ax::mojom::Role::kContentInsertion:
- ia2_role = IA2_ROLE_CONTENT_INSERTION;
- break;
- case ax::mojom::Role::kContentInfo:
- case ax::mojom::Role::kFooter:
- // CORE-AAM recommends LANDMARK instead of FOOTER.
- ia2_role = IA2_ROLE_LANDMARK;
- break;
- case ax::mojom::Role::kDate:
- case ax::mojom::Role::kDateTime:
- ia2_role = IA2_ROLE_DATE_EDITOR;
- break;
- case ax::mojom::Role::kDefinition:
- ia2_role = IA2_ROLE_PARAGRAPH;
- break;
- case ax::mojom::Role::kDescriptionListDetail:
- ia2_role = IA2_ROLE_PARAGRAPH;
- break;
- case ax::mojom::Role::kDocAcknowledgments:
- case ax::mojom::Role::kDocAfterword:
- case ax::mojom::Role::kDocAppendix:
- case ax::mojom::Role::kDocBibliography:
- case ax::mojom::Role::kDocChapter:
- case ax::mojom::Role::kDocConclusion:
- case ax::mojom::Role::kDocCredits:
- case ax::mojom::Role::kDocEndnotes:
- case ax::mojom::Role::kDocEpilogue:
- case ax::mojom::Role::kDocErrata:
- case ax::mojom::Role::kDocForeword:
- case ax::mojom::Role::kDocGlossary:
- case ax::mojom::Role::kDocIndex:
- case ax::mojom::Role::kDocIntroduction:
- case ax::mojom::Role::kDocPageList:
- case ax::mojom::Role::kDocPart:
- case ax::mojom::Role::kDocPreface:
- case ax::mojom::Role::kDocPrologue:
- case ax::mojom::Role::kDocToc:
- ia2_role = IA2_ROLE_LANDMARK;
- break;
- case ax::mojom::Role::kDocAbstract:
- case ax::mojom::Role::kDocColophon:
- case ax::mojom::Role::kDocCredit:
- case ax::mojom::Role::kDocDedication:
- case ax::mojom::Role::kDocEpigraph:
- case ax::mojom::Role::kDocExample:
- case ax::mojom::Role::kDocPullquote:
- case ax::mojom::Role::kDocQna:
- ia2_role = IA2_ROLE_SECTION;
- break;
- case ax::mojom::Role::kDocSubtitle:
- ia2_role = IA2_ROLE_HEADING;
- break;
- case ax::mojom::Role::kDocTip:
- case ax::mojom::Role::kDocNotice:
- ia2_role = IA2_ROLE_NOTE;
- break;
- case ax::mojom::Role::kDocFootnote:
- ia2_role = IA2_ROLE_FOOTNOTE;
- break;
- case ax::mojom::Role::kEmbeddedObject:
- // Even though the HTML-AAM has IA2_ROLE_EMBEDDED_OBJECT for <embed>, we
- // are forced to use IA2_ROLE_SECTION when the <embed> has children in the
- // accessibility tree.
- // https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings
- //
- // Screen readers Jaws and NVDA do not "see" any of the <embed>'s contents
- // if they are represented as its children in the accessibility tree. For
- // example, one of the places that would be negatively impacted is the
- // reading of PDFs.
- if (GetDelegate()->GetChildCount()) {
- ia2_role = IA2_ROLE_SECTION;
- } else {
- ia2_role = IA2_ROLE_EMBEDDED_OBJECT;
- }
- break;
- case ax::mojom::Role::kFigcaption:
- ia2_role = IA2_ROLE_CAPTION;
- break;
- case ax::mojom::Role::kFooterAsNonLandmark:
- case ax::mojom::Role::kHeaderAsNonLandmark:
- ia2_role = IA2_ROLE_SECTION;
- break;
- case ax::mojom::Role::kForm:
- ia2_role = IA2_ROLE_FORM;
- break;
- case ax::mojom::Role::kGenericContainer:
- ia2_role = IA2_ROLE_SECTION;
- break;
- case ax::mojom::Role::kHeading:
- ia2_role = IA2_ROLE_HEADING;
- break;
- case ax::mojom::Role::kIframe:
- ia2_role = IA2_ROLE_INTERNAL_FRAME;
- break;
- case ax::mojom::Role::kImageMap:
- ia2_role = IA2_ROLE_IMAGE_MAP;
- break;
- case ax::mojom::Role::kLabelText:
- case ax::mojom::Role::kLegend:
- ia2_role = IA2_ROLE_LABEL;
- break;
- case ax::mojom::Role::kMain:
- ia2_role = IA2_ROLE_LANDMARK;
- break;
- case ax::mojom::Role::kMark:
- ia2_role = IA2_ROLE_MARK;
- break;
- case ax::mojom::Role::kMenuItemCheckBox:
- ia2_role = IA2_ROLE_CHECK_MENU_ITEM;
- break;
- case ax::mojom::Role::kMenuItemRadio:
- ia2_role = IA2_ROLE_RADIO_MENU_ITEM;
- break;
- case ax::mojom::Role::kMeter:
- // TODO(accessibiity) Uncomment IA2_ROLE_LEVEL_BAR once screen readers
- // adopt it. Currently, a <meter> ends up being spoken as a progress
- // bar, which is confusing. IA2_ROLE_LEVEL_BAR is the correct mapping
- // according to CORE-AAM. ia2_role = IA2_ROLE_LEVEL_BAR;
- break;
- case ax::mojom::Role::kNavigation:
- ia2_role = IA2_ROLE_LANDMARK;
- break;
- case ax::mojom::Role::kNote:
- ia2_role = IA2_ROLE_NOTE;
- break;
- case ax::mojom::Role::kParagraph:
- ia2_role = IA2_ROLE_PARAGRAPH;
- break;
- case ax::mojom::Role::kPluginObject:
- // See also case ax::mojom::Role::kEmbeddedObject.
- if (GetDelegate()->GetChildCount()) {
- ia2_role = IA2_ROLE_SECTION;
- } else {
- ia2_role = IA2_ROLE_EMBEDDED_OBJECT;
- }
- break;
- case ax::mojom::Role::kPre:
- ia2_role = IA2_ROLE_PARAGRAPH;
- break;
- case ax::mojom::Role::kRegion:
- ia2_role = IA2_ROLE_LANDMARK;
- break;
- case ax::mojom::Role::kRuby:
- ia2_role = IA2_ROLE_TEXT_FRAME;
- break;
- case ax::mojom::Role::kSearch:
- ia2_role = IA2_ROLE_LANDMARK;
- break;
- case ax::mojom::Role::kSection: {
- if (GetNameAsString16().empty()) {
- // Do not use ARIA mapping for nameless <section>.
- ia2_role = IA2_ROLE_SECTION;
- } else {
- // Use ARIA mapping.
- ia2_role = IA2_ROLE_LANDMARK;
- }
- break;
- }
- case ax::mojom::Role::kSwitch:
- ia2_role = IA2_ROLE_TOGGLE_BUTTON;
- break;
- case ax::mojom::Role::kTableHeaderContainer:
- ia2_role = IA2_ROLE_SECTION;
- break;
- case ax::mojom::Role::kToggleButton:
- ia2_role = IA2_ROLE_TOGGLE_BUTTON;
- break;
- case ax::mojom::Role::kAbbr:
- case ax::mojom::Role::kCode:
- case ax::mojom::Role::kEmphasis:
- case ax::mojom::Role::kStrong:
- case ax::mojom::Role::kTime:
- ia2_role = IA2_ROLE_TEXT_FRAME;
- break;
- default:
- break;
- }
- return ia2_role;
-}
-
-std::vector<base::string16> AXPlatformNodeWin::ComputeIA2Attributes() {
- std::vector<base::string16> attribute_list;
- ComputeAttributes(&attribute_list);
- return attribute_list;
-}
-
-base::string16 AXPlatformNodeWin::UIAAriaRole() {
- // If this is a web area for a presentational iframe, give it a role of
- // something other than document so that the fact that it's a separate doc
- // is not exposed to AT.
- if (IsWebAreaForPresentationalIframe())
- return L"group";
-
- switch (GetData().role) {
- case ax::mojom::Role::kAlert:
- return L"alert";
-
- case ax::mojom::Role::kAlertDialog:
- // Our MSAA implementation suggests the use of
- // "alert", not "alertdialog" because some
- // Windows screen readers are not compatible with
- // |ax::mojom::Role::kAlertDialog| yet.
- return L"alert";
-
- case ax::mojom::Role::kAnchor:
- return L"link";
-
- case ax::mojom::Role::kComment:
- case ax::mojom::Role::kSuggestion:
- return L"group";
-
- case ax::mojom::Role::kApplication:
- return L"application";
-
- case ax::mojom::Role::kArticle:
- return L"article";
-
- case ax::mojom::Role::kAudio:
- return L"group";
-
- case ax::mojom::Role::kBanner:
- case ax::mojom::Role::kHeader:
- return L"banner";
-
- case ax::mojom::Role::kBlockquote:
- return L"group";
-
- case ax::mojom::Role::kButton:
- return L"button";
-
- case ax::mojom::Role::kCanvas:
- return L"img";
-
- case ax::mojom::Role::kCaption:
- return L"description";
-
- case ax::mojom::Role::kCaret:
- return L"region";
-
- case ax::mojom::Role::kCell:
- return L"gridcell";
-
- case ax::mojom::Role::kCode:
- return L"code";
-
- case ax::mojom::Role::kCheckBox:
- return L"checkbox";
-
- case ax::mojom::Role::kClient:
- return L"region";
-
- case ax::mojom::Role::kColorWell:
- return L"textbox";
-
- case ax::mojom::Role::kColumn:
- return L"region";
-
- case ax::mojom::Role::kColumnHeader:
- return L"columnheader";
-
- case ax::mojom::Role::kComboBoxGrouping:
- case ax::mojom::Role::kComboBoxMenuButton:
- return L"combobox";
-
- case ax::mojom::Role::kComplementary:
- return L"complementary";
-
- case ax::mojom::Role::kContentDeletion:
- case ax::mojom::Role::kContentInsertion:
- return L"group";
-
- case ax::mojom::Role::kContentInfo:
- case ax::mojom::Role::kFooter:
- return L"contentinfo";
-
- case ax::mojom::Role::kDate:
- case ax::mojom::Role::kDateTime:
- return L"textbox";
-
- case ax::mojom::Role::kDefinition:
- return L"definition";
-
- case ax::mojom::Role::kDescriptionListDetail:
- return L"description";
-
- case ax::mojom::Role::kDescriptionList:
- return L"list";
-
- case ax::mojom::Role::kDescriptionListTerm:
- return L"listitem";
-
- case ax::mojom::Role::kDesktop:
- return L"document";
-
- case ax::mojom::Role::kDetails:
- return L"group";
-
- case ax::mojom::Role::kDialog:
- return L"dialog";
-
- case ax::mojom::Role::kDisclosureTriangle:
- return L"button";
-
- case ax::mojom::Role::kDirectory:
- return L"directory";
-
- case ax::mojom::Role::kDocCover:
- return L"img";
-
- case ax::mojom::Role::kDocBackLink:
- case ax::mojom::Role::kDocBiblioRef:
- case ax::mojom::Role::kDocGlossRef:
- case ax::mojom::Role::kDocNoteRef:
- return L"link";
-
- case ax::mojom::Role::kDocBiblioEntry:
- case ax::mojom::Role::kDocEndnote:
- case ax::mojom::Role::kDocFootnote:
- return L"listitem";
-
- case ax::mojom::Role::kDocPageBreak:
- return L"separator";
-
- case ax::mojom::Role::kDocAbstract:
- case ax::mojom::Role::kDocAcknowledgments:
- case ax::mojom::Role::kDocAfterword:
- case ax::mojom::Role::kDocAppendix:
- case ax::mojom::Role::kDocBibliography:
- case ax::mojom::Role::kDocChapter:
- case ax::mojom::Role::kDocColophon:
- case ax::mojom::Role::kDocConclusion:
- case ax::mojom::Role::kDocCredit:
- case ax::mojom::Role::kDocCredits:
- case ax::mojom::Role::kDocDedication:
- case ax::mojom::Role::kDocEndnotes:
- case ax::mojom::Role::kDocEpigraph:
- case ax::mojom::Role::kDocEpilogue:
- case ax::mojom::Role::kDocErrata:
- case ax::mojom::Role::kDocExample:
- case ax::mojom::Role::kDocForeword:
- case ax::mojom::Role::kDocGlossary:
- case ax::mojom::Role::kDocIndex:
- case ax::mojom::Role::kDocIntroduction:
- case ax::mojom::Role::kDocNotice:
- case ax::mojom::Role::kDocPageList:
- case ax::mojom::Role::kDocPart:
- case ax::mojom::Role::kDocPreface:
- case ax::mojom::Role::kDocPrologue:
- case ax::mojom::Role::kDocPullquote:
- case ax::mojom::Role::kDocQna:
- case ax::mojom::Role::kDocSubtitle:
- case ax::mojom::Role::kDocTip:
- case ax::mojom::Role::kDocToc:
- return L"group";
-
- case ax::mojom::Role::kDocument:
- case ax::mojom::Role::kRootWebArea:
- case ax::mojom::Role::kWebArea:
- return L"document";
-
- case ax::mojom::Role::kEmbeddedObject:
- if (GetDelegate()->GetChildCount()) {
- return L"group";
- } else {
- return L"document";
- }
-
- case ax::mojom::Role::kEmphasis:
- return L"emphasis";
-
- case ax::mojom::Role::kFeed:
- return L"group";
-
- case ax::mojom::Role::kFigcaption:
- return L"description";
-
- case ax::mojom::Role::kFigure:
- return L"group";
-
- case ax::mojom::Role::kFooterAsNonLandmark:
- case ax::mojom::Role::kHeaderAsNonLandmark:
- return L"group";
-
- case ax::mojom::Role::kForm:
- return L"form";
-
- case ax::mojom::Role::kGenericContainer:
- return L"group";
-
- case ax::mojom::Role::kGraphicsDocument:
- return L"document";
-
- case ax::mojom::Role::kGraphicsObject:
- return L"region";
-
- case ax::mojom::Role::kGraphicsSymbol:
- return L"img";
-
- case ax::mojom::Role::kGrid:
- return L"grid";
-
- case ax::mojom::Role::kGroup:
- return L"group";
-
- case ax::mojom::Role::kHeading:
- return L"heading";
-
- case ax::mojom::Role::kIframe:
- return L"document";
-
- case ax::mojom::Role::kIframePresentational:
- return L"group";
-
- case ax::mojom::Role::kImage:
- return L"img";
-
- case ax::mojom::Role::kImageMap:
- return L"document";
-
- case ax::mojom::Role::kImeCandidate:
- // Internal role, not used on Windows.
- return L"group";
-
- case ax::mojom::Role::kInputTime:
- return L"group";
-
- case ax::mojom::Role::kInlineTextBox:
- return L"textbox";
-
- case ax::mojom::Role::kKeyboard:
- return L"group";
-
- case ax::mojom::Role::kLabelText:
- case ax::mojom::Role::kLegend:
- return L"description";
-
- case ax::mojom::Role::kLayoutTable:
- return L"grid";
-
- case ax::mojom::Role::kLayoutTableCell:
- return L"gridcell";
-
- case ax::mojom::Role::kLayoutTableRow:
- return L"row";
-
- case ax::mojom::Role::kLink:
- return L"link";
-
- case ax::mojom::Role::kList:
- return L"list";
-
- case ax::mojom::Role::kListBox:
- return L"listbox";
-
- case ax::mojom::Role::kListBoxOption:
- return L"option";
-
- case ax::mojom::Role::kListGrid:
- return L"listview";
-
- case ax::mojom::Role::kListItem:
- return L"listitem";
-
- case ax::mojom::Role::kListMarker:
- if (!GetDelegate()->GetChildCount()) {
- // There's only a name attribute when using Legacy layout. With Legacy
- // layout, list markers have no child and are considered as StaticText.
- // We consider a list marker as a group in LayoutNG since it has
- // a text child node.
- return L"description";
- }
- return L"group";
-
- case ax::mojom::Role::kLog:
- return L"log";
-
- case ax::mojom::Role::kMain:
- return L"main";
-
- case ax::mojom::Role::kMark:
- return L"description";
-
- case ax::mojom::Role::kMarquee:
- return L"marquee";
-
- case ax::mojom::Role::kMath:
- return L"group";
-
- case ax::mojom::Role::kMenu:
- return L"menu";
-
- case ax::mojom::Role::kMenuBar:
- return L"menubar";
-
- case ax::mojom::Role::kMenuItem:
- return L"menuitem";
-
- case ax::mojom::Role::kMenuItemCheckBox:
- return L"menuitemcheckbox";
-
- case ax::mojom::Role::kMenuItemRadio:
- return L"menuitemradio";
-
- case ax::mojom::Role::kMenuListPopup:
- return L"list";
-
- case ax::mojom::Role::kMenuListOption:
- return L"listitem";
-
- case ax::mojom::Role::kMeter:
- return L"progressbar";
-
- case ax::mojom::Role::kNavigation:
- return L"navigation";
-
- case ax::mojom::Role::kNote:
- return L"note";
-
- case ax::mojom::Role::kParagraph:
- return L"group";
-
- case ax::mojom::Role::kPdfActionableHighlight:
- return L"button";
-
- case ax::mojom::Role::kPluginObject:
- if (GetDelegate()->GetChildCount()) {
- return L"group";
- } else {
- return L"document";
- }
-
- case ax::mojom::Role::kPopUpButton: {
- std::string html_tag =
- GetData().GetStringAttribute(ax::mojom::StringAttribute::kHtmlTag);
- if (html_tag == "select")
- return L"combobox";
- return L"button";
- }
-
- case ax::mojom::Role::kPortal:
- return L"button";
-
- case ax::mojom::Role::kPre:
- return L"region";
-
- case ax::mojom::Role::kProgressIndicator:
- return L"progressbar";
-
- case ax::mojom::Role::kRadioButton:
- return L"radio";
-
- case ax::mojom::Role::kRadioGroup:
- return L"radiogroup";
-
- case ax::mojom::Role::kRegion:
- return L"region";
-
- case ax::mojom::Role::kRow: {
- // Role changes depending on whether row is inside a treegrid
- // https://www.w3.org/TR/core-aam-1.1/#role-map-row
- return IsInTreeGrid() ? L"treeitem" : L"row";
- }
-
- case ax::mojom::Role::kRowGroup:
- return L"rowgroup";
-
- case ax::mojom::Role::kRowHeader:
- return L"rowheader";
-
- case ax::mojom::Role::kRuby:
- return L"region";
-
- case ax::mojom::Role::kSection: {
- if (GetNameAsString16().empty()) {
- // Do not use ARIA mapping for nameless <section>.
- return L"group";
- }
- // Use ARIA mapping.
- return L"region";
- }
-
- case ax::mojom::Role::kScrollBar:
- return L"scrollbar";
-
- case ax::mojom::Role::kScrollView:
- return L"region";
-
- case ax::mojom::Role::kSearch:
- return L"search";
-
- case ax::mojom::Role::kSlider:
- return L"slider";
-
- case ax::mojom::Role::kSliderThumb:
- return L"slider";
-
- case ax::mojom::Role::kSpinButton:
- return L"spinbutton";
-
- case ax::mojom::Role::kStrong:
- return L"strong";
-
- case ax::mojom::Role::kSwitch:
- return L"switch";
-
- case ax::mojom::Role::kRubyAnnotation:
- case ax::mojom::Role::kStaticText:
- return L"description";
-
- case ax::mojom::Role::kStatus:
- return L"status";
-
- case ax::mojom::Role::kSplitter:
- return L"separator";
-
- case ax::mojom::Role::kSvgRoot:
- return L"img";
-
- case ax::mojom::Role::kTab:
- return L"tab";
-
- case ax::mojom::Role::kTable:
- return L"grid";
-
- case ax::mojom::Role::kTableHeaderContainer:
- return L"group";
-
- case ax::mojom::Role::kTabList:
- return L"tablist";
-
- case ax::mojom::Role::kTabPanel:
- return L"tabpanel";
-
- case ax::mojom::Role::kTerm:
- return L"listitem";
-
- case ax::mojom::Role::kTitleBar:
- return L"document";
-
- case ax::mojom::Role::kToggleButton:
- return L"button";
-
- case ax::mojom::Role::kTextField:
- return L"textbox";
-
- case ax::mojom::Role::kSearchBox:
- return L"searchbox";
-
- case ax::mojom::Role::kTextFieldWithComboBox:
- return L"combobox";
-
- case ax::mojom::Role::kAbbr:
- return L"description";
-
- case ax::mojom::Role::kTime:
- return L"time";
-
- case ax::mojom::Role::kTimer:
- return L"timer";
-
- case ax::mojom::Role::kToolbar:
- return L"toolbar";
-
- case ax::mojom::Role::kTooltip:
- return L"tooltip";
-
- case ax::mojom::Role::kTree:
- return L"tree";
-
- case ax::mojom::Role::kTreeGrid:
- return L"treegrid";
-
- case ax::mojom::Role::kTreeItem:
- return L"treeitem";
-
- case ax::mojom::Role::kLineBreak:
- return L"separator";
-
- case ax::mojom::Role::kVideo:
- return L"group";
-
- case ax::mojom::Role::kWebView:
- return L"document";
-
- case ax::mojom::Role::kPane:
- case ax::mojom::Role::kWindow:
- case ax::mojom::Role::kIgnored:
- case ax::mojom::Role::kNone:
- case ax::mojom::Role::kPresentational:
- case ax::mojom::Role::kUnknown:
- return L"region";
- }
-
- NOTREACHED();
- return L"document";
-}
-
-base::string16 AXPlatformNodeWin::ComputeUIAProperties() {
- std::vector<base::string16> properties;
- const AXNodeData& data = GetData();
-
- BoolAttributeToUIAAriaProperty(
- properties, ax::mojom::BoolAttribute::kLiveAtomic, "atomic");
- BoolAttributeToUIAAriaProperty(properties, ax::mojom::BoolAttribute::kBusy,
- "busy");
-
- switch (data.GetCheckedState()) {
- case ax::mojom::CheckedState::kNone:
- break;
- case ax::mojom::CheckedState::kFalse:
- if (data.role == ax::mojom::Role::kToggleButton) {
- properties.emplace_back(L"pressed=false");
- } else if (data.role == ax::mojom::Role::kSwitch) {
- // ARIA switches are exposed to Windows accessibility as toggle
- // buttons. For maximum compatibility with ATs, we expose both the
- // pressed and checked states.
- properties.emplace_back(L"pressed=false");
- properties.emplace_back(L"checked=false");
- } else {
- properties.emplace_back(L"checked=false");
- }
- break;
- case ax::mojom::CheckedState::kTrue:
- if (data.role == ax::mojom::Role::kToggleButton) {
- properties.emplace_back(L"pressed=true");
- } else if (data.role == ax::mojom::Role::kSwitch) {
- // ARIA switches are exposed to Windows accessibility as toggle
- // buttons. For maximum compatibility with ATs, we expose both the
- // pressed and checked states.
- properties.emplace_back(L"pressed=true");
- properties.emplace_back(L"checked=true");
- } else {
- properties.emplace_back(L"checked=true");
- }
- break;
- case ax::mojom::CheckedState::kMixed:
- if (data.role == ax::mojom::Role::kToggleButton) {
- properties.emplace_back(L"pressed=mixed");
- } else if (data.role == ax::mojom::Role::kSwitch) {
- // This is disallowed both by the ARIA standard and by Blink.
- NOTREACHED();
- } else {
- properties.emplace_back(L"checked=mixed");
- }
- break;
- }
-
- const auto restriction = static_cast<ax::mojom::Restriction>(
- GetIntAttribute(ax::mojom::IntAttribute::kRestriction));
- if (restriction == ax::mojom::Restriction::kDisabled) {
- properties.push_back(L"disabled=true");
- } else {
- // The readonly property is complex on Windows. We set "readonly=true"
- // on *some* document structure roles such as paragraph, heading or list
- // even if the node data isn't marked as read only, as long as the
- // node is not editable.
- if (GetData().IsReadOnlyOrDisabled())
- properties.push_back(L"readonly=true");
- }
-
- // aria-dropeffect is deprecated in WAI-ARIA 1.1.
- if (data.HasIntAttribute(ax::mojom::IntAttribute::kDropeffect)) {
- properties.push_back(L"dropeffect=" +
- base::UTF8ToUTF16(data.DropeffectBitfieldToString()));
- }
- StateToUIAAriaProperty(properties, ax::mojom::State::kExpanded, "expanded");
- BoolAttributeToUIAAriaProperty(properties, ax::mojom::BoolAttribute::kGrabbed,
- "grabbed");
-
- switch (static_cast<ax::mojom::HasPopup>(
- data.GetIntAttribute(ax::mojom::IntAttribute::kHasPopup))) {
- case ax::mojom::HasPopup::kFalse:
- break;
- case ax::mojom::HasPopup::kTrue:
- properties.push_back(L"haspopup=true");
- break;
- case ax::mojom::HasPopup::kMenu:
- properties.push_back(L"haspopup=menu");
- break;
- case ax::mojom::HasPopup::kListbox:
- properties.push_back(L"haspopup=listbox");
- break;
- case ax::mojom::HasPopup::kTree:
- properties.push_back(L"haspopup=tree");
- break;
- case ax::mojom::HasPopup::kGrid:
- properties.push_back(L"haspopup=grid");
- break;
- case ax::mojom::HasPopup::kDialog:
- properties.push_back(L"haspopup=dialog");
- break;
- }
-
- if (IsInvisibleOrIgnored())
- properties.push_back(L"hidden=true");
-
- if (HasIntAttribute(ax::mojom::IntAttribute::kInvalidState) &&
- GetIntAttribute(ax::mojom::IntAttribute::kInvalidState) !=
- static_cast<int32_t>(ax::mojom::InvalidState::kFalse)) {
- properties.push_back(L"invalid=true");
- }
-
- IntAttributeToUIAAriaProperty(
- properties, ax::mojom::IntAttribute::kHierarchicalLevel, "level");
- StringAttributeToUIAAriaProperty(
- properties, ax::mojom::StringAttribute::kLiveStatus, "live");
- StateToUIAAriaProperty(properties, ax::mojom::State::kMultiline, "multiline");
- StateToUIAAriaProperty(properties, ax::mojom::State::kMultiselectable,
- "multiselectable");
- IntAttributeToUIAAriaProperty(properties, ax::mojom::IntAttribute::kPosInSet,
- "posinset");
- StringAttributeToUIAAriaProperty(
- properties, ax::mojom::StringAttribute::kLiveRelevant, "relevant");
- StateToUIAAriaProperty(properties, ax::mojom::State::kRequired, "required");
- BoolAttributeToUIAAriaProperty(
- properties, ax::mojom::BoolAttribute::kSelected, "selected");
- IntAttributeToUIAAriaProperty(properties, ax::mojom::IntAttribute::kSetSize,
- "setsize");
-
- int32_t sort_direction;
- if (IsTableHeader(data.role) &&
- GetIntAttribute(ax::mojom::IntAttribute::kSortDirection,
- &sort_direction)) {
- switch (static_cast<ax::mojom::SortDirection>(sort_direction)) {
- case ax::mojom::SortDirection::kNone:
- break;
- case ax::mojom::SortDirection::kUnsorted:
- properties.push_back(L"sort=none");
- break;
- case ax::mojom::SortDirection::kAscending:
- properties.push_back(L"sort=ascending");
- break;
- case ax::mojom::SortDirection::kDescending:
- properties.push_back(L"sort=descending");
- break;
- case ax::mojom::SortDirection::kOther:
- properties.push_back(L"sort=other");
- break;
- }
- }
-
- if (data.IsRangeValueSupported()) {
- FloatAttributeToUIAAriaProperty(
- properties, ax::mojom::FloatAttribute::kMaxValueForRange, "valuemax");
- FloatAttributeToUIAAriaProperty(
- properties, ax::mojom::FloatAttribute::kMinValueForRange, "valuemin");
- StringAttributeToUIAAriaProperty(
- properties, ax::mojom::StringAttribute::kValue, "valuetext");
-
- base::string16 value_now = GetRangeValueText();
- SanitizeStringAttributeForUIAAriaProperty(value_now, &value_now);
- if (!value_now.empty())
- properties.push_back(L"valuenow=" + value_now);
- }
-
- base::string16 result = base::JoinString(properties, L";");
- return result;
-}
-
-LONG AXPlatformNodeWin::ComputeUIAControlType() { // NOLINT(runtime/int)
- // If this is a web area for a presentational iframe, give it a role of
- // something other than document so that the fact that it's a separate doc
- // is not exposed to AT.
- if (IsWebAreaForPresentationalIframe())
- return UIA_GroupControlTypeId;
-
- switch (GetData().role) {
- case ax::mojom::Role::kAlert:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kAlertDialog:
- // Our MSAA implementation suggests the use of
- // |UIA_TextControlTypeId|, not |UIA_PaneControlTypeId| because some
- // Windows screen readers are not compatible with
- // |ax::mojom::Role::kAlertDialog| yet.
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kAnchor:
- return UIA_HyperlinkControlTypeId;
-
- case ax::mojom::Role::kComment:
- case ax::mojom::Role::kSuggestion:
- return ROLE_SYSTEM_GROUPING;
-
- case ax::mojom::Role::kApplication:
- return UIA_PaneControlTypeId;
-
- case ax::mojom::Role::kArticle:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kAudio:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kBanner:
- case ax::mojom::Role::kHeader:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kBlockquote:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kButton:
- return UIA_ButtonControlTypeId;
-
- case ax::mojom::Role::kCanvas:
- return UIA_ImageControlTypeId;
-
- case ax::mojom::Role::kCaption:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kCaret:
- return UIA_PaneControlTypeId;
-
- case ax::mojom::Role::kCell:
- return UIA_DataItemControlTypeId;
-
- case ax::mojom::Role::kCheckBox:
- return UIA_CheckBoxControlTypeId;
-
- case ax::mojom::Role::kClient:
- return UIA_PaneControlTypeId;
-
- case ax::mojom::Role::kCode:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kColorWell:
- return UIA_ButtonControlTypeId;
-
- case ax::mojom::Role::kColumn:
- return UIA_PaneControlTypeId;
-
- case ax::mojom::Role::kColumnHeader:
- return UIA_DataItemControlTypeId;
-
- case ax::mojom::Role::kComboBoxGrouping:
- case ax::mojom::Role::kComboBoxMenuButton:
- return UIA_ComboBoxControlTypeId;
-
- case ax::mojom::Role::kComplementary:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kContentDeletion:
- case ax::mojom::Role::kContentInsertion:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kContentInfo:
- case ax::mojom::Role::kFooter:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kDate:
- case ax::mojom::Role::kDateTime:
- return UIA_EditControlTypeId;
-
- case ax::mojom::Role::kDefinition:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kDescriptionListDetail:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kDescriptionList:
- return UIA_ListControlTypeId;
-
- case ax::mojom::Role::kDescriptionListTerm:
- return UIA_ListItemControlTypeId;
-
- case ax::mojom::Role::kDesktop:
- return UIA_DocumentControlTypeId;
-
- case ax::mojom::Role::kDetails:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kDialog:
- return UIA_PaneControlTypeId;
-
- case ax::mojom::Role::kDisclosureTriangle:
- return UIA_ButtonControlTypeId;
-
- case ax::mojom::Role::kDirectory:
- return UIA_ListControlTypeId;
-
- case ax::mojom::Role::kDocCover:
- return UIA_ImageControlTypeId;
-
- case ax::mojom::Role::kDocBackLink:
- case ax::mojom::Role::kDocBiblioRef:
- case ax::mojom::Role::kDocGlossRef:
- case ax::mojom::Role::kDocNoteRef:
- return UIA_HyperlinkControlTypeId;
-
- case ax::mojom::Role::kDocBiblioEntry:
- case ax::mojom::Role::kDocEndnote:
- case ax::mojom::Role::kDocFootnote:
- return UIA_ListItemControlTypeId;
-
- case ax::mojom::Role::kDocPageBreak:
- return UIA_SeparatorControlTypeId;
-
- case ax::mojom::Role::kDocAbstract:
- case ax::mojom::Role::kDocAcknowledgments:
- case ax::mojom::Role::kDocAfterword:
- case ax::mojom::Role::kDocAppendix:
- case ax::mojom::Role::kDocBibliography:
- case ax::mojom::Role::kDocChapter:
- case ax::mojom::Role::kDocColophon:
- case ax::mojom::Role::kDocConclusion:
- case ax::mojom::Role::kDocCredit:
- case ax::mojom::Role::kDocCredits:
- case ax::mojom::Role::kDocDedication:
- case ax::mojom::Role::kDocEndnotes:
- case ax::mojom::Role::kDocEpigraph:
- case ax::mojom::Role::kDocEpilogue:
- case ax::mojom::Role::kDocErrata:
- case ax::mojom::Role::kDocExample:
- case ax::mojom::Role::kDocForeword:
- case ax::mojom::Role::kDocGlossary:
- case ax::mojom::Role::kDocIndex:
- case ax::mojom::Role::kDocIntroduction:
- case ax::mojom::Role::kDocNotice:
- case ax::mojom::Role::kDocPageList:
- case ax::mojom::Role::kDocPart:
- case ax::mojom::Role::kDocPreface:
- case ax::mojom::Role::kDocPrologue:
- case ax::mojom::Role::kDocPullquote:
- case ax::mojom::Role::kDocQna:
- case ax::mojom::Role::kDocSubtitle:
- case ax::mojom::Role::kDocTip:
- case ax::mojom::Role::kDocToc:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kDocument:
- case ax::mojom::Role::kRootWebArea:
- case ax::mojom::Role::kWebArea:
- return UIA_DocumentControlTypeId;
-
- case ax::mojom::Role::kEmbeddedObject:
- return UIA_PaneControlTypeId;
-
- case ax::mojom::Role::kEmphasis:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kFeed:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kFigcaption:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kFigure:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kFooterAsNonLandmark:
- case ax::mojom::Role::kHeaderAsNonLandmark:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kForm:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kGenericContainer:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kGraphicsDocument:
- return UIA_DocumentControlTypeId;
-
- case ax::mojom::Role::kGraphicsObject:
- return UIA_PaneControlTypeId;
-
- case ax::mojom::Role::kGraphicsSymbol:
- return UIA_ImageControlTypeId;
-
- case ax::mojom::Role::kGrid:
- return UIA_DataGridControlTypeId;
-
- case ax::mojom::Role::kGroup:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kHeading:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kIframe:
- return UIA_DocumentControlTypeId;
-
- case ax::mojom::Role::kIframePresentational:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kImage:
- return UIA_ImageControlTypeId;
-
- case ax::mojom::Role::kImageMap:
- return UIA_DocumentControlTypeId;
-
- case ax::mojom::Role::kInputTime:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kInlineTextBox:
- return UIA_DocumentControlTypeId;
-
- case ax::mojom::Role::kLabelText:
- case ax::mojom::Role::kLegend:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kLayoutTable:
- return UIA_TableControlTypeId;
-
- case ax::mojom::Role::kLayoutTableCell:
- return UIA_DataItemControlTypeId;
-
- case ax::mojom::Role::kLayoutTableRow:
- return UIA_DataItemControlTypeId;
-
- case ax::mojom::Role::kLink:
- return UIA_HyperlinkControlTypeId;
-
- case ax::mojom::Role::kList:
- return UIA_ListControlTypeId;
-
- case ax::mojom::Role::kListBox:
- return UIA_ListControlTypeId;
-
- case ax::mojom::Role::kListBoxOption:
- return UIA_ListItemControlTypeId;
-
- case ax::mojom::Role::kListGrid:
- return UIA_DataGridControlTypeId;
-
- case ax::mojom::Role::kListItem:
- return UIA_ListItemControlTypeId;
-
- case ax::mojom::Role::kListMarker:
- if (!GetDelegate()->GetChildCount()) {
- // There's only a name attribute when using Legacy layout. With Legacy
- // layout, list markers have no child and are considered as StaticText.
- // We consider a list marker as a group in LayoutNG since it has
- // a text child node.
- return UIA_TextControlTypeId;
- }
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kLog:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kMain:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kMark:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kMarquee:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kMath:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kMenu:
- return UIA_MenuControlTypeId;
-
- case ax::mojom::Role::kMenuBar:
- return UIA_MenuBarControlTypeId;
-
- case ax::mojom::Role::kMenuItem:
- return UIA_MenuItemControlTypeId;
-
- case ax::mojom::Role::kMenuItemCheckBox:
- return UIA_CheckBoxControlTypeId;
-
- case ax::mojom::Role::kMenuItemRadio:
- return UIA_RadioButtonControlTypeId;
-
- case ax::mojom::Role::kMenuListPopup:
- return UIA_ListControlTypeId;
-
- case ax::mojom::Role::kMenuListOption:
- return UIA_ListItemControlTypeId;
-
- case ax::mojom::Role::kMeter:
- return UIA_ProgressBarControlTypeId;
-
- case ax::mojom::Role::kNavigation:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kNote:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kParagraph:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kPdfActionableHighlight:
- return UIA_CustomControlTypeId;
-
- case ax::mojom::Role::kPluginObject:
- if (GetDelegate()->GetChildCount()) {
- return UIA_GroupControlTypeId;
- } else {
- return UIA_DocumentControlTypeId;
- }
-
- case ax::mojom::Role::kPopUpButton: {
- std::string html_tag =
- GetData().GetStringAttribute(ax::mojom::StringAttribute::kHtmlTag);
- if (html_tag == "select")
- return UIA_ComboBoxControlTypeId;
- return UIA_ButtonControlTypeId;
- }
-
- case ax::mojom::Role::kPortal:
- return UIA_ButtonControlTypeId;
-
- case ax::mojom::Role::kPre:
- return UIA_PaneControlTypeId;
-
- case ax::mojom::Role::kProgressIndicator:
- return UIA_ProgressBarControlTypeId;
-
- case ax::mojom::Role::kRadioButton:
- return UIA_RadioButtonControlTypeId;
-
- case ax::mojom::Role::kRadioGroup:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kRegion:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kRow: {
- // Role changes depending on whether row is inside a treegrid
- // https://www.w3.org/TR/core-aam-1.1/#role-map-row
- return IsInTreeGrid() ? UIA_TreeItemControlTypeId
- : UIA_DataItemControlTypeId;
- }
-
- case ax::mojom::Role::kRowGroup:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kRowHeader:
- return UIA_DataItemControlTypeId;
-
- case ax::mojom::Role::kRuby:
- return UIA_PaneControlTypeId;
-
- case ax::mojom::Role::kSection:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kScrollBar:
- return UIA_ScrollBarControlTypeId;
-
- case ax::mojom::Role::kScrollView:
- return UIA_PaneControlTypeId;
-
- case ax::mojom::Role::kSearch:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kSlider:
- return UIA_SliderControlTypeId;
-
- case ax::mojom::Role::kSliderThumb:
- return UIA_SliderControlTypeId;
-
- case ax::mojom::Role::kSpinButton:
- return UIA_SpinnerControlTypeId;
-
- case ax::mojom::Role::kSwitch:
- return UIA_ButtonControlTypeId;
-
- case ax::mojom::Role::kRubyAnnotation:
- case ax::mojom::Role::kStaticText:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kStatus:
- return UIA_StatusBarControlTypeId;
-
- case ax::mojom::Role::kStrong:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kSplitter:
- return UIA_SeparatorControlTypeId;
-
- case ax::mojom::Role::kSvgRoot:
- return UIA_ImageControlTypeId;
-
- case ax::mojom::Role::kTab:
- return UIA_TabItemControlTypeId;
-
- case ax::mojom::Role::kTable:
- return UIA_TableControlTypeId;
-
- case ax::mojom::Role::kTableHeaderContainer:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kTabList:
- return UIA_TabControlTypeId;
-
- case ax::mojom::Role::kTabPanel:
- return UIA_PaneControlTypeId;
-
- case ax::mojom::Role::kTerm:
- return UIA_ListItemControlTypeId;
-
- case ax::mojom::Role::kTitleBar:
- return UIA_DocumentControlTypeId;
-
- case ax::mojom::Role::kToggleButton:
- return UIA_ButtonControlTypeId;
-
- case ax::mojom::Role::kTextField:
- case ax::mojom::Role::kSearchBox:
- return UIA_EditControlTypeId;
-
- case ax::mojom::Role::kTextFieldWithComboBox:
- return UIA_ComboBoxControlTypeId;
-
- case ax::mojom::Role::kAbbr:
- case ax::mojom::Role::kTime:
- return UIA_TextControlTypeId;
-
- case ax::mojom::Role::kTimer:
- return UIA_PaneControlTypeId;
-
- case ax::mojom::Role::kToolbar:
- return UIA_ToolBarControlTypeId;
-
- case ax::mojom::Role::kTooltip:
- return UIA_ToolTipControlTypeId;
-
- case ax::mojom::Role::kTree:
- return UIA_TreeControlTypeId;
-
- case ax::mojom::Role::kTreeGrid:
- return UIA_DataGridControlTypeId;
-
- case ax::mojom::Role::kTreeItem:
- return UIA_TreeItemControlTypeId;
-
- case ax::mojom::Role::kLineBreak:
- return UIA_SeparatorControlTypeId;
-
- case ax::mojom::Role::kVideo:
- return UIA_GroupControlTypeId;
-
- case ax::mojom::Role::kWebView:
- return UIA_DocumentControlTypeId;
-
- case ax::mojom::Role::kPane:
- case ax::mojom::Role::kWindow:
- case ax::mojom::Role::kIgnored:
- case ax::mojom::Role::kImeCandidate:
- case ax::mojom::Role::kKeyboard:
- case ax::mojom::Role::kNone:
- case ax::mojom::Role::kPresentational:
- case ax::mojom::Role::kUnknown:
- return UIA_PaneControlTypeId;
- }
-
- NOTREACHED();
- return UIA_DocumentControlTypeId;
-}
-
-AXPlatformNodeWin* AXPlatformNodeWin::ComputeUIALabeledBy() {
- // Not all control types expect a value for this property.
- if (!CanHaveUIALabeledBy())
- return nullptr;
-
- // This property only accepts static text elements to be returned. Find the
- // first static text used to label this node.
- for (int32_t id : GetData().GetIntListAttribute(
- ax::mojom::IntListAttribute::kLabelledbyIds)) {
- auto* node_win =
- static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(id));
- if (!node_win)
- continue;
-
- // If this node is a static text, then simply return the node itself.
- if (IsValidUiaRelationTarget(node_win) &&
- node_win->GetData().role == ax::mojom::Role::kStaticText) {
- return node_win;
- }
-
- // Otherwise, find the first static text node in its descendants.
- for (auto iter = node_win->GetDelegate()->ChildrenBegin();
- *iter != *node_win->GetDelegate()->ChildrenEnd(); ++(*iter)) {
- AXPlatformNodeWin* child = static_cast<AXPlatformNodeWin*>(
- AXPlatformNode::FromNativeViewAccessible(
- iter->GetNativeViewAccessible()));
- if (IsValidUiaRelationTarget(child) &&
- child->GetData().role == ax::mojom::Role::kStaticText) {
- return child;
- }
- }
- }
-
- return nullptr;
-}
-
-bool AXPlatformNodeWin::CanHaveUIALabeledBy() {
- // Not all control types expect a value for this property. See
- // https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-supportinguiautocontroltypes
- // for a complete list of control types. Each one of them has specific
- // expectations regarding the UIA_LabeledByPropertyId.
- switch (ComputeUIAControlType()) {
- case UIA_ButtonControlTypeId:
- case UIA_CheckBoxControlTypeId:
- case UIA_DataItemControlTypeId:
- case UIA_MenuControlTypeId:
- case UIA_MenuBarControlTypeId:
- case UIA_RadioButtonControlTypeId:
- case UIA_ScrollBarControlTypeId:
- case UIA_SeparatorControlTypeId:
- case UIA_StatusBarControlTypeId:
- case UIA_TabItemControlTypeId:
- case UIA_TextControlTypeId:
- case UIA_ToolBarControlTypeId:
- case UIA_ToolTipControlTypeId:
- case UIA_TreeItemControlTypeId:
- return false;
- default:
- return true;
- }
-}
-
-bool AXPlatformNodeWin::IsNameExposed() const {
- const AXNodeData& data = GetData();
- switch (data.role) {
- case ax::mojom::Role::kListMarker:
- return !GetDelegate()->GetChildCount();
- default:
- return true;
- }
-}
-
-bool AXPlatformNodeWin::IsUIAControl() const {
- // UIA provides multiple "views": raw, content and control. We only want to
- // populate the content and control views with items that make sense to
- // traverse over.
-
- if (GetDelegate()->IsWebContent()) {
- // Invisible or ignored elements should not show up in control view at all.
- if (IsInvisibleOrIgnored())
- return false;
-
- if (IsText()) {
- // A text leaf can be a UIAControl, but text inside of a heading, link,
- // button, etc. where the role allows the name to be generated from the
- // content is not. We want to avoid reading out a button, moving to the
- // next item, and then reading out the button's text child, causing the
- // text to be effectively repeated.
- auto* parent = FromNativeViewAccessible(GetDelegate()->GetParent());
- while (parent) {
- const AXNodeData& data = parent->GetData();
- if (IsCellOrTableHeader(data.role))
- return false;
- switch (data.role) {
- case ax::mojom::Role::kButton:
- case ax::mojom::Role::kCheckBox:
- case ax::mojom::Role::kGroup:
- case ax::mojom::Role::kHeading:
- case ax::mojom::Role::kLineBreak:
- case ax::mojom::Role::kLink:
- case ax::mojom::Role::kListBoxOption:
- case ax::mojom::Role::kListItem:
- case ax::mojom::Role::kMenuItem:
- case ax::mojom::Role::kMenuItemCheckBox:
- case ax::mojom::Role::kMenuItemRadio:
- case ax::mojom::Role::kMenuListOption:
- case ax::mojom::Role::kPdfActionableHighlight:
- case ax::mojom::Role::kRadioButton:
- case ax::mojom::Role::kRow:
- case ax::mojom::Role::kRowGroup:
- case ax::mojom::Role::kStaticText:
- case ax::mojom::Role::kSwitch:
- case ax::mojom::Role::kTab:
- case ax::mojom::Role::kTooltip:
- case ax::mojom::Role::kTreeItem:
- return false;
- default:
- break;
- }
- parent = FromNativeViewAccessible(parent->GetParent());
- }
- } // end of text only case.
-
- const AXNodeData& data = GetData();
- // https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-treeoverview#control-view
- // The control view also includes noninteractive UI items that contribute
- // to the logical structure of the UI.
- if (IsControl(data.role) || ComputeUIALandmarkType() ||
- IsTableLike(data.role) || IsList(data.role)) {
- return true;
- }
- if (IsImage(data.role)) {
- // If the author provides an explicitly empty alt text attribute then
- // the image is decorational and should not be considered as a control.
- if (data.role == ax::mojom::Role::kImage &&
- data.GetNameFrom() ==
- ax::mojom::NameFrom::kAttributeExplicitlyEmpty) {
- return false;
- }
- return true;
- }
- switch (data.role) {
- case ax::mojom::Role::kArticle:
- case ax::mojom::Role::kBlockquote:
- case ax::mojom::Role::kDetails:
- case ax::mojom::Role::kFigure:
- case ax::mojom::Role::kFooter:
- case ax::mojom::Role::kFooterAsNonLandmark:
- case ax::mojom::Role::kHeader:
- case ax::mojom::Role::kHeaderAsNonLandmark:
- case ax::mojom::Role::kLabelText:
- case ax::mojom::Role::kListBoxOption:
- case ax::mojom::Role::kListItem:
- case ax::mojom::Role::kMeter:
- case ax::mojom::Role::kProgressIndicator:
- case ax::mojom::Role::kSection:
- case ax::mojom::Role::kSplitter:
- case ax::mojom::Role::kTime:
- return true;
- default:
- break;
- }
- // Classify generic containers that are not clickable or focusable and have
- // no name, description, landmark type, and is not the root of editable
- // content as not controls.
- // Doing so helps Narrator find all the content of live regions.
- if (!data.GetBoolAttribute(ax::mojom::BoolAttribute::kHasAriaAttribute) &&
- !data.GetBoolAttribute(ax::mojom::BoolAttribute::kEditableRoot) &&
- GetNameAsString16().empty() &&
- data.GetStringAttribute(ax::mojom::StringAttribute::kDescription)
- .empty() &&
- !data.HasState(ax::mojom::State::kFocusable) && !data.IsClickable()) {
- return false;
- }
-
- return true;
- } // end of web-content only case.
-
- const AXNodeData& data = GetData();
- return !((IsReadOnlySupported(data.role) && data.IsReadOnlyOrDisabled()) ||
- data.HasState(ax::mojom::State::kInvisible) ||
- (data.IsIgnored() && !data.HasState(ax::mojom::State::kFocusable)));
-}
-
-base::Optional<LONG> AXPlatformNodeWin::ComputeUIALandmarkType() const {
- const AXNodeData& data = GetData();
- switch (data.role) {
- case ax::mojom::Role::kBanner:
- case ax::mojom::Role::kComplementary:
- case ax::mojom::Role::kContentInfo:
- case ax::mojom::Role::kFooter:
- case ax::mojom::Role::kHeader:
- return UIA_CustomLandmarkTypeId;
-
- case ax::mojom::Role::kForm:
- // https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings
- // https://w3c.github.io/core-aam/#mapping_role_table
- // While the HTML-AAM spec states that <form> without an accessible name
- // should have no corresponding role, removing the role breaks both
- // aria-setsize and aria-posinset.
- // The only other difference for UIA is that it should not be a landmark.
- // If the author provided an accessible name, or the role was explicit,
- // then allow the form landmark.
- if (data.HasStringAttribute(ax::mojom::StringAttribute::kName) ||
- data.HasStringAttribute(ax::mojom::StringAttribute::kRole)) {
- return UIA_FormLandmarkTypeId;
- }
- return {};
-
- case ax::mojom::Role::kMain:
- return UIA_MainLandmarkTypeId;
-
- case ax::mojom::Role::kNavigation:
- return UIA_NavigationLandmarkTypeId;
-
- case ax::mojom::Role::kSearch:
- return UIA_SearchLandmarkTypeId;
-
- case ax::mojom::Role::kRegion:
- case ax::mojom::Role::kSection:
- if (data.HasStringAttribute(ax::mojom::StringAttribute::kName))
- return UIA_CustomLandmarkTypeId;
- FALLTHROUGH;
-
- default:
- return {};
- }
-}
-
-bool AXPlatformNodeWin::IsInaccessibleDueToAncestor() const {
- AXPlatformNodeWin* parent = static_cast<AXPlatformNodeWin*>(
- AXPlatformNode::FromNativeViewAccessible(GetParent()));
- while (parent) {
- if (parent->ShouldHideChildrenForUIA())
- return true;
- parent = static_cast<AXPlatformNodeWin*>(
- FromNativeViewAccessible(parent->GetParent()));
- }
- return false;
-}
-
-bool AXPlatformNodeWin::ShouldHideChildrenForUIA() const {
- if (IsPlainTextField())
- return true;
-
- auto role = GetData().role;
- if (HasPresentationalChildren(role))
- return true;
-
- switch (role) {
- // Other elements that are expected by UIA to hide their children without
- // having "Children Presentational: True".
- //
- // TODO(bebeaudr): We might be able to remove ax::mojom::Role::kLink once
- // http://crbug.com/1054514 is fixed. Links should not have to hide their
- // children.
- // TODO(virens): |kPdfActionableHighlight| needs to follow a fix similar to
- // links. At present Pdf highlghts have text nodes as children. But, we may
- // enable pdf highlights to have complex children like links based on user
- // feedback.
- case ax::mojom::Role::kLink:
- // Links with a single text-only child should hide their subtree.
- if (GetChildCount() == 1) {
- AXPlatformNodeBase* only_child = GetFirstChild();
- return only_child && only_child->IsText();
- }
- return false;
- case ax::mojom::Role::kPdfActionableHighlight:
- return true;
- default:
- return false;
- }
-}
-
-base::string16 AXPlatformNodeWin::GetValue() const {
- base::string16 value = AXPlatformNodeBase::GetValue();
-
- // If this doesn't have a value and is linked then set its value to the URL
- // attribute. This allows screen readers to read an empty link's
- // destination.
- // TODO(dougt): Look into ensuring that on click handlers correctly provide
- // a value here.
- if (value.empty() && (MSAAState() & STATE_SYSTEM_LINKED))
- value = GetString16Attribute(ax::mojom::StringAttribute::kUrl);
-
- return value;
-}
-
-bool AXPlatformNodeWin::IsPlatformCheckable() const {
- if (GetData().role == ax::mojom::Role::kToggleButton)
- return false;
-
- return AXPlatformNodeBase::IsPlatformCheckable();
-}
-
-bool AXPlatformNodeWin::ShouldNodeHaveFocusableState(
- const AXNodeData& data) const {
- switch (data.role) {
- case ax::mojom::Role::kDocument:
- case ax::mojom::Role::kGraphicsDocument:
- case ax::mojom::Role::kWebArea:
- return true;
-
- case ax::mojom::Role::kRootWebArea: {
- AXPlatformNodeBase* parent = FromNativeViewAccessible(GetParent());
- return !parent || parent->GetData().role != ax::mojom::Role::kPortal;
- }
-
- case ax::mojom::Role::kIframe:
- return false;
-
- case ax::mojom::Role::kListBoxOption:
- case ax::mojom::Role::kMenuListOption:
- if (data.HasBoolAttribute(ax::mojom::BoolAttribute::kSelected))
- return true;
- break;
-
- default:
- break;
- }
-
- return data.HasState(ax::mojom::State::kFocusable);
-}
-
-int AXPlatformNodeWin::MSAAState() const {
- const AXNodeData& data = GetData();
- int msaa_state = 0;
-
- // Map the ax::mojom::State to MSAA state. Note that some of the states are
- // not currently handled.
-
- if (data.GetBoolAttribute(ax::mojom::BoolAttribute::kBusy))
- msaa_state |= STATE_SYSTEM_BUSY;
-
- if (data.HasState(ax::mojom::State::kCollapsed))
- msaa_state |= STATE_SYSTEM_COLLAPSED;
-
- if (data.HasState(ax::mojom::State::kDefault))
- msaa_state |= STATE_SYSTEM_DEFAULT;
-
- // TODO(dougt) unhandled ux::ax::mojom::State::kEditable
-
- if (data.HasState(ax::mojom::State::kExpanded))
- msaa_state |= STATE_SYSTEM_EXPANDED;
-
- if (ShouldNodeHaveFocusableState(data))
- msaa_state |= STATE_SYSTEM_FOCUSABLE;
-
- // Built-in autofill and autocomplete wil also set has popup.
- if (data.HasIntAttribute(ax::mojom::IntAttribute::kHasPopup))
- msaa_state |= STATE_SYSTEM_HASPOPUP;
-
- // TODO(dougt) unhandled ux::ax::mojom::State::kHorizontal
-
- if (data.HasState(ax::mojom::State::kHovered)) {
- // Expose whether or not the mouse is over an element, but suppress
- // this for tests because it can make the test results flaky depending
- // on the position of the mouse.
- if (GetDelegate()->ShouldIgnoreHoveredStateForTesting())
- msaa_state |= STATE_SYSTEM_HOTTRACKED;
- }
-
- // If the role is IGNORED, we want these elements to be invisible so that
- // these nodes are hidden from the screen reader.
- if (IsInvisibleOrIgnored())
- msaa_state |= STATE_SYSTEM_INVISIBLE;
-
- if (data.HasState(ax::mojom::State::kLinked))
- msaa_state |= STATE_SYSTEM_LINKED;
-
- // TODO(dougt) unhandled ux::ax::mojom::State::kMultiline
-
- if (data.HasState(ax::mojom::State::kMultiselectable)) {
- msaa_state |= STATE_SYSTEM_EXTSELECTABLE;
- msaa_state |= STATE_SYSTEM_MULTISELECTABLE;
- }
-
- if (GetDelegate()->IsOffscreen())
- msaa_state |= STATE_SYSTEM_OFFSCREEN;
-
- if (data.HasState(ax::mojom::State::kProtected))
- msaa_state |= STATE_SYSTEM_PROTECTED;
-
- // TODO(dougt) unhandled ux::ax::mojom::State::kRequired
- // TODO(dougt) unhandled ux::ax::mojom::State::kRichlyEditable
-
- if (data.IsSelectable())
- msaa_state |= STATE_SYSTEM_SELECTABLE;
-
- if (data.GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
- msaa_state |= STATE_SYSTEM_SELECTED;
-
- // TODO(dougt) unhandled VERTICAL
-
- if (data.HasState(ax::mojom::State::kVisited))
- msaa_state |= STATE_SYSTEM_TRAVERSED;
-
- //
- // Checked state
- //
-
- switch (data.GetCheckedState()) {
- case ax::mojom::CheckedState::kNone:
- case ax::mojom::CheckedState::kFalse:
- break;
- case ax::mojom::CheckedState::kTrue:
- if (data.role == ax::mojom::Role::kToggleButton) {
- msaa_state |= STATE_SYSTEM_PRESSED;
- } else if (data.role == ax::mojom::Role::kSwitch) {
- // ARIA switches are exposed to Windows accessibility as toggle
- // buttons. For maximum compatibility with ATs, we expose both the
- // pressed and checked states.
- msaa_state |= STATE_SYSTEM_PRESSED | STATE_SYSTEM_CHECKED;
- } else {
- msaa_state |= STATE_SYSTEM_CHECKED;
- }
- break;
- case ax::mojom::CheckedState::kMixed:
- msaa_state |= STATE_SYSTEM_MIXED;
- break;
- }
-
- const auto restriction = static_cast<ax::mojom::Restriction>(
- GetIntAttribute(ax::mojom::IntAttribute::kRestriction));
- switch (restriction) {
- case ax::mojom::Restriction::kDisabled:
- msaa_state |= STATE_SYSTEM_UNAVAILABLE;
- break;
- case ax::mojom::Restriction::kReadOnly:
- msaa_state |= STATE_SYSTEM_READONLY;
- break;
- default:
- // READONLY state is complex on Windows. We set STATE_SYSTEM_READONLY
- // on *some* document structure roles such as paragraph, heading or list
- // even if the node data isn't marked as read only, as long as the
- // node is not editable.
- if (!data.HasState(ax::mojom::State::kRichlyEditable) &&
- ShouldHaveReadonlyStateByDefault(data.role)) {
- msaa_state |= STATE_SYSTEM_READONLY;
- }
- break;
- }
-
- // Windowless plugins should have STATE_SYSTEM_UNAVAILABLE.
- //
- // (All of our plugins are windowless.)
- if (data.role == ax::mojom::Role::kPluginObject ||
- data.role == ax::mojom::Role::kEmbeddedObject) {
- msaa_state |= STATE_SYSTEM_UNAVAILABLE;
- }
-
- //
- // Handle STATE_SYSTEM_FOCUSED
- //
- gfx::NativeViewAccessible focus = GetDelegate()->GetFocus();
- if (focus == const_cast<AXPlatformNodeWin*>(this)->GetNativeViewAccessible())
- msaa_state |= STATE_SYSTEM_FOCUSED;
-
- // In focused single selection UI menus and listboxes, mirror item selection
- // to focus. This helps NVDA read the selected option as it changes.
- if ((data.role == ax::mojom::Role::kListBoxOption || IsMenuItem(data.role)) &&
- data.GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
- AXPlatformNodeBase* container = FromNativeViewAccessible(GetParent());
- if (container && container->GetParent() == focus) {
- AXNodeData container_data = container->GetData();
- if ((container_data.role == ax::mojom::Role::kListBox ||
- container_data.role == ax::mojom::Role::kMenu) &&
- !container_data.HasState(ax::mojom::State::kMultiselectable)) {
- msaa_state |= STATE_SYSTEM_FOCUSED;
- }
- }
- }
-
- // On Windows, the "focus" bit should be set on certain containers, like
- // menu bars, when visible.
- //
- // TODO(dmazzoni): this should probably check if focus is actually inside
- // the menu bar, but we don't currently track focus inside menu pop-ups,
- // and Chrome only has one menu visible at a time so this works for now.
- if (data.role == ax::mojom::Role::kMenuBar &&
- !(data.HasState(ax::mojom::State::kInvisible))) {
- msaa_state |= STATE_SYSTEM_FOCUSED;
- }
-
- // Handle STATE_SYSTEM_LINKED
- if (GetData().role == ax::mojom::Role::kLink)
- msaa_state |= STATE_SYSTEM_LINKED;
-
- // Special case for indeterminate progressbar.
- if (GetData().role == ax::mojom::Role::kProgressIndicator &&
- !HasFloatAttribute(ax::mojom::FloatAttribute::kValueForRange))
- msaa_state |= STATE_SYSTEM_MIXED;
-
- return msaa_state;
-}
-
-// static
-base::Optional<DWORD> AXPlatformNodeWin::MojoEventToMSAAEvent(
- ax::mojom::Event event) {
- switch (event) {
- case ax::mojom::Event::kAlert:
- return EVENT_SYSTEM_ALERT;
- case ax::mojom::Event::kActiveDescendantChanged:
- return IA2_EVENT_ACTIVE_DESCENDANT_CHANGED;
- case ax::mojom::Event::kCheckedStateChanged:
- case ax::mojom::Event::kExpandedChanged:
- case ax::mojom::Event::kStateChanged:
- return EVENT_OBJECT_STATECHANGE;
- case ax::mojom::Event::kFocus:
- case ax::mojom::Event::kFocusContext:
- return EVENT_OBJECT_FOCUS;
- case ax::mojom::Event::kLiveRegionChanged:
- return EVENT_OBJECT_LIVEREGIONCHANGED;
- case ax::mojom::Event::kMenuStart:
- return EVENT_SYSTEM_MENUSTART;
- case ax::mojom::Event::kMenuEnd:
- return EVENT_SYSTEM_MENUEND;
- case ax::mojom::Event::kMenuPopupStart:
- return EVENT_SYSTEM_MENUPOPUPSTART;
- case ax::mojom::Event::kMenuPopupEnd:
- return EVENT_SYSTEM_MENUPOPUPEND;
- case ax::mojom::Event::kSelection:
- return EVENT_OBJECT_SELECTION;
- case ax::mojom::Event::kSelectionAdd:
- return EVENT_OBJECT_SELECTIONADD;
- case ax::mojom::Event::kSelectionRemove:
- return EVENT_OBJECT_SELECTIONREMOVE;
- case ax::mojom::Event::kTextChanged:
- return EVENT_OBJECT_NAMECHANGE;
- case ax::mojom::Event::kTextSelectionChanged:
- return IA2_EVENT_TEXT_CARET_MOVED;
- case ax::mojom::Event::kTooltipClosed:
- return EVENT_OBJECT_HIDE;
- case ax::mojom::Event::kTooltipOpened:
- return EVENT_OBJECT_SHOW;
- case ax::mojom::Event::kValueChanged:
- return EVENT_OBJECT_VALUECHANGE;
- default:
- return base::nullopt;
- }
-}
-
-// static
-base::Optional<EVENTID> AXPlatformNodeWin::MojoEventToUIAEvent(
- ax::mojom::Event event) {
- if (!::switches::IsExperimentalAccessibilityPlatformUIAEnabled())
- return base::nullopt;
-
- switch (event) {
- case ax::mojom::Event::kAlert:
- return UIA_SystemAlertEventId;
- case ax::mojom::Event::kFocus:
- case ax::mojom::Event::kFocusContext:
- case ax::mojom::Event::kFocusAfterMenuClose:
- return UIA_AutomationFocusChangedEventId;
- case ax::mojom::Event::kLiveRegionChanged:
- return UIA_LiveRegionChangedEventId;
- case ax::mojom::Event::kSelection:
- return UIA_SelectionItem_ElementSelectedEventId;
- case ax::mojom::Event::kSelectionAdd:
- return UIA_SelectionItem_ElementAddedToSelectionEventId;
- case ax::mojom::Event::kSelectionRemove:
- return UIA_SelectionItem_ElementRemovedFromSelectionEventId;
- case ax::mojom::Event::kTooltipClosed:
- return UIA_ToolTipClosedEventId;
- case ax::mojom::Event::kTooltipOpened:
- return UIA_ToolTipOpenedEventId;
- default:
- return base::nullopt;
- }
-}
-
-// static
-base::Optional<PROPERTYID> AXPlatformNodeWin::MojoEventToUIAProperty(
- ax::mojom::Event event) {
- if (!::switches::IsExperimentalAccessibilityPlatformUIAEnabled())
- return base::nullopt;
-
- switch (event) {
- case ax::mojom::Event::kControlsChanged:
- return UIA_ControllerForPropertyId;
- case ax::mojom::Event::kCheckedStateChanged:
- return UIA_ToggleToggleStatePropertyId;
- case ax::mojom::Event::kRowCollapsed:
- case ax::mojom::Event::kRowExpanded:
- return UIA_ExpandCollapseExpandCollapseStatePropertyId;
- case ax::mojom::Event::kSelection:
- case ax::mojom::Event::kSelectionAdd:
- case ax::mojom::Event::kSelectionRemove:
- return UIA_SelectionItemIsSelectedPropertyId;
- default:
- return base::nullopt;
- }
-}
-
-// static
-BSTR AXPlatformNodeWin::GetValueAttributeAsBstr(AXPlatformNodeWin* target) {
- // GetValueAttributeAsBstr() has two sets of special cases depending on the
- // node's role.
- // The first set apply without regard for the nodes |value| attribute. That is
- // the nodes value attribute isn't consider for the first set of special
- // cases. For example, if the node role is ax::mojom::Role::kColorWell, we do
- // not care at all about the node's ax::mojom::StringAttribute::kValue
- // attribute. The second set of special cases only apply if the value
- // attribute for the node is empty. That is, if
- // ax::mojom::StringAttribute::kValue is empty, we do something special.
- base::string16 result;
-
- //
- // Color Well special case (Use ax::mojom::IntAttribute::kColorValue)
- //
- if (target->GetData().role == ax::mojom::Role::kColorWell) {
- // static cast because SkColor is a 4-byte unsigned int
- unsigned int color = static_cast<unsigned int>(
- target->GetIntAttribute(ax::mojom::IntAttribute::kColorValue));
-
- unsigned int red = SkColorGetR(color);
- unsigned int green = SkColorGetG(color);
- unsigned int blue = SkColorGetB(color);
- base::string16 value_text;
- value_text = base::NumberToString16(red * 100 / 255) + L"% red " +
- base::NumberToString16(green * 100 / 255) + L"% green " +
- base::NumberToString16(blue * 100 / 255) + L"% blue";
- BSTR value = SysAllocString(value_text.c_str());
- DCHECK(value);
- return value;
- }
-
- //
- // Document special case (Use the document's URL)
- //
- if (target->GetData().role == ax::mojom::Role::kRootWebArea ||
- target->GetData().role == ax::mojom::Role::kWebArea) {
- result = base::UTF8ToUTF16(target->GetDelegate()->GetTreeData().url);
- BSTR value = SysAllocString(result.c_str());
- DCHECK(value);
- return value;
- }
-
- //
- // Links (Use ax::mojom::StringAttribute::kUrl)
- //
- if (target->GetData().role == ax::mojom::Role::kLink) {
- result = target->GetString16Attribute(ax::mojom::StringAttribute::kUrl);
- BSTR value = SysAllocString(result.c_str());
- DCHECK(value);
- return value;
- }
-
- // For range controls, e.g. sliders and spin buttons, |ax_attr_value| holds
- // the aria-valuetext if present but not the inner text. The actual value,
- // provided either via aria-valuenow or the actual control's value is held in
- // |ax::mojom::FloatAttribute::kValueForRange|.
- result = target->GetString16Attribute(ax::mojom::StringAttribute::kValue);
- if (result.empty() && target->GetData().IsRangeValueSupported()) {
- float fval;
- if (target->GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange,
- &fval)) {
- result = base::NumberToString16(fval);
- BSTR value = SysAllocString(result.c_str());
- DCHECK(value);
- return value;
- }
- }
-
- if (result.empty() && target->IsRichTextField())
- result = target->GetInnerText();
-
- BSTR value = SysAllocString(result.c_str());
- DCHECK(value);
- return value;
-}
-
-HRESULT AXPlatformNodeWin::GetStringAttributeAsBstr(
- ax::mojom::StringAttribute attribute,
- BSTR* value_bstr) const {
- base::string16 str;
-
- if (!GetString16Attribute(attribute, &str))
- return S_FALSE;
-
- *value_bstr = SysAllocString(str.c_str());
- DCHECK(*value_bstr);
-
- return S_OK;
-}
-
-HRESULT AXPlatformNodeWin::GetNameAsBstr(BSTR* value_bstr) const {
- base::string16 str = GetNameAsString16();
- *value_bstr = SysAllocString(str.c_str());
- DCHECK(*value_bstr);
- return S_OK;
-}
-
-void AXPlatformNodeWin::AddAlertTarget() {
- g_alert_targets.Get().insert(this);
-}
-
-void AXPlatformNodeWin::RemoveAlertTarget() {
- if (g_alert_targets.Get().find(this) != g_alert_targets.Get().end())
- g_alert_targets.Get().erase(this);
-}
-
-void AXPlatformNodeWin::HandleSpecialTextOffset(LONG* offset) {
- if (*offset == IA2_TEXT_OFFSET_LENGTH) {
- *offset = static_cast<LONG>(GetHypertext().length());
- } else if (*offset == IA2_TEXT_OFFSET_CARET) {
- int selection_start, selection_end;
- GetSelectionOffsets(&selection_start, &selection_end);
- // TODO(nektar): Deprecate selection_start and selection_end in favor of
- // anchor_offset/focus_offset. See https://crbug.com/645596.
- if (selection_end < 0)
- *offset = 0;
- else
- *offset = static_cast<LONG>(selection_end);
- }
-}
-
-LONG AXPlatformNodeWin::FindBoundary(IA2TextBoundaryType ia2_boundary,
- LONG start_offset,
- ax::mojom::MoveDirection direction) {
- HandleSpecialTextOffset(&start_offset);
-
- // If the |start_offset| is equal to the location of the caret, then use the
- // focus affinity, otherwise default to downstream affinity.
- ax::mojom::TextAffinity affinity = ax::mojom::TextAffinity::kDownstream;
- int selection_start, selection_end;
- GetSelectionOffsets(&selection_start, &selection_end);
- if (selection_end >= 0 && start_offset == selection_end)
- affinity = GetDelegate()->GetTreeData().sel_focus_affinity;
-
- ax::mojom::TextBoundary boundary = FromIA2TextBoundary(ia2_boundary);
- return static_cast<LONG>(
- FindTextBoundary(boundary, start_offset, direction, affinity));
-}
-
-AXPlatformNodeWin* AXPlatformNodeWin::GetTargetFromChildID(
- const VARIANT& var_id) {
- if (V_VT(&var_id) != VT_I4)
- return nullptr;
-
- LONG child_id = V_I4(&var_id);
- if (child_id == CHILDID_SELF)
- return this;
-
- if (child_id >= 1 && child_id <= GetDelegate()->GetChildCount()) {
- // Positive child ids are a 1-based child index, used by clients
- // that want to enumerate all immediate children.
- AXPlatformNodeBase* base =
- FromNativeViewAccessible(GetDelegate()->ChildAtIndex(child_id - 1));
- return static_cast<AXPlatformNodeWin*>(base);
- }
-
- if (child_id >= 0)
- return nullptr;
-
- // Negative child ids can be used to map to any descendant.
- AXPlatformNode* node = GetFromUniqueId(-child_id);
- if (!node)
- return nullptr;
-
- AXPlatformNodeBase* base =
- FromNativeViewAccessible(node->GetNativeViewAccessible());
- if (base && !IsDescendant(base))
- base = nullptr;
-
- return static_cast<AXPlatformNodeWin*>(base);
-}
-
-bool AXPlatformNodeWin::IsInTreeGrid() {
- AXPlatformNodeBase* container = FromNativeViewAccessible(GetParent());
-
- // If parent was a rowgroup, we need to look at the grandparent
- if (container && container->GetData().role == ax::mojom::Role::kRowGroup)
- container = FromNativeViewAccessible(container->GetParent());
-
- if (!container)
- return false;
-
- return container->GetData().role == ax::mojom::Role::kTreeGrid;
-}
-
-HRESULT AXPlatformNodeWin::AllocateComArrayFromVector(
- std::vector<LONG>& results,
- LONG max,
- LONG** selected,
- LONG* n_selected) {
- DCHECK_GT(max, 0);
- DCHECK(selected);
- DCHECK(n_selected);
-
- auto count = std::min((LONG)results.size(), max);
- *n_selected = count;
- *selected = static_cast<LONG*>(CoTaskMemAlloc(sizeof(LONG) * count));
-
- for (LONG i = 0; i < count; i++)
- (*selected)[i] = results[i];
- return S_OK;
-}
-
-bool AXPlatformNodeWin::IsPlaceholderText() const {
- if (GetData().role != ax::mojom::Role::kStaticText)
- return false;
- AXPlatformNodeWin* parent =
- static_cast<AXPlatformNodeWin*>(FromNativeViewAccessible(GetParent()));
- // Static text nodes are always expected to have a parent.
- DCHECK(parent);
- return parent->IsTextField() &&
- parent->HasStringAttribute(ax::mojom::StringAttribute::kPlaceholder);
-}
-
-bool AXPlatformNodeWin::IsHyperlink() {
- int32_t hyperlink_index = -1;
- AXPlatformNodeWin* parent =
- static_cast<AXPlatformNodeWin*>(FromNativeViewAccessible(GetParent()));
- if (parent) {
- hyperlink_index = parent->GetHyperlinkIndexFromChild(this);
- }
-
- if (hyperlink_index >= 0)
- return true;
- return false;
-}
-
-void AXPlatformNodeWin::ComputeHypertextRemovedAndInserted(size_t* start,
- size_t* old_len,
- size_t* new_len) {
- AXPlatformNodeBase::ComputeHypertextRemovedAndInserted(old_hypertext_, start,
- old_len, new_len);
-}
-
-double AXPlatformNodeWin::GetHorizontalScrollPercent() {
- if (!IsHorizontallyScrollable())
- return UIA_ScrollPatternNoScroll;
-
- float x_min = GetIntAttribute(ax::mojom::IntAttribute::kScrollXMin);
- float x_max = GetIntAttribute(ax::mojom::IntAttribute::kScrollXMax);
- float x = GetIntAttribute(ax::mojom::IntAttribute::kScrollX);
- return 100.0 * (x - x_min) / (x_max - x_min);
-}
-
-double AXPlatformNodeWin::GetVerticalScrollPercent() {
- if (!IsVerticallyScrollable())
- return UIA_ScrollPatternNoScroll;
-
- float y_min = GetIntAttribute(ax::mojom::IntAttribute::kScrollYMin);
- float y_max = GetIntAttribute(ax::mojom::IntAttribute::kScrollYMax);
- float y = GetIntAttribute(ax::mojom::IntAttribute::kScrollY);
- return 100.0 * (y - y_min) / (y_max - y_min);
-}
-
-BSTR AXPlatformNodeWin::GetFontNameAttributeAsBSTR() const {
- const base::string16 string =
- GetInheritedString16Attribute(ax::mojom::StringAttribute::kFontFamily);
-
- return SysAllocString(string.c_str());
-}
-
-BSTR AXPlatformNodeWin::GetStyleNameAttributeAsBSTR() const {
- base::string16 style_name =
- GetDelegate()->GetStyleNameAttributeAsLocalizedString();
-
- return SysAllocString(style_name.c_str());
-}
-
-TextDecorationLineStyle AXPlatformNodeWin::GetUIATextDecorationStyle(
- const ax::mojom::IntAttribute int_attribute) const {
- const ax::mojom::TextDecorationStyle text_decoration_style =
- static_cast<ax::mojom::TextDecorationStyle>(
- GetIntAttribute(int_attribute));
-
- switch (text_decoration_style) {
- case ax::mojom::TextDecorationStyle::kNone:
- return TextDecorationLineStyle::TextDecorationLineStyle_None;
- case ax::mojom::TextDecorationStyle::kDotted:
- return TextDecorationLineStyle::TextDecorationLineStyle_Dot;
- case ax::mojom::TextDecorationStyle::kDashed:
- return TextDecorationLineStyle::TextDecorationLineStyle_Dash;
- case ax::mojom::TextDecorationStyle::kSolid:
- return TextDecorationLineStyle::TextDecorationLineStyle_Single;
- case ax::mojom::TextDecorationStyle::kDouble:
- return TextDecorationLineStyle::TextDecorationLineStyle_Double;
- case ax::mojom::TextDecorationStyle::kWavy:
- return TextDecorationLineStyle::TextDecorationLineStyle_Wavy;
- }
-}
-
-// IRawElementProviderSimple support methods.
-
-AXPlatformNodeWin::PatternProviderFactoryMethod
-AXPlatformNodeWin::GetPatternProviderFactoryMethod(PATTERNID pattern_id) {
- const AXNodeData& data = GetData();
-
- switch (pattern_id) {
- case UIA_ExpandCollapsePatternId:
- if (data.SupportsExpandCollapse()) {
- return &PatternProvider<IExpandCollapseProvider>;
- }
- break;
-
- case UIA_GridPatternId:
- if (IsTableLike(data.role)) {
- return &PatternProvider<IGridProvider>;
- }
- break;
-
- case UIA_GridItemPatternId:
- if (IsCellOrTableHeader(data.role)) {
- return &PatternProvider<IGridItemProvider>;
- }
- break;
-
- case UIA_InvokePatternId:
- if (data.IsInvocable()) {
- return &PatternProvider<IInvokeProvider>;
- }
- break;
-
- case UIA_RangeValuePatternId:
- if (data.IsRangeValueSupported()) {
- return &PatternProvider<IRangeValueProvider>;
- }
- break;
-
- case UIA_ScrollPatternId:
- if (IsScrollable()) {
- return &PatternProvider<IScrollProvider>;
- }
- break;
-
- case UIA_ScrollItemPatternId:
- return &PatternProvider<IScrollItemProvider>;
- break;
-
- case UIA_SelectionItemPatternId:
- if (IsSelectionItemSupported()) {
- return &PatternProvider<ISelectionItemProvider>;
- }
- break;
-
- case UIA_SelectionPatternId:
- if (IsContainerWithSelectableChildren(data.role)) {
- return &PatternProvider<ISelectionProvider>;
- }
- break;
-
- case UIA_TablePatternId:
- // https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcore/nn-uiautomationcore-itableprovider
- // This control pattern is analogous to IGridProvider with the distinction
- // that any control implementing ITableProvider must also expose a column
- // and/or row header relationship for each child element.
- if (IsTableLike(data.role)) {
- base::Optional<bool> table_has_headers =
- GetDelegate()->GetTableHasColumnOrRowHeaderNode();
- if (table_has_headers.has_value() && table_has_headers.value()) {
- return &PatternProvider<ITableProvider>;
- }
- }
- break;
-
- case UIA_TableItemPatternId:
- // https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcore/nn-uiautomationcore-itableitemprovider
- // This control pattern is analogous to IGridItemProvider with the
- // distinction that any control implementing ITableItemProvider must
- // expose the relationship between the individual cell and its row and
- // column information.
- if (IsCellOrTableHeader(data.role)) {
- base::Optional<bool> table_has_headers =
- GetDelegate()->GetTableHasColumnOrRowHeaderNode();
- if (table_has_headers.has_value() && table_has_headers.value()) {
- return &PatternProvider<ITableItemProvider>;
- }
- }
- break;
-
- case UIA_TextChildPatternId:
- if (AXPlatformNodeTextChildProviderWin::GetTextContainer(this)) {
- return &AXPlatformNodeTextChildProviderWin::CreateIUnknown;
- }
- break;
-
- case UIA_TextEditPatternId:
- case UIA_TextPatternId:
- if (IsText() || IsDocument() ||
- HasBoolAttribute(ax::mojom::BoolAttribute::kEditableRoot)) {
- return &AXPlatformNodeTextProviderWin::CreateIUnknown;
- }
- break;
-
- case UIA_TogglePatternId:
- if (SupportsToggle(data.role)) {
- return &PatternProvider<IToggleProvider>;
- }
- break;
-
- case UIA_ValuePatternId:
- if (IsValuePatternSupported(GetDelegate())) {
- return &PatternProvider<IValueProvider>;
- }
- break;
-
- case UIA_WindowPatternId:
- if (HasBoolAttribute(ax::mojom::BoolAttribute::kModal)) {
- return &PatternProvider<IWindowProvider>;
- }
- break;
-
- // Not currently implemented.
- case UIA_AnnotationPatternId:
- case UIA_CustomNavigationPatternId:
- case UIA_DockPatternId:
- case UIA_DragPatternId:
- case UIA_DropTargetPatternId:
- case UIA_ItemContainerPatternId:
- case UIA_MultipleViewPatternId:
- case UIA_ObjectModelPatternId:
- case UIA_SpreadsheetPatternId:
- case UIA_SpreadsheetItemPatternId:
- case UIA_StylesPatternId:
- case UIA_SynchronizedInputPatternId:
- case UIA_TextPattern2Id:
- case UIA_TransformPatternId:
- case UIA_TransformPattern2Id:
- case UIA_VirtualizedItemPatternId:
- break;
-
- // Provided by UIA Core; we should not implement.
- case UIA_LegacyIAccessiblePatternId:
- break;
- }
- return nullptr;
-}
-
-void AXPlatformNodeWin::FireLiveRegionChangeRecursive() {
- const auto live_status_attr = ax::mojom::StringAttribute::kLiveStatus;
- if (HasStringAttribute(live_status_attr) &&
- GetStringAttribute(live_status_attr) != "off") {
- DCHECK(GetDelegate()->IsWebContent());
- ::UiaRaiseAutomationEvent(this, UIA_LiveRegionChangedEventId);
- return;
- }
-
- for (int index = 0; index < GetChildCount(); ++index) {
- auto* child = static_cast<AXPlatformNodeWin*>(
- FromNativeViewAccessible(ChildAtIndex(index)));
-
- // We assume that only web-content will have live regions; also because
- // this will be called on each fragment-root, there is no need to walk
- // through non-content nodes.
- if (child->GetDelegate()->IsWebContent())
- child->FireLiveRegionChangeRecursive();
- }
-}
-
-AXPlatformNodeWin* AXPlatformNodeWin::GetLowestAccessibleElement() {
- if (!IsInaccessibleDueToAncestor())
- return this;
-
- AXPlatformNodeWin* parent = static_cast<AXPlatformNodeWin*>(
- AXPlatformNode::FromNativeViewAccessible(GetParent()));
- while (parent) {
- if (parent->ShouldHideChildrenForUIA())
- return parent;
- parent = static_cast<AXPlatformNodeWin*>(
- AXPlatformNode::FromNativeViewAccessible(parent->GetParent()));
- }
-
- NOTREACHED();
- return nullptr;
-}
-
-AXPlatformNodeWin* AXPlatformNodeWin::GetFirstTextOnlyDescendant() {
- for (auto* child = static_cast<AXPlatformNodeWin*>(GetFirstChild()); child;
- child = static_cast<AXPlatformNodeWin*>(child->GetNextSibling())) {
- if (child->IsText())
- return child;
- if (AXPlatformNodeWin* descendant = child->GetFirstTextOnlyDescendant())
- return descendant;
- }
- return nullptr;
-}
-
-void AXPlatformNodeWin::SanitizeTextAttributeValue(const std::string& input,
- std::string* output) const {
- SanitizeStringAttributeForIA2(input, output);
-}
-
-// static
-void AXPlatformNodeWin::SanitizeStringAttributeForIA2(const std::string& input,
- std::string* output) {
- DCHECK(output);
- // According to the IA2 Spec, these characters need to be escaped with a
- // backslash: backslash, colon, comma, equals and semicolon.
- // Note that backslash must be replaced first.
- base::ReplaceChars(input, "\\", "\\\\", output);
- base::ReplaceChars(*output, ":", "\\:", output);
- base::ReplaceChars(*output, ",", "\\,", output);
- base::ReplaceChars(*output, "=", "\\=", output);
- base::ReplaceChars(*output, ";", "\\;", output);
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_win.h b/third_party/accessibility/ax/platform/ax_platform_node_win.h
deleted file mode 100644
index 25a4873..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_win.h
+++ /dev/null
@@ -1,1452 +0,0 @@
-//
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_WIN_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_WIN_H_
-
-#include <objbase.h>
-#include <oleacc.h>
-#include <oleauto.h>
-#include <uiautomation.h>
-#include <wrl/client.h>
-
-#include <array>
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/gtest_prod_util.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/observer_list.h"
-#include "base/win/atl.h"
-#include "third_party/iaccessible2/ia2_api_all.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_text_utils.h"
-#include "ui/accessibility/platform/ax_platform_node_base.h"
-#include "ui/accessibility/platform/ax_platform_text_boundary.h"
-#include "ui/accessibility/platform/ichromeaccessible.h"
-#include "ui/gfx/range/range.h"
-
-// IMPORTANT!
-// These values are written to logs. Do not renumber or delete
-// existing items; add new entries to the end of the list.
-enum {
- UMA_API_ACC_DO_DEFAULT_ACTION = 0,
- UMA_API_ACC_HIT_TEST = 1,
- UMA_API_ACC_LOCATION = 2,
- UMA_API_ACC_NAVIGATE = 3,
- UMA_API_ACC_SELECT = 4,
- UMA_API_ADD_SELECTION = 5,
- UMA_API_CONVERT_RETURNED_ELEMENT = 6,
- UMA_API_DO_ACTION = 7,
- UMA_API_GET_ACCESSIBLE_AT = 8,
- UMA_API_GET_ACC_CHILD = 9,
- UMA_API_GET_ACC_CHILD_COUNT = 10,
- UMA_API_GET_ACC_DEFAULT_ACTION = 11,
- UMA_API_GET_ACC_DESCRIPTION = 12,
- UMA_API_GET_ACC_FOCUS = 13,
- UMA_API_GET_ACC_HELP = 14,
- UMA_API_GET_ACC_HELP_TOPIC = 15,
- UMA_API_GET_ACC_KEYBOARD_SHORTCUT = 16,
- UMA_API_GET_ACC_NAME = 17,
- UMA_API_GET_ACC_PARENT = 18,
- UMA_API_GET_ACC_ROLE = 19,
- UMA_API_GET_ACC_SELECTION = 20,
- UMA_API_GET_ACC_STATE = 21,
- UMA_API_GET_ACC_VALUE = 22,
- UMA_API_GET_ANCHOR = 23,
- UMA_API_GET_ANCHOR_TARGET = 24,
- UMA_API_GET_APP_NAME = 25,
- UMA_API_GET_APP_VERSION = 26,
- UMA_API_GET_ATTRIBUTES_FOR_NAMES = 27,
- UMA_API_GET_CAPTION = 28,
- UMA_API_GET_CARET_OFFSET = 29,
- UMA_API_GET_CELL_AT = 30,
- UMA_API_GET_CHARACTER_EXTENTS = 31,
- UMA_API_GET_CHILD_AT = 32,
- UMA_API_GET_CHILD_INDEX = 33,
- UMA_API_GET_CLIPPED_SUBSTRING_BOUNDS = 34,
- UMA_API_GET_COLUMN_DESCRIPTION = 35,
- UMA_API_GET_COLUMN_EXTENT = 36,
- UMA_API_GET_COLUMN_EXTENT_AT = 37,
- UMA_API_GET_COLUMN_HEADER = 38,
- UMA_API_GET_COLUMN_HEADER_CELLS = 39,
- UMA_API_GET_COLUMN_INDEX = 40,
- UMA_API_GET_COMPUTED_STYLE = 41,
- UMA_API_GET_COMPUTED_STYLE_FOR_PROPERTIES = 42,
- UMA_API_GET_CURRENT_VALUE = 43,
- UMA_API_GET_DESCRIPTION = 44,
- UMA_API_GET_DOC_TYPE = 45,
- UMA_API_GET_DOM_TEXT = 46,
- UMA_API_GET_END_INDEX = 47,
- UMA_API_GET_EXTENDED_ROLE = 48,
- UMA_API_GET_EXTENDED_STATES = 49,
- UMA_API_GET_FIRST_CHILD = 50,
- UMA_API_GET_FONT_FAMILY = 51,
- UMA_API_GET_GROUP_POSITION = 52,
- UMA_API_GET_HOST_RAW_ELEMENT_PROVIDER = 53,
- UMA_API_GET_HYPERLINK = 54,
- UMA_API_GET_HYPERLINK_INDEX = 55,
- UMA_API_GET_IACCESSIBLE_PAIR = 56,
- UMA_API_GET_IMAGE_POSITION = 57,
- UMA_API_GET_IMAGE_SIZE = 58,
- UMA_API_GET_INDEX_IN_PARENT = 59,
- UMA_API_GET_INNER_HTML = 60,
- UMA_API_GET_IS_COLUMN_SELECTED = 61,
- UMA_API_GET_IS_ROW_SELECTED = 62,
- UMA_API_GET_IS_SELECTED = 63,
- UMA_API_GET_KEY_BINDING = 64,
- UMA_API_GET_LANGUAGE = 65,
- UMA_API_GET_LAST_CHILD = 66,
- UMA_API_GET_LOCALE = 67,
- UMA_API_GET_LOCALIZED_EXTENDED_ROLE = 68,
- UMA_API_GET_LOCALIZED_EXTENDED_STATES = 69,
- UMA_API_GET_LOCALIZED_NAME = 70,
- UMA_API_GET_LOCAL_INTERFACE = 71,
- UMA_API_GET_MAXIMUM_VALUE = 72,
- UMA_API_GET_MIME_TYPE = 73,
- UMA_API_GET_MINIMUM_VALUE = 74,
- UMA_API_GET_NAME = 75,
- UMA_API_GET_NAMESPACE_URI_FOR_ID = 76,
- UMA_API_GET_NEW_TEXT = 77,
- UMA_API_GET_NEXT_SIBLING = 78,
- UMA_API_GET_NODE_INFO = 79,
- UMA_API_GET_N_CHARACTERS = 80,
- UMA_API_GET_N_COLUMNS = 81,
- UMA_API_GET_N_EXTENDED_STATES = 82,
- UMA_API_GET_N_HYPERLINKS = 83,
- UMA_API_GET_N_RELATIONS = 84,
- UMA_API_GET_N_ROWS = 85,
- UMA_API_GET_N_SELECTED_CELLS = 86,
- UMA_API_GET_N_SELECTED_CHILDREN = 87,
- UMA_API_GET_N_SELECTED_COLUMNS = 88,
- UMA_API_GET_N_SELECTED_ROWS = 89,
- UMA_API_GET_N_SELECTIONS = 90,
- UMA_API_GET_OBJECT_FOR_CHILD = 91,
- UMA_API_GET_OFFSET_AT_POINT = 92,
- UMA_API_GET_OLD_TEXT = 93,
- UMA_API_GET_PARENT_NODE = 94,
- UMA_API_GET_PATTERN_PROVIDER = 95,
- UMA_API_GET_PREVIOUS_SIBLING = 96,
- UMA_API_GET_PROPERTY_VALUE = 97,
- UMA_API_GET_PROVIDER_OPTIONS = 98,
- UMA_API_GET_RELATION = 99,
- UMA_API_GET_RELATIONS = 100,
- UMA_API_GET_ROW_COLUMN_EXTENTS = 101,
- UMA_API_GET_ROW_COLUMN_EXTENTS_AT_INDEX = 102,
- UMA_API_GET_ROW_DESCRIPTION = 103,
- UMA_API_GET_ROW_EXTENT = 104,
- UMA_API_GET_ROW_EXTENT_AT = 105,
- UMA_API_GET_ROW_HEADER = 106,
- UMA_API_GET_ROW_HEADER_CELLS = 107,
- UMA_API_GET_ROW_INDEX = 108,
- UMA_API_GET_RUNTIME_ID = 109,
- UMA_API_GET_SELECTED_CELLS = 110,
- UMA_API_GET_SELECTED_CHILDREN = 111,
- UMA_API_GET_SELECTED_COLUMNS = 112,
- UMA_API_GET_SELECTED_ROWS = 113,
- UMA_API_GET_SELECTION = 114,
- UMA_API_GET_START_INDEX = 115,
- UMA_API_GET_STATES = 116,
- UMA_API_GET_SUMMARY = 117,
- UMA_API_GET_TABLE = 118,
- UMA_API_GET_TEXT = 119,
- UMA_API_GET_TEXT_AFTER_OFFSET = 120,
- UMA_API_GET_TEXT_AT_OFFSET = 121,
- UMA_API_GET_TEXT_BEFORE_OFFSET = 122,
- UMA_API_GET_TITLE = 123,
- UMA_API_GET_TOOLKIT_NAME = 124,
- UMA_API_GET_TOOLKIT_VERSION = 125,
- UMA_API_GET_UNCLIPPED_SUBSTRING_BOUNDS = 126,
- UMA_API_GET_UNIQUE_ID = 127,
- UMA_API_GET_URL = 128,
- UMA_API_GET_VALID = 129,
- UMA_API_GET_WINDOW_HANDLE = 130,
- UMA_API_IA2_GET_ATTRIBUTES = 131,
- UMA_API_IA2_SCROLL_TO = 132,
- UMA_API_IAACTION_GET_DESCRIPTION = 133,
- UMA_API_IATEXT_GET_ATTRIBUTES = 134,
- UMA_API_ISIMPLEDOMNODE_GET_ATTRIBUTES = 135,
- UMA_API_ISIMPLEDOMNODE_SCROLL_TO = 136,
- UMA_API_N_ACTIONS = 137,
- UMA_API_PUT_ALTERNATE_VIEW_MEDIA_TYPES = 138,
- UMA_API_QUERY_SERVICE = 139,
- UMA_API_REMOVE_SELECTION = 140,
- UMA_API_ROLE = 141,
- UMA_API_SCROLL_SUBSTRING_TO = 142,
- UMA_API_SCROLL_SUBSTRING_TO_POINT = 143,
- UMA_API_SCROLL_TO_POINT = 144,
- UMA_API_SCROLL_TO_SUBSTRING = 145,
- UMA_API_SELECT_COLUMN = 146,
- UMA_API_SELECT_ROW = 147,
- UMA_API_SET_CARET_OFFSET = 148,
- UMA_API_SET_CURRENT_VALUE = 149,
- UMA_API_SET_SELECTION = 150,
- UMA_API_TABLE2_GET_SELECTED_COLUMNS = 151,
- UMA_API_TABLE2_GET_SELECTED_ROWS = 152,
- UMA_API_TABLECELL_GET_COLUMN_INDEX = 153,
- UMA_API_TABLECELL_GET_IS_SELECTED = 154,
- UMA_API_TABLECELL_GET_ROW_INDEX = 155,
- UMA_API_UNSELECT_COLUMN = 156,
- UMA_API_UNSELECT_ROW = 157,
- UMA_API_GET_BOUNDINGRECTANGLE = 158,
- UMA_API_GET_FRAGMENTROOT = 159,
- UMA_API_GETEMBEDDEDFRAGMENTROOTS = 160,
- UMA_API_NAVIGATE = 161,
- UMA_API_SETFOCUS = 162,
- UMA_API_SHOWCONTEXTMENU = 163,
- UMA_API_EXPANDCOLLAPSE_COLLAPSE = 164,
- UMA_API_EXPANDCOLLAPSE_EXPAND = 165,
- UMA_API_EXPANDCOLLAPSE_GET_EXPANDCOLLAPSESTATE = 166,
- UMA_API_GRIDITEM_GET_COLUMN = 167,
- UMA_API_GRIDITEM_GET_COLUMNSPAN = 168,
- UMA_API_GRIDITEM_GET_CONTAININGGRID = 169,
- UMA_API_GRIDITEM_GET_ROW = 170,
- UMA_API_GRIDITEM_GET_ROWSPAN = 171,
- UMA_API_GRID_GETITEM = 172,
- UMA_API_GRID_GET_ROWCOUNT = 173,
- UMA_API_GRID_GET_COLUMNCOUNT = 174,
- UMA_API_INVOKE_INVOKE = 175,
- UMA_API_RANGEVALUE_SETVALUE = 176,
- UMA_API_RANGEVALUE_GET_LARGECHANGE = 177,
- UMA_API_RANGEVALUE_GET_MAXIMUM = 178,
- UMA_API_RANGEVALUE_GET_MINIMUM = 179,
- UMA_API_RANGEVALUE_GET_SMALLCHANGE = 180,
- UMA_API_RANGEVALUE_GET_VALUE = 181,
- UMA_API_SCROLLITEM_SCROLLINTOVIEW = 182,
- UMA_API_SCROLL_SCROLL = 183,
- UMA_API_SCROLL_SETSCROLLPERCENT = 184,
- UMA_API_SCROLL_GET_HORIZONTALLYSCROLLABLE = 185,
- UMA_API_SCROLL_GET_HORIZONTALSCROLLPERCENT = 186,
- UMA_API_SCROLL_GET_HORIZONTALVIEWSIZE = 187,
- UMA_API_SCROLL_GET_VERTICALLYSCROLLABLE = 188,
- UMA_API_SCROLL_GET_VERTICALSCROLLPERCENT = 189,
- UMA_API_SCROLL_GET_VERTICALVIEWSIZE = 190,
- UMA_API_SELECTIONITEM_ADDTOSELECTION = 191,
- UMA_API_SELECTIONITEM_REMOVEFROMSELECTION = 192,
- UMA_API_SELECTIONITEM_SELECT = 193,
- UMA_API_SELECTIONITEM_GET_ISSELECTED = 194,
- UMA_API_SELECTIONITEM_GET_SELECTIONCONTAINER = 195,
- UMA_API_SELECTION_GETSELECTION = 196,
- UMA_API_SELECTION_GET_CANSELECTMULTIPLE = 197,
- UMA_API_SELECTION_GET_ISSELECTIONREQUIRED = 198,
- UMA_API_TABLEITEM_GETCOLUMNHEADERITEMS = 199,
- UMA_API_TABLEITEM_GETROWHEADERITEMS = 200,
- UMA_API_TABLE_GETCOLUMNHEADERS = 201,
- UMA_API_TABLE_GETROWHEADERS = 202,
- UMA_API_TABLE_GET_ROWORCOLUMNMAJOR = 203,
- UMA_API_TEXT_GETSELECTION = 204,
- UMA_API_TEXT_GETVISIBLERANGES = 205,
- UMA_API_TEXT_RANGEFROMCHILD = 206,
- UMA_API_TEXT_RANGEFROMPOINT = 207,
- UMA_API_TEXT_GET_DOCUMENTRANGE = 208,
- UMA_API_TEXT_GET_SUPPORTEDTEXTSELECTION = 209,
- UMA_API_TEXTCHILD_GET_TEXTCONTAINER = 210,
- UMA_API_TEXTCHILD_GET_TEXTRANGE = 211,
- UMA_API_TEXTEDIT_GETACTIVECOMPOSITION = 212,
- UMA_API_TEXTEDIT_GETCONVERSIONTARGET = 213,
- UMA_API_TEXTRANGE_CLONE = 214,
- UMA_API_TEXTRANGE_COMPARE = 215,
- UMA_API_TEXTRANGE_COMPAREENDPOINTS = 216,
- UMA_API_TEXTRANGE_EXPANDTOENCLOSINGUNIT = 217,
- UMA_API_TEXTRANGE_FINDATTRIBUTE = 218,
- UMA_API_TEXTRANGE_FINDTEXT = 219,
- UMA_API_TEXTRANGE_GETATTRIBUTEVALUE = 220,
- UMA_API_TEXTRANGE_GETBOUNDINGRECTANGLES = 221,
- UMA_API_TEXTRANGE_GETENCLOSINGELEMENT = 222,
- UMA_API_TEXTRANGE_GETTEXT = 223,
- UMA_API_TEXTRANGE_MOVE = 224,
- UMA_API_TEXTRANGE_MOVEENDPOINTBYUNIT = 225,
- UMA_API_TEXTRANGE_MOVEENPOINTBYRANGE = 226,
- UMA_API_TEXTRANGE_SELECT = 227,
- UMA_API_TEXTRANGE_ADDTOSELECTION = 228,
- UMA_API_TEXTRANGE_REMOVEFROMSELECTION = 229,
- UMA_API_TEXTRANGE_SCROLLINTOVIEW = 230,
- UMA_API_TEXTRANGE_GETCHILDREN = 231,
- UMA_API_TOGGLE_TOGGLE = 232,
- UMA_API_TOGGLE_GET_TOGGLESTATE = 233,
- UMA_API_VALUE_SETVALUE = 234,
- UMA_API_VALUE_GET_ISREADONLY = 235,
- UMA_API_VALUE_GET_VALUE = 236,
- UMA_API_WINDOW_SETVISUALSTATE = 237,
- UMA_API_WINDOW_CLOSE = 238,
- UMA_API_WINDOW_WAITFORINPUTIDLE = 239,
- UMA_API_WINDOW_GET_CANMAXIMIZE = 240,
- UMA_API_WINDOW_GET_CANMINIMIZE = 241,
- UMA_API_WINDOW_GET_ISMODAL = 242,
- UMA_API_WINDOW_GET_WINDOWVISUALSTATE = 243,
- UMA_API_WINDOW_GET_WINDOWINTERACTIONSTATE = 244,
- UMA_API_WINDOW_GET_ISTOPMOST = 245,
- UMA_API_ELEMENT_PROVIDER_FROM_POINT = 246,
- UMA_API_GET_FOCUS = 247,
- UMA_API_ADVISE_EVENT_ADDED = 248,
- UMA_API_ADVISE_EVENT_REMOVED = 249,
- UMA_API_ITEMCONTAINER_FINDITEMBYPROPERTY = 250,
-
- // This must always be the last enum. It's okay for its value to
- // increase, but none of the other enum values may change.
- UMA_API_MAX
-};
-
-#define WIN_ACCESSIBILITY_API_HISTOGRAM(enum_value) \
- UMA_HISTOGRAM_ENUMERATION("Accessibility.WinAPIs", enum_value, UMA_API_MAX)
-
-#define WIN_ACCESSIBILITY_API_PERF_HISTOGRAM(enum_value) \
- SCOPED_UMA_HISTOGRAM_SHORT_TIMER( \
- "Accessibility.Performance.WinAPIs." #enum_value)
-
-//
-// Macros to use at the top of any AXPlatformNodeWin (or derived class) method
-// that implements a UIA COM interface. The error code UIA_E_ELEMENTNOTAVAILABLE
-// signals to the OS that the object is no longer valid and no further methods
-// should be called on it.
-//
-#define UIA_VALIDATE_CALL() \
- if (!AXPlatformNodeBase::GetDelegate()) \
- return UIA_E_ELEMENTNOTAVAILABLE;
-#define UIA_VALIDATE_CALL_1_ARG(arg) \
- if (!AXPlatformNodeBase::GetDelegate()) \
- return UIA_E_ELEMENTNOTAVAILABLE; \
- if (!arg) \
- return E_INVALIDARG; \
- *arg = {};
-
-namespace base {
-namespace win {
-class VariantVector;
-} // namespace win
-} // namespace base
-
-namespace ui {
-
-class AXPlatformNodeWin;
-class AXPlatformRelationWin;
-
-// A simple interface for a class that wants to be notified when Windows
-// accessibility APIs are used by a client, a strong indication that full
-// accessibility support should be enabled.
-class AX_EXPORT WinAccessibilityAPIUsageObserver {
- public:
- WinAccessibilityAPIUsageObserver();
- virtual ~WinAccessibilityAPIUsageObserver();
- virtual void OnIAccessible2Used() = 0;
- virtual void OnScreenReaderHoneyPotQueried() = 0;
- virtual void OnAccNameCalled() = 0;
- virtual void OnUIAutomationUsed() = 0;
-};
-
-// Get an observer list that allows modules across the codebase to
-// listen to when usage of Windows accessibility APIs is detected.
-extern AX_EXPORT
- base::ObserverList<WinAccessibilityAPIUsageObserver>::Unchecked&
- GetWinAccessibilityAPIUsageObserverList();
-
-// TODO(nektar): Remove multithread superclass since we don't support it.
-class AX_EXPORT __declspec(uuid("26f5641a-246d-457b-a96d-07f3fae6acf2"))
- AXPlatformNodeWin : public CComObjectRootEx<CComMultiThreadModel>,
- public IDispatchImpl<IAccessible2_4,
- &IID_IAccessible2_4,
- &LIBID_IAccessible2Lib>,
- public IAccessibleEx,
- public IAccessibleHypertext,
- public IAccessibleTable,
- public IAccessibleTable2,
- public IAccessibleTableCell,
- public IAccessibleValue,
- public IExpandCollapseProvider,
- public IGridItemProvider,
- public IGridProvider,
- public IInvokeProvider,
- public IRangeValueProvider,
- public IRawElementProviderFragment,
- public IRawElementProviderSimple2,
- public IScrollItemProvider,
- public IScrollProvider,
- public ISelectionItemProvider,
- public ISelectionProvider,
- public IServiceProvider,
- public ITableItemProvider,
- public ITableProvider,
- public IToggleProvider,
- public IValueProvider,
- public IWindowProvider,
- public IChromeAccessible,
- public AXPlatformNodeBase {
- using IDispatchImpl::Invoke;
-
- public:
- BEGIN_COM_MAP(AXPlatformNodeWin)
- // TODO(nektar): Change the following to COM_INTERFACE_ENTRY(IDispatch).
- COM_INTERFACE_ENTRY2(IDispatch, IAccessible2_2)
- COM_INTERFACE_ENTRY2(IUnknown, IDispatchImpl)
- // TODO(nektar): Find a way to remove the following entry because it's not
- // an interface.
- COM_INTERFACE_ENTRY(AXPlatformNodeWin)
- COM_INTERFACE_ENTRY(IAccessible)
- COM_INTERFACE_ENTRY(IAccessible2)
- COM_INTERFACE_ENTRY(IAccessible2_2)
- COM_INTERFACE_ENTRY(IAccessible2_3)
- COM_INTERFACE_ENTRY(IAccessible2_4)
- COM_INTERFACE_ENTRY(IAccessibleEx)
- COM_INTERFACE_ENTRY(IAccessibleText)
- COM_INTERFACE_ENTRY(IAccessibleHypertext)
- COM_INTERFACE_ENTRY(IAccessibleTable)
- COM_INTERFACE_ENTRY(IAccessibleTable2)
- COM_INTERFACE_ENTRY(IAccessibleTableCell)
- COM_INTERFACE_ENTRY(IAccessibleValue)
- COM_INTERFACE_ENTRY(IChromeAccessible)
- COM_INTERFACE_ENTRY(IExpandCollapseProvider)
- COM_INTERFACE_ENTRY(IGridItemProvider)
- COM_INTERFACE_ENTRY(IGridProvider)
- COM_INTERFACE_ENTRY(IInvokeProvider)
- COM_INTERFACE_ENTRY(IRangeValueProvider)
- COM_INTERFACE_ENTRY(IRawElementProviderFragment)
- COM_INTERFACE_ENTRY(IRawElementProviderSimple)
- COM_INTERFACE_ENTRY(IRawElementProviderSimple2)
- COM_INTERFACE_ENTRY(IScrollItemProvider)
- COM_INTERFACE_ENTRY(IScrollProvider)
- COM_INTERFACE_ENTRY(ISelectionItemProvider)
- COM_INTERFACE_ENTRY(ISelectionProvider)
- COM_INTERFACE_ENTRY(ITableItemProvider)
- COM_INTERFACE_ENTRY(ITableProvider)
- COM_INTERFACE_ENTRY(IToggleProvider)
- COM_INTERFACE_ENTRY(IValueProvider)
- COM_INTERFACE_ENTRY(IWindowProvider)
- COM_INTERFACE_ENTRY(IServiceProvider)
- END_COM_MAP()
-
- ~AXPlatformNodeWin() override;
-
- void Init(AXPlatformNodeDelegate* delegate) override;
-
- // Clear any AXPlatformRelationWin nodes owned by this node.
- void ClearOwnRelations();
-
- // AXPlatformNode overrides.
- gfx::NativeViewAccessible GetNativeViewAccessible() override;
- void NotifyAccessibilityEvent(ax::mojom::Event event_type) override;
-
- // AXPlatformNodeBase overrides.
- void Destroy() override;
- base::string16 GetValue() const override;
- bool IsPlatformCheckable() const override;
-
- //
- // IAccessible methods.
- //
-
- // Retrieves the child element or child object at a given point on the screen.
- IFACEMETHODIMP accHitTest(LONG screen_physical_pixel_x,
- LONG screen_physical_pixel_y,
- VARIANT* child) override;
-
- // Performs the object's default action.
- IFACEMETHODIMP accDoDefaultAction(VARIANT var_id) override;
-
- // Retrieves the specified object's current screen location.
- IFACEMETHODIMP accLocation(LONG* physical_pixel_left,
- LONG* physical_pixel_top,
- LONG* width,
- LONG* height,
- VARIANT var_id) override;
-
- // Traverses to another UI element and retrieves the object.
- IFACEMETHODIMP accNavigate(LONG nav_dir,
- VARIANT start,
- VARIANT* end) override;
-
- // Retrieves an IDispatch interface pointer for the specified child.
- IFACEMETHODIMP get_accChild(VARIANT var_child,
- IDispatch** disp_child) override;
-
- // Retrieves the number of accessible children.
- IFACEMETHODIMP get_accChildCount(LONG* child_count) override;
-
- // Retrieves a string that describes the object's default action.
- IFACEMETHODIMP get_accDefaultAction(VARIANT var_id,
- BSTR* default_action) override;
-
- // Retrieves the tooltip description.
- IFACEMETHODIMP get_accDescription(VARIANT var_id, BSTR* desc) override;
-
- // Retrieves the object that has the keyboard focus.
- IFACEMETHODIMP get_accFocus(VARIANT* focus_child) override;
-
- // Retrieves the specified object's shortcut.
- IFACEMETHODIMP get_accKeyboardShortcut(VARIANT var_id,
- BSTR* access_key) override;
-
- // Retrieves the name of the specified object.
- IFACEMETHODIMP get_accName(VARIANT var_id, BSTR* name) override;
-
- // Retrieves the IDispatch interface of the object's parent.
- IFACEMETHODIMP get_accParent(IDispatch** disp_parent) override;
-
- // Retrieves information describing the role of the specified object.
- IFACEMETHODIMP get_accRole(VARIANT var_id, VARIANT* role) override;
-
- // Retrieves the current state of the specified object.
- IFACEMETHODIMP get_accState(VARIANT var_id, VARIANT* state) override;
-
- // Gets the help string for the specified object.
- IFACEMETHODIMP get_accHelp(VARIANT var_id, BSTR* help) override;
-
- // Retrieve or set the string value associated with the specified object.
- // Setting the value is not typically used by screen readers, but it's
- // used frequently by automation software.
- IFACEMETHODIMP get_accValue(VARIANT var_id, BSTR* value) override;
- IFACEMETHODIMP put_accValue(VARIANT var_id, BSTR new_value) override;
-
- // IAccessible methods not implemented.
- IFACEMETHODIMP get_accSelection(VARIANT* selected) override;
- IFACEMETHODIMP accSelect(LONG flags_sel, VARIANT var_id) override;
- IFACEMETHODIMP get_accHelpTopic(BSTR* help_file,
- VARIANT var_id,
- LONG* topic_id) override;
- IFACEMETHODIMP put_accName(VARIANT var_id, BSTR put_name) override;
-
- //
- // IAccessible2 methods.
- //
-
- IFACEMETHODIMP role(LONG* role) override;
-
- IFACEMETHODIMP get_states(AccessibleStates* states) override;
-
- IFACEMETHODIMP get_uniqueID(LONG* unique_id) override;
-
- IFACEMETHODIMP get_windowHandle(HWND* window_handle) override;
-
- IFACEMETHODIMP get_relationTargetsOfType(BSTR type,
- LONG max_targets,
- IUnknown*** targets,
- LONG* n_targets) override;
-
- IFACEMETHODIMP get_attributes(BSTR* attributes) override;
-
- IFACEMETHODIMP get_indexInParent(LONG* index_in_parent) override;
-
- IFACEMETHODIMP get_nRelations(LONG* n_relations) override;
-
- IFACEMETHODIMP get_relation(LONG relation_index,
- IAccessibleRelation** relation) override;
-
- IFACEMETHODIMP get_relations(LONG max_relations,
- IAccessibleRelation** relations,
- LONG* n_relations) override;
-
- IFACEMETHODIMP get_attribute(BSTR name, VARIANT* attribute) override;
- IFACEMETHODIMP get_extendedRole(BSTR* extended_role) override;
- IFACEMETHODIMP scrollTo(enum IA2ScrollType scroll_type) override;
- IFACEMETHODIMP scrollToPoint(enum IA2CoordinateType coordinate_type,
- LONG x,
- LONG y) override;
- IFACEMETHODIMP get_groupPosition(LONG* group_level,
- LONG* similar_items_in_group,
- LONG* position_in_group) override;
- IFACEMETHODIMP get_localizedExtendedRole(
- BSTR* localized_extended_role) override;
- IFACEMETHODIMP get_nExtendedStates(LONG* n_extended_states) override;
- IFACEMETHODIMP get_extendedStates(LONG max_extended_states,
- BSTR** extended_states,
- LONG* n_extended_states) override;
- IFACEMETHODIMP get_localizedExtendedStates(
- LONG max_localized_extended_states,
- BSTR** localized_extended_states,
- LONG* n_localized_extended_states) override;
- IFACEMETHODIMP get_locale(IA2Locale* locale) override;
- IFACEMETHODIMP get_accessibleWithCaret(IUnknown** accessible,
- LONG* caret_offset) override;
-
- //
- // IAccessible2_3 methods.
- //
-
- IFACEMETHODIMP get_selectionRanges(IA2Range** ranges, LONG* nRanges) override;
-
- //
- // IAccessible2_4 methods.
- //
-
- IFACEMETHODIMP setSelectionRanges(LONG nRanges, IA2Range* ranges) override;
-
- //
- // IAccessibleEx methods.
- //
-
- IFACEMETHODIMP GetObjectForChild(LONG child_id,
- IAccessibleEx** result) override;
-
- IFACEMETHODIMP GetIAccessiblePair(IAccessible** accessible,
- LONG* child_id) override;
-
- //
- // IExpandCollapseProvider methods.
- //
-
- IFACEMETHODIMP Collapse() override;
-
- IFACEMETHODIMP Expand() override;
-
- IFACEMETHODIMP get_ExpandCollapseState(ExpandCollapseState* result) override;
-
- //
- // IGridItemProvider methods.
- //
-
- IFACEMETHODIMP get_Column(int* result) override;
-
- IFACEMETHODIMP get_ColumnSpan(int* result) override;
-
- IFACEMETHODIMP get_ContainingGrid(
- IRawElementProviderSimple** result) override;
-
- IFACEMETHODIMP get_Row(int* result) override;
-
- IFACEMETHODIMP get_RowSpan(int* result) override;
-
- //
- // IGridProvider methods.
- //
-
- IFACEMETHODIMP GetItem(int row,
- int column,
- IRawElementProviderSimple** result) override;
-
- IFACEMETHODIMP get_RowCount(int* result) override;
-
- IFACEMETHODIMP get_ColumnCount(int* result) override;
-
- //
- // IInvokeProvider methods.
- //
-
- IFACEMETHODIMP Invoke() override;
-
- //
- // IScrollItemProvider methods.
- //
-
- IFACEMETHODIMP ScrollIntoView() override;
-
- //
- // IScrollProvider methods.
- //
-
- IFACEMETHODIMP Scroll(ScrollAmount horizontal_amount,
- ScrollAmount vertical_amount) override;
-
- IFACEMETHODIMP SetScrollPercent(double horizontal_percent,
- double vertical_percent) override;
-
- IFACEMETHODIMP get_HorizontallyScrollable(BOOL* result) override;
-
- IFACEMETHODIMP get_HorizontalScrollPercent(double* result) override;
-
- // Horizontal size of the viewable region as a percentage of the total content
- // area.
- IFACEMETHODIMP get_HorizontalViewSize(double* result) override;
-
- IFACEMETHODIMP get_VerticallyScrollable(BOOL* result) override;
-
- IFACEMETHODIMP get_VerticalScrollPercent(double* result) override;
-
- // Vertical size of the viewable region as a percentage of the total content
- // area.
- IFACEMETHODIMP get_VerticalViewSize(double* result) override;
-
- //
- // ISelectionItemProvider methods.
- //
-
- IFACEMETHODIMP AddToSelection() override;
-
- IFACEMETHODIMP RemoveFromSelection() override;
-
- IFACEMETHODIMP Select() override;
-
- IFACEMETHODIMP get_IsSelected(BOOL* result) override;
-
- IFACEMETHODIMP get_SelectionContainer(
- IRawElementProviderSimple** result) override;
-
- //
- // ISelectionProvider methods.
- //
-
- IFACEMETHODIMP GetSelection(SAFEARRAY** result) override;
-
- IFACEMETHODIMP get_CanSelectMultiple(BOOL* result) override;
-
- IFACEMETHODIMP get_IsSelectionRequired(BOOL* result) override;
-
- //
- // ITableItemProvider methods.
- //
-
- IFACEMETHODIMP GetColumnHeaderItems(SAFEARRAY** result) override;
-
- IFACEMETHODIMP GetRowHeaderItems(SAFEARRAY** result) override;
-
- //
- // ITableProvider methods.
- //
-
- IFACEMETHODIMP GetColumnHeaders(SAFEARRAY** result) override;
-
- IFACEMETHODIMP GetRowHeaders(SAFEARRAY** result) override;
-
- IFACEMETHODIMP get_RowOrColumnMajor(RowOrColumnMajor* result) override;
-
- //
- // IToggleProvider methods.
- //
-
- IFACEMETHODIMP Toggle() override;
-
- IFACEMETHODIMP get_ToggleState(ToggleState* result) override;
-
- //
- // IValueProvider methods.
- //
-
- IFACEMETHODIMP SetValue(LPCWSTR val) override;
-
- IFACEMETHODIMP get_IsReadOnly(BOOL* result) override;
-
- IFACEMETHODIMP get_Value(BSTR* result) override;
-
- //
- // IWindowProvider methods.
- //
-
- IFACEMETHODIMP SetVisualState(WindowVisualState window_visual_state) override;
-
- IFACEMETHODIMP Close() override;
-
- IFACEMETHODIMP WaitForInputIdle(int milliseconds, BOOL* result) override;
-
- IFACEMETHODIMP get_CanMaximize(BOOL* result) override;
-
- IFACEMETHODIMP get_CanMinimize(BOOL* result) override;
-
- IFACEMETHODIMP get_IsModal(BOOL* result) override;
-
- IFACEMETHODIMP get_WindowVisualState(WindowVisualState* result) override;
-
- IFACEMETHODIMP get_WindowInteractionState(
- WindowInteractionState* result) override;
-
- IFACEMETHODIMP get_IsTopmost(BOOL* result) override;
-
- //
- // IRangeValueProvider methods.
- //
-
- IFACEMETHODIMP SetValue(double val) override;
-
- IFACEMETHODIMP get_LargeChange(double* result) override;
-
- IFACEMETHODIMP get_Maximum(double* result) override;
-
- IFACEMETHODIMP get_Minimum(double* result) override;
-
- IFACEMETHODIMP get_SmallChange(double* result) override;
-
- IFACEMETHODIMP get_Value(double* result) override;
-
- // IAccessibleEx methods not implemented.
- IFACEMETHODIMP
- ConvertReturnedElement(IRawElementProviderSimple* element,
- IAccessibleEx** acc) override;
-
- //
- // IAccessibleText methods.
- //
-
- IFACEMETHODIMP get_nCharacters(LONG* n_characters) override;
-
- IFACEMETHODIMP get_caretOffset(LONG* offset) override;
-
- IFACEMETHODIMP get_nSelections(LONG* n_selections) override;
-
- IFACEMETHODIMP get_selection(LONG selection_index,
- LONG* start_offset,
- LONG* end_offset) override;
-
- IFACEMETHODIMP get_text(LONG start_offset,
- LONG end_offset,
- BSTR* text) override;
-
- IFACEMETHODIMP get_textAtOffset(LONG offset,
- enum IA2TextBoundaryType boundary_type,
- LONG* start_offset,
- LONG* end_offset,
- BSTR* text) override;
-
- IFACEMETHODIMP get_textBeforeOffset(LONG offset,
- enum IA2TextBoundaryType boundary_type,
- LONG* start_offset,
- LONG* end_offset,
- BSTR* text) override;
-
- IFACEMETHODIMP get_textAfterOffset(LONG offset,
- enum IA2TextBoundaryType boundary_type,
- LONG* start_offset,
- LONG* end_offset,
- BSTR* text) override;
-
- IFACEMETHODIMP get_offsetAtPoint(LONG x,
- LONG y,
- enum IA2CoordinateType coord_type,
- LONG* offset) override;
-
- //
- // IAccessibleTable methods.
- //
-
- // get_description - also used by IAccessibleImage
-
- IFACEMETHODIMP get_accessibleAt(LONG row,
- LONG column,
- IUnknown** accessible) override;
-
- IFACEMETHODIMP get_caption(IUnknown** accessible) override;
-
- IFACEMETHODIMP get_childIndex(LONG row_index,
- LONG column_index,
- LONG* cell_index) override;
-
- IFACEMETHODIMP get_columnDescription(LONG column, BSTR* description) override;
-
- IFACEMETHODIMP
- get_columnExtentAt(LONG row, LONG column, LONG* n_columns_spanned) override;
-
- IFACEMETHODIMP
- get_columnHeader(IAccessibleTable** accessible_table,
- LONG* starting_row_index) override;
-
- IFACEMETHODIMP get_columnIndex(LONG cell_index, LONG* column_index) override;
-
- IFACEMETHODIMP get_nColumns(LONG* column_count) override;
-
- IFACEMETHODIMP get_nRows(LONG* row_count) override;
-
- IFACEMETHODIMP get_nSelectedChildren(LONG* cell_count) override;
-
- IFACEMETHODIMP get_nSelectedColumns(LONG* column_count) override;
-
- IFACEMETHODIMP get_nSelectedRows(LONG* row_count) override;
-
- IFACEMETHODIMP get_rowDescription(LONG row, BSTR* description) override;
-
- IFACEMETHODIMP get_rowExtentAt(LONG row,
- LONG column,
- LONG* n_rows_spanned) override;
-
- IFACEMETHODIMP
- get_rowHeader(IAccessibleTable** accessible_table,
- LONG* starting_column_index) override;
-
- IFACEMETHODIMP get_rowIndex(LONG cell_index, LONG* row_index) override;
-
- IFACEMETHODIMP get_selectedChildren(LONG max_children,
- LONG** children,
- LONG* n_children) override;
-
- IFACEMETHODIMP get_selectedColumns(LONG max_columns,
- LONG** columns,
- LONG* n_columns) override;
-
- IFACEMETHODIMP get_selectedRows(LONG max_rows,
- LONG** rows,
- LONG* n_rows) override;
-
- IFACEMETHODIMP get_summary(IUnknown** accessible) override;
-
- IFACEMETHODIMP
- get_isColumnSelected(LONG column, boolean* is_selected) override;
-
- IFACEMETHODIMP get_isRowSelected(LONG row, boolean* is_selected) override;
-
- IFACEMETHODIMP get_isSelected(LONG row,
- LONG column,
- boolean* is_selected) override;
-
- IFACEMETHODIMP
- get_rowColumnExtentsAtIndex(LONG index,
- LONG* row,
- LONG* column,
- LONG* row_extents,
- LONG* column_extents,
- boolean* is_selected) override;
-
- IFACEMETHODIMP selectRow(LONG row) override;
-
- IFACEMETHODIMP selectColumn(LONG column) override;
-
- IFACEMETHODIMP unselectRow(LONG row) override;
-
- IFACEMETHODIMP unselectColumn(LONG column) override;
-
- IFACEMETHODIMP
- get_modelChange(IA2TableModelChange* model_change) override;
-
- //
- // IAccessibleTable2 methods.
- //
- // (Most of these are duplicates of IAccessibleTable methods, only the
- // unique ones are included here.)
- //
-
- IFACEMETHODIMP get_cellAt(LONG row, LONG column, IUnknown** cell) override;
-
- IFACEMETHODIMP get_nSelectedCells(LONG* cell_count) override;
-
- IFACEMETHODIMP
- get_selectedCells(IUnknown*** cells, LONG* n_selected_cells) override;
-
- IFACEMETHODIMP get_selectedColumns(LONG** columns, LONG* n_columns) override;
-
- IFACEMETHODIMP get_selectedRows(LONG** rows, LONG* n_rows) override;
-
- //
- // IAccessibleTableCell methods.
- //
-
- IFACEMETHODIMP
- get_columnExtent(LONG* n_columns_spanned) override;
-
- IFACEMETHODIMP
- get_columnHeaderCells(IUnknown*** cell_accessibles,
- LONG* n_column_header_cells) override;
-
- IFACEMETHODIMP get_columnIndex(LONG* column_index) override;
-
- IFACEMETHODIMP get_rowExtent(LONG* n_rows_spanned) override;
-
- IFACEMETHODIMP
- get_rowHeaderCells(IUnknown*** cell_accessibles,
- LONG* n_row_header_cells) override;
-
- IFACEMETHODIMP get_rowIndex(LONG* row_index) override;
-
- IFACEMETHODIMP get_isSelected(boolean* is_selected) override;
-
- IFACEMETHODIMP
- get_rowColumnExtents(LONG* row,
- LONG* column,
- LONG* row_extents,
- LONG* column_extents,
- boolean* is_selected) override;
-
- IFACEMETHODIMP get_table(IUnknown** table) override;
-
- //
- // IAccessibleHypertext methods not implemented.
- //
-
- IFACEMETHODIMP get_nHyperlinks(LONG* hyperlink_count) override;
-
- IFACEMETHODIMP
- get_hyperlink(LONG index, IAccessibleHyperlink** hyperlink) override;
-
- IFACEMETHODIMP
- get_hyperlinkIndex(LONG char_index, LONG* hyperlink_index) override;
-
- //
- // IAccessibleText methods not implemented.
- //
-
- IFACEMETHODIMP get_newText(IA2TextSegment* new_text) override;
- IFACEMETHODIMP get_oldText(IA2TextSegment* old_text) override;
- IFACEMETHODIMP addSelection(LONG start_offset, LONG end_offset) override;
- IFACEMETHODIMP get_attributes(LONG offset,
- LONG* start_offset,
- LONG* end_offset,
- BSTR* text_attributes) override;
- IFACEMETHODIMP get_characterExtents(LONG offset,
- enum IA2CoordinateType coord_type,
- LONG* x,
- LONG* y,
- LONG* width,
- LONG* height) override;
- IFACEMETHODIMP removeSelection(LONG selection_index) override;
- IFACEMETHODIMP setCaretOffset(LONG offset) override;
- IFACEMETHODIMP setSelection(LONG selection_index,
- LONG start_offset,
- LONG end_offset) override;
- IFACEMETHODIMP scrollSubstringTo(LONG start_index,
- LONG end_index,
- enum IA2ScrollType scroll_type) override;
- IFACEMETHODIMP scrollSubstringToPoint(LONG start_index,
- LONG end_index,
- enum IA2CoordinateType coordinate_type,
- LONG x,
- LONG y) override;
-
- //
- // IAccessibleValue methods.
- //
-
- IFACEMETHODIMP get_currentValue(VARIANT* value) override;
-
- IFACEMETHODIMP get_minimumValue(VARIANT* value) override;
-
- IFACEMETHODIMP get_maximumValue(VARIANT* value) override;
-
- IFACEMETHODIMP setCurrentValue(VARIANT new_value) override;
-
- //
- // IRawElementProviderFragment methods.
- //
-
- IFACEMETHODIMP Navigate(
- NavigateDirection direction,
- IRawElementProviderFragment** element_provider) override;
- IFACEMETHODIMP GetRuntimeId(SAFEARRAY** runtime_id) override;
- IFACEMETHODIMP get_BoundingRectangle(
- UiaRect* screen_physical_pixel_bounds) override;
- IFACEMETHODIMP GetEmbeddedFragmentRoots(
- SAFEARRAY** embedded_fragment_roots) override;
- IFACEMETHODIMP SetFocus() override;
- IFACEMETHODIMP get_FragmentRoot(
- IRawElementProviderFragmentRoot** fragment_root) override;
-
- //
- // IRawElementProviderSimple methods.
- //
-
- IFACEMETHODIMP GetPatternProvider(PATTERNID pattern_id,
- IUnknown** result) override;
-
- IFACEMETHODIMP GetPropertyValue(PROPERTYID property_id,
- VARIANT* result) override;
-
- IFACEMETHODIMP
- get_ProviderOptions(enum ProviderOptions* ret) override;
-
- IFACEMETHODIMP
- get_HostRawElementProvider(IRawElementProviderSimple** provider) override;
-
- //
- // IRawElementProviderSimple2 methods.
- //
-
- IFACEMETHODIMP ShowContextMenu() override;
-
- //
- // IChromeAccessible methods.
- //
-
- IFACEMETHODIMP get_bulkFetch(BSTR input_json,
- LONG request_id,
- IChromeAccessibleDelegate* delegate) override;
-
- IFACEMETHODIMP get_hitTest(LONG screen_physical_pixel_x,
- LONG screen_physical_pixel_y,
- LONG request_id,
- IChromeAccessibleDelegate* delegate) override;
-
- //
- // IServiceProvider methods.
- //
-
- IFACEMETHODIMP QueryService(REFGUID guidService,
- REFIID riid,
- void** object) override;
-
- //
- // Methods used by the ATL COM map.
- //
-
- // Called by BEGIN_COM_MAP() / END_COM_MAP().
- static STDMETHODIMP InternalQueryInterface(void* this_ptr,
- const _ATL_INTMAP_ENTRY* entries,
- REFIID riid,
- void** object);
-
- // Support method for ITextRangeProvider::GetAttributeValue.
- // If either |start_offset| or |end_offset| are not provided then the
- // endpoint is treated as the start or end of the node respectively.
- HRESULT GetTextAttributeValue(TEXTATTRIBUTEID attribute_id,
- const base::Optional<int>& start_offset,
- const base::Optional<int>& end_offset,
- base::win::VariantVector* result);
-
- // IRawElementProviderSimple support method.
- bool IsPatternProviderSupported(PATTERNID pattern_id);
-
- // Prefer GetPatternProviderImpl when calling internally. We should avoid
- // calling external APIs internally as it will cause the histograms to become
- // innaccurate.
- HRESULT GetPatternProviderImpl(PATTERNID pattern_id, IUnknown** result);
-
- // Prefer GetPropertyValueImpl when calling internally. We should avoid
- // calling external APIs internally as it will cause the histograms to become
- // innaccurate.
- HRESULT GetPropertyValueImpl(PROPERTYID property_id, VARIANT* result);
-
- // Helper to return the runtime id (without going through a SAFEARRAY)
- using RuntimeIdArray = std::array<int, 2>;
- void GetRuntimeIdArray(RuntimeIdArray& runtime_id);
-
- // Updates the active composition range and fires UIA text edit event about
- // composition (active or committed)
- void OnActiveComposition(const gfx::Range& range,
- const base::string16& active_composition_text,
- bool is_composition_committed);
- // Returns true if there is an active composition
- bool HasActiveComposition() const;
- // Returns the start/end offsets of the active composition
- gfx::Range GetActiveCompositionOffsets() const;
-
- // Helper to recursively find live-regions and fire a change event on them
- void FireLiveRegionChangeRecursive();
-
- // Returns the parent node that makes this node inaccessible.
- AXPlatformNodeWin* GetLowestAccessibleElement();
-
- // Returns the first |IsTextOnlyObject| descendant using
- // depth-first pre-order traversal.
- AXPlatformNodeWin* GetFirstTextOnlyDescendant();
-
- // Convert a mojo event to an MSAA event. Exposed for testing.
- static base::Optional<DWORD> MojoEventToMSAAEvent(ax::mojom::Event event);
-
- // Convert a mojo event to a UIA event. Exposed for testing.
- static base::Optional<EVENTID> MojoEventToUIAEvent(ax::mojom::Event event);
-
- // Convert a mojo event to a UIA property id. Exposed for testing.
- static base::Optional<PROPERTYID> MojoEventToUIAProperty(
- ax::mojom::Event event);
-
- protected:
- // This is hard-coded; all products based on the Chromium engine will have the
- // same framework name, so that assistive technology can detect any
- // Chromium-based product.
- static constexpr const base::char16* FRAMEWORK_ID = L"Chrome";
-
- AXPlatformNodeWin();
-
- int MSAAState() const;
-
- int MSAARole();
-
- int32_t ComputeIA2State();
-
- int32_t ComputeIA2Role();
-
- std::vector<base::string16> ComputeIA2Attributes();
-
- base::string16 UIAAriaRole();
-
- base::string16 ComputeUIAProperties();
-
- LONG ComputeUIAControlType();
-
- AXPlatformNodeWin* ComputeUIALabeledBy();
-
- bool CanHaveUIALabeledBy();
-
- bool IsNameExposed() const;
-
- bool IsUIAControl() const;
-
- base::Optional<LONG> ComputeUIALandmarkType() const;
-
- bool IsInaccessibleDueToAncestor() const;
-
- bool ShouldHideChildrenForUIA() const;
-
- ExpandCollapseState ComputeExpandCollapseState() const;
-
- // AXPlatformNodeBase overrides.
- void Dispose() override;
-
- // Relationships between this node and other nodes.
- std::vector<Microsoft::WRL::ComPtr<AXPlatformRelationWin>> relations_;
-
- AXHypertext old_hypertext_;
-
- // These protected methods are still used by BrowserAccessibilityComWin. At
- // some point post conversion, we can probably move these to be private
- // methods.
- //
- // Helper methods for IA2 hyperlinks.
- //
- // Hyperlink is an IA2 misnomer. It refers to objects embedded within other
- // objects, such as a numbered list within a contenteditable div.
- // Also, in IA2, text that includes embedded objects is called hypertext.
- // Returns true if the current object is an IA2 hyperlink.
- bool IsHyperlink();
- void ComputeHypertextRemovedAndInserted(size_t* start,
- size_t* old_len,
- size_t* new_len);
-
- // If offset is a member of IA2TextSpecialOffsets this function updates the
- // value of offset and returns, otherwise offset remains unchanged.
- void HandleSpecialTextOffset(LONG* offset);
-
- // A helper to add the given string value to |attributes|.
- void AddAttributeToList(const char* name,
- const char* value,
- PlatformAttributeList* attributes) override;
-
- // Escape special characters as specified by the IA2 spec.
- void SanitizeTextAttributeValue(const std::string& input,
- std::string* output) const override;
-
- // Escapes characters in string attributes as required by the IA2 Spec.
- // It's okay for input to be the same as output.
- static void SanitizeStringAttributeForIA2(const std::string& input,
- std::string* output);
- FRIEND_TEST_ALL_PREFIXES(AXPlatformNodeWinTest,
- SanitizeStringAttributeForIA2);
-
- private:
- bool IsWebAreaForPresentationalIframe();
- bool ShouldNodeHaveFocusableState(const AXNodeData& data) const;
-
- // Get the value attribute as a Bstr, this means something different depending
- // on the type of element being queried. (e.g. kColorWell uses kColorValue).
- static BSTR GetValueAttributeAsBstr(AXPlatformNodeWin* target);
-
- HRESULT GetStringAttributeAsBstr(ax::mojom::StringAttribute attribute,
- BSTR* value_bstr) const;
-
- HRESULT GetNameAsBstr(BSTR* value_bstr) const;
-
- // Sets the selection given a start and end offset in IA2 Hypertext.
- void SetIA2HypertextSelection(LONG start_offset, LONG end_offset);
-
- // Escapes characters in string attributes as required by the UIA Aria
- // Property Spec. It's okay for input to be the same as output.
- static void SanitizeStringAttributeForUIAAriaProperty(
- const base::string16& input,
- base::string16* output);
-
- // If the string attribute |attribute| is present, add its value as a
- // UIA AriaProperties Property with the name |uia_aria_property|.
- void StringAttributeToUIAAriaProperty(std::vector<base::string16>& properties,
- ax::mojom::StringAttribute attribute,
- const char* uia_aria_property);
-
- // If the bool attribute |attribute| is present, add its value as a
- // UIA AriaProperties Property with the name |uia_aria_property|.
- void BoolAttributeToUIAAriaProperty(std::vector<base::string16>& properties,
- ax::mojom::BoolAttribute attribute,
- const char* uia_aria_property);
-
- // If the int attribute |attribute| is present, add its value as a
- // UIA AriaProperties Property with the name |uia_aria_property|.
- void IntAttributeToUIAAriaProperty(std::vector<base::string16>& properties,
- ax::mojom::IntAttribute attribute,
- const char* uia_aria_property);
-
- // If the float attribute |attribute| is present, add its value as a
- // UIA AriaProperties Property with the name |uia_aria_property|.
- void FloatAttributeToUIAAriaProperty(std::vector<base::string16>& properties,
- ax::mojom::FloatAttribute attribute,
- const char* uia_aria_property);
-
- // If the state |state| exists, set the
- // UIA AriaProperties Property with the name |uia_aria_property| to "true".
- // Otherwise set the AriaProperties Property to "false".
- void StateToUIAAriaProperty(std::vector<base::string16>& properties,
- ax::mojom::State state,
- const char* uia_aria_property);
-
- // If the Html attribute |html_attribute_name| is present, add its value as a
- // UIA AriaProperties Property with the name |uia_aria_property|.
- void HtmlAttributeToUIAAriaProperty(std::vector<base::string16>& properties,
- const char* html_attribute_name,
- const char* uia_aria_property);
-
- // If the IntList attribute |attribute| is present, return an array
- // of automation elements referenced by the ids in the
- // IntList attribute. Otherwise return an empty array.
- // The function will skip over any ids that cannot be resolved.
- SAFEARRAY* CreateUIAElementsArrayForRelation(
- const ax::mojom::IntListAttribute& attribute);
-
- // Return an array of automation elements based on the attribute
- // IntList::kControlsIds for web content and IntAttribute::kViewPopupId. These
- // two attributes denote the controllees, web content elements and view popup
- // element respectively.
- // The function will skip over any ids that cannot be resolved.
- SAFEARRAY* CreateUIAControllerForArray();
-
- // Return an unordered array of automation elements which reference this node
- // for the given attribute.
- SAFEARRAY* CreateUIAElementsArrayForReverseRelation(
- const ax::mojom::IntListAttribute& attribute);
-
- // Return a vector of AXPlatformNodeWin referenced by the ids in function
- // argument. The function will skip over any ids that cannot be resolved as
- // valid relation target.
- std::vector<AXPlatformNodeWin*> CreatePlatformNodeVectorFromRelationIdVector(
- std::vector<int32_t>& relation_id_list);
-
- // Create a safearray of automation elements from a vector of
- // AXPlatformNodeWin.
- // The caller should validate that all of the given ax platform nodes are
- // valid relation targets.
- SAFEARRAY* CreateUIAElementsSafeArray(
- std::vector<AXPlatformNodeWin*>& platform_node_list);
-
- // Return an array that contains the center x, y coordinates of the
- // clickable point.
- SAFEARRAY* CreateClickablePointArray();
-
- // Returns the scroll offsets to which UI Automation should scroll an
- // accessible object, given the horizontal and vertical scroll amounts.
- gfx::Vector2d CalculateUIAScrollPoint(
- const ScrollAmount horizontal_amount,
- const ScrollAmount vertical_amount) const;
-
- void AddAlertTarget();
- void RemoveAlertTarget();
-
- // Enum used to specify whether IAccessibleText is requesting text
- // At, Before, or After a specified offset.
- enum class TextOffsetType { kAtOffset, kBeforeOffset, kAfterOffset };
-
- // Helper for implementing IAccessibleText::get_text{At|Before|After}Offset.
- HRESULT IAccessibleTextGetTextForOffsetType(
- TextOffsetType text_offset_type,
- LONG offset,
- enum IA2TextBoundaryType boundary_type,
- LONG* start_offset,
- LONG* end_offset,
- BSTR* text);
-
- // Search forwards or backwards from the given offset until the given IA2
- // text boundary is found, and return the offset of that boundary.
- LONG FindBoundary(IA2TextBoundaryType ia2_boundary,
- LONG start_offset,
- ax::mojom::MoveDirection direction);
-
- // Many MSAA methods take a var_id parameter indicating that the operation
- // should be performed on a particular child ID, rather than this object.
- // This method tries to figure out the target object from |var_id| and
- // returns a pointer to the target object if it exists, otherwise nullptr.
- // Does not return a new reference.
- AXPlatformNodeWin* GetTargetFromChildID(const VARIANT& var_id);
-
- // Returns true if this node is in a treegrid.
- bool IsInTreeGrid();
-
- // Helper method for returning selected indicies. It is expected that the
- // caller ensures that the input has been validated.
- HRESULT AllocateComArrayFromVector(std::vector<LONG>& results,
- LONG max,
- LONG** selected,
- LONG* n_selected);
-
- // Helper method for mutating the ISelectionItemProvider selected state
- HRESULT ISelectionItemProviderSetSelected(bool selected) const;
-
- // Helper method getting the selected status.
- bool ISelectionItemProviderIsSelected() const;
-
- //
- // Getters for UIA GetTextAttributeValue
- //
-
- // Computes the AnnotationTypes Attribute for the current node.
- HRESULT GetAnnotationTypesAttribute(const base::Optional<int>& start_offset,
- const base::Optional<int>& end_offset,
- base::win::VariantVector* result);
- // Lookup the LCID for the language this node is using.
- // Returns base::nullopt if there was an error.
- base::Optional<LCID> GetCultureAttributeAsLCID() const;
- // Converts an int attribute to a COLORREF
- COLORREF GetIntAttributeAsCOLORREF(ax::mojom::IntAttribute attribute) const;
- // Converts the ListStyle to UIA BulletStyle
- BulletStyle ComputeUIABulletStyle() const;
- // Helper to get the UIA StyleId enumeration for this node
- LONG ComputeUIAStyleId() const;
- // Convert mojom TextAlign to UIA HorizontalTextAlignment enumeration
- static base::Optional<HorizontalTextAlignment>
- AXTextAlignToUIAHorizontalTextAlignment(ax::mojom::TextAlign text_align);
- // Converts IntAttribute::kHierarchicalLevel to UIA StyleId enumeration
- static LONG AXHierarchicalLevelToUIAStyleId(int32_t hierarchical_level);
- // Converts a ListStyle to UIA StyleId enumeration
- static LONG AXListStyleToUIAStyleId(ax::mojom::ListStyle list_style);
- // Convert mojom TextDirection to UIA FlowDirections enumeration
- static FlowDirections TextDirectionToFlowDirections(
- ax::mojom::WritingDirection);
-
- // Helper method for |GetMarkerTypeFromRange| which aggregates all
- // of the ranges for |marker_type| attached to |node|.
- static void AggregateRangesForMarkerType(
- AXPlatformNodeBase* node,
- ax::mojom::MarkerType marker_type,
- int offset_ranges_amount,
- std::vector<std::pair<int, int>>* ranges);
-
- enum class MarkerTypeRangeResult {
- // The MarkerType does not overlap the range.
- kNone,
- // The MarkerType overlaps the entire range.
- kMatch,
- // The MarkerType partially overlaps the range.
- kMixed,
- };
-
- // Determine if a text range overlaps a |marker_type|, and whether
- // the overlap is a partial or or complete match.
- MarkerTypeRangeResult GetMarkerTypeFromRange(
- const base::Optional<int>& start_offset,
- const base::Optional<int>& end_offset,
- ax::mojom::MarkerType marker_type);
-
- bool IsAncestorComboBox();
-
- bool IsPlaceholderText() const;
-
- // Helper method for getting the horizontal scroll percent.
- double GetHorizontalScrollPercent();
-
- // Helper method for getting the vertical scroll percent.
- double GetVerticalScrollPercent();
-
- // Helper to get the UIA FontName for this node as a BSTR.
- BSTR GetFontNameAttributeAsBSTR() const;
-
- // Helper to get the UIA StyleName for this node as a BSTR.
- BSTR GetStyleNameAttributeAsBSTR() const;
-
- // Gets the TextDecorationLineStyle based on the provided int attribute.
- TextDecorationLineStyle GetUIATextDecorationStyle(
- const ax::mojom::IntAttribute int_attribute) const;
-
- // IRawElementProviderSimple support methods.
-
- using PatternProviderFactoryMethod = void (*)(AXPlatformNodeWin*, IUnknown**);
-
- PatternProviderFactoryMethod GetPatternProviderFactoryMethod(
- PATTERNID pattern_id);
-
- // Fires UIA text edit event about composition (active or committed)
- void FireUiaTextEditTextChangedEvent(
- const gfx::Range& range,
- const base::string16& active_composition_text,
- bool is_composition_committed);
-
- // Return true if the given element is valid enough to be returned as a value
- // for a UIA relation property (e.g. ControllerFor).
- static bool IsValidUiaRelationTarget(AXPlatformNode* ax_platform_node);
-
- // Start and end offsets of an active composition
- gfx::Range active_composition_range_;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_WIN_H_
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_win_unittest.cc b/third_party/accessibility/ax/platform/ax_platform_node_win_unittest.cc
deleted file mode 100644
index 5aa07d7..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_win_unittest.cc
+++ /dev/null
@@ -1,7017 +0,0 @@
-//
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_node_win_unittest.h"
-
-#include <oleacc.h>
-#include <wrl/client.h>
-
-#include <memory>
-
-#include "base/auto_reset.h"
-#include "base/json/json_reader.h"
-#include "base/run_loop.h"
-#include "base/stl_util.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/task_environment.h"
-#include "base/win/atl.h"
-#include "base/win/scoped_bstr.h"
-#include "base/win/scoped_safearray.h"
-#include "base/win/scoped_variant.h"
-#include "testing/gmock/include/gmock/gmock-matchers.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/iaccessible2/ia2_api_all.h"
-#include "ui/accessibility/accessibility_features.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/platform/ax_fragment_root_win.h"
-#include "ui/accessibility/platform/ax_platform_node_win.h"
-#include "ui/accessibility/platform/test_ax_node_wrapper.h"
-#include "ui/base/win/atl_module.h"
-
-using base::win::ScopedBstr;
-using base::win::ScopedVariant;
-using Microsoft::WRL::ComPtr;
-
-namespace ui {
-
-const base::string16 AXPlatformNodeWinTest::kEmbeddedCharacterAsString = {
- ui::AXPlatformNodeBase::kEmbeddedCharacter};
-
-namespace {
-
-// Most IAccessible functions require a VARIANT set to CHILDID_SELF as
-// the first argument.
-ScopedVariant SELF(CHILDID_SELF);
-
-} // namespace
-
-// Helper macros for UIAutomation HRESULT expectations
-#define EXPECT_UIA_ELEMENTNOTAVAILABLE(expr) \
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE), (expr))
-#define EXPECT_UIA_INVALIDOPERATION(expr) \
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_INVALIDOPERATION), (expr))
-#define EXPECT_UIA_ELEMENTNOTENABLED(expr) \
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTENABLED), (expr))
-#define EXPECT_UIA_NOTSUPPORTED(expr) \
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_NOTSUPPORTED), (expr))
-
-#define ASSERT_UIA_ELEMENTNOTAVAILABLE(expr) \
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE), (expr))
-#define ASSERT_UIA_INVALIDOPERATION(expr) \
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_INVALIDOPERATION), (expr))
-#define ASSERT_UIA_ELEMENTNOTENABLED(expr) \
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTENABLED), (expr))
-#define ASSERT_UIA_NOTSUPPORTED(expr) \
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_NOTSUPPORTED), (expr))
-
-// Helper macros for testing UIAutomation property values and maintain
-// correct stack tracing and failure causality.
-//
-// WARNING: These aren't intended to be generic EXPECT_BSTR_EQ macros
-// as the logic is specific to extracting and comparing UIA property
-// values.
-#define EXPECT_UIA_EMPTY(node, property_id) \
- { \
- ScopedVariant actual; \
- ASSERT_HRESULT_SUCCEEDED( \
- node->GetPropertyValue(property_id, actual.Receive())); \
- EXPECT_EQ(VT_EMPTY, actual.type()); \
- }
-
-#define EXPECT_UIA_VALUE_EQ(node, property_id, expectedVariant) \
- { \
- ScopedVariant actual; \
- ASSERT_HRESULT_SUCCEEDED( \
- node->GetPropertyValue(property_id, actual.Receive())); \
- EXPECT_EQ(0, actual.Compare(expectedVariant)); \
- }
-
-#define EXPECT_UIA_BSTR_EQ(node, property_id, expected) \
- { \
- ScopedVariant expectedVariant(expected); \
- ASSERT_EQ(VT_BSTR, expectedVariant.type()); \
- ASSERT_NE(nullptr, expectedVariant.ptr()->bstrVal); \
- ScopedVariant actual; \
- ASSERT_HRESULT_SUCCEEDED( \
- node->GetPropertyValue(property_id, actual.Receive())); \
- ASSERT_EQ(VT_BSTR, actual.type()); \
- ASSERT_NE(nullptr, actual.ptr()->bstrVal); \
- EXPECT_STREQ(expectedVariant.ptr()->bstrVal, actual.ptr()->bstrVal); \
- }
-
-#define EXPECT_UIA_BOOL_EQ(node, property_id, expected) \
- { \
- ScopedVariant expectedVariant(expected); \
- ASSERT_EQ(VT_BOOL, expectedVariant.type()); \
- ScopedVariant actual; \
- ASSERT_HRESULT_SUCCEEDED( \
- node->GetPropertyValue(property_id, actual.Receive())); \
- EXPECT_EQ(expectedVariant.ptr()->boolVal, actual.ptr()->boolVal); \
- }
-
-#define EXPECT_UIA_DOUBLE_ARRAY_EQ(node, array_property_id, \
- expected_property_values) \
- { \
- ScopedVariant array; \
- ASSERT_HRESULT_SUCCEEDED( \
- node->GetPropertyValue(array_property_id, array.Receive())); \
- ASSERT_EQ(VT_ARRAY | VT_R8, array.type()); \
- ASSERT_EQ(1u, SafeArrayGetDim(array.ptr()->parray)); \
- LONG array_lower_bound; \
- ASSERT_HRESULT_SUCCEEDED( \
- SafeArrayGetLBound(array.ptr()->parray, 1, &array_lower_bound)); \
- LONG array_upper_bound; \
- ASSERT_HRESULT_SUCCEEDED( \
- SafeArrayGetUBound(array.ptr()->parray, 1, &array_upper_bound)); \
- double* array_data; \
- ASSERT_HRESULT_SUCCEEDED(::SafeArrayAccessData( \
- array.ptr()->parray, reinterpret_cast<void**>(&array_data))); \
- size_t count = array_upper_bound - array_lower_bound + 1; \
- ASSERT_EQ(expected_property_values.size(), count); \
- for (size_t i = 0; i < count; ++i) { \
- EXPECT_EQ(array_data[i], expected_property_values[i]); \
- } \
- ASSERT_HRESULT_SUCCEEDED(::SafeArrayUnaccessData(array.ptr()->parray)); \
- }
-
-#define EXPECT_UIA_INT_EQ(node, property_id, expected) \
- { \
- ScopedVariant expectedVariant(expected); \
- ASSERT_EQ(VT_I4, expectedVariant.type()); \
- ScopedVariant actual; \
- ASSERT_HRESULT_SUCCEEDED( \
- node->GetPropertyValue(property_id, actual.Receive())); \
- EXPECT_EQ(expectedVariant.ptr()->intVal, actual.ptr()->intVal); \
- }
-
-#define EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(array, element_test_property_id, \
- expected_property_values) \
- { \
- ASSERT_EQ(1u, SafeArrayGetDim(array)); \
- LONG array_lower_bound; \
- ASSERT_HRESULT_SUCCEEDED( \
- SafeArrayGetLBound(array, 1, &array_lower_bound)); \
- LONG array_upper_bound; \
- ASSERT_HRESULT_SUCCEEDED( \
- SafeArrayGetUBound(array, 1, &array_upper_bound)); \
- IUnknown** array_data; \
- ASSERT_HRESULT_SUCCEEDED( \
- ::SafeArrayAccessData(array, reinterpret_cast<void**>(&array_data))); \
- size_t count = array_upper_bound - array_lower_bound + 1; \
- ASSERT_EQ(expected_property_values.size(), count); \
- for (size_t i = 0; i < count; ++i) { \
- ComPtr<IRawElementProviderSimple> element; \
- ASSERT_HRESULT_SUCCEEDED( \
- array_data[i]->QueryInterface(IID_PPV_ARGS(&element))); \
- EXPECT_UIA_BSTR_EQ(element, element_test_property_id, \
- expected_property_values[i].c_str()); \
- } \
- ASSERT_HRESULT_SUCCEEDED(::SafeArrayUnaccessData(array)); \
- }
-
-#define EXPECT_UIA_PROPERTY_ELEMENT_ARRAY_BSTR_EQ(node, array_property_id, \
- element_test_property_id, \
- expected_property_values) \
- { \
- ScopedVariant array; \
- ASSERT_HRESULT_SUCCEEDED( \
- node->GetPropertyValue(array_property_id, array.Receive())); \
- ASSERT_EQ(VT_ARRAY | VT_UNKNOWN, array.type()); \
- EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(array.ptr()->parray, \
- element_test_property_id, \
- expected_property_values); \
- }
-
-#define EXPECT_UIA_PROPERTY_UNORDERED_ELEMENT_ARRAY_BSTR_EQ( \
- node, array_property_id, element_test_property_id, \
- expected_property_values) \
- { \
- ScopedVariant array; \
- ASSERT_HRESULT_SUCCEEDED( \
- node->GetPropertyValue(array_property_id, array.Receive())); \
- ASSERT_EQ(VT_ARRAY | VT_UNKNOWN, array.type()); \
- ASSERT_EQ(1u, SafeArrayGetDim(array.ptr()->parray)); \
- LONG array_lower_bound; \
- ASSERT_HRESULT_SUCCEEDED( \
- SafeArrayGetLBound(array.ptr()->parray, 1, &array_lower_bound)); \
- LONG array_upper_bound; \
- ASSERT_HRESULT_SUCCEEDED( \
- SafeArrayGetUBound(array.ptr()->parray, 1, &array_upper_bound)); \
- IUnknown** array_data; \
- ASSERT_HRESULT_SUCCEEDED(::SafeArrayAccessData( \
- array.ptr()->parray, reinterpret_cast<void**>(&array_data))); \
- size_t count = array_upper_bound - array_lower_bound + 1; \
- ASSERT_EQ(expected_property_values.size(), count); \
- std::vector<std::wstring> property_values; \
- for (size_t i = 0; i < count; ++i) { \
- ComPtr<IRawElementProviderSimple> element; \
- ASSERT_HRESULT_SUCCEEDED( \
- array_data[i]->QueryInterface(IID_PPV_ARGS(&element))); \
- ScopedVariant actual; \
- ASSERT_HRESULT_SUCCEEDED(element->GetPropertyValue( \
- element_test_property_id, actual.Receive())); \
- ASSERT_EQ(VT_BSTR, actual.type()); \
- ASSERT_NE(nullptr, actual.ptr()->bstrVal); \
- property_values.push_back(std::wstring( \
- V_BSTR(actual.ptr()), SysStringLen(V_BSTR(actual.ptr())))); \
- } \
- ASSERT_HRESULT_SUCCEEDED(::SafeArrayUnaccessData(array.ptr()->parray)); \
- EXPECT_THAT(property_values, \
- testing::UnorderedElementsAreArray(expected_property_values)); \
- }
-
-MockIRawElementProviderSimple::MockIRawElementProviderSimple() = default;
-MockIRawElementProviderSimple::~MockIRawElementProviderSimple() = default;
-
-HRESULT
-MockIRawElementProviderSimple::CreateMockIRawElementProviderSimple(
- IRawElementProviderSimple** provider) {
- CComObject<MockIRawElementProviderSimple>* raw_element_provider = nullptr;
- HRESULT hr = CComObject<MockIRawElementProviderSimple>::CreateInstance(
- &raw_element_provider);
- if (SUCCEEDED(hr)) {
- *provider = raw_element_provider;
- }
-
- return hr;
-}
-
-//
-// IRawElementProviderSimple methods.
-//
-IFACEMETHODIMP MockIRawElementProviderSimple::GetPatternProvider(
- PATTERNID pattern_id,
- IUnknown** result) {
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP MockIRawElementProviderSimple::GetPropertyValue(
- PROPERTYID property_id,
- VARIANT* result) {
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP
-MockIRawElementProviderSimple::get_ProviderOptions(enum ProviderOptions* ret) {
- return E_NOTIMPL;
-}
-
-IFACEMETHODIMP MockIRawElementProviderSimple::get_HostRawElementProvider(
- IRawElementProviderSimple** provider) {
- return E_NOTIMPL;
-}
-
-AXPlatformNodeWinTest::AXPlatformNodeWinTest() {
- scoped_feature_list_.InitAndEnableFeature(features::kIChromeAccessible);
-}
-
-AXPlatformNodeWinTest::~AXPlatformNodeWinTest() {}
-
-void AXPlatformNodeWinTest::SetUp() {
- win::CreateATLModuleIfNeeded();
-}
-
-void AXPlatformNodeWinTest::TearDown() {
- // Destroy the tree and make sure we're not leaking any objects.
- ax_fragment_root_.reset(nullptr);
- DestroyTree();
- TestAXNodeWrapper::SetGlobalIsWebContent(false);
- ASSERT_EQ(0U, AXPlatformNodeBase::GetInstanceCountForTesting());
-}
-
-AXPlatformNode* AXPlatformNodeWinTest::AXPlatformNodeFromNode(AXNode* node) {
- const TestAXNodeWrapper* wrapper =
- TestAXNodeWrapper::GetOrCreate(GetTree(), node);
- return wrapper ? wrapper->ax_platform_node() : nullptr;
-}
-
-template <typename T>
-ComPtr<T> AXPlatformNodeWinTest::QueryInterfaceFromNodeId(AXNode::AXID id) {
- return QueryInterfaceFromNode<T>(GetNodeFromTree(id));
-}
-
-template <typename T>
-ComPtr<T> AXPlatformNodeWinTest::QueryInterfaceFromNode(AXNode* node) {
- AXPlatformNode* ax_platform_node = AXPlatformNodeFromNode(node);
- if (!ax_platform_node)
- return ComPtr<T>();
- ComPtr<T> result;
- EXPECT_HRESULT_SUCCEEDED(
- ax_platform_node->GetNativeViewAccessible()->QueryInterface(__uuidof(T),
- &result));
- return result;
-}
-
-ComPtr<IRawElementProviderSimple>
-AXPlatformNodeWinTest::GetRootIRawElementProviderSimple() {
- return QueryInterfaceFromNode<IRawElementProviderSimple>(GetRootAsAXNode());
-}
-
-ComPtr<IRawElementProviderSimple>
-AXPlatformNodeWinTest::GetIRawElementProviderSimpleFromChildIndex(
- int child_index) {
- if (!GetRootAsAXNode() || child_index < 0 ||
- size_t{child_index} >= GetRootAsAXNode()->children().size()) {
- return ComPtr<IRawElementProviderSimple>();
- }
-
- return QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetRootAsAXNode()->children()[size_t{child_index}]);
-}
-
-Microsoft::WRL::ComPtr<IRawElementProviderSimple>
-AXPlatformNodeWinTest::GetIRawElementProviderSimpleFromTree(
- const ui::AXTreeID tree_id,
- const AXNode::AXID node_id) {
- return QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetNodeFromTree(tree_id, node_id));
-}
-
-ComPtr<IRawElementProviderFragment>
-AXPlatformNodeWinTest::GetRootIRawElementProviderFragment() {
- return QueryInterfaceFromNode<IRawElementProviderFragment>(GetRootAsAXNode());
-}
-
-Microsoft::WRL::ComPtr<IRawElementProviderFragment>
-AXPlatformNodeWinTest::IRawElementProviderFragmentFromNode(AXNode* node) {
- AXPlatformNode* platform_node = AXPlatformNodeFromNode(node);
- gfx::NativeViewAccessible native_view =
- platform_node->GetNativeViewAccessible();
- ComPtr<IUnknown> unknown_node = native_view;
- ComPtr<IRawElementProviderFragment> fragment_node;
- unknown_node.As(&fragment_node);
-
- return fragment_node;
-}
-
-ComPtr<IAccessible> AXPlatformNodeWinTest::IAccessibleFromNode(AXNode* node) {
- return QueryInterfaceFromNode<IAccessible>(node);
-}
-
-ComPtr<IAccessible> AXPlatformNodeWinTest::GetRootIAccessible() {
- return IAccessibleFromNode(GetRootAsAXNode());
-}
-
-ComPtr<IAccessible2> AXPlatformNodeWinTest::ToIAccessible2(
- ComPtr<IUnknown> unknown) {
- CHECK(unknown);
- ComPtr<IServiceProvider> service_provider;
- unknown.As(&service_provider);
- ComPtr<IAccessible2> result;
- CHECK(SUCCEEDED(
- service_provider->QueryService(IID_IAccessible2, IID_PPV_ARGS(&result))));
- return result;
-}
-
-ComPtr<IAccessible2> AXPlatformNodeWinTest::ToIAccessible2(
- ComPtr<IAccessible> accessible) {
- CHECK(accessible);
- ComPtr<IServiceProvider> service_provider;
- accessible.As(&service_provider);
- ComPtr<IAccessible2> result;
- CHECK(SUCCEEDED(
- service_provider->QueryService(IID_IAccessible2, IID_PPV_ARGS(&result))));
- return result;
-}
-
-ComPtr<IAccessible2_2> AXPlatformNodeWinTest::ToIAccessible2_2(
- ComPtr<IAccessible> accessible) {
- CHECK(accessible);
- ComPtr<IServiceProvider> service_provider;
- accessible.As(&service_provider);
- ComPtr<IAccessible2_2> result;
- CHECK(SUCCEEDED(service_provider->QueryService(IID_IAccessible2_2,
- IID_PPV_ARGS(&result))));
- return result;
-}
-
-void AXPlatformNodeWinTest::CheckVariantHasName(const ScopedVariant& variant,
- const wchar_t* expected_name) {
- ASSERT_NE(nullptr, variant.ptr());
- ComPtr<IAccessible> accessible;
- ASSERT_HRESULT_SUCCEEDED(
- V_DISPATCH(variant.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)));
- ScopedBstr name;
- EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive()));
- EXPECT_STREQ(expected_name, name.Get());
-}
-
-void AXPlatformNodeWinTest::CheckIUnknownHasName(ComPtr<IUnknown> unknown,
- const wchar_t* expected_name) {
- ComPtr<IAccessible2> accessible = ToIAccessible2(unknown);
- ASSERT_NE(nullptr, accessible.Get());
-
- ScopedBstr name;
- EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive()));
- EXPECT_STREQ(expected_name, name.Get());
-}
-
-ComPtr<IAccessibleTableCell> AXPlatformNodeWinTest::GetCellInTable() {
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable2> table;
- root_obj.As(&table);
- if (!table)
- return ComPtr<IAccessibleTableCell>();
-
- ComPtr<IUnknown> cell;
- table->get_cellAt(1, 1, &cell);
- if (!cell)
- return ComPtr<IAccessibleTableCell>();
-
- ComPtr<IAccessibleTableCell> table_cell;
- cell.As(&table_cell);
- return table_cell;
-}
-
-void AXPlatformNodeWinTest::InitFragmentRoot() {
- test_fragment_root_delegate_ = std::make_unique<TestFragmentRootDelegate>();
- ax_fragment_root_.reset(InitNodeAsFragmentRoot(
- GetRootAsAXNode(), test_fragment_root_delegate_.get()));
-}
-
-AXFragmentRootWin* AXPlatformNodeWinTest::InitNodeAsFragmentRoot(
- AXNode* node,
- TestFragmentRootDelegate* delegate) {
- delegate->child_ = AXPlatformNodeFromNode(node)->GetNativeViewAccessible();
- if (node->parent())
- delegate->parent_ =
- AXPlatformNodeFromNode(node->parent())->GetNativeViewAccessible();
-
- return new AXFragmentRootWin(gfx::kMockAcceleratedWidget, delegate);
-}
-
-ComPtr<IRawElementProviderFragmentRoot>
-AXPlatformNodeWinTest::GetFragmentRoot() {
- ComPtr<IRawElementProviderFragmentRoot> fragment_root_provider;
- ax_fragment_root_->GetNativeViewAccessible()->QueryInterface(
- IID_PPV_ARGS(&fragment_root_provider));
- return fragment_root_provider;
-}
-
-AXPlatformNodeWinTest::PatternSet
-AXPlatformNodeWinTest::GetSupportedPatternsFromNodeId(AXNode::AXID id) {
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- QueryInterfaceFromNodeId<IRawElementProviderSimple>(id);
- PatternSet supported_patterns;
- static const std::vector<LONG> all_supported_patterns_ = {
- UIA_TextChildPatternId, UIA_TextEditPatternId,
- UIA_TextPatternId, UIA_WindowPatternId,
- UIA_InvokePatternId, UIA_ExpandCollapsePatternId,
- UIA_GridPatternId, UIA_GridItemPatternId,
- UIA_RangeValuePatternId, UIA_ScrollPatternId,
- UIA_ScrollItemPatternId, UIA_TablePatternId,
- UIA_TableItemPatternId, UIA_SelectionItemPatternId,
- UIA_SelectionPatternId, UIA_TogglePatternId,
- UIA_ValuePatternId,
- };
- for (LONG property_id : all_supported_patterns_) {
- ComPtr<IUnknown> provider;
- if (SUCCEEDED(raw_element_provider_simple->GetPatternProvider(property_id,
- &provider)) &&
- provider) {
- supported_patterns.insert(property_id);
- }
- }
- return supported_patterns;
-}
-
-TestFragmentRootDelegate::TestFragmentRootDelegate() = default;
-
-TestFragmentRootDelegate::~TestFragmentRootDelegate() = default;
-
-gfx::NativeViewAccessible TestFragmentRootDelegate::GetChildOfAXFragmentRoot() {
- return child_;
-}
-
-gfx::NativeViewAccessible
-TestFragmentRootDelegate::GetParentOfAXFragmentRoot() {
- return parent_;
-}
-
-bool TestFragmentRootDelegate::IsAXFragmentRootAControlElement() {
- return is_control_element_;
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleDetachedObject) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.SetName("Name");
- Init(root);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ScopedBstr name;
- EXPECT_EQ(S_OK, root_obj->get_accName(SELF, name.Receive()));
- EXPECT_STREQ(L"Name", name.Get());
-
- // Create an empty tree.
- SetTree(std::make_unique<AXTree>());
- ScopedBstr name2;
- EXPECT_EQ(E_FAIL, root_obj->get_accName(SELF, name2.Receive()));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleHitTest) {
- AXNodeData root;
- root.id = 1;
- root.relative_bounds.bounds = gfx::RectF(0, 0, 40, 40);
-
- AXNodeData node1;
- node1.id = 2;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.relative_bounds.bounds = gfx::RectF(0, 0, 10, 10);
- node1.SetName("Name1");
- root.child_ids.push_back(node1.id);
-
- AXNodeData node2;
- node2.id = 3;
- node2.role = ax::mojom::Role::kGenericContainer;
- node2.relative_bounds.bounds = gfx::RectF(20, 20, 20, 20);
- node2.SetName("Name2");
- root.child_ids.push_back(node2.id);
-
- Init(root, node1, node2);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- // This is way outside of the root node.
- ScopedVariant obj_1;
- EXPECT_EQ(S_FALSE, root_obj->accHitTest(50, 50, obj_1.Receive()));
- EXPECT_EQ(VT_EMPTY, obj_1.type());
-
- // This is directly on node 1.
- EXPECT_EQ(S_OK, root_obj->accHitTest(5, 5, obj_1.Receive()));
- ASSERT_NE(nullptr, obj_1.ptr());
- CheckVariantHasName(obj_1, L"Name1");
-
- // This is directly on node 2 with a scale factor of 1.5.
- ScopedVariant obj_2;
- std::unique_ptr<base::AutoReset<float>> scale_factor_reset =
- TestAXNodeWrapper::SetScaleFactor(1.5);
- EXPECT_EQ(S_OK, root_obj->accHitTest(38, 38, obj_2.Receive()));
- ASSERT_NE(nullptr, obj_2.ptr());
- CheckVariantHasName(obj_2, L"Name2");
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleHitTestDoesNotLoopForever) {
- AXNodeData root;
- root.id = 1;
- root.relative_bounds.bounds = gfx::RectF(0, 0, 40, 40);
-
- AXNodeData node1;
- node1.id = 2;
- node1.role = ax::mojom::Role::kGenericContainer;
- node1.relative_bounds.bounds = gfx::RectF(0, 0, 10, 10);
- node1.SetName("Name1");
- root.child_ids.push_back(node1.id);
-
- Init(root, node1);
-
- // Set up the endless loop.
- TestAXNodeWrapper::SetHitTestResult(1, 2);
- TestAXNodeWrapper::SetHitTestResult(2, 1);
-
- // Hit testing on the root returns the child. Hit testing on the
- // child returns the root, but that should be rejected rather than
- // looping endlessly.
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ScopedVariant obj_1;
- EXPECT_EQ(S_OK, root_obj->accHitTest(5, 5, obj_1.Receive()));
- ASSERT_NE(nullptr, obj_1.ptr());
- CheckVariantHasName(obj_1, L"Name1");
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleName) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.SetName("Name");
- Init(root);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ScopedBstr name;
- EXPECT_EQ(S_OK, root_obj->get_accName(SELF, name.Receive()));
- EXPECT_STREQ(L"Name", name.Get());
-
- EXPECT_EQ(E_INVALIDARG, root_obj->get_accName(SELF, nullptr));
- ScopedVariant bad_id(999);
- ScopedBstr name2;
- EXPECT_EQ(E_INVALIDARG, root_obj->get_accName(bad_id, name2.Receive()));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleDescription) {
- AXNodeData root;
- root.id = 1;
- root.AddStringAttribute(ax::mojom::StringAttribute::kDescription,
- "Description");
- Init(root);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ScopedBstr description;
- EXPECT_EQ(S_OK, root_obj->get_accDescription(SELF, description.Receive()));
- EXPECT_STREQ(L"Description", description.Get());
-
- EXPECT_EQ(E_INVALIDARG, root_obj->get_accDescription(SELF, nullptr));
- ScopedVariant bad_id(999);
- ScopedBstr d2;
- EXPECT_EQ(E_INVALIDARG, root_obj->get_accDescription(bad_id, d2.Receive()));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleAccValue) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTextField;
- root.AddStringAttribute(ax::mojom::StringAttribute::kValue, "Value");
- Init(root);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ScopedBstr value;
- EXPECT_EQ(S_OK, root_obj->get_accValue(SELF, value.Receive()));
- EXPECT_STREQ(L"Value", value.Get());
-
- EXPECT_EQ(E_INVALIDARG, root_obj->get_accValue(SELF, nullptr));
- ScopedVariant bad_id(999);
- ScopedBstr v2;
- EXPECT_EQ(E_INVALIDARG, root_obj->get_accValue(bad_id, v2.Receive()));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleShortcut) {
- AXNodeData root;
- root.id = 1;
- root.AddStringAttribute(ax::mojom::StringAttribute::kKeyShortcuts,
- "Shortcut");
- Init(root);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ScopedBstr shortcut;
- EXPECT_EQ(S_OK, root_obj->get_accKeyboardShortcut(SELF, shortcut.Receive()));
- EXPECT_STREQ(L"Shortcut", shortcut.Get());
-
- EXPECT_EQ(E_INVALIDARG, root_obj->get_accKeyboardShortcut(SELF, nullptr));
- ScopedVariant bad_id(999);
- ScopedBstr k2;
- EXPECT_EQ(E_INVALIDARG,
- root_obj->get_accKeyboardShortcut(bad_id, k2.Receive()));
-}
-
-TEST_F(AXPlatformNodeWinTest,
- IAccessibleSelectionListBoxOptionNothingSelected) {
- AXNodeData list;
- list.id = 1;
- list.role = ax::mojom::Role::kListBox;
-
- AXNodeData list_item_1;
- list_item_1.id = 2;
- list_item_1.role = ax::mojom::Role::kListBoxOption;
- list_item_1.SetName("Name1");
-
- AXNodeData list_item_2;
- list_item_2.id = 3;
- list_item_2.role = ax::mojom::Role::kListBoxOption;
- list_item_2.SetName("Name2");
-
- list.child_ids.push_back(list_item_1.id);
- list.child_ids.push_back(list_item_2.id);
-
- Init(list, list_item_1, list_item_2);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ASSERT_NE(nullptr, root_obj.Get());
-
- ScopedVariant selection;
- EXPECT_EQ(S_OK, root_obj->get_accSelection(selection.Receive()));
- EXPECT_EQ(VT_EMPTY, selection.type());
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleSelectionListBoxOptionOneSelected) {
- AXNodeData list;
- list.id = 1;
- list.role = ax::mojom::Role::kListBox;
-
- AXNodeData list_item_1;
- list_item_1.id = 2;
- list_item_1.role = ax::mojom::Role::kListBoxOption;
- list_item_1.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- list_item_1.SetName("Name1");
-
- AXNodeData list_item_2;
- list_item_2.id = 3;
- list_item_2.role = ax::mojom::Role::kListBoxOption;
- list_item_2.SetName("Name2");
-
- list.child_ids.push_back(list_item_1.id);
- list.child_ids.push_back(list_item_2.id);
-
- Init(list, list_item_1, list_item_2);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ASSERT_NE(nullptr, root_obj.Get());
-
- ScopedVariant selection;
- EXPECT_EQ(S_OK, root_obj->get_accSelection(selection.Receive()));
- EXPECT_EQ(VT_DISPATCH, selection.type());
-
- CheckVariantHasName(selection, L"Name1");
-}
-
-TEST_F(AXPlatformNodeWinTest,
- IAccessibleSelectionListBoxOptionMultipleSelected) {
- AXNodeData list;
- list.id = 1;
- list.role = ax::mojom::Role::kListBox;
-
- AXNodeData list_item_1;
- list_item_1.id = 2;
- list_item_1.role = ax::mojom::Role::kListBoxOption;
- list_item_1.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- list_item_1.SetName("Name1");
-
- AXNodeData list_item_2;
- list_item_2.id = 3;
- list_item_2.role = ax::mojom::Role::kListBoxOption;
- list_item_2.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- list_item_2.SetName("Name2");
-
- AXNodeData list_item_3;
- list_item_3.id = 4;
- list_item_3.role = ax::mojom::Role::kListBoxOption;
- list_item_3.SetName("Name3");
-
- list.child_ids.push_back(list_item_1.id);
- list.child_ids.push_back(list_item_2.id);
- list.child_ids.push_back(list_item_3.id);
-
- Init(list, list_item_1, list_item_2, list_item_3);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ASSERT_NE(nullptr, root_obj.Get());
-
- ScopedVariant selection;
- EXPECT_EQ(S_OK, root_obj->get_accSelection(selection.Receive()));
- EXPECT_EQ(VT_UNKNOWN, selection.type());
- ASSERT_NE(nullptr, selection.ptr());
-
- // Loop through the selections and make sure we have the right ones.
- ComPtr<IEnumVARIANT> accessibles;
- ASSERT_HRESULT_SUCCEEDED(
- V_UNKNOWN(selection.ptr())->QueryInterface(IID_PPV_ARGS(&accessibles)));
- ULONG retrieved_count;
-
- // Check out the first selected item.
- {
- ScopedVariant item;
- HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count);
- EXPECT_EQ(S_OK, hr);
-
- ComPtr<IAccessible> accessible;
- ASSERT_HRESULT_SUCCEEDED(
- V_DISPATCH(item.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)));
- ScopedBstr name;
- EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive()));
- EXPECT_STREQ(L"Name1", name.Get());
- }
-
- // And the second selected element.
- {
- ScopedVariant item;
- HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count);
- EXPECT_EQ(S_OK, hr);
-
- ComPtr<IAccessible> accessible;
- ASSERT_HRESULT_SUCCEEDED(
- V_DISPATCH(item.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)));
- ScopedBstr name;
- EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive()));
- EXPECT_STREQ(L"Name2", name.Get());
- }
-
- // There shouldn't be any more selected.
- {
- ScopedVariant item;
- HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count);
- EXPECT_EQ(S_FALSE, hr);
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleSelectionTableNothingSelected) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ASSERT_NE(nullptr, root_obj.Get());
-
- ScopedVariant selection;
- EXPECT_EQ(S_OK, root_obj->get_accSelection(selection.Receive()));
- EXPECT_EQ(VT_EMPTY, selection.type());
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleSelectionTableRowOneSelected) {
- AXTreeUpdate update = Build3X3Table();
-
- // 5 == table_row_1
- update.nodes[5].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ASSERT_NE(nullptr, root_obj.Get());
-
- ScopedVariant selection;
- EXPECT_EQ(S_OK, root_obj->get_accSelection(selection.Receive()));
- EXPECT_EQ(VT_DISPATCH, selection.type());
- ASSERT_NE(nullptr, selection.ptr());
-
- ComPtr<IAccessible> row;
- ASSERT_HRESULT_SUCCEEDED(
- V_DISPATCH(selection.ptr())->QueryInterface(IID_PPV_ARGS(&row)));
-
- ScopedVariant role;
- EXPECT_HRESULT_SUCCEEDED(row->get_accRole(SELF, role.Receive()));
- EXPECT_EQ(ROLE_SYSTEM_ROW, V_I4(role.ptr()));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleSelectionTableRowMultipleSelected) {
- AXTreeUpdate update = Build3X3Table();
-
- // 5 == table_row_1
- // 9 == table_row_2
- update.nodes[5].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[9].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ASSERT_NE(nullptr, root_obj.Get());
-
- ScopedVariant selection;
- EXPECT_EQ(S_OK, root_obj->get_accSelection(selection.Receive()));
- EXPECT_EQ(VT_UNKNOWN, selection.type());
- ASSERT_NE(nullptr, selection.ptr());
-
- // Loop through the selections and make sure we have the right ones.
- ComPtr<IEnumVARIANT> accessibles;
- ASSERT_HRESULT_SUCCEEDED(
- V_UNKNOWN(selection.ptr())->QueryInterface(IID_PPV_ARGS(&accessibles)));
- ULONG retrieved_count;
-
- // Check out the first selected row.
- {
- ScopedVariant item;
- HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count);
- EXPECT_EQ(S_OK, hr);
-
- ComPtr<IAccessible> accessible;
- ASSERT_HRESULT_SUCCEEDED(
- V_DISPATCH(item.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)));
- ScopedVariant role;
- EXPECT_HRESULT_SUCCEEDED(accessible->get_accRole(SELF, role.Receive()));
- EXPECT_EQ(ROLE_SYSTEM_ROW, V_I4(role.ptr()));
- }
-
- // And the second selected element.
- {
- ScopedVariant item;
- HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count);
- EXPECT_EQ(S_OK, hr);
-
- ComPtr<IAccessible> accessible;
- ASSERT_HRESULT_SUCCEEDED(
- V_DISPATCH(item.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)));
- ScopedVariant role;
- EXPECT_HRESULT_SUCCEEDED(accessible->get_accRole(SELF, role.Receive()));
- EXPECT_EQ(ROLE_SYSTEM_ROW, V_I4(role.ptr()));
- }
-
- // There shouldn't be any more selected.
- {
- ScopedVariant item;
- HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count);
- EXPECT_EQ(S_FALSE, hr);
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleSelectionTableCellOneSelected) {
- AXTreeUpdate update = Build3X3Table();
-
- // 7 == table_cell_1
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ASSERT_NE(nullptr, root_obj.Get());
-
- ComPtr<IDispatch> row2;
- ASSERT_HRESULT_SUCCEEDED(root_obj->get_accChild(ScopedVariant(2), &row2));
- ComPtr<IAccessible> row2_accessible;
- ASSERT_HRESULT_SUCCEEDED(row2.As(&row2_accessible));
-
- ScopedVariant selection;
- EXPECT_EQ(S_OK, row2_accessible->get_accSelection(selection.Receive()));
- EXPECT_EQ(VT_DISPATCH, selection.type());
- ASSERT_NE(nullptr, selection.ptr());
-
- ComPtr<IAccessible> cell;
- ASSERT_HRESULT_SUCCEEDED(
- V_DISPATCH(selection.ptr())->QueryInterface(IID_PPV_ARGS(&cell)));
-
- ScopedVariant role;
- EXPECT_HRESULT_SUCCEEDED(cell->get_accRole(SELF, role.Receive()));
- EXPECT_EQ(ROLE_SYSTEM_CELL, V_I4(role.ptr()));
-
- ScopedBstr name;
- EXPECT_EQ(S_OK, cell->get_accName(SELF, name.Receive()));
- EXPECT_STREQ(L"1", name.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleSelectionTableCellMultipleSelected) {
- AXTreeUpdate update = Build3X3Table();
-
- // 11 == table_cell_3
- // 12 == table_cell_4
- update.nodes[11].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[12].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ASSERT_NE(nullptr, root_obj.Get());
-
- ComPtr<IDispatch> row3;
- ASSERT_HRESULT_SUCCEEDED(root_obj->get_accChild(ScopedVariant(3), &row3));
- ComPtr<IAccessible> row3_accessible;
- ASSERT_HRESULT_SUCCEEDED(row3.As(&row3_accessible));
-
- ScopedVariant selection;
- EXPECT_EQ(S_OK, row3_accessible->get_accSelection(selection.Receive()));
- EXPECT_EQ(VT_UNKNOWN, selection.type());
- ASSERT_NE(nullptr, selection.ptr());
-
- // Loop through the selections and make sure we have the right ones.
- ComPtr<IEnumVARIANT> accessibles;
- ASSERT_HRESULT_SUCCEEDED(
- V_UNKNOWN(selection.ptr())->QueryInterface(IID_PPV_ARGS(&accessibles)));
- ULONG retrieved_count;
-
- // Check out the first selected cell.
- {
- ScopedVariant item;
- HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count);
- EXPECT_EQ(S_OK, hr);
-
- ComPtr<IAccessible> accessible;
- ASSERT_HRESULT_SUCCEEDED(
- V_DISPATCH(item.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)));
- ScopedBstr name;
- EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive()));
- EXPECT_STREQ(L"3", name.Get());
- }
-
- // And the second selected cell.
- {
- ScopedVariant item;
- HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count);
- EXPECT_EQ(S_OK, hr);
-
- ComPtr<IAccessible> accessible;
- ASSERT_HRESULT_SUCCEEDED(
- V_DISPATCH(item.ptr())->QueryInterface(IID_PPV_ARGS(&accessible)));
- ScopedBstr name;
- EXPECT_EQ(S_OK, accessible->get_accName(SELF, name.Receive()));
- EXPECT_STREQ(L"4", name.Get());
- }
-
- // There shouldn't be any more selected.
- {
- ScopedVariant item;
- HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count);
- EXPECT_EQ(S_FALSE, hr);
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleRole) {
- AXNodeData root;
- root.id = 1;
- root.child_ids.push_back(2);
-
- AXNodeData child;
- child.id = 2;
-
- Init(root, child);
- AXNode* child_node = GetRootAsAXNode()->children()[0];
- ComPtr<IAccessible> child_iaccessible(IAccessibleFromNode(child_node));
-
- ScopedVariant role;
-
- child.role = ax::mojom::Role::kAlert;
- child_node->SetData(child);
- EXPECT_EQ(S_OK, child_iaccessible->get_accRole(SELF, role.Receive()));
- EXPECT_EQ(ROLE_SYSTEM_ALERT, V_I4(role.ptr()));
-
- child.role = ax::mojom::Role::kButton;
- child_node->SetData(child);
- EXPECT_EQ(S_OK, child_iaccessible->get_accRole(SELF, role.Receive()));
- EXPECT_EQ(ROLE_SYSTEM_PUSHBUTTON, V_I4(role.ptr()));
-
- child.role = ax::mojom::Role::kPopUpButton;
- child_node->SetData(child);
- EXPECT_EQ(S_OK, child_iaccessible->get_accRole(SELF, role.Receive()));
- EXPECT_EQ(ROLE_SYSTEM_BUTTONMENU, V_I4(role.ptr()));
-
- EXPECT_EQ(E_INVALIDARG, child_iaccessible->get_accRole(SELF, nullptr));
- ScopedVariant bad_id(999);
- EXPECT_EQ(E_INVALIDARG,
- child_iaccessible->get_accRole(bad_id, role.Receive()));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleLocation) {
- AXNodeData root;
- root.id = 1;
- root.relative_bounds.bounds = gfx::RectF(10, 40, 800, 600);
- Init(root);
-
- TestAXNodeWrapper::SetGlobalCoordinateOffset(gfx::Vector2d(100, 200));
-
- LONG x_left, y_top, width, height;
- EXPECT_EQ(S_OK, GetRootIAccessible()->accLocation(&x_left, &y_top, &width,
- &height, SELF));
- EXPECT_EQ(110, x_left);
- EXPECT_EQ(240, y_top);
- EXPECT_EQ(800, width);
- EXPECT_EQ(600, height);
-
- EXPECT_EQ(E_INVALIDARG, GetRootIAccessible()->accLocation(
- nullptr, &y_top, &width, &height, SELF));
- EXPECT_EQ(E_INVALIDARG, GetRootIAccessible()->accLocation(
- &x_left, nullptr, &width, &height, SELF));
- EXPECT_EQ(E_INVALIDARG, GetRootIAccessible()->accLocation(
- &x_left, &y_top, nullptr, &height, SELF));
- EXPECT_EQ(E_INVALIDARG, GetRootIAccessible()->accLocation(
- &x_left, &y_top, &width, nullptr, SELF));
- ScopedVariant bad_id(999);
- EXPECT_EQ(E_INVALIDARG, GetRootIAccessible()->accLocation(
- &x_left, &y_top, &width, &height, bad_id));
-
- // Un-set the global offset so that it doesn't affect subsequent tests.
- TestAXNodeWrapper::SetGlobalCoordinateOffset(gfx::Vector2d(0, 0));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleChildAndParent) {
- AXNodeData root;
- root.id = 1;
- root.child_ids.push_back(2);
- root.child_ids.push_back(3);
-
- AXNodeData button;
- button.role = ax::mojom::Role::kButton;
- button.id = 2;
-
- AXNodeData checkbox;
- checkbox.role = ax::mojom::Role::kCheckBox;
- checkbox.id = 3;
-
- Init(root, button, checkbox);
- AXNode* button_node = GetRootAsAXNode()->children()[0];
- AXNode* checkbox_node = GetRootAsAXNode()->children()[1];
- ComPtr<IAccessible> root_iaccessible(GetRootIAccessible());
- ComPtr<IAccessible> button_iaccessible(IAccessibleFromNode(button_node));
- ComPtr<IAccessible> checkbox_iaccessible(IAccessibleFromNode(checkbox_node));
-
- LONG child_count;
- EXPECT_EQ(S_OK, root_iaccessible->get_accChildCount(&child_count));
- EXPECT_EQ(2L, child_count);
- EXPECT_EQ(S_OK, button_iaccessible->get_accChildCount(&child_count));
- EXPECT_EQ(0L, child_count);
- EXPECT_EQ(S_OK, checkbox_iaccessible->get_accChildCount(&child_count));
- EXPECT_EQ(0L, child_count);
-
- {
- ComPtr<IDispatch> result;
- EXPECT_EQ(S_OK, root_iaccessible->get_accChild(SELF, &result));
- EXPECT_EQ(result.Get(), root_iaccessible.Get());
- }
-
- {
- ComPtr<IDispatch> result;
- ScopedVariant child1(1);
- EXPECT_EQ(S_OK, root_iaccessible->get_accChild(child1, &result));
- EXPECT_EQ(result.Get(), button_iaccessible.Get());
- }
-
- {
- ComPtr<IDispatch> result;
- ScopedVariant child2(2);
- EXPECT_EQ(S_OK, root_iaccessible->get_accChild(child2, &result));
- EXPECT_EQ(result.Get(), checkbox_iaccessible.Get());
- }
-
- {
- // Asking for child id 3 should fail.
- ComPtr<IDispatch> result;
- ScopedVariant child3(3);
- EXPECT_EQ(E_INVALIDARG, root_iaccessible->get_accChild(child3, &result));
- }
-
- // We should be able to ask for the button by its unique id too.
- LONG button_unique_id;
- ComPtr<IAccessible2> button_iaccessible2 = ToIAccessible2(button_iaccessible);
- button_iaccessible2->get_uniqueID(&button_unique_id);
- ASSERT_LT(button_unique_id, 0);
- {
- ComPtr<IDispatch> result;
- ScopedVariant button_id_variant(button_unique_id);
- EXPECT_EQ(S_OK, root_iaccessible->get_accChild(button_id_variant, &result));
- EXPECT_EQ(result.Get(), button_iaccessible.Get());
- }
-
- // We shouldn't be able to ask for the root node by its unique ID
- // from one of its children, though.
- LONG root_unique_id;
- ComPtr<IAccessible2> root_iaccessible2 = ToIAccessible2(root_iaccessible);
- root_iaccessible2->get_uniqueID(&root_unique_id);
- ASSERT_LT(root_unique_id, 0);
- {
- ComPtr<IDispatch> result;
- ScopedVariant root_id_variant(root_unique_id);
- EXPECT_EQ(E_INVALIDARG,
- button_iaccessible->get_accChild(root_id_variant, &result));
- }
-
- // Now check parents.
- {
- ComPtr<IDispatch> result;
- EXPECT_EQ(S_OK, button_iaccessible->get_accParent(&result));
- EXPECT_EQ(result.Get(), root_iaccessible.Get());
- }
-
- {
- ComPtr<IDispatch> result;
- EXPECT_EQ(S_OK, checkbox_iaccessible->get_accParent(&result));
- EXPECT_EQ(result.Get(), root_iaccessible.Get());
- }
-
- {
- ComPtr<IDispatch> result;
- EXPECT_EQ(S_FALSE, root_iaccessible->get_accParent(&result));
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessible2IndexInParent) {
- AXNodeData root;
- root.id = 1;
- root.child_ids.push_back(2);
- root.child_ids.push_back(3);
-
- AXNodeData left;
- left.id = 2;
-
- AXNodeData right;
- right.id = 3;
-
- Init(root, left, right);
- ComPtr<IAccessible> root_iaccessible(GetRootIAccessible());
- ComPtr<IAccessible2> root_iaccessible2 = ToIAccessible2(root_iaccessible);
- ComPtr<IAccessible> left_iaccessible(
- IAccessibleFromNode(GetRootAsAXNode()->children()[0]));
- ComPtr<IAccessible2> left_iaccessible2 = ToIAccessible2(left_iaccessible);
- ComPtr<IAccessible> right_iaccessible(
- IAccessibleFromNode(GetRootAsAXNode()->children()[1]));
- ComPtr<IAccessible2> right_iaccessible2 = ToIAccessible2(right_iaccessible);
-
- LONG index;
- EXPECT_EQ(E_FAIL, root_iaccessible2->get_indexInParent(&index));
-
- EXPECT_EQ(S_OK, left_iaccessible2->get_indexInParent(&index));
- EXPECT_EQ(0, index);
-
- EXPECT_EQ(S_OK, right_iaccessible2->get_indexInParent(&index));
- EXPECT_EQ(1, index);
-}
-
-TEST_F(AXPlatformNodeWinTest, AccNavigate) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kStaticText;
- root.child_ids.push_back(2);
-
- AXNodeData child2;
- child2.id = 3;
- child2.role = ax::mojom::Role::kStaticText;
- root.child_ids.push_back(3);
-
- Init(root, child1, child2);
- ComPtr<IAccessible> ia_root(GetRootIAccessible());
- ComPtr<IDispatch> disp_root;
- ASSERT_HRESULT_SUCCEEDED(ia_root.As(&disp_root));
- ScopedVariant var_root(disp_root.Get());
- ComPtr<IAccessible> ia_child1(
- IAccessibleFromNode(GetRootAsAXNode()->children()[0]));
- ComPtr<IDispatch> disp_child1;
- ASSERT_HRESULT_SUCCEEDED(ia_child1.As(&disp_child1));
- ScopedVariant var_child1(disp_child1.Get());
- ComPtr<IAccessible> ia_child2(
- IAccessibleFromNode(GetRootAsAXNode()->children()[1]));
- ComPtr<IDispatch> disp_child2;
- ASSERT_HRESULT_SUCCEEDED(ia_child2.As(&disp_child2));
- ScopedVariant var_child2(disp_child2.Get());
- ScopedVariant end;
-
- // Invalid arguments.
- EXPECT_EQ(
- E_INVALIDARG,
- ia_root->accNavigate(NAVDIR_NEXT, ScopedVariant::kEmptyVariant, nullptr));
- EXPECT_EQ(E_INVALIDARG,
- ia_child1->accNavigate(NAVDIR_NEXT, ScopedVariant::kEmptyVariant,
- end.AsInput()));
- EXPECT_EQ(VT_EMPTY, end.type());
-
- // Navigating to first/last child should only be from self.
- EXPECT_EQ(E_INVALIDARG,
- ia_root->accNavigate(NAVDIR_FIRSTCHILD, var_root, end.AsInput()));
- EXPECT_EQ(VT_EMPTY, end.type());
- EXPECT_EQ(E_INVALIDARG,
- ia_root->accNavigate(NAVDIR_LASTCHILD, var_root, end.AsInput()));
- EXPECT_EQ(VT_EMPTY, end.type());
-
- // Spatial directions are not supported.
- EXPECT_EQ(E_NOTIMPL, ia_child1->accNavigate(NAVDIR_UP, SELF, end.AsInput()));
- EXPECT_EQ(E_NOTIMPL, ia_root->accNavigate(NAVDIR_DOWN, SELF, end.AsInput()));
- EXPECT_EQ(E_NOTIMPL,
- ia_child1->accNavigate(NAVDIR_RIGHT, SELF, end.AsInput()));
- EXPECT_EQ(E_NOTIMPL,
- ia_child2->accNavigate(NAVDIR_LEFT, SELF, end.AsInput()));
- EXPECT_EQ(VT_EMPTY, end.type());
-
- // Logical directions should be supported.
- EXPECT_EQ(S_OK, ia_root->accNavigate(NAVDIR_FIRSTCHILD, SELF, end.AsInput()));
- EXPECT_EQ(VT_DISPATCH, end.type());
- EXPECT_EQ(V_DISPATCH(var_child1.ptr()), V_DISPATCH(end.ptr()));
-
- EXPECT_EQ(S_OK, ia_root->accNavigate(NAVDIR_LASTCHILD, SELF, end.AsInput()));
- EXPECT_EQ(VT_DISPATCH, end.type());
- EXPECT_EQ(V_DISPATCH(var_child2.ptr()), V_DISPATCH(end.ptr()));
-
- EXPECT_EQ(S_OK, ia_child1->accNavigate(NAVDIR_NEXT, SELF, end.AsInput()));
- EXPECT_EQ(VT_DISPATCH, end.type());
- EXPECT_EQ(V_DISPATCH(var_child2.ptr()), V_DISPATCH(end.ptr()));
-
- EXPECT_EQ(S_OK, ia_child2->accNavigate(NAVDIR_PREVIOUS, SELF, end.AsInput()));
- EXPECT_EQ(VT_DISPATCH, end.type());
- EXPECT_EQ(V_DISPATCH(var_child1.ptr()), V_DISPATCH(end.ptr()));
-
- // Child indices can also be passed by variant.
- // Indices are one-based.
- EXPECT_EQ(S_OK,
- ia_root->accNavigate(NAVDIR_NEXT, ScopedVariant(1), end.AsInput()));
- EXPECT_EQ(VT_DISPATCH, end.type());
- EXPECT_EQ(V_DISPATCH(var_child2.ptr()), V_DISPATCH(end.ptr()));
-
- EXPECT_EQ(S_OK, ia_root->accNavigate(NAVDIR_PREVIOUS, ScopedVariant(2),
- end.AsInput()));
- EXPECT_EQ(VT_DISPATCH, end.type());
- EXPECT_EQ(V_DISPATCH(var_child1.ptr()), V_DISPATCH(end.ptr()));
-
- // Test out-of-bounds.
- EXPECT_EQ(S_FALSE,
- ia_child1->accNavigate(NAVDIR_PREVIOUS, SELF, end.AsInput()));
- EXPECT_EQ(VT_EMPTY, end.type());
- EXPECT_EQ(S_FALSE, ia_child2->accNavigate(NAVDIR_NEXT, SELF, end.AsInput()));
- EXPECT_EQ(VT_EMPTY, end.type());
-
- EXPECT_EQ(S_FALSE, ia_root->accNavigate(NAVDIR_PREVIOUS, ScopedVariant(1),
- end.AsInput()));
- EXPECT_EQ(VT_EMPTY, end.type());
- EXPECT_EQ(S_FALSE,
- ia_root->accNavigate(NAVDIR_NEXT, ScopedVariant(2), end.AsInput()));
- EXPECT_EQ(VT_EMPTY, end.type());
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessible2TextFieldSetSelection) {
- Init(BuildTextField());
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- EXPECT_HRESULT_SUCCEEDED(text_field->setSelection(0, 0, 1));
- EXPECT_HRESULT_SUCCEEDED(text_field->setSelection(0, 1, 0));
- EXPECT_HRESULT_SUCCEEDED(text_field->setSelection(0, 2, 2));
- EXPECT_HRESULT_SUCCEEDED(text_field->setSelection(0, IA2_TEXT_OFFSET_CARET,
- IA2_TEXT_OFFSET_LENGTH));
-
- EXPECT_HRESULT_FAILED(text_field->setSelection(1, 0, 0));
- EXPECT_HRESULT_FAILED(text_field->setSelection(0, 0, 50));
-}
-
-// This test is disabled until UpdateStep2ComputeHypertext is migrated over
-// to AXPlatformNodeWin because |hypertext_| is only initialized
-// on the BrowserAccessibility side.
-TEST_F(AXPlatformNodeWinTest,
- DISABLED_IAccessible2ContentEditableSetSelection) {
- Init(BuildContentEditable());
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> content_editable;
- ia2_text_field.As(&content_editable);
- ASSERT_NE(nullptr, content_editable.Get());
-
- EXPECT_HRESULT_SUCCEEDED(content_editable->setSelection(0, 0, 1));
- EXPECT_HRESULT_SUCCEEDED(content_editable->setSelection(0, 1, 0));
- EXPECT_HRESULT_SUCCEEDED(content_editable->setSelection(0, 2, 2));
- EXPECT_HRESULT_SUCCEEDED(content_editable->setSelection(
- 0, IA2_TEXT_OFFSET_CARET, IA2_TEXT_OFFSET_LENGTH));
-
- EXPECT_HRESULT_FAILED(content_editable->setSelection(1, 0, 0));
- EXPECT_HRESULT_FAILED(content_editable->setSelection(0, 0, 50));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetAccessibilityAt) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- ComPtr<IUnknown> cell_1;
- EXPECT_EQ(S_OK, result->get_accessibleAt(1, 1, &cell_1));
- CheckIUnknownHasName(cell_1, L"1");
-
- ComPtr<IUnknown> cell_2;
- EXPECT_EQ(S_OK, result->get_accessibleAt(1, 2, &cell_2));
- CheckIUnknownHasName(cell_2, L"2");
-
- ComPtr<IUnknown> cell_3;
- EXPECT_EQ(S_OK, result->get_accessibleAt(2, 1, &cell_3));
- CheckIUnknownHasName(cell_3, L"3");
-
- ComPtr<IUnknown> cell_4;
- EXPECT_EQ(S_OK, result->get_accessibleAt(2, 2, &cell_4));
- CheckIUnknownHasName(cell_4, L"4");
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetAccessibilityAtOutOfBounds) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- {
- ComPtr<IUnknown> cell;
- EXPECT_EQ(E_INVALIDARG, result->get_accessibleAt(-1, -1, &cell));
- }
-
- {
- ComPtr<IUnknown> cell;
- EXPECT_EQ(E_INVALIDARG, result->get_accessibleAt(0, 5, &cell));
- }
-
- {
- ComPtr<IUnknown> cell;
- EXPECT_EQ(E_INVALIDARG, result->get_accessibleAt(5, 0, &cell));
- }
-
- {
- ComPtr<IUnknown> cell;
- EXPECT_EQ(E_INVALIDARG, result->get_accessibleAt(10, 10, &cell));
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableQueryInterfaceOnNonTable) {
- ComPtr<IAccessibleTable> table;
- ComPtr<IAccessibleTable2> table2;
-
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kWebArea;
- Init(root);
-
- ComPtr<IAccessible> root_obj = GetRootIAccessible();
- EXPECT_EQ(E_NOINTERFACE, root_obj->QueryInterface(IID_PPV_ARGS(&table)));
- EXPECT_EQ(E_NOINTERFACE, root_obj->QueryInterface(IID_PPV_ARGS(&table2)));
-
- AXTreeUpdate update = Build3X3Table();
- update.node_id_to_clear = 1;
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
- EXPECT_EQ(E_NOINTERFACE, cell->QueryInterface(IID_PPV_ARGS(&table)));
- EXPECT_EQ(E_NOINTERFACE, cell->QueryInterface(IID_PPV_ARGS(&table2)));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableCellQueryInterfaceOnNonCell) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj = GetRootIAccessible();
- ComPtr<IAccessibleTableCell> cell;
- EXPECT_EQ(E_NOINTERFACE, root_obj->QueryInterface(IID_PPV_ARGS(&cell)));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessible2ScrollToPoint) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.relative_bounds.bounds = gfx::RectF(0, 0, 2000, 2000);
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kStaticText;
- child1.relative_bounds.bounds = gfx::RectF(10, 10, 10, 10);
- root.child_ids.push_back(2);
-
- Init(root, child1);
-
- ComPtr<IAccessible> root_iaccessible(GetRootIAccessible());
- ComPtr<IDispatch> result;
- EXPECT_EQ(S_OK, root_iaccessible->get_accChild(ScopedVariant(1), &result));
- ComPtr<IAccessible2> ax_child1;
- EXPECT_EQ(S_OK, result.As(&ax_child1));
- result.Reset();
-
- LONG x_left, y_top, width, height;
- EXPECT_EQ(S_OK,
- ax_child1->accLocation(&x_left, &y_top, &width, &height, SELF));
- EXPECT_EQ(10, x_left);
- EXPECT_EQ(10, y_top);
- EXPECT_EQ(10, width);
- EXPECT_EQ(10, height);
-
- ComPtr<IAccessible2> root_iaccessible2 = ToIAccessible2(root_iaccessible);
- EXPECT_EQ(S_OK, root_iaccessible2->scrollToPoint(
- IA2_COORDTYPE_SCREEN_RELATIVE, 600, 650));
-
- EXPECT_EQ(S_OK,
- ax_child1->accLocation(&x_left, &y_top, &width, &height, SELF));
- EXPECT_EQ(610, x_left);
- EXPECT_EQ(660, y_top);
- EXPECT_EQ(10, width);
- EXPECT_EQ(10, height);
-
- EXPECT_EQ(S_OK, root_iaccessible2->scrollToPoint(
- IA2_COORDTYPE_PARENT_RELATIVE, 0, 0));
-
- EXPECT_EQ(S_OK,
- ax_child1->accLocation(&x_left, &y_top, &width, &height, SELF));
- EXPECT_EQ(10, x_left);
- EXPECT_EQ(10, y_top);
- EXPECT_EQ(10, width);
- EXPECT_EQ(10, height);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessible2ScrollTo) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.relative_bounds.bounds = gfx::RectF(0, 0, 2000, 2000);
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kStaticText;
- child1.relative_bounds.bounds = gfx::RectF(10, 10, 10, 10);
- root.child_ids.push_back(2);
-
- Init(root, child1);
-
- ComPtr<IAccessible> root_iaccessible(GetRootIAccessible());
- ComPtr<IDispatch> result;
- EXPECT_EQ(S_OK, root_iaccessible->get_accChild(ScopedVariant(1), &result));
- ComPtr<IAccessible2> ax_child1;
- EXPECT_EQ(S_OK, result.As(&ax_child1));
- result.Reset();
-
- LONG x_left, y_top, width, height;
- EXPECT_EQ(S_OK,
- ax_child1->accLocation(&x_left, &y_top, &width, &height, SELF));
- EXPECT_EQ(10, x_left);
- EXPECT_EQ(10, y_top);
- EXPECT_EQ(10, width);
- EXPECT_EQ(10, height);
-
- ComPtr<IAccessible2> root_iaccessible2 = ToIAccessible2(root_iaccessible);
- EXPECT_EQ(S_OK, ax_child1->scrollTo(IA2_SCROLL_TYPE_ANYWHERE));
-
- EXPECT_EQ(S_OK,
- ax_child1->accLocation(&x_left, &y_top, &width, &height, SELF));
- EXPECT_EQ(0, x_left);
- EXPECT_EQ(0, y_top);
- EXPECT_EQ(10, width);
- EXPECT_EQ(10, height);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetChildIndex) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG id;
- EXPECT_EQ(S_OK, result->get_childIndex(0, 0, &id));
- EXPECT_EQ(id, 0);
-
- EXPECT_EQ(S_OK, result->get_childIndex(0, 1, &id));
- EXPECT_EQ(id, 1);
-
- EXPECT_EQ(S_OK, result->get_childIndex(1, 0, &id));
- EXPECT_EQ(id, 3);
-
- EXPECT_EQ(S_OK, result->get_childIndex(1, 1, &id));
- EXPECT_EQ(id, 4);
-
- EXPECT_EQ(E_INVALIDARG, result->get_childIndex(-1, -1, &id));
- EXPECT_EQ(E_INVALIDARG, result->get_childIndex(0, 5, &id));
- EXPECT_EQ(E_INVALIDARG, result->get_childIndex(5, 0, &id));
- EXPECT_EQ(E_INVALIDARG, result->get_childIndex(5, 5, &id));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetColumnDescription) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- {
- ScopedBstr name;
- EXPECT_EQ(S_FALSE, result->get_columnDescription(0, name.Receive()));
- }
- {
- ScopedBstr name;
- EXPECT_EQ(S_OK, result->get_columnDescription(1, name.Receive()));
- EXPECT_STREQ(L"column header 1", name.Get());
- }
-
- {
- ScopedBstr name;
- EXPECT_EQ(S_OK, result->get_columnDescription(2, name.Receive()));
- EXPECT_STREQ(L"column header 2", name.Get());
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetColumnExtentAt) {
- // TODO(dougt) This table doesn't have any spanning cells. This test
- // tests get_columnExtentAt for (1) and an invalid input.
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG columns_spanned;
- EXPECT_EQ(S_OK, result->get_columnExtentAt(1, 1, &columns_spanned));
- EXPECT_EQ(columns_spanned, 1);
-
- EXPECT_EQ(E_INVALIDARG, result->get_columnExtentAt(-1, -1, &columns_spanned));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetColumnIndex) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG index;
- EXPECT_EQ(S_OK, result->get_columnIndex(2, &index));
- EXPECT_EQ(index, 2);
- EXPECT_EQ(S_OK, result->get_columnIndex(3, &index));
- EXPECT_EQ(index, 0);
-
- EXPECT_EQ(E_INVALIDARG, result->get_columnIndex(-1, &index));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetNColumns) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG count;
- EXPECT_EQ(S_OK, result->get_nColumns(&count));
- EXPECT_EQ(count, 3);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetNRows) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG count;
- EXPECT_EQ(S_OK, result->get_nRows(&count));
- EXPECT_EQ(count, 3);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetRowDescription) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- {
- ScopedBstr name;
- EXPECT_EQ(S_FALSE, result->get_rowDescription(0, name.Receive()));
- }
-
- {
- ScopedBstr name;
- EXPECT_EQ(S_OK, result->get_rowDescription(1, name.Receive()));
- EXPECT_STREQ(L"row header 1", name.Get());
- }
-
- {
- ScopedBstr name;
- EXPECT_EQ(S_OK, result->get_rowDescription(2, name.Receive()));
- EXPECT_STREQ(L"row header 2", name.Get());
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetRowExtentAt) {
- // TODO(dougt) This table doesn't have any spanning cells. This test
- // tests get_rowExtentAt for (1) and an invalid input.
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG rows_spanned;
- EXPECT_EQ(S_OK, result->get_rowExtentAt(0, 1, &rows_spanned));
- EXPECT_EQ(1, rows_spanned);
-
- EXPECT_EQ(E_INVALIDARG, result->get_columnExtentAt(-1, -1, &rows_spanned));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetRowIndex) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG index;
- EXPECT_EQ(S_OK, result->get_rowIndex(2, &index));
- EXPECT_EQ(0, index);
- EXPECT_EQ(S_OK, result->get_rowIndex(3, &index));
- EXPECT_EQ(1, index);
-
- EXPECT_EQ(E_INVALIDARG, result->get_rowIndex(-1, &index));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetRowColumnExtentsAtIndex) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG row, column, row_extents, column_extents;
- BOOLEAN is_selected = false;
- EXPECT_EQ(S_OK,
- result->get_rowColumnExtentsAtIndex(0, &row, &column, &row_extents,
- &column_extents, &is_selected));
-
- EXPECT_EQ(0, row);
- EXPECT_EQ(0, column);
- EXPECT_EQ(1, row_extents);
- EXPECT_EQ(1, column_extents);
- EXPECT_FALSE(is_selected);
-
- EXPECT_EQ(E_INVALIDARG,
- result->get_rowColumnExtentsAtIndex(-1, &row, &column, &row_extents,
- &column_extents, &is_selected));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetCellAt) {
- Init(Build3X3Table());
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- ComPtr<IAccessibleTable2> result;
- root_obj.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- {
- ComPtr<IUnknown> cell;
- EXPECT_EQ(S_OK, result->get_cellAt(1, 1, &cell));
- CheckIUnknownHasName(cell, L"1");
- }
-
- {
- ComPtr<IUnknown> cell;
- EXPECT_EQ(E_INVALIDARG, result->get_cellAt(-1, -1, &cell));
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableCellGetColumnExtent) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- LONG column_spanned;
- EXPECT_EQ(S_OK, cell->get_columnExtent(&column_spanned));
- EXPECT_EQ(1, column_spanned);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableCellGetColumnHeaderCells) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- IUnknown** cell_accessibles;
-
- LONG number_cells;
- EXPECT_EQ(S_OK,
- cell->get_columnHeaderCells(&cell_accessibles, &number_cells));
- EXPECT_EQ(1, number_cells);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableCellGetColumnIndex) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- LONG index;
- EXPECT_EQ(S_OK, cell->get_columnIndex(&index));
- EXPECT_EQ(index, 1);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableCellGetRowExtent) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- LONG rows_spanned;
- EXPECT_EQ(S_OK, cell->get_rowExtent(&rows_spanned));
- EXPECT_EQ(rows_spanned, 1);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableCellGetRowHeaderCells) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- IUnknown** cell_accessibles;
-
- LONG number_cells;
- EXPECT_EQ(S_OK, cell->get_rowHeaderCells(&cell_accessibles, &number_cells));
- EXPECT_EQ(number_cells, 1);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableCellGetRowIndex) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- LONG index;
- EXPECT_EQ(S_OK, cell->get_rowIndex(&index));
- EXPECT_EQ(index, 1);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableCellGetRowColumnExtent) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- LONG row, column, row_extents, column_extents;
- BOOLEAN is_selected = false;
- EXPECT_EQ(S_OK, cell->get_rowColumnExtents(&row, &column, &row_extents,
- &column_extents, &is_selected));
- EXPECT_EQ(1, row);
- EXPECT_EQ(1, column);
- EXPECT_EQ(1, row_extents);
- EXPECT_EQ(1, column_extents);
- EXPECT_FALSE(is_selected);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableCellGetTable) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- // Check to make sure that this is the right table by checking one cell.
- ComPtr<IUnknown> cell_1;
- EXPECT_EQ(S_OK, result->get_accessibleAt(1, 1, &cell_1));
- CheckIUnknownHasName(cell_1, L"1");
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessible2GetNRelations) {
- // This is is a duplicated of
- // BrowserAccessibilityTest::TestIAccessible2Relations but without the
- // specific COM/BrowserAccessibility knowledge.
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
-
- std::vector<AXNode::AXID> describedby_ids = {1, 2, 3};
- root.AddIntListAttribute(ax::mojom::IntListAttribute::kDescribedbyIds,
- describedby_ids);
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kStaticText;
-
- root.child_ids.push_back(2);
-
- AXNodeData child2;
- child2.id = 3;
- child2.role = ax::mojom::Role::kStaticText;
-
- root.child_ids.push_back(3);
-
- Init(root, child1, child2);
- ComPtr<IAccessible> root_iaccessible(GetRootIAccessible());
- ComPtr<IAccessible2> root_iaccessible2 = ToIAccessible2(root_iaccessible);
-
- ComPtr<IDispatch> result;
- EXPECT_EQ(S_OK, root_iaccessible2->get_accChild(ScopedVariant(1), &result));
- ComPtr<IAccessible2> ax_child1;
- EXPECT_EQ(S_OK, result.As(&ax_child1));
- result.Reset();
-
- EXPECT_EQ(S_OK, root_iaccessible2->get_accChild(ScopedVariant(2), &result));
- ComPtr<IAccessible2> ax_child2;
- EXPECT_EQ(S_OK, result.As(&ax_child2));
- result.Reset();
-
- LONG n_relations = 0;
- LONG n_targets = 0;
- ScopedBstr relation_type;
- ComPtr<IAccessibleRelation> describedby_relation;
- ComPtr<IAccessibleRelation> description_for_relation;
- ComPtr<IUnknown> target;
-
- EXPECT_HRESULT_SUCCEEDED(root_iaccessible2->get_nRelations(&n_relations));
- EXPECT_EQ(1, n_relations);
-
- EXPECT_HRESULT_SUCCEEDED(
- root_iaccessible2->get_relation(0, &describedby_relation));
-
- EXPECT_HRESULT_SUCCEEDED(
- describedby_relation->get_relationType(relation_type.Receive()));
- EXPECT_EQ(L"describedBy", base::string16(relation_type.Get()));
-
- relation_type.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(describedby_relation->get_nTargets(&n_targets));
- EXPECT_EQ(2, n_targets);
-
- EXPECT_HRESULT_SUCCEEDED(describedby_relation->get_target(0, &target));
- target.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(describedby_relation->get_target(1, &target));
- target.Reset();
-
- describedby_relation.Reset();
-
- // Test the reverse relations.
- EXPECT_HRESULT_SUCCEEDED(ax_child1->get_nRelations(&n_relations));
- EXPECT_EQ(1, n_relations);
-
- EXPECT_HRESULT_SUCCEEDED(
- ax_child1->get_relation(0, &description_for_relation));
- EXPECT_HRESULT_SUCCEEDED(
- description_for_relation->get_relationType(relation_type.Receive()));
- EXPECT_EQ(L"descriptionFor", base::string16(relation_type.Get()));
- relation_type.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(description_for_relation->get_nTargets(&n_targets));
- EXPECT_EQ(1, n_targets);
-
- EXPECT_HRESULT_SUCCEEDED(description_for_relation->get_target(0, &target));
- target.Reset();
- description_for_relation.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(ax_child2->get_nRelations(&n_relations));
- EXPECT_EQ(1, n_relations);
-
- EXPECT_HRESULT_SUCCEEDED(
- ax_child2->get_relation(0, &description_for_relation));
- EXPECT_HRESULT_SUCCEEDED(
- description_for_relation->get_relationType(relation_type.Receive()));
- EXPECT_EQ(L"descriptionFor", base::string16(relation_type.Get()));
- relation_type.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(description_for_relation->get_nTargets(&n_targets));
- EXPECT_EQ(1, n_targets);
-
- EXPECT_HRESULT_SUCCEEDED(description_for_relation->get_target(0, &target));
- target.Reset();
-
- // TODO(dougt): Try adding one more relation.
-}
-
-TEST_F(AXPlatformNodeWinTest,
- IAccessible2TestPopupForRelationMapsToControlledByRelation) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kTextField;
- child1.AddIntListAttribute(ax::mojom::IntListAttribute::kControlsIds, {3});
- root.child_ids.push_back(2);
-
- // Add listbox that is popup for the textfield.
- AXNodeData child2;
- child2.id = 3;
- child2.role = ax::mojom::Role::kListBox;
- child2.AddIntAttribute(ax::mojom::IntAttribute::kPopupForId, 2);
- root.child_ids.push_back(3);
-
- Init(root, child1, child2);
- ComPtr<IAccessible> root_iaccessible(GetRootIAccessible());
- ComPtr<IAccessible2> root_iaccessible2 = ToIAccessible2(root_iaccessible);
-
- ComPtr<IDispatch> result;
- EXPECT_EQ(S_OK, root_iaccessible2->get_accChild(ScopedVariant(1), &result));
- ComPtr<IAccessible2> ax_child1;
- EXPECT_EQ(S_OK, result.As(&ax_child1));
- result.Reset();
-
- EXPECT_EQ(S_OK, root_iaccessible2->get_accChild(ScopedVariant(2), &result));
- ComPtr<IAccessible2> ax_child2;
- EXPECT_EQ(S_OK, result.As(&ax_child2));
- result.Reset();
-
- LONG n_relations = 0;
- LONG n_targets = 0;
- ScopedBstr relation_type;
- ComPtr<IAccessibleRelation> controls_relation;
- ComPtr<IAccessibleRelation> controlled_by_relation;
- ComPtr<IUnknown> target;
-
- EXPECT_HRESULT_SUCCEEDED(ax_child1->get_nRelations(&n_relations));
- EXPECT_EQ(1, n_relations);
-
- EXPECT_HRESULT_SUCCEEDED(ax_child1->get_relation(0, &controls_relation));
-
- EXPECT_HRESULT_SUCCEEDED(
- controls_relation->get_relationType(relation_type.Receive()));
- EXPECT_EQ(L"controllerFor", base::string16(relation_type.Get()));
-
- relation_type.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(controls_relation->get_nTargets(&n_targets));
- EXPECT_EQ(1, n_targets);
-
- EXPECT_HRESULT_SUCCEEDED(controls_relation->get_target(0, &target));
- target.Reset();
-
- controls_relation.Reset();
-
- // Test the controlled by relation, mapped from the popup for relation.
- EXPECT_HRESULT_SUCCEEDED(ax_child2->get_nRelations(&n_relations));
- // The test is currently outsmarting us, and automatically mapping the
- // reverse relation in addition to mapping the popup for -> controlled by.
- // Therefore, the same relation will exist twice in this test, which
- // actually shows that the popup for -> controlled by relation is working.
- // As a result, both relations should have the same result in this test.
- EXPECT_EQ(2, n_relations);
-
- // Both relations should have the same result in this test.
- EXPECT_HRESULT_SUCCEEDED(ax_child2->get_relation(0, &controlled_by_relation));
- EXPECT_HRESULT_SUCCEEDED(
- controlled_by_relation->get_relationType(relation_type.Receive()));
- EXPECT_EQ(L"controlledBy", base::string16(relation_type.Get()));
- relation_type.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(controlled_by_relation->get_nTargets(&n_targets));
- EXPECT_EQ(1, n_targets);
-
- EXPECT_HRESULT_SUCCEEDED(controlled_by_relation->get_target(0, &target));
- target.Reset();
- controlled_by_relation.Reset();
-
- // Both relations should have the same result in this test.
- EXPECT_HRESULT_SUCCEEDED(ax_child2->get_relation(1, &controlled_by_relation));
- EXPECT_HRESULT_SUCCEEDED(
- controlled_by_relation->get_relationType(relation_type.Receive()));
- EXPECT_EQ(L"controlledBy", base::string16(relation_type.Get()));
- relation_type.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(controlled_by_relation->get_nTargets(&n_targets));
- EXPECT_EQ(1, n_targets);
-
- EXPECT_HRESULT_SUCCEEDED(controlled_by_relation->get_target(0, &target));
- target.Reset();
-}
-
-TEST_F(AXPlatformNodeWinTest, DISABLED_TestRelationTargetsOfType) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.AddIntListAttribute(ax::mojom::IntListAttribute::kDetailsIds, {2});
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kStaticText;
-
- root.child_ids.push_back(2);
-
- AXNodeData child2;
- child2.id = 3;
- child2.role = ax::mojom::Role::kStaticText;
- std::vector<AXNode::AXID> labelledby_ids = {1, 4};
- child2.AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
- labelledby_ids);
-
- root.child_ids.push_back(3);
-
- AXNodeData child3;
- child3.id = 4;
- child3.role = ax::mojom::Role::kStaticText;
- child3.AddIntListAttribute(ax::mojom::IntListAttribute::kDetailsIds, {2});
-
- root.child_ids.push_back(4);
-
- Init(root, child1, child2, child3);
- ComPtr<IAccessible> root_iaccessible(GetRootIAccessible());
- ComPtr<IAccessible2_2> root_iaccessible2 = ToIAccessible2_2(root_iaccessible);
-
- ComPtr<IDispatch> result;
- EXPECT_EQ(S_OK, root_iaccessible2->get_accChild(ScopedVariant(1), &result));
- ComPtr<IAccessible2_2> ax_child1;
- EXPECT_EQ(S_OK, result.As(&ax_child1));
- result.Reset();
-
- EXPECT_EQ(S_OK, root_iaccessible2->get_accChild(ScopedVariant(2), &result));
- ComPtr<IAccessible2_2> ax_child2;
- EXPECT_EQ(S_OK, result.As(&ax_child2));
- result.Reset();
-
- EXPECT_EQ(S_OK, root_iaccessible2->get_accChild(ScopedVariant(3), &result));
- ComPtr<IAccessible2_2> ax_child3;
- EXPECT_EQ(S_OK, result.As(&ax_child3));
- result.Reset();
-
- {
- ScopedBstr type(L"details");
- IUnknown** targets;
- LONG n_targets;
- EXPECT_EQ(S_OK, root_iaccessible2->get_relationTargetsOfType(
- type.Get(), 0, &targets, &n_targets));
- ASSERT_EQ(1, n_targets);
- EXPECT_EQ(ax_child1.Get(), targets[0]);
- CoTaskMemFree(targets);
- }
-
- {
- ScopedBstr type(IA2_RELATION_LABELLED_BY);
- IUnknown** targets;
- LONG n_targets;
- EXPECT_EQ(S_OK, ax_child2->get_relationTargetsOfType(type.Get(), 0,
- &targets, &n_targets));
- ASSERT_EQ(2, n_targets);
- EXPECT_EQ(root_iaccessible2.Get(), targets[0]);
- EXPECT_EQ(ax_child3.Get(), targets[1]);
- CoTaskMemFree(targets);
- }
-
- {
- ScopedBstr type(L"detailsFor");
- IUnknown** targets;
- LONG n_targets;
- EXPECT_EQ(S_OK, ax_child1->get_relationTargetsOfType(type.Get(), 0,
- &targets, &n_targets));
- ASSERT_EQ(2, n_targets);
- EXPECT_EQ(root_iaccessible2.Get(), targets[0]);
- EXPECT_EQ(ax_child3.Get(), targets[1]);
- CoTaskMemFree(targets);
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetNSelectedChildrenZero) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG selectedChildren;
- EXPECT_EQ(S_OK, result->get_nSelectedChildren(&selectedChildren));
- EXPECT_EQ(0, selectedChildren);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetNSelectedChildrenOne) {
- AXTreeUpdate update = Build3X3Table();
-
- // 7 == table_cell_1
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG selectedChildren;
- EXPECT_EQ(S_OK, result->get_nSelectedChildren(&selectedChildren));
- EXPECT_EQ(1, selectedChildren);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetNSelectedChildrenMany) {
- AXTreeUpdate update = Build3X3Table();
-
- // 7 == table_cell_1
- // 8 == table_cell_2
- // 11 == table_cell_3
- // 12 == table_cell_4
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[8].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[11].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[12].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG selectedChildren;
- EXPECT_EQ(S_OK, result->get_nSelectedChildren(&selectedChildren));
- EXPECT_EQ(4, selectedChildren);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetNSelectedColumnsZero) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG selectedColumns;
- EXPECT_EQ(S_OK, result->get_nSelectedColumns(&selectedColumns));
- EXPECT_EQ(0, selectedColumns);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetNSelectedColumnsOne) {
- AXTreeUpdate update = Build3X3Table();
-
- // 3 == table_column_header_2
- // 7 == table_cell_1
- // 11 == table_cell_3
- update.nodes[3].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[11].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG selectedColumns;
- EXPECT_EQ(S_OK, result->get_nSelectedColumns(&selectedColumns));
- EXPECT_EQ(1, selectedColumns);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetNSelectedColumnsMany) {
- AXTreeUpdate update = Build3X3Table();
-
- // 3 == table_column_header_2
- // 7 == table_cell_1
- // 11 == table_cell_3
- update.nodes[3].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[11].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- // 4 == table_column_header_3
- // 8 == table_cell_2
- // 12 == table_cell_4
- update.nodes[4].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[8].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[12].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG selectedColumns;
- EXPECT_EQ(S_OK, result->get_nSelectedColumns(&selectedColumns));
- EXPECT_EQ(2, selectedColumns);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetNSelectedRowsZero) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG selectedRows;
- EXPECT_EQ(S_OK, result->get_nSelectedRows(&selectedRows));
- EXPECT_EQ(0, selectedRows);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetNSelectedRowsOne) {
- AXTreeUpdate update = Build3X3Table();
-
- // 6 == table_row_header_1
- // 7 == table_cell_1
- // 8 == table_cell_2
- update.nodes[6].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[8].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG selectedRows;
- EXPECT_EQ(S_OK, result->get_nSelectedRows(&selectedRows));
- EXPECT_EQ(1, selectedRows);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetNSelectedRowsMany) {
- AXTreeUpdate update = Build3X3Table();
-
- // 6 == table_row_header_3
- // 7 == table_cell_1
- // 8 == table_cell_2
- update.nodes[6].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[8].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- // 10 == table_row_header_3
- // 11 == table_cell_1
- // 12 == table_cell_2
- update.nodes[10].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[11].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[12].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG selectedRows;
- EXPECT_EQ(S_OK, result->get_nSelectedRows(&selectedRows));
- EXPECT_EQ(2, selectedRows);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetSelectedChildren) {
- AXTreeUpdate update = Build3X3Table();
-
- // 7 == table_cell_1
- // 12 == table_cell_4
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[12].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG max = 10;
- LONG* indices;
- LONG count;
- EXPECT_EQ(S_OK, result->get_selectedChildren(max, &indices, &count));
- EXPECT_EQ(2, count);
- EXPECT_EQ(4, indices[0]);
- EXPECT_EQ(8, indices[1]);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetSelectedChildrenZeroMax) {
- AXTreeUpdate update = Build3X3Table();
-
- // 7 == table_cell_1
- // 12 == table_cell_4
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[12].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG* indices;
- LONG count;
- EXPECT_EQ(E_INVALIDARG, result->get_selectedChildren(0, &indices, &count));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetSelectedColumnsZero) {
- AXTreeUpdate update = Build3X3Table();
-
- // 7 == table_cell_1
- // 11 == table_cell_3
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[11].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG max_columns = 10;
- LONG* columns;
- LONG n_columns;
- EXPECT_EQ(S_OK,
- result->get_selectedColumns(max_columns, &columns, &n_columns));
- EXPECT_EQ(0, n_columns);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetSelectedColumnsOne) {
- AXTreeUpdate update = Build3X3Table();
-
- // 3 == table_column_header_2
- // 7 == table_cell_1
- // 11 == table_cell_3
- update.nodes[3].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[11].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG max_columns = 10;
- LONG* columns;
- LONG n_columns;
- EXPECT_EQ(S_OK,
- result->get_selectedColumns(max_columns, &columns, &n_columns));
- EXPECT_EQ(1, n_columns);
- EXPECT_EQ(1, columns[0]);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetSelectedColumnsMany) {
- AXTreeUpdate update = Build3X3Table();
-
- // 3 == table_column_header_2
- // 7 == table_cell_1
- // 11 == table_cell_3
- update.nodes[3].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[11].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- // 4 == table_column_header_3
- // 8 == table_cell_2
- // 12 == table_cell_4
- update.nodes[4].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[8].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[12].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG max_columns = 10;
- LONG* columns;
- LONG n_columns;
- EXPECT_EQ(S_OK,
- result->get_selectedColumns(max_columns, &columns, &n_columns));
- EXPECT_EQ(2, n_columns);
- EXPECT_EQ(1, columns[0]);
- EXPECT_EQ(2, columns[1]);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetSelectedRowsZero) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG max_rows = 10;
- LONG* rows;
- LONG n_rows;
- EXPECT_EQ(S_OK, result->get_selectedRows(max_rows, &rows, &n_rows));
- EXPECT_EQ(0, n_rows);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetSelectedRowsOne) {
- AXTreeUpdate update = Build3X3Table();
-
- // 6 == table_row_header_1
- // 7 == table_cell_1
- // 8 == table_cell_2
- update.nodes[6].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[8].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG max_rows = 10;
- LONG* rows;
- LONG n_rows;
- EXPECT_EQ(S_OK, result->get_selectedRows(max_rows, &rows, &n_rows));
- EXPECT_EQ(1, n_rows);
- EXPECT_EQ(1, rows[0]);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableGetSelectedRowsMany) {
- AXTreeUpdate update = Build3X3Table();
-
- // 6 == table_row_header_3
- // 7 == table_cell_1
- // 8 == table_cell_2
- update.nodes[6].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[8].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- // 10 == table_row_header_3
- // 11 == table_cell_1
- // 12 == table_cell_2
- update.nodes[10].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[11].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[12].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- LONG max_rows = 10;
- LONG* rows;
- LONG n_rows;
- EXPECT_EQ(S_OK, result->get_selectedRows(max_rows, &rows, &n_rows));
- EXPECT_EQ(2, n_rows);
- EXPECT_EQ(1, rows[0]);
- EXPECT_EQ(2, rows[1]);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableIsColumnSelected) {
- AXTreeUpdate update = Build3X3Table();
-
- // 3 == table_column_header_2
- // 7 == table_cell_1
- // 11 == table_cell_3
- update.nodes[3].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[11].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- BOOLEAN selected = false;
- EXPECT_EQ(S_OK, result->get_isColumnSelected(0, &selected));
- EXPECT_FALSE(selected);
-
- EXPECT_EQ(S_OK, result->get_isColumnSelected(1, &selected));
- EXPECT_TRUE(selected);
-
- EXPECT_EQ(S_OK, result->get_isColumnSelected(2, &selected));
- EXPECT_FALSE(selected);
-
- EXPECT_EQ(E_INVALIDARG, result->get_isColumnSelected(3, &selected));
- EXPECT_EQ(E_INVALIDARG, result->get_isColumnSelected(-3, &selected));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableIsRowSelected) {
- AXTreeUpdate update = Build3X3Table();
-
- // 6 == table_row_header_3
- // 7 == table_cell_1
- // 8 == table_cell_2
- update.nodes[6].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[8].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- BOOLEAN selected;
- EXPECT_EQ(S_OK, result->get_isRowSelected(0, &selected));
- EXPECT_FALSE(selected);
-
- EXPECT_EQ(S_OK, result->get_isRowSelected(1, &selected));
- EXPECT_TRUE(selected);
-
- EXPECT_EQ(S_OK, result->get_isRowSelected(2, &selected));
- EXPECT_FALSE(selected);
-
- EXPECT_EQ(E_INVALIDARG, result->get_isRowSelected(3, &selected));
- EXPECT_EQ(E_INVALIDARG, result->get_isRowSelected(-3, &selected));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTableIsSelected) {
- AXTreeUpdate update = Build3X3Table();
-
- // 6 == table_row_header_3
- // 7 == table_cell_1
- // 8 == table_cell_2
- update.nodes[6].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[8].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- BOOLEAN selected = false;
- EXPECT_EQ(S_OK, result->get_isSelected(0, 0, &selected));
- EXPECT_FALSE(selected);
-
- EXPECT_EQ(S_OK, result->get_isSelected(0, 1, &selected));
- EXPECT_FALSE(selected);
-
- EXPECT_EQ(S_OK, result->get_isSelected(0, 2, &selected));
- EXPECT_FALSE(selected);
-
- EXPECT_EQ(E_INVALIDARG, result->get_isSelected(0, 4, &selected));
-
- EXPECT_EQ(S_OK, result->get_isSelected(1, 0, &selected));
- EXPECT_TRUE(selected);
-
- EXPECT_EQ(S_OK, result->get_isSelected(1, 1, &selected));
- EXPECT_TRUE(selected);
-
- EXPECT_EQ(S_OK, result->get_isSelected(1, 2, &selected));
- EXPECT_TRUE(selected);
-
- EXPECT_EQ(E_INVALIDARG, result->get_isSelected(1, 4, &selected));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTable2GetSelectedChildrenZero) {
- Init(Build3X3Table());
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable2> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- IUnknown** cell_accessibles;
- LONG count;
- EXPECT_EQ(S_OK, result->get_selectedCells(&cell_accessibles, &count));
- EXPECT_EQ(0, count);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTable2GetSelectedChildren) {
- AXTreeUpdate update = Build3X3Table();
-
- // 7 == table_cell_1
- // 12 == table_cell_4
- update.nodes[7].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- update.nodes[12].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
-
- Init(update);
-
- ComPtr<IAccessibleTableCell> cell = GetCellInTable();
- ASSERT_NE(nullptr, cell.Get());
-
- ComPtr<IUnknown> table;
- EXPECT_EQ(S_OK, cell->get_table(&table));
-
- ComPtr<IAccessibleTable2> result;
- table.As(&result);
- ASSERT_NE(nullptr, result.Get());
-
- IUnknown** cell_accessibles;
- LONG count;
- EXPECT_EQ(S_OK, result->get_selectedCells(&cell_accessibles, &count));
- EXPECT_EQ(2, count);
-
- ComPtr<IUnknown> table_cell_1(cell_accessibles[0]);
- CheckIUnknownHasName(table_cell_1, L"1");
-
- ComPtr<IUnknown> table_cell_4(cell_accessibles[1]);
- CheckIUnknownHasName(table_cell_4, L"4");
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessible2GetGroupPosition) {
- AXNodeData root;
- root.id = 1;
- root.AddIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel, 1);
- root.AddIntAttribute(ax::mojom::IntAttribute::kSetSize, 1);
- root.AddIntAttribute(ax::mojom::IntAttribute::kPosInSet, 1);
- Init(root);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ComPtr<IAccessible2> iaccessible2 = ToIAccessible2(root_obj);
- LONG level, similar, position;
- EXPECT_EQ(S_OK, iaccessible2->get_groupPosition(&level, &similar, &position));
- EXPECT_EQ(1, level);
- EXPECT_EQ(0, similar);
- EXPECT_EQ(0, position);
-
- EXPECT_EQ(E_INVALIDARG,
- iaccessible2->get_groupPosition(nullptr, nullptr, nullptr));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessible2GetLocalizedExtendedRole) {
- AXNodeData root;
- root.id = 1;
- root.AddStringAttribute(ax::mojom::StringAttribute::kRoleDescription,
- "extended role");
- Init(root);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ComPtr<IAccessible2> iaccessible2 = ToIAccessible2(root_obj);
- ScopedBstr role;
- EXPECT_EQ(S_OK, iaccessible2->get_localizedExtendedRole(role.Receive()));
- EXPECT_STREQ(L"extended role", role.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, UnlabeledImageRoleDescription) {
- AXTreeUpdate tree;
- tree.root_id = 1;
- tree.nodes.resize(3);
- tree.nodes[0].id = 1;
- tree.nodes[0].child_ids = {2, 3};
-
- tree.nodes[1].id = 2;
- tree.nodes[1].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kEligibleForAnnotation);
- tree.nodes[1].role = ax::mojom::Role::kImage;
-
- tree.nodes[2].id = 3;
- tree.nodes[2].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kSilentlyEligibleForAnnotation);
- tree.nodes[2].role = ax::mojom::Role::kImage;
-
- Init(tree);
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- for (int child_index = 0; child_index < int{tree.nodes[0].child_ids.size()};
- ++child_index) {
- ComPtr<IDispatch> child_dispatch;
- ASSERT_HRESULT_SUCCEEDED(root_obj->get_accChild(
- ScopedVariant(child_index + 1), &child_dispatch));
- ComPtr<IAccessible> child;
- ASSERT_HRESULT_SUCCEEDED(child_dispatch.As(&child));
- ComPtr<IAccessible2> ia2_child = ToIAccessible2(child);
-
- ScopedBstr role_description;
- ASSERT_EQ(S_OK,
- ia2_child->get_localizedExtendedRole(role_description.Receive()));
- EXPECT_STREQ(L"Unlabeled image", role_description.Get());
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, UnlabeledImageAttributes) {
- AXTreeUpdate tree;
- tree.root_id = 1;
- tree.nodes.resize(3);
- tree.nodes[0].id = 1;
- tree.nodes[0].child_ids = {2, 3};
-
- tree.nodes[1].id = 2;
- tree.nodes[1].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kEligibleForAnnotation);
- tree.nodes[1].role = ax::mojom::Role::kImage;
-
- tree.nodes[2].id = 3;
- tree.nodes[2].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kSilentlyEligibleForAnnotation);
- tree.nodes[2].role = ax::mojom::Role::kImage;
-
- Init(tree);
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- for (int child_index = 0; child_index < int{tree.nodes[0].child_ids.size()};
- ++child_index) {
- ComPtr<IDispatch> child_dispatch;
- ASSERT_HRESULT_SUCCEEDED(root_obj->get_accChild(
- ScopedVariant(child_index + 1), &child_dispatch));
- ComPtr<IAccessible> child;
- ASSERT_HRESULT_SUCCEEDED(child_dispatch.As(&child));
- ComPtr<IAccessible2> ia2_child = ToIAccessible2(child);
-
- ScopedBstr attributes_bstr;
- ASSERT_EQ(S_OK, ia2_child->get_attributes(attributes_bstr.Receive()));
- base::string16 attributes(attributes_bstr.Get());
-
- std::vector<base::string16> attribute_vector = base::SplitString(
- attributes, L";", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
- EXPECT_TRUE(
- base::Contains(attribute_vector, L"roledescription:Unlabeled image"));
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, AnnotatedImageName) {
- std::vector<const wchar_t*> expected_names;
-
- AXTreeUpdate tree;
- tree.root_id = 1;
- tree.nodes.resize(11);
- tree.nodes[0].id = 1;
- tree.nodes[0].child_ids = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
-
- // If the status is EligibleForAnnotation and there's no existing label,
- // the name should be the discoverability string.
- tree.nodes[1].id = 2;
- tree.nodes[1].role = ax::mojom::Role::kImage;
- tree.nodes[1].AddStringAttribute(ax::mojom::StringAttribute::kImageAnnotation,
- "Annotation");
- tree.nodes[1].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kEligibleForAnnotation);
- expected_names.push_back(
- L"To get missing image descriptions, open the context menu.");
-
- // If the status is EligibleForAnnotation, the discoverability string
- // should be appended to the existing name.
- tree.nodes[2].id = 3;
- tree.nodes[2].role = ax::mojom::Role::kImage;
- tree.nodes[2].AddStringAttribute(ax::mojom::StringAttribute::kImageAnnotation,
- "Annotation");
- tree.nodes[2].SetName("ExistingLabel");
- tree.nodes[2].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kEligibleForAnnotation);
- expected_names.push_back(
- L"ExistingLabel. To get missing image descriptions, open the context "
- L"menu.");
-
- // If the status is SilentlyEligibleForAnnotation, the discoverability string
- // should not be appended to the existing name.
- tree.nodes[3].id = 4;
- tree.nodes[3].role = ax::mojom::Role::kImage;
- tree.nodes[3].AddStringAttribute(ax::mojom::StringAttribute::kImageAnnotation,
- "Annotation");
- tree.nodes[3].SetName("ExistingLabel");
- tree.nodes[3].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kSilentlyEligibleForAnnotation);
- expected_names.push_back(L"ExistingLabel");
-
- // If the status is IneligibleForAnnotation, nothing should be appended.
- tree.nodes[4].id = 5;
- tree.nodes[4].role = ax::mojom::Role::kImage;
- tree.nodes[4].AddStringAttribute(ax::mojom::StringAttribute::kImageAnnotation,
- "Annotation");
- tree.nodes[4].SetName("ExistingLabel");
- tree.nodes[4].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kIneligibleForAnnotation);
- expected_names.push_back(L"ExistingLabel");
-
- // If the status is AnnotationPending, pending text should be appended
- // to the name.
- tree.nodes[5].id = 6;
- tree.nodes[5].role = ax::mojom::Role::kImage;
- tree.nodes[5].AddStringAttribute(ax::mojom::StringAttribute::kImageAnnotation,
- "Annotation");
- tree.nodes[5].SetName("ExistingLabel");
- tree.nodes[5].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kAnnotationPending);
- expected_names.push_back(L"ExistingLabel. Getting description...");
-
- // If the status is AnnotationSucceeded, and there's no annotation,
- // nothing should be appended. (Ideally this shouldn't happen.)
- tree.nodes[6].id = 7;
- tree.nodes[6].role = ax::mojom::Role::kImage;
- tree.nodes[6].SetName("ExistingLabel");
- tree.nodes[6].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kAnnotationSucceeded);
- expected_names.push_back(L"ExistingLabel");
-
- // If the status is AnnotationSucceeded, the annotation should be appended
- // to the existing label.
- tree.nodes[7].id = 8;
- tree.nodes[7].role = ax::mojom::Role::kImage;
- tree.nodes[7].AddStringAttribute(ax::mojom::StringAttribute::kImageAnnotation,
- "Annotation");
- tree.nodes[7].SetName("ExistingLabel");
- tree.nodes[7].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kAnnotationSucceeded);
- expected_names.push_back(L"ExistingLabel. Annotation");
-
- // If the status is AnnotationEmpty, failure text should be added to the
- // name.
- tree.nodes[8].id = 9;
- tree.nodes[8].role = ax::mojom::Role::kImage;
- tree.nodes[8].AddStringAttribute(ax::mojom::StringAttribute::kImageAnnotation,
- "Annotation");
- tree.nodes[8].SetName("ExistingLabel");
- tree.nodes[8].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kAnnotationEmpty);
- expected_names.push_back(L"ExistingLabel. No description available.");
-
- // If the status is AnnotationAdult, appropriate text should be appended
- // to the name.
- tree.nodes[9].id = 10;
- tree.nodes[9].role = ax::mojom::Role::kImage;
- tree.nodes[9].AddStringAttribute(ax::mojom::StringAttribute::kImageAnnotation,
- "Annotation");
- tree.nodes[9].SetName("ExistingLabel");
- tree.nodes[9].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kAnnotationAdult);
- expected_names.push_back(
- L"ExistingLabel. Appears to contain adult content. No description "
- L"available.");
-
- // If the status is AnnotationProcessFailed, failure text should be added
- // to the name.
- tree.nodes[10].id = 11;
- tree.nodes[10].role = ax::mojom::Role::kImage;
- tree.nodes[10].AddStringAttribute(
- ax::mojom::StringAttribute::kImageAnnotation, "Annotation");
- tree.nodes[10].SetName("ExistingLabel");
- tree.nodes[10].SetImageAnnotationStatus(
- ax::mojom::ImageAnnotationStatus::kAnnotationProcessFailed);
- expected_names.push_back(L"ExistingLabel. No description available.");
-
- // We should have one expected name per child of the root.
- ASSERT_EQ(expected_names.size(), tree.nodes[0].child_ids.size());
- int child_count = static_cast<int>(expected_names.size());
-
- Init(tree);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
-
- for (int child_index = 0; child_index < child_count; child_index++) {
- ComPtr<IDispatch> child_dispatch;
- ASSERT_HRESULT_SUCCEEDED(root_obj->get_accChild(
- ScopedVariant(child_index + 1), &child_dispatch));
- ComPtr<IAccessible> child;
- ASSERT_HRESULT_SUCCEEDED(child_dispatch.As(&child));
-
- ScopedBstr name;
- EXPECT_EQ(S_OK, child->get_accName(SELF, name.Receive()));
- EXPECT_STREQ(expected_names[child_index], name.Get());
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTextGetNCharacters) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
-
- AXNodeData node;
- node.id = 2;
- node.role = ax::mojom::Role::kStaticText;
- node.SetName("Name");
- root.child_ids.push_back(node.id);
-
- Init(root, node);
-
- AXNode* child_node = GetRootAsAXNode()->children()[0];
- ComPtr<IAccessible> child_iaccessible(IAccessibleFromNode(child_node));
- ASSERT_NE(nullptr, child_iaccessible.Get());
-
- ComPtr<IAccessibleText> text;
- child_iaccessible.As(&text);
- ASSERT_NE(nullptr, text.Get());
-
- LONG count;
- EXPECT_HRESULT_SUCCEEDED(text->get_nCharacters(&count));
- EXPECT_EQ(4, count);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTextGetOffsetAtPoint) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kWebArea;
- root.relative_bounds.bounds = gfx::RectF(0, 0, 300, 200);
- root.child_ids = {2, 3};
-
- AXNodeData button;
- button.id = 2;
- button.role = ax::mojom::Role::kButton;
- button.SetName("button");
- button.relative_bounds.bounds = gfx::RectF(20, 0, 10, 10);
-
- AXNodeData static_text1;
- static_text1.id = 3;
- static_text1.role = ax::mojom::Role::kStaticText;
- static_text1.SetName("line 1");
- static_text1.relative_bounds.bounds = gfx::RectF(0, 20, 30, 10);
- static_text1.child_ids = {4};
-
- AXNodeData inline_box1;
- inline_box1.id = 4;
- inline_box1.role = ax::mojom::Role::kInlineTextBox;
- inline_box1.SetName("line 1");
- inline_box1.relative_bounds.bounds = gfx::RectF(0, 20, 30, 10);
- std::vector<int32_t> character_offsets1;
- // The width of each character is 5px, height is 10px.
- character_offsets1.push_back(5); // "l" {0, 20, 5x10}
- character_offsets1.push_back(10); // "i" {5, 20, 5x10}
- character_offsets1.push_back(15); // "n" {10, 20, 5x10}
- character_offsets1.push_back(20); // "e" {15, 20, 5x10}
- character_offsets1.push_back(25); // " " {20, 20, 5x10}
- character_offsets1.push_back(30); // "1" {25, 20, 5x10}
-
- inline_box1.AddIntListAttribute(
- ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets1);
- inline_box1.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
- std::vector<int32_t>{0, 5});
- inline_box1.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
- std::vector<int32_t>{4, 6});
-
- Init(root, button, static_text1, inline_box1);
-
- LONG offset_result;
- ComPtr<IAccessible> root_iaccessible(IAccessibleFromNode(GetRootAsAXNode()));
- ASSERT_NE(nullptr, root_iaccessible.Get());
-
- ComPtr<IAccessibleText> root_text;
- root_iaccessible.As(&root_text);
- ASSERT_NE(nullptr, root_text.Get());
-
- // Test point(0, 0) with coordinate parent relative, which is not supported.
- // Expected result: S_FALSE.
- EXPECT_EQ(S_FALSE, root_text->get_offsetAtPoint(
- 0, 0, IA2CoordinateType::IA2_COORDTYPE_PARENT_RELATIVE,
- &offset_result));
- EXPECT_EQ(-1, offset_result);
-
- // Test point(0, 0) retrieved from IAccessibleText of the root web area is
- // outside of any text. Expected result: S_FALSE.
- EXPECT_EQ(S_FALSE, root_text->get_offsetAtPoint(
- 0, 0, IA2CoordinateType::IA2_COORDTYPE_SCREEN_RELATIVE,
- &offset_result));
- EXPECT_EQ(-1, offset_result);
-
- // Test point(25, 5) retrieved from IAccessibleText of the root web area is
- // on button, and outside of any text. Expected result: S_FALSE.
- EXPECT_EQ(S_FALSE,
- root_text->get_offsetAtPoint(
- 25, 5, IA2CoordinateType::IA2_COORDTYPE_SCREEN_RELATIVE,
- &offset_result));
- EXPECT_EQ(-1, offset_result);
-
- // Test point(0, 20) retrieved from IAccessibleText of the root web area is
- // on "line 1", character="l". Expected result: S_OK, offset=0.
- EXPECT_EQ(S_OK, root_text->get_offsetAtPoint(
- 0, 20, IA2CoordinateType::IA2_COORDTYPE_SCREEN_RELATIVE,
- &offset_result));
- EXPECT_EQ(0, offset_result);
-
- AXNode* static_text1_node = GetRootAsAXNode()->children()[1];
- ComPtr<IAccessible> text1_iaccessible(IAccessibleFromNode(static_text1_node));
- ASSERT_NE(nullptr, text1_iaccessible.Get());
-
- ComPtr<IAccessibleText> text1;
- text1_iaccessible.As(&text1);
- ASSERT_NE(nullptr, text1.Get());
-
- // "l" 4 points of bounds {(0, 20), (5, 20), (0, 30), (5, 30)}
- // "i" 4 points of bounds {(5, 20), (10, 20), (5, 30), (10, 30)}
- // "n" 4 points of bounds {(10, 20), (15, 20), (10, 30), (15, 30)}
- // "e" 4 points of bounds {(15, 20), (20, 20), (15, 30), (20, 30)}
- // " " 4 points of bounds {(20, 20), (25, 20), (20, 30), (25, 30)}
- // "1" 4 points of bounds {(25, 20), (30, 20), (25, 30), (30, 30)}
-
- // Test point(0, 0) outside of any character bounds and text.
- EXPECT_EQ(S_FALSE, text1->get_offsetAtPoint(
- 0, 0, IA2CoordinateType::IA2_COORDTYPE_SCREEN_RELATIVE,
- &offset_result));
- EXPECT_EQ(-1, offset_result);
-
- // Test point(30, 30) outside of any character bounds but on the text.
- EXPECT_EQ(S_OK, text1->get_offsetAtPoint(
- 30, 30, IA2CoordinateType::IA2_COORDTYPE_SCREEN_RELATIVE,
- &offset_result));
- EXPECT_EQ(-1, offset_result);
-
- // Test point(0, 20) inside bounds of "l", text offset=0
- // character bounds={(0, 20), (5, 20), (0, 30), (5, 30)}
- EXPECT_HRESULT_SUCCEEDED(text1->get_offsetAtPoint(
- 0, 20, IA2CoordinateType::IA2_COORDTYPE_SCREEN_RELATIVE, &offset_result));
- EXPECT_EQ(0, offset_result);
-
- // Test point(9, 20) inside bounds of "i", text offset=1
- // character bounds={(5, 20), (10, 20), (5, 30), (10, 30)}
- EXPECT_HRESULT_SUCCEEDED(text1->get_offsetAtPoint(
- 9, 20, IA2CoordinateType::IA2_COORDTYPE_SCREEN_RELATIVE, &offset_result));
- EXPECT_EQ(1, offset_result);
-
- // Test point(10, 30) inside bounds of "n", text offset=2
- // character bounds={(10, 20), (15, 20), (10, 30), (15, 30)}
- EXPECT_HRESULT_SUCCEEDED(text1->get_offsetAtPoint(
- 10, 29, IA2CoordinateType::IA2_COORDTYPE_SCREEN_RELATIVE,
- &offset_result));
- EXPECT_EQ(2, offset_result);
-
- // Test point(19, 29) inside bounds of "e", text offset=3
- // character bounds={(15, 20), (20, 20), (15, 30), (20, 30)
- EXPECT_HRESULT_SUCCEEDED(text1->get_offsetAtPoint(
- 19, 29, IA2CoordinateType::IA2_COORDTYPE_SCREEN_RELATIVE,
- &offset_result));
- EXPECT_EQ(3, offset_result);
-
- // Test point(23, 25) inside bounds of " ", text offset=4
- // character bounds={(20, 20), (25, 20), (20, 30), (25, 30)}
- EXPECT_HRESULT_SUCCEEDED(text1->get_offsetAtPoint(
- 23, 25, IA2CoordinateType::IA2_COORDTYPE_SCREEN_RELATIVE,
- &offset_result));
- EXPECT_EQ(4, offset_result);
-
- // Test point(25, 20) inside bounds of "1", text offset=5
- // character bounds={(25, 20), (30, 20), (25, 30), (30, 30)}
- EXPECT_HRESULT_SUCCEEDED(text1->get_offsetAtPoint(
- 25, 20, IA2CoordinateType::IA2_COORDTYPE_SCREEN_RELATIVE,
- &offset_result));
- EXPECT_EQ(5, offset_result);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTextTextFieldRemoveSelection) {
- Init(BuildTextFieldWithSelectionRange(1, 2));
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG start_offset, end_offset;
- EXPECT_HRESULT_SUCCEEDED(
- text_field->get_selection(0, &start_offset, &end_offset));
- EXPECT_EQ(1, start_offset);
- EXPECT_EQ(2, end_offset);
-
- EXPECT_HRESULT_SUCCEEDED(text_field->removeSelection(0));
-
- // There is no selection, just a caret.
- EXPECT_EQ(E_INVALIDARG,
- text_field->get_selection(0, &start_offset, &end_offset));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTextContentEditableRemoveSelection) {
- Init(BuildTextFieldWithSelectionRange(1, 2));
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG start_offset, end_offset;
- EXPECT_HRESULT_SUCCEEDED(
- text_field->get_selection(0, &start_offset, &end_offset));
- EXPECT_EQ(1, start_offset);
- EXPECT_EQ(2, end_offset);
-
- EXPECT_HRESULT_SUCCEEDED(text_field->removeSelection(0));
-
- // There is no selection, just a caret.
- EXPECT_EQ(E_INVALIDARG,
- text_field->get_selection(0, &start_offset, &end_offset));
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTextTextFieldGetSelected) {
- Init(BuildTextFieldWithSelectionRange(1, 2));
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG start_offset, end_offset;
-
- // We only care about selection_index of zero, so passing anything but 0 as
- // the first parameter should fail.
- EXPECT_EQ(E_INVALIDARG,
- text_field->get_selection(1, &start_offset, &end_offset));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_field->get_selection(0, &start_offset, &end_offset));
- EXPECT_EQ(1, start_offset);
- EXPECT_EQ(2, end_offset);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTextTextFieldGetSelectedBackward) {
- Init(BuildTextFieldWithSelectionRange(1, 2));
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG start_offset, end_offset;
- EXPECT_HRESULT_SUCCEEDED(
- text_field->get_selection(0, &start_offset, &end_offset));
- EXPECT_EQ(1, start_offset);
- EXPECT_EQ(2, end_offset);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleContentEditabledGetSelected) {
- Init(BuildContentEditableWithSelectionRange(1, 2));
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG start_offset, end_offset;
-
- // We only care about selection_index of zero, so passing anything but 0 as
- // the first parameter should fail.
- EXPECT_EQ(E_INVALIDARG,
- text_field->get_selection(1, &start_offset, &end_offset));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_field->get_selection(0, &start_offset, &end_offset));
- EXPECT_EQ(1, start_offset);
- EXPECT_EQ(2, end_offset);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleContentEditabledGetSelectedBackward) {
- Init(BuildContentEditableWithSelectionRange(1, 2));
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG start_offset, end_offset;
- EXPECT_HRESULT_SUCCEEDED(
- text_field->get_selection(0, &start_offset, &end_offset));
- EXPECT_EQ(1, start_offset);
- EXPECT_EQ(2, end_offset);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTextTextFieldAddSelection) {
- Init(BuildTextField());
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG start_offset, end_offset;
- // There is no selection, just a caret.
- EXPECT_EQ(E_INVALIDARG,
- text_field->get_selection(0, &start_offset, &end_offset));
-
- EXPECT_HRESULT_SUCCEEDED(text_field->addSelection(1, 2));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_field->get_selection(0, &start_offset, &end_offset));
- EXPECT_EQ(1, start_offset);
- EXPECT_EQ(2, end_offset);
-}
-
-// This test is disabled until UpdateStep2ComputeHypertext is migrated over
-// to AXPlatformNodeWin because |hypertext_| is only initialized
-// on the BrowserAccessibility side.
-TEST_F(AXPlatformNodeWinTest,
- DISABLED_IAccessibleTextContentEditableAddSelection) {
- Init(BuildContentEditable());
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG start_offset, end_offset;
- // There is no selection, just a caret.
- EXPECT_EQ(E_INVALIDARG,
- text_field->get_selection(0, &start_offset, &end_offset));
-
- EXPECT_HRESULT_SUCCEEDED(text_field->addSelection(1, 2));
-
- EXPECT_HRESULT_SUCCEEDED(
- text_field->get_selection(0, &start_offset, &end_offset));
- EXPECT_EQ(1, start_offset);
- EXPECT_EQ(2, end_offset);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTextTextFieldGetNSelectionsZero) {
- Init(BuildTextField());
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG selections;
- EXPECT_HRESULT_SUCCEEDED(text_field->get_nSelections(&selections));
- EXPECT_EQ(0, selections);
-}
-
-TEST_F(AXPlatformNodeWinTest,
- IAccessibleTextContentEditableGetNSelectionsZero) {
- Init(BuildContentEditable());
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG selections;
- EXPECT_HRESULT_SUCCEEDED(text_field->get_nSelections(&selections));
- EXPECT_EQ(0, selections);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTextContentEditableGetNSelections) {
- Init(BuildContentEditableWithSelectionRange(1, 2));
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG selections;
- EXPECT_HRESULT_SUCCEEDED(text_field->get_nSelections(&selections));
- EXPECT_EQ(1, selections);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTextTextFieldGetCaretOffsetNoCaret) {
- Init(BuildTextField());
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG offset;
- EXPECT_EQ(S_FALSE, text_field->get_caretOffset(&offset));
- EXPECT_EQ(0, offset);
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleTextTextFieldGetCaretOffsetHasCaret) {
- Init(BuildTextFieldWithSelectionRange(1, 2));
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG offset;
- EXPECT_HRESULT_SUCCEEDED(text_field->get_caretOffset(&offset));
- EXPECT_EQ(2, offset);
-}
-
-TEST_F(AXPlatformNodeWinTest,
- IAccessibleTextContextEditableGetCaretOffsetNoCaret) {
- Init(BuildContentEditable());
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG offset;
- EXPECT_EQ(S_FALSE, text_field->get_caretOffset(&offset));
- EXPECT_EQ(0, offset);
-}
-
-TEST_F(AXPlatformNodeWinTest,
- IAccessibleTextContentEditableGetCaretOffsetHasCaret) {
- Init(BuildContentEditableWithSelectionRange(1, 2));
-
- ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible());
- ComPtr<IAccessibleText> text_field;
- ia2_text_field.As(&text_field);
- ASSERT_NE(nullptr, text_field.Get());
-
- LONG offset;
- EXPECT_HRESULT_SUCCEEDED(text_field->get_caretOffset(&offset));
- EXPECT_EQ(2, offset);
-}
-
-TEST_F(AXPlatformNodeWinTest, IGridProviderGetRowCount) {
- Init(BuildAriaColumnAndRowCountGrids());
-
- // Empty Grid
- ComPtr<IGridProvider> grid1_provider =
- QueryInterfaceFromNode<IGridProvider>(GetRootAsAXNode()->children()[0]);
-
- // Grid with a cell that defines aria-rowindex (4) and aria-colindex (5)
- ComPtr<IGridProvider> grid2_provider =
- QueryInterfaceFromNode<IGridProvider>(GetRootAsAXNode()->children()[1]);
-
- // Grid that specifies aria-rowcount (2) and aria-colcount (3)
- ComPtr<IGridProvider> grid3_provider =
- QueryInterfaceFromNode<IGridProvider>(GetRootAsAXNode()->children()[2]);
-
- // Grid that specifies aria-rowcount and aria-colcount are both (-1)
- ComPtr<IGridProvider> grid4_provider =
- QueryInterfaceFromNode<IGridProvider>(GetRootAsAXNode()->children()[3]);
-
- int row_count;
-
- EXPECT_HRESULT_SUCCEEDED(grid1_provider->get_RowCount(&row_count));
- EXPECT_EQ(row_count, 0);
-
- EXPECT_HRESULT_SUCCEEDED(grid2_provider->get_RowCount(&row_count));
- EXPECT_EQ(row_count, 4);
-
- EXPECT_HRESULT_SUCCEEDED(grid3_provider->get_RowCount(&row_count));
- EXPECT_EQ(row_count, 2);
-
- EXPECT_EQ(E_UNEXPECTED, grid4_provider->get_RowCount(&row_count));
-}
-
-TEST_F(AXPlatformNodeWinTest, IGridProviderGetColumnCount) {
- Init(BuildAriaColumnAndRowCountGrids());
-
- // Empty Grid
- ComPtr<IGridProvider> grid1_provider =
- QueryInterfaceFromNode<IGridProvider>(GetRootAsAXNode()->children()[0]);
-
- // Grid with a cell that defines aria-rowindex (4) and aria-colindex (5)
- ComPtr<IGridProvider> grid2_provider =
- QueryInterfaceFromNode<IGridProvider>(GetRootAsAXNode()->children()[1]);
-
- // Grid that specifies aria-rowcount (2) and aria-colcount (3)
- ComPtr<IGridProvider> grid3_provider =
- QueryInterfaceFromNode<IGridProvider>(GetRootAsAXNode()->children()[2]);
-
- // Grid that specifies aria-rowcount and aria-colcount are both (-1)
- ComPtr<IGridProvider> grid4_provider =
- QueryInterfaceFromNode<IGridProvider>(GetRootAsAXNode()->children()[3]);
-
- int column_count;
-
- EXPECT_HRESULT_SUCCEEDED(grid1_provider->get_ColumnCount(&column_count));
- EXPECT_EQ(column_count, 0);
-
- EXPECT_HRESULT_SUCCEEDED(grid2_provider->get_ColumnCount(&column_count));
- EXPECT_EQ(column_count, 5);
-
- EXPECT_HRESULT_SUCCEEDED(grid3_provider->get_ColumnCount(&column_count));
- EXPECT_EQ(column_count, 3);
-
- EXPECT_EQ(E_UNEXPECTED, grid4_provider->get_ColumnCount(&column_count));
-}
-
-TEST_F(AXPlatformNodeWinTest, IGridProviderGetItem) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kGrid;
- root.AddIntAttribute(ax::mojom::IntAttribute::kAriaRowCount, 1);
- root.AddIntAttribute(ax::mojom::IntAttribute::kAriaColumnCount, 1);
-
- AXNodeData row1;
- row1.id = 2;
- row1.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row1.id);
-
- AXNodeData cell1;
- cell1.id = 3;
- cell1.role = ax::mojom::Role::kCell;
- row1.child_ids.push_back(cell1.id);
-
- Init(root, row1, cell1);
-
- ComPtr<IGridProvider> root_igridprovider(
- QueryInterfaceFromNode<IGridProvider>(GetRootAsAXNode()));
-
- ComPtr<IRawElementProviderSimple> cell1_irawelementprovidersimple(
- QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetRootAsAXNode()->children()[0]->children()[0]));
-
- IRawElementProviderSimple* grid_item = nullptr;
- EXPECT_HRESULT_SUCCEEDED(root_igridprovider->GetItem(0, 0, &grid_item));
- EXPECT_NE(nullptr, grid_item);
- EXPECT_EQ(cell1_irawelementprovidersimple.Get(), grid_item);
-}
-
-TEST_F(AXPlatformNodeWinTest, ITableProviderGetColumnHeaders) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTable;
-
- AXNodeData row1;
- row1.id = 2;
- row1.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row1.id);
-
- AXNodeData column_header;
- column_header.id = 3;
- column_header.role = ax::mojom::Role::kColumnHeader;
- column_header.SetName(L"column_header");
- row1.child_ids.push_back(column_header.id);
-
- AXNodeData row_header;
- row_header.id = 4;
- row_header.role = ax::mojom::Role::kRowHeader;
- row_header.SetName(L"row_header");
- row1.child_ids.push_back(row_header.id);
-
- Init(root, row1, column_header, row_header);
-
- ComPtr<ITableProvider> root_itableprovider(
- QueryInterfaceFromNode<ITableProvider>(GetRootAsAXNode()));
-
- base::win::ScopedSafearray safearray;
- EXPECT_HRESULT_SUCCEEDED(
- root_itableprovider->GetColumnHeaders(safearray.Receive()));
- EXPECT_NE(nullptr, safearray.Get());
-
- std::vector<std::wstring> expected_names = {L"column_header"};
- EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(safearray.Get(), UIA_NamePropertyId,
- expected_names);
-
- // Remove column_header's native event target and verify it's no longer
- // returned.
- TestAXNodeWrapper* column_header_wrapper = TestAXNodeWrapper::GetOrCreate(
- GetTree(), GetRootAsAXNode()->children()[0]->children()[0]);
- column_header_wrapper->ResetNativeEventTarget();
-
- safearray.Release();
- EXPECT_HRESULT_SUCCEEDED(
- root_itableprovider->GetColumnHeaders(safearray.Receive()));
- EXPECT_EQ(nullptr, safearray.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, ITableProviderGetColumnHeadersMultipleHeaders) {
- // Build a table like this:
- // header_r1c1 | header_r1c2 | header_r1c3
- // cell_r2c1 | cell_r2c2 | cell_r2c3
- // cell_r3c1 | header_r3c2 |
-
- // <table>
- // <tr aria-label="row1">
- // <th>header_r1c1</th>
- // <th>header_r1c2</th>
- // <th>header_r1c3</th>
- // </tr>
- // <tr aria-label="row2">
- // <td>cell_r2c1</td>
- // <td>cell_r2c2</td>
- // <td>cell_r2c3</td>
- // </tr>
- // <tr aria-label="row3">
- // <td>cell_r3c1</td>
- // <th>header_r3c2</th>
- // </tr>
- // </table>
-
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTable;
-
- AXNodeData row1;
- row1.id = 2;
- row1.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row1.id);
-
- AXNodeData row2;
- row2.id = 3;
- row2.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row2.id);
-
- AXNodeData row3;
- row3.id = 4;
- row3.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row3.id);
-
- // <tr aria-label="row1">
- // <th>header_r1c1</th> <th>header_r1c2</th> <th>header_r1c3</th>
- // </tr>
- AXNodeData header_r1c1;
- header_r1c1.id = 5;
- header_r1c1.role = ax::mojom::Role::kColumnHeader;
- header_r1c1.SetName(L"header_r1c1");
- row1.child_ids.push_back(header_r1c1.id);
-
- AXNodeData header_r1c2;
- header_r1c2.id = 6;
- header_r1c2.role = ax::mojom::Role::kColumnHeader;
- header_r1c2.SetName(L"header_r1c2");
- row1.child_ids.push_back(header_r1c2.id);
-
- AXNodeData header_r1c3;
- header_r1c3.id = 7;
- header_r1c3.role = ax::mojom::Role::kColumnHeader;
- header_r1c3.SetName(L"header_r1c3");
- row1.child_ids.push_back(header_r1c3.id);
-
- // <tr aria-label="row2">
- // <td>cell_r2c1</td> <td>cell_r2c2</td> <td>cell_r2c3</td>
- // </tr>
- AXNodeData cell_r2c1;
- cell_r2c1.id = 8;
- cell_r2c1.role = ax::mojom::Role::kCell;
- cell_r2c1.SetName(L"cell_r2c1");
- row2.child_ids.push_back(cell_r2c1.id);
-
- AXNodeData cell_r2c2;
- cell_r2c2.id = 9;
- cell_r2c2.role = ax::mojom::Role::kCell;
- cell_r2c2.SetName(L"cell_r2c2");
- row2.child_ids.push_back(cell_r2c2.id);
-
- AXNodeData cell_r2c3;
- cell_r2c3.id = 10;
- cell_r2c3.role = ax::mojom::Role::kCell;
- cell_r2c3.SetName(L"cell_r2c3");
- row2.child_ids.push_back(cell_r2c3.id);
-
- // <tr aria-label="row3">
- // <td>cell_r3c1</td> <th>header_r3c2</th>
- // </tr>
- AXNodeData cell_r3c1;
- cell_r3c1.id = 11;
- cell_r3c1.role = ax::mojom::Role::kCell;
- cell_r3c1.SetName(L"cell_r3c1");
- row3.child_ids.push_back(cell_r3c1.id);
-
- AXNodeData header_r3c2;
- header_r3c2.id = 12;
- header_r3c2.role = ax::mojom::Role::kColumnHeader;
- header_r3c2.SetName(L"header_r3c2");
- row3.child_ids.push_back(header_r3c2.id);
-
- Init(root, row1, row2, row3, header_r1c1, header_r1c2, header_r1c3, cell_r2c1,
- cell_r2c2, cell_r2c3, cell_r3c1, header_r3c2);
-
- ComPtr<ITableProvider> root_itableprovider(
- QueryInterfaceFromNode<ITableProvider>(GetRootAsAXNode()));
-
- base::win::ScopedSafearray safearray;
- EXPECT_HRESULT_SUCCEEDED(
- root_itableprovider->GetColumnHeaders(safearray.Receive()));
- EXPECT_NE(nullptr, safearray.Get());
-
- // Validate that we retrieve all column headers of the table and in the order
- // below.
- std::vector<std::wstring> expected_names = {L"header_r1c1", L"header_r1c2",
- L"header_r3c2", L"header_r1c3"};
- EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(safearray.Get(), UIA_NamePropertyId,
- expected_names);
-}
-
-TEST_F(AXPlatformNodeWinTest, ITableProviderGetRowHeaders) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTable;
-
- AXNodeData row1;
- row1.id = 2;
- row1.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row1.id);
-
- AXNodeData column_header;
- column_header.id = 3;
- column_header.role = ax::mojom::Role::kColumnHeader;
- column_header.SetName(L"column_header");
- row1.child_ids.push_back(column_header.id);
-
- AXNodeData row_header;
- row_header.id = 4;
- row_header.role = ax::mojom::Role::kRowHeader;
- row_header.SetName(L"row_header");
- row1.child_ids.push_back(row_header.id);
-
- Init(root, row1, column_header, row_header);
-
- ComPtr<ITableProvider> root_itableprovider(
- QueryInterfaceFromNode<ITableProvider>(GetRootAsAXNode()));
-
- base::win::ScopedSafearray safearray;
- EXPECT_HRESULT_SUCCEEDED(
- root_itableprovider->GetRowHeaders(safearray.Receive()));
- EXPECT_NE(nullptr, safearray.Get());
- std::vector<std::wstring> expected_names = {L"row_header"};
- EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(safearray.Get(), UIA_NamePropertyId,
- expected_names);
-
- // Remove row_header's native event target and verify it's no longer returned.
- TestAXNodeWrapper* row_header_wrapper = TestAXNodeWrapper::GetOrCreate(
- GetTree(), GetRootAsAXNode()->children()[0]->children()[1]);
- row_header_wrapper->ResetNativeEventTarget();
-
- safearray.Release();
- EXPECT_HRESULT_SUCCEEDED(
- root_itableprovider->GetRowHeaders(safearray.Receive()));
- EXPECT_EQ(nullptr, safearray.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, ITableProviderGetRowOrColumnMajor) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTable;
-
- Init(root);
-
- ComPtr<ITableProvider> root_itableprovider(
- QueryInterfaceFromNode<ITableProvider>(GetRootAsAXNode()));
-
- RowOrColumnMajor row_or_column_major;
- EXPECT_HRESULT_SUCCEEDED(
- root_itableprovider->get_RowOrColumnMajor(&row_or_column_major));
- EXPECT_EQ(row_or_column_major, RowOrColumnMajor_RowMajor);
-}
-
-TEST_F(AXPlatformNodeWinTest, ITableItemProviderGetColumnHeaderItems) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTable;
-
- AXNodeData row1;
- row1.id = 2;
- row1.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row1.id);
-
- AXNodeData column_header_1;
- column_header_1.id = 3;
- column_header_1.role = ax::mojom::Role::kColumnHeader;
- column_header_1.SetName(L"column_header_1");
- row1.child_ids.push_back(column_header_1.id);
-
- AXNodeData column_header_2;
- column_header_2.id = 4;
- column_header_2.role = ax::mojom::Role::kColumnHeader;
- column_header_2.SetName(L"column_header_2");
- row1.child_ids.push_back(column_header_2.id);
-
- AXNodeData row2;
- row2.id = 5;
- row2.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row2.id);
-
- AXNodeData cell;
- cell.id = 6;
- cell.role = ax::mojom::Role::kCell;
- row2.child_ids.push_back(cell.id);
-
- Init(root, row1, column_header_1, column_header_2, row2, cell);
-
- TestAXNodeWrapper* root_wrapper =
- TestAXNodeWrapper::GetOrCreate(GetTree(), GetRootAsAXNode());
- root_wrapper->BuildAllWrappers(GetTree(), GetRootAsAXNode());
-
- ComPtr<ITableItemProvider> cell_itableitemprovider(
- QueryInterfaceFromNode<ITableItemProvider>(
- GetRootAsAXNode()->children()[1]->children()[0]));
-
- base::win::ScopedSafearray safearray;
- EXPECT_HRESULT_SUCCEEDED(
- cell_itableitemprovider->GetColumnHeaderItems(safearray.Receive()));
- EXPECT_NE(nullptr, safearray.Get());
-
- std::vector<std::wstring> expected_names = {L"column_header_1"};
- EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(safearray.Get(), UIA_NamePropertyId,
- expected_names);
-
- // Remove column_header_1's native event target and verify it's no longer
- // returned.
- TestAXNodeWrapper* column_header_wrapper = TestAXNodeWrapper::GetOrCreate(
- GetTree(), GetRootAsAXNode()->children()[0]->children()[0]);
- column_header_wrapper->ResetNativeEventTarget();
-
- safearray.Release();
- EXPECT_HRESULT_SUCCEEDED(
- cell_itableitemprovider->GetColumnHeaderItems(safearray.Receive()));
- EXPECT_EQ(nullptr, safearray.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, ITableItemProviderGetRowHeaderItems) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTable;
-
- AXNodeData row1;
- row1.id = 2;
- row1.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row1.id);
-
- AXNodeData row_header_1;
- row_header_1.id = 3;
- row_header_1.role = ax::mojom::Role::kRowHeader;
- row_header_1.SetName(L"row_header_1");
- row1.child_ids.push_back(row_header_1.id);
-
- AXNodeData cell;
- cell.id = 4;
- cell.role = ax::mojom::Role::kCell;
- row1.child_ids.push_back(cell.id);
-
- AXNodeData row2;
- row2.id = 5;
- row2.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row2.id);
-
- AXNodeData row_header_2;
- row_header_2.id = 6;
- row_header_2.role = ax::mojom::Role::kRowHeader;
- row_header_2.SetName(L"row_header_2");
- row2.child_ids.push_back(row_header_2.id);
-
- Init(root, row1, row_header_1, cell, row2, row_header_2);
-
- TestAXNodeWrapper* root_wrapper =
- TestAXNodeWrapper::GetOrCreate(GetTree(), GetRootAsAXNode());
- root_wrapper->BuildAllWrappers(GetTree(), GetRootAsAXNode());
-
- ComPtr<ITableItemProvider> cell_itableitemprovider(
- QueryInterfaceFromNode<ITableItemProvider>(
- GetRootAsAXNode()->children()[0]->children()[1]));
-
- base::win::ScopedSafearray safearray;
- EXPECT_HRESULT_SUCCEEDED(
- cell_itableitemprovider->GetRowHeaderItems(safearray.Receive()));
- EXPECT_NE(nullptr, safearray.Get());
- std::vector<std::wstring> expected_names = {L"row_header_1"};
- EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(safearray.Get(), UIA_NamePropertyId,
- expected_names);
-
- // Remove row_header_1's native event target and verify it's no longer
- // returned.
- TestAXNodeWrapper* row_header_wrapper = TestAXNodeWrapper::GetOrCreate(
- GetTree(), GetRootAsAXNode()->children()[0]->children()[0]);
- row_header_wrapper->ResetNativeEventTarget();
-
- safearray.Release();
- EXPECT_HRESULT_SUCCEEDED(
- cell_itableitemprovider->GetRowHeaderItems(safearray.Receive()));
- EXPECT_EQ(nullptr, safearray.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, IA2GetAttribute) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kButton;
- root.AddStringAttribute(ax::mojom::StringAttribute::kRoleDescription,
- "Potato");
- Init(root);
-
- ComPtr<IAccessible> root_obj(GetRootIAccessible());
- ComPtr<IAccessible2_2> iaccessible2 = ToIAccessible2_2(root_obj);
-
- ScopedBstr roledescription(L"roledescription");
- ScopedVariant result;
- ASSERT_EQ(S_OK, iaccessible2->get_attribute(roledescription.Get(),
- result.Receive()));
- ScopedBstr expected_bstr(L"Potato");
- ASSERT_EQ(VT_BSTR, result.type());
- EXPECT_STREQ(expected_bstr.Get(), result.ptr()->bstrVal);
-
- ScopedBstr smoothness(L"smoothness");
- ScopedVariant result2;
- EXPECT_EQ(S_FALSE,
- iaccessible2->get_attribute(smoothness.Get(), result2.Receive()));
-
- EXPECT_EQ(E_INVALIDARG, iaccessible2->get_attribute(nullptr, nullptr));
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetPropertySimple) {
- AXNodeData root;
- root.role = ax::mojom::Role::kList;
- root.SetName("fake name");
- root.AddStringAttribute(ax::mojom::StringAttribute::kAccessKey, "Ctrl+Q");
- root.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "en-us");
- root.AddStringAttribute(ax::mojom::StringAttribute::kKeyShortcuts, "Alt+F4");
- root.AddStringAttribute(ax::mojom::StringAttribute::kDescription,
- "fake description");
- root.AddIntAttribute(ax::mojom::IntAttribute::kSetSize, 2);
- root.AddIntAttribute(ax::mojom::IntAttribute::kInvalidState, 1);
- root.id = 1;
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kListItem;
- child1.AddIntAttribute(ax::mojom::IntAttribute::kPosInSet, 1);
- child1.SetName("child1");
- root.child_ids.push_back(child1.id);
-
- Init(root, child1);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
- ScopedVariant uia_id;
- EXPECT_UIA_BSTR_EQ(root_node, UIA_AccessKeyPropertyId, L"Ctrl+Q");
- EXPECT_UIA_BSTR_EQ(root_node, UIA_AcceleratorKeyPropertyId, L"Alt+F4");
- ASSERT_HRESULT_SUCCEEDED(root_node->GetPropertyValue(
- UIA_AutomationIdPropertyId, uia_id.Receive()));
- EXPECT_UIA_BSTR_EQ(root_node, UIA_AutomationIdPropertyId,
- uia_id.ptr()->bstrVal);
- EXPECT_UIA_BSTR_EQ(root_node, UIA_FullDescriptionPropertyId,
- L"fake description");
- EXPECT_UIA_BSTR_EQ(root_node, UIA_AriaRolePropertyId, L"list");
- EXPECT_UIA_BSTR_EQ(root_node, UIA_AriaPropertiesPropertyId,
- L"readonly=true;expanded=false;multiline=false;"
- L"multiselectable=false;required=false;setsize=2");
- constexpr int en_us_lcid = 1033;
- EXPECT_UIA_INT_EQ(root_node, UIA_CulturePropertyId, en_us_lcid);
- EXPECT_UIA_BSTR_EQ(root_node, UIA_NamePropertyId, L"fake name");
- EXPECT_UIA_INT_EQ(root_node, UIA_ControlTypePropertyId,
- int{UIA_ListControlTypeId});
- EXPECT_UIA_INT_EQ(root_node, UIA_OrientationPropertyId,
- int{OrientationType_None});
- EXPECT_UIA_INT_EQ(root_node, UIA_SizeOfSetPropertyId, 2);
- EXPECT_UIA_INT_EQ(root_node, UIA_ToggleToggleStatePropertyId,
- int{ToggleState_Off});
- EXPECT_UIA_BOOL_EQ(root_node, UIA_IsPasswordPropertyId, false);
- EXPECT_UIA_BOOL_EQ(root_node, UIA_IsEnabledPropertyId, true);
- EXPECT_UIA_BOOL_EQ(root_node, UIA_HasKeyboardFocusPropertyId, false);
- EXPECT_UIA_BOOL_EQ(root_node, UIA_IsRequiredForFormPropertyId, false);
- EXPECT_UIA_BOOL_EQ(root_node, UIA_IsDataValidForFormPropertyId, true);
- EXPECT_UIA_BOOL_EQ(root_node, UIA_IsKeyboardFocusablePropertyId, false);
- EXPECT_UIA_BOOL_EQ(root_node, UIA_IsOffscreenPropertyId, false);
- ComPtr<IRawElementProviderSimple> child_node1 =
- QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetRootAsAXNode()->children()[0]);
- EXPECT_UIA_INT_EQ(child_node1, UIA_PositionInSetPropertyId, 1);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetPropertyValueClickablePoint) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kButton;
- root.relative_bounds.bounds = gfx::RectF(20, 30, 100, 200);
- Init(root);
-
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetRootIRawElementProviderSimple();
-
- // The clickable point of a rectangle {20, 30, 100, 200} is the rectangle's
- // center, with coordinates {x: 70, y: 130}.
- std::vector<double> expected_values = {70, 130};
- EXPECT_UIA_DOUBLE_ARRAY_EQ(raw_element_provider_simple,
- UIA_ClickablePointPropertyId, expected_values);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetPropertyValue_Histogram) {
- AXNodeData root;
- root.id = 1;
- Init(root);
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
-
- // Log a known property ID
- {
- base::HistogramTester histogram_tester;
- ScopedVariant property_value;
- root_node->GetPropertyValue(UIA_NamePropertyId, property_value.Receive());
- histogram_tester.ExpectUniqueSample(
- "Accessibility.WinAPIs.GetPropertyValue", UIA_NamePropertyId, 1);
- histogram_tester.ExpectTotalCount(
- "Accessibility.Performance.WinAPIs.UMA_API_GET_PROPERTY_VALUE", 1);
- }
-
- // Collapse unknown property IDs to zero
- {
- base::HistogramTester histogram_tester;
- ScopedVariant property_value;
- root_node->GetPropertyValue(42, property_value.Receive());
- histogram_tester.ExpectUniqueSample(
- "Accessibility.WinAPIs.GetPropertyValue", 0, 1);
- histogram_tester.ExpectTotalCount(
- "Accessibility.Performance.WinAPIs.UMA_API_GET_PROPERTY_VALUE", 1);
- }
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetPropertyValueIsDialog) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.child_ids = {2, 3};
-
- AXNodeData alert_dialog;
- alert_dialog.id = 2;
- alert_dialog.role = ax::mojom::Role::kAlertDialog;
-
- AXNodeData dialog;
- dialog.id = 3;
- dialog.role = ax::mojom::Role::kDialog;
-
- Init(root, alert_dialog, dialog);
-
- EXPECT_UIA_BOOL_EQ(GetRootIRawElementProviderSimple(), UIA_IsDialogPropertyId,
- false);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromChildIndex(0),
- UIA_IsDialogPropertyId, true);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromChildIndex(1),
- UIA_IsDialogPropertyId, true);
-}
-
-TEST_F(AXPlatformNodeWinTest,
- UIAGetPropertyValueIsControlElementIgnoredInvisible) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.child_ids = {2, 3, 4, 5, 6, 7, 8};
-
- AXNodeData normal_button;
- normal_button.id = 2;
- normal_button.role = ax::mojom::Role::kButton;
-
- AXNodeData ignored_button;
- ignored_button.id = 3;
- ignored_button.role = ax::mojom::Role::kButton;
- ignored_button.AddState(ax::mojom::State::kIgnored);
-
- AXNodeData invisible_button;
- invisible_button.id = 4;
- invisible_button.role = ax::mojom::Role::kButton;
- invisible_button.AddState(ax::mojom::State::kInvisible);
-
- AXNodeData invisible_focusable_button;
- invisible_focusable_button.id = 5;
- invisible_focusable_button.role = ax::mojom::Role::kButton;
- invisible_focusable_button.AddState(ax::mojom::State::kInvisible);
- invisible_focusable_button.AddState(ax::mojom::State::kFocusable);
-
- AXNodeData focusable_generic_container;
- focusable_generic_container.id = 6;
- focusable_generic_container.role = ax::mojom::Role::kGenericContainer;
- focusable_generic_container.AddState(ax::mojom::State::kFocusable);
-
- AXNodeData ignored_focusable_generic_container;
- ignored_focusable_generic_container.id = 7;
- ignored_focusable_generic_container.role = ax::mojom::Role::kGenericContainer;
- ignored_focusable_generic_container.AddState(ax::mojom::State::kIgnored);
- focusable_generic_container.AddState(ax::mojom::State::kFocusable);
-
- AXNodeData invisible_focusable_generic_container;
- invisible_focusable_generic_container.id = 8;
- invisible_focusable_generic_container.role =
- ax::mojom::Role::kGenericContainer;
- invisible_focusable_generic_container.AddState(ax::mojom::State::kInvisible);
- invisible_focusable_generic_container.AddState(ax::mojom::State::kFocusable);
-
- Init(root, normal_button, ignored_button, invisible_button,
- invisible_focusable_button, focusable_generic_container,
- ignored_focusable_generic_container,
- invisible_focusable_generic_container);
-
- // Turn on web content mode for the AXTree.
- TestAXNodeWrapper::SetGlobalIsWebContent(true);
-
- // Normal button (id=2), no invisible or ignored state set. Should be a
- // control element.
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromChildIndex(0),
- UIA_IsControlElementPropertyId, true);
-
- // Button with ignored state (id=3). Should not be a control element.
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromChildIndex(1),
- UIA_IsControlElementPropertyId, false);
-
- // Button with invisible state (id=4). Should not be a control element.
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromChildIndex(2),
- UIA_IsControlElementPropertyId, false);
-
- // Button with invisible state, but focusable (id=5). Should not be a control
- // element.
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromChildIndex(3),
- UIA_IsControlElementPropertyId, false);
-
- // Generic container, focusable (id=6). Should be a control
- // element.
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromChildIndex(4),
- UIA_IsControlElementPropertyId, true);
-
- // Generic container, ignored but focusable (id=7). Should not be a control
- // element.
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromChildIndex(5),
- UIA_IsControlElementPropertyId, false);
-
- // Generic container, invisible and ignored, but focusable (id=8). Should not
- // be a control element.
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromChildIndex(6),
- UIA_IsControlElementPropertyId, false);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetControllerForPropertyId) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.child_ids = {2, 3, 4};
-
- AXNodeData tab;
- tab.id = 2;
- tab.role = ax::mojom::Role::kTab;
- tab.SetName("tab");
- std::vector<AXNode::AXID> controller_ids = {3, 4};
- tab.AddIntListAttribute(ax::mojom::IntListAttribute::kControlsIds,
- controller_ids);
-
- AXNodeData panel1;
- panel1.id = 3;
- panel1.role = ax::mojom::Role::kTabPanel;
- panel1.SetName("panel1");
-
- AXNodeData panel2;
- panel2.id = 4;
- panel2.role = ax::mojom::Role::kTabPanel;
- panel2.SetName("panel2");
-
- Init(root, tab, panel1, panel2);
- TestAXNodeWrapper* root_wrapper =
- TestAXNodeWrapper::GetOrCreate(GetTree(), GetRootAsAXNode());
- root_wrapper->BuildAllWrappers(GetTree(), GetRootAsAXNode());
-
- ComPtr<IRawElementProviderSimple> tab_node =
- QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetRootAsAXNode()->children()[0]);
-
- std::vector<std::wstring> expected_names_1 = {L"panel1", L"panel2"};
- EXPECT_UIA_PROPERTY_ELEMENT_ARRAY_BSTR_EQ(
- tab_node, UIA_ControllerForPropertyId, UIA_NamePropertyId,
- expected_names_1);
-
- // Remove panel1's native event target and verify it's no longer returned.
- TestAXNodeWrapper* panel1_wrapper = TestAXNodeWrapper::GetOrCreate(
- GetTree(), GetRootAsAXNode()->children()[1]);
- panel1_wrapper->ResetNativeEventTarget();
- std::vector<std::wstring> expected_names_2 = {L"panel2"};
- EXPECT_UIA_PROPERTY_ELEMENT_ARRAY_BSTR_EQ(
- tab_node, UIA_ControllerForPropertyId, UIA_NamePropertyId,
- expected_names_2);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetDescribedByPropertyId) {
- AXNodeData root;
- std::vector<AXNode::AXID> describedby_ids = {2, 3, 4};
- root.AddIntListAttribute(ax::mojom::IntListAttribute::kDescribedbyIds,
- describedby_ids);
- root.id = 1;
- root.role = ax::mojom::Role::kMarquee;
- root.SetName("root");
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kStaticText;
- child1.SetName("child1");
-
- root.child_ids.push_back(child1.id);
-
- AXNodeData child2;
- child2.id = 3;
- child2.role = ax::mojom::Role::kStaticText;
- child2.SetName("child2");
-
- root.child_ids.push_back(child2.id);
-
- Init(root, child1, child2);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
-
- std::vector<std::wstring> expected_names = {L"child1", L"child2"};
- EXPECT_UIA_PROPERTY_ELEMENT_ARRAY_BSTR_EQ(
- root_node, UIA_DescribedByPropertyId, UIA_NamePropertyId, expected_names);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAItemStatusPropertyId) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTable;
-
- AXNodeData row1;
- row1.id = 2;
- row1.role = ax::mojom::Role::kRow;
- row1.AddIntAttribute(ax::mojom::IntAttribute::kSortDirection,
- static_cast<int>(ax::mojom::SortDirection::kAscending));
- root.child_ids.push_back(row1.id);
-
- AXNodeData header1;
- header1.id = 3;
- header1.role = ax::mojom::Role::kRowHeader;
- header1.AddIntAttribute(
- ax::mojom::IntAttribute::kSortDirection,
- static_cast<int>(ax::mojom::SortDirection::kAscending));
- row1.child_ids.push_back(header1.id);
-
- AXNodeData header2;
- header2.id = 4;
- header2.role = ax::mojom::Role::kColumnHeader;
- header2.AddIntAttribute(
- ax::mojom::IntAttribute::kSortDirection,
- static_cast<int>(ax::mojom::SortDirection::kDescending));
- row1.child_ids.push_back(header2.id);
-
- AXNodeData header3;
- header3.id = 5;
- header3.role = ax::mojom::Role::kColumnHeader;
- header3.AddIntAttribute(ax::mojom::IntAttribute::kSortDirection,
- static_cast<int>(ax::mojom::SortDirection::kOther));
- row1.child_ids.push_back(header3.id);
-
- AXNodeData header4;
- header4.id = 6;
- header4.role = ax::mojom::Role::kColumnHeader;
- header4.AddIntAttribute(
- ax::mojom::IntAttribute::kSortDirection,
- static_cast<int>(ax::mojom::SortDirection::kUnsorted));
- row1.child_ids.push_back(header4.id);
-
- Init(root, row1, header1, header2, header3, header4);
-
- auto* row_node = GetRootAsAXNode()->children()[0];
-
- EXPECT_UIA_BSTR_EQ(QueryInterfaceFromNode<IRawElementProviderSimple>(
- row_node->children()[0]),
- UIA_ItemStatusPropertyId, L"ascending");
-
- EXPECT_UIA_BSTR_EQ(QueryInterfaceFromNode<IRawElementProviderSimple>(
- row_node->children()[1]),
- UIA_ItemStatusPropertyId, L"descending");
-
- EXPECT_UIA_BSTR_EQ(QueryInterfaceFromNode<IRawElementProviderSimple>(
- row_node->children()[2]),
- UIA_ItemStatusPropertyId, L"other");
-
- EXPECT_UIA_VALUE_EQ(QueryInterfaceFromNode<IRawElementProviderSimple>(
- row_node->children()[3]),
- UIA_ItemStatusPropertyId, ScopedVariant::kEmptyVariant);
-
- EXPECT_UIA_VALUE_EQ(
- QueryInterfaceFromNode<IRawElementProviderSimple>(row_node),
- UIA_ItemStatusPropertyId, ScopedVariant::kEmptyVariant);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetFlowsToPropertyId) {
- AXNodeData root;
- std::vector<AXNode::AXID> flowto_ids = {2, 3, 4};
- root.AddIntListAttribute(ax::mojom::IntListAttribute::kFlowtoIds, flowto_ids);
- root.id = 1;
- root.role = ax::mojom::Role::kMarquee;
- root.SetName("root");
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kStaticText;
- child1.SetName("child1");
-
- root.child_ids.push_back(child1.id);
-
- AXNodeData child2;
- child2.id = 3;
- child2.role = ax::mojom::Role::kStaticText;
- child2.SetName("child2");
-
- root.child_ids.push_back(child2.id);
-
- Init(root, child1, child2);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
- std::vector<std::wstring> expected_names = {L"child1", L"child2"};
- EXPECT_UIA_PROPERTY_ELEMENT_ARRAY_BSTR_EQ(root_node, UIA_FlowsToPropertyId,
- UIA_NamePropertyId, expected_names);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetPropertyValueFlowsFromNone) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.SetName("root");
-
- Init(root);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
-
- ScopedVariant property_value;
- EXPECT_HRESULT_SUCCEEDED(root_node->GetPropertyValue(
- UIA_FlowsFromPropertyId, property_value.Receive()));
- EXPECT_EQ(VT_ARRAY | VT_UNKNOWN, property_value.type());
- EXPECT_EQ(nullptr, V_ARRAY(property_value.ptr()));
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetPropertyValueFlowsFromSingle) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.SetName("root");
- root.AddIntListAttribute(ax::mojom::IntListAttribute::kFlowtoIds, {2});
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kGenericContainer;
- child1.SetName("child1");
- root.child_ids.push_back(child1.id);
-
- Init(root, child1);
- ASSERT_NE(nullptr,
- TestAXNodeWrapper::GetOrCreate(GetTree(), GetRootAsAXNode()));
-
- ComPtr<IRawElementProviderSimple> child_node1 =
- QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetRootAsAXNode()->children()[0]);
- std::vector<std::wstring> expected_names = {L"root"};
- EXPECT_UIA_PROPERTY_ELEMENT_ARRAY_BSTR_EQ(
- child_node1, UIA_FlowsFromPropertyId, UIA_NamePropertyId, expected_names);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetPropertyValueFlowsFromMultiple) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.SetName("root");
- root.AddIntListAttribute(ax::mojom::IntListAttribute::kFlowtoIds, {2, 3});
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kGenericContainer;
- child1.SetName("child1");
- child1.AddIntListAttribute(ax::mojom::IntListAttribute::kFlowtoIds, {3});
- root.child_ids.push_back(child1.id);
-
- AXNodeData child2;
- child2.id = 3;
- child2.role = ax::mojom::Role::kGenericContainer;
- child2.SetName("child2");
- root.child_ids.push_back(child2.id);
-
- Init(root, child1, child2);
- ASSERT_NE(nullptr,
- TestAXNodeWrapper::GetOrCreate(GetTree(), GetRootAsAXNode()));
- ASSERT_NE(nullptr, TestAXNodeWrapper::GetOrCreate(
- GetTree(), GetRootAsAXNode()->children()[0]));
-
- ComPtr<IRawElementProviderSimple> child_node2 =
- QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetRootAsAXNode()->children()[1]);
- std::vector<std::wstring> expected_names_1 = {L"root", L"child1"};
- EXPECT_UIA_PROPERTY_UNORDERED_ELEMENT_ARRAY_BSTR_EQ(
- child_node2, UIA_FlowsFromPropertyId, UIA_NamePropertyId,
- expected_names_1);
-
- // Remove child1's native event target and verify it's no longer returned.
- TestAXNodeWrapper* child1_wrapper = TestAXNodeWrapper::GetOrCreate(
- GetTree(), GetRootAsAXNode()->children()[0]);
- child1_wrapper->ResetNativeEventTarget();
- std::vector<std::wstring> expected_names_2 = {L"root"};
- EXPECT_UIA_PROPERTY_UNORDERED_ELEMENT_ARRAY_BSTR_EQ(
- child_node2, UIA_FlowsFromPropertyId, UIA_NamePropertyId,
- expected_names_2);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetPropertyValueFrameworkId) {
- AXNodeData root_ax_node_data;
- root_ax_node_data.id = 1;
- root_ax_node_data.role = ax::mojom::Role::kRootWebArea;
- Init(root_ax_node_data);
-
- ComPtr<IRawElementProviderSimple> root_raw_element_provider_simple =
- GetRootIRawElementProviderSimple();
- EXPECT_UIA_BSTR_EQ(root_raw_element_provider_simple,
- UIA_FrameworkIdPropertyId, L"Chrome");
-}
-
-TEST_F(AXPlatformNodeWinTest, GetPropertyValue_LabeledByTest) {
- // ++1 root
- // ++++2 kGenericContainer LabeledBy 3
- // ++++++3 kStaticText "Hello"
- // ++++4 kGenericContainer LabeledBy 5
- // ++++++5 kGenericContainer
- // ++++++++6 kStaticText "3.14"
- // ++++7 kAlert LabeledBy 6
- AXNodeData root_1;
- AXNodeData gc_2;
- AXNodeData static_text_3;
- AXNodeData gc_4;
- AXNodeData gc_5;
- AXNodeData static_text_6;
- AXNodeData alert_7;
-
- root_1.id = 1;
- gc_2.id = 2;
- static_text_3.id = 3;
- gc_4.id = 4;
- gc_5.id = 5;
- static_text_6.id = 6;
- alert_7.id = 7;
-
- root_1.role = ax::mojom::Role::kRootWebArea;
- root_1.child_ids = {gc_2.id, gc_4.id, alert_7.id};
-
- gc_2.role = ax::mojom::Role::kGenericContainer;
- gc_2.AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
- {static_text_3.id});
- gc_2.child_ids = {static_text_3.id};
-
- static_text_3.role = ax::mojom::Role::kStaticText;
- static_text_3.SetName("Hello");
-
- gc_4.role = ax::mojom::Role::kGenericContainer;
- gc_4.AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
- {gc_5.id});
- gc_4.child_ids = {gc_5.id};
-
- gc_5.role = ax::mojom::Role::kGenericContainer;
- gc_5.child_ids = {static_text_6.id};
-
- static_text_6.role = ax::mojom::Role::kStaticText;
- static_text_6.SetName("3.14");
-
- alert_7.role = ax::mojom::Role::kAlert;
- alert_7.AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
- {static_text_6.id});
-
- Init(root_1, gc_2, static_text_3, gc_4, gc_5, static_text_6, alert_7);
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* gc_2_node = root_node->children()[0];
- AXNode* static_text_3_node = gc_2_node->children()[0];
- AXNode* gc_4_node = root_node->children()[1];
- AXNode* static_text_6_node = gc_4_node->children()[0]->children()[0];
- AXNode* alert_7_node = root_node->children()[2];
-
- // Case 1: |gc_2| is labeled by |static_text_3|.
-
- ComPtr<IRawElementProviderSimple> gc_2_provider =
- GetIRawElementProviderSimpleFromTree(gc_2_node->tree()->GetAXTreeID(),
- gc_2_node->id());
- ScopedVariant property_value;
- EXPECT_EQ(S_OK, gc_2_provider->GetPropertyValue(UIA_LabeledByPropertyId,
- property_value.Receive()));
- ASSERT_EQ(property_value.type(), VT_UNKNOWN);
- ComPtr<IRawElementProviderSimple> static_text_3_provider;
- EXPECT_EQ(S_OK, property_value.ptr()->punkVal->QueryInterface(
- IID_PPV_ARGS(&static_text_3_provider)));
- EXPECT_UIA_BSTR_EQ(static_text_3_provider, UIA_NamePropertyId, L"Hello");
-
- // Case 2: |gc_4| is labeled by |gc_5| and should return the first static text
- // child of that node, which is |static_text_6|.
-
- ComPtr<IRawElementProviderSimple> gc_4_provider =
- GetIRawElementProviderSimpleFromTree(gc_4_node->tree()->GetAXTreeID(),
- gc_4_node->id());
- property_value.Reset();
- EXPECT_EQ(S_OK, gc_4_provider->GetPropertyValue(UIA_LabeledByPropertyId,
- property_value.Receive()));
- ASSERT_EQ(property_value.type(), VT_UNKNOWN);
- ComPtr<IRawElementProviderSimple> static_text_6_provider;
- EXPECT_EQ(S_OK, property_value.ptr()->punkVal->QueryInterface(
- IID_PPV_ARGS(&static_text_6_provider)));
- EXPECT_UIA_BSTR_EQ(static_text_6_provider, UIA_NamePropertyId, L"3.14");
-
- // Case 3: Some UIA control types always expect an empty value for this
- // property. The role kAlert corresponds to UIA_TextControlTypeId, which
- // always expects an empty value. |alert_7| is marked as labeled by
- // |static_text_6|, but shouldn't expose it to the UIA_LabeledByPropertyId.
-
- ComPtr<IRawElementProviderSimple> alert_7_provider =
- GetIRawElementProviderSimpleFromTree(alert_7_node->tree()->GetAXTreeID(),
- alert_7_node->id());
- property_value.Reset();
- EXPECT_EQ(S_OK, alert_7_provider->GetPropertyValue(UIA_LabeledByPropertyId,
- property_value.Receive()));
- ASSERT_EQ(property_value.type(), VT_EMPTY);
-
- // Remove the referenced nodes' native event targets and verify it's no longer
- // returned.
-
- // Case 1.
- TestAXNodeWrapper* static_text_3_node_wrapper =
- TestAXNodeWrapper::GetOrCreate(GetTree(), static_text_3_node);
- static_text_3_node_wrapper->ResetNativeEventTarget();
-
- property_value.Reset();
- EXPECT_EQ(S_OK, gc_2_provider->GetPropertyValue(UIA_LabeledByPropertyId,
- property_value.Receive()));
- EXPECT_EQ(property_value.type(), VT_EMPTY);
-
- // Case 2.
- TestAXNodeWrapper* static_text_6_node_wrapper =
- TestAXNodeWrapper::GetOrCreate(GetTree(), static_text_6_node);
- static_text_6_node_wrapper->ResetNativeEventTarget();
-
- property_value.Reset();
- EXPECT_EQ(S_OK, gc_4_provider->GetPropertyValue(UIA_LabeledByPropertyId,
- property_value.Receive()));
- EXPECT_EQ(property_value.type(), VT_EMPTY);
-}
-
-TEST_F(AXPlatformNodeWinTest, GetPropertyValue_HelpText) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
-
- // Test Placeholder StringAttribute is exposed
- AXNodeData input1;
- input1.id = 2;
- input1.role = ax::mojom::Role::kTextField;
- input1.SetName("name-from-title");
- input1.AddIntAttribute(ax::mojom::IntAttribute::kNameFrom,
- static_cast<int>(ax::mojom::NameFrom::kTitle));
- input1.AddStringAttribute(ax::mojom::StringAttribute::kPlaceholder,
- "placeholder");
- root.child_ids.push_back(input1.id);
-
- // Test NameFrom Title is exposed
- AXNodeData input2;
- input2.id = 3;
- input2.role = ax::mojom::Role::kTextField;
- input2.SetName("name-from-title");
- input2.AddIntAttribute(ax::mojom::IntAttribute::kNameFrom,
- static_cast<int>(ax::mojom::NameFrom::kTitle));
- root.child_ids.push_back(input2.id);
-
- // Test NameFrom Placeholder is exposed
- AXNodeData input3;
- input3.id = 4;
- input3.role = ax::mojom::Role::kTextField;
- input3.SetName("name-from-placeholder");
- input3.AddIntAttribute(ax::mojom::IntAttribute::kNameFrom,
- static_cast<int>(ax::mojom::NameFrom::kPlaceholder));
- root.child_ids.push_back(input3.id);
-
- // Test Title StringAttribute is exposed
- AXNodeData input4;
- input4.id = 5;
- input4.role = ax::mojom::Role::kTextField;
- input4.SetName("name-from-attribute");
- input4.AddIntAttribute(ax::mojom::IntAttribute::kNameFrom,
- static_cast<int>(ax::mojom::NameFrom::kAttribute));
- input4.AddStringAttribute(ax::mojom::StringAttribute::kTooltip, "tooltip");
- root.child_ids.push_back(input4.id);
-
- // Test NameFrom (other), without explicit
- // Title / Placeholder StringAttribute is not exposed
- AXNodeData input5;
- input5.id = 6;
- input5.role = ax::mojom::Role::kTextField;
- input5.SetName("name-from-attribute");
- input5.AddIntAttribute(ax::mojom::IntAttribute::kNameFrom,
- static_cast<int>(ax::mojom::NameFrom::kAttribute));
- root.child_ids.push_back(input5.id);
-
- Init(root, input1, input2, input3, input4, input5);
-
- auto* root_node = GetRootAsAXNode();
- EXPECT_UIA_BSTR_EQ(QueryInterfaceFromNode<IRawElementProviderSimple>(
- root_node->children()[0]),
- UIA_HelpTextPropertyId, L"placeholder");
- EXPECT_UIA_BSTR_EQ(QueryInterfaceFromNode<IRawElementProviderSimple>(
- root_node->children()[1]),
- UIA_HelpTextPropertyId, L"name-from-title");
- EXPECT_UIA_BSTR_EQ(QueryInterfaceFromNode<IRawElementProviderSimple>(
- root_node->children()[2]),
- UIA_HelpTextPropertyId, L"name-from-placeholder");
- EXPECT_UIA_BSTR_EQ(QueryInterfaceFromNode<IRawElementProviderSimple>(
- root_node->children()[3]),
- UIA_HelpTextPropertyId, L"tooltip");
- EXPECT_UIA_VALUE_EQ(QueryInterfaceFromNode<IRawElementProviderSimple>(
- root_node->children()[4]),
- UIA_HelpTextPropertyId, ScopedVariant::kEmptyVariant);
-}
-
-TEST_F(AXPlatformNodeWinTest, GetPropertyValue_LocalizedControlType) {
- AXNodeData root;
- root.role = ax::mojom::Role::kUnknown;
- root.id = 1;
- root.AddStringAttribute(ax::mojom::StringAttribute::kRoleDescription,
- "root role description");
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kSearchBox;
- child1.AddStringAttribute(ax::mojom::StringAttribute::kRoleDescription,
- "child1 role description");
- root.child_ids.push_back(2);
-
- AXNodeData child2;
- child2.id = 3;
- child2.role = ax::mojom::Role::kSearchBox;
- root.child_ids.push_back(3);
-
- Init(root, child1, child2);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
- EXPECT_UIA_BSTR_EQ(root_node, UIA_LocalizedControlTypePropertyId,
- L"root role description");
- EXPECT_UIA_BSTR_EQ(QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetRootAsAXNode()->children()[0]),
- UIA_LocalizedControlTypePropertyId,
- L"child1 role description");
- EXPECT_UIA_BSTR_EQ(QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetRootAsAXNode()->children()[1]),
- UIA_LocalizedControlTypePropertyId, L"search box");
-}
-
-TEST_F(AXPlatformNodeWinTest, GetPropertyValue_IsControlElement) {
- AXTreeUpdate update;
- ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.tree_data.tree_id = tree_id;
- update.has_tree_data = true;
- update.root_id = 1;
- update.nodes.resize(17);
- update.nodes[0].id = 1;
- update.nodes[0].role = ax::mojom::Role::kRootWebArea;
- update.nodes[0].child_ids = {2, 4, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17};
- update.nodes[1].id = 2;
- update.nodes[1].role = ax::mojom::Role::kButton;
- update.nodes[1].child_ids = {3};
- update.nodes[2].id = 3;
- update.nodes[2].role = ax::mojom::Role::kStaticText;
- update.nodes[2].SetName("some text");
- update.nodes[3].id = 4;
- update.nodes[3].role = ax::mojom::Role::kGenericContainer;
- update.nodes[3].child_ids = {5};
- update.nodes[4].id = 5;
- update.nodes[4].role = ax::mojom::Role::kStaticText;
- update.nodes[4].SetName("more text");
- update.nodes[5].id = 6;
- update.nodes[5].role = ax::mojom::Role::kTable;
- update.nodes[6].id = 7;
- update.nodes[6].role = ax::mojom::Role::kList;
- update.nodes[7].id = 8;
- update.nodes[7].role = ax::mojom::Role::kForm;
- update.nodes[8].id = 9;
- update.nodes[8].role = ax::mojom::Role::kImage;
- update.nodes[9].id = 10;
- update.nodes[9].role = ax::mojom::Role::kImage;
- update.nodes[9].SetNameExplicitlyEmpty();
- update.nodes[10].id = 11;
- update.nodes[10].role = ax::mojom::Role::kArticle;
- update.nodes[11].id = 12;
- update.nodes[11].role = ax::mojom::Role::kGenericContainer;
- update.nodes[11].AddBoolAttribute(ax::mojom::BoolAttribute::kHasAriaAttribute,
- true);
- update.nodes[12].id = 13;
- update.nodes[12].role = ax::mojom::Role::kGenericContainer;
- update.nodes[12].AddBoolAttribute(ax::mojom::BoolAttribute::kEditableRoot,
- true);
- update.nodes[13].id = 14;
- update.nodes[13].role = ax::mojom::Role::kGenericContainer;
- update.nodes[13].SetName("name");
- update.nodes[14].id = 15;
- update.nodes[14].role = ax::mojom::Role::kGenericContainer;
- update.nodes[14].SetDescription("description");
- update.nodes[15].id = 16;
- update.nodes[15].role = ax::mojom::Role::kGenericContainer;
- update.nodes[15].AddState(ax::mojom::State::kFocusable);
- update.nodes[16].id = 17;
- update.nodes[16].role = ax::mojom::Role::kForm;
- update.nodes[16].SetName("name");
-
- Init(update);
- TestAXNodeWrapper::SetGlobalIsWebContent(true);
-
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 2),
- UIA_IsControlElementPropertyId, true);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 3),
- UIA_IsControlElementPropertyId, false);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 4),
- UIA_IsControlElementPropertyId, false);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 5),
- UIA_IsControlElementPropertyId, true);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 6),
- UIA_IsControlElementPropertyId, true);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 7),
- UIA_IsControlElementPropertyId, true);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 8),
- UIA_IsControlElementPropertyId, false);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 9),
- UIA_IsControlElementPropertyId, true);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 10),
- UIA_IsControlElementPropertyId, false);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 11),
- UIA_IsControlElementPropertyId, true);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 12),
- UIA_IsControlElementPropertyId, true);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 13),
- UIA_IsControlElementPropertyId, true);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 14),
- UIA_IsControlElementPropertyId, true);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 15),
- UIA_IsControlElementPropertyId, true);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 16),
- UIA_IsControlElementPropertyId, true);
- EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 17),
- UIA_IsControlElementPropertyId, true);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetProviderOptions) {
- AXNodeData root_data;
- Init(root_data);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
-
- ProviderOptions provider_options = static_cast<ProviderOptions>(0);
- EXPECT_HRESULT_SUCCEEDED(root_node->get_ProviderOptions(&provider_options));
- EXPECT_EQ(ProviderOptions_ServerSideProvider |
- ProviderOptions_UseComThreading |
- ProviderOptions_RefuseNonClientSupport |
- ProviderOptions_HasNativeIAccessible,
- provider_options);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetHostRawElementProvider) {
- AXNodeData root_data;
- Init(root_data);
-
- ComPtr<IRawElementProviderSimple> root_node =
- GetRootIRawElementProviderSimple();
-
- ComPtr<IRawElementProviderSimple> host_provider;
- EXPECT_HRESULT_SUCCEEDED(
- root_node->get_HostRawElementProvider(&host_provider));
- EXPECT_EQ(nullptr, host_provider.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetBoundingRectangle) {
- AXNodeData root_data;
- root_data.id = 1;
- root_data.relative_bounds.bounds = gfx::RectF(10, 20, 30, 50);
- Init(root_data);
-
- ComPtr<IRawElementProviderFragment> root_node =
- GetRootIRawElementProviderFragment();
-
- UiaRect bounding_rectangle;
- EXPECT_HRESULT_SUCCEEDED(
- root_node->get_BoundingRectangle(&bounding_rectangle));
- EXPECT_EQ(10, bounding_rectangle.left);
- EXPECT_EQ(20, bounding_rectangle.top);
- EXPECT_EQ(30, bounding_rectangle.width);
- EXPECT_EQ(50, bounding_rectangle.height);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetFragmentRoot) {
- // This test needs to be run on a child node since AXPlatformRootNodeWin
- // overrides the method.
- AXNodeData root_data;
- root_data.id = 1;
-
- AXNodeData element1_data;
- element1_data.id = 2;
- root_data.child_ids.push_back(element1_data.id);
-
- Init(root_data, element1_data);
- InitFragmentRoot();
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* element1_node = root_node->children()[0];
-
- ComPtr<IRawElementProviderFragment> element1_provider =
- QueryInterfaceFromNode<IRawElementProviderFragment>(element1_node);
- ComPtr<IRawElementProviderFragmentRoot> expected_fragment_root =
- GetFragmentRoot();
-
- ComPtr<IRawElementProviderFragmentRoot> actual_fragment_root;
- EXPECT_HRESULT_SUCCEEDED(
- element1_provider->get_FragmentRoot(&actual_fragment_root));
- EXPECT_EQ(expected_fragment_root.Get(), actual_fragment_root.Get());
-
- // Test the case where the fragment root has gone away.
- ax_fragment_root_.reset();
- actual_fragment_root.Reset();
- EXPECT_UIA_ELEMENTNOTAVAILABLE(
- element1_provider->get_FragmentRoot(&actual_fragment_root));
-
- // Test the case where the widget has gone away.
- TestAXNodeWrapper* element1_wrapper =
- TestAXNodeWrapper::GetOrCreate(GetTree(), element1_node);
- element1_wrapper->ResetNativeEventTarget();
- EXPECT_UIA_ELEMENTNOTAVAILABLE(
- element1_provider->get_FragmentRoot(&actual_fragment_root));
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetEmbeddedFragmentRoots) {
- AXNodeData root_data;
- root_data.id = 1;
- Init(root_data);
-
- ComPtr<IRawElementProviderFragment> root_provider =
- GetRootIRawElementProviderFragment();
-
- base::win::ScopedSafearray embedded_fragment_roots;
- EXPECT_HRESULT_SUCCEEDED(root_provider->GetEmbeddedFragmentRoots(
- embedded_fragment_roots.Receive()));
- EXPECT_EQ(nullptr, embedded_fragment_roots.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAGetRuntimeId) {
- AXNodeData root_data;
- root_data.id = 1;
- Init(root_data);
-
- ComPtr<IRawElementProviderFragment> root_provider =
- GetRootIRawElementProviderFragment();
-
- base::win::ScopedSafearray runtime_id;
- EXPECT_HRESULT_SUCCEEDED(root_provider->GetRuntimeId(runtime_id.Receive()));
-
- LONG array_lower_bound;
- EXPECT_HRESULT_SUCCEEDED(
- ::SafeArrayGetLBound(runtime_id.Get(), 1, &array_lower_bound));
- EXPECT_EQ(0, array_lower_bound);
-
- LONG array_upper_bound;
- EXPECT_HRESULT_SUCCEEDED(
- ::SafeArrayGetUBound(runtime_id.Get(), 1, &array_upper_bound));
- EXPECT_EQ(1, array_upper_bound);
-
- int* array_data;
- EXPECT_HRESULT_SUCCEEDED(::SafeArrayAccessData(
- runtime_id.Get(), reinterpret_cast<void**>(&array_data)));
- EXPECT_EQ(UiaAppendRuntimeId, array_data[0]);
- EXPECT_NE(-1, array_data[1]);
-
- EXPECT_HRESULT_SUCCEEDED(::SafeArrayUnaccessData(runtime_id.Get()));
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAIWindowProviderGetIsModalUnset) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- Init(root);
-
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetRootIRawElementProviderSimple();
- ComPtr<IWindowProvider> window_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_WindowPatternId, &window_provider));
- ASSERT_EQ(nullptr, window_provider.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAIWindowProviderGetIsModalFalse) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.AddBoolAttribute(ax::mojom::BoolAttribute::kModal, false);
- Init(root);
-
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetRootIRawElementProviderSimple();
- ComPtr<IWindowProvider> window_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_WindowPatternId, &window_provider));
- ASSERT_NE(nullptr, window_provider.Get());
-
- BOOL is_modal;
- EXPECT_HRESULT_SUCCEEDED(window_provider->get_IsModal(&is_modal));
- ASSERT_FALSE(is_modal);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAIWindowProviderGetIsModalTrue) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.AddBoolAttribute(ax::mojom::BoolAttribute::kModal, true);
- Init(root);
-
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetRootIRawElementProviderSimple();
- ComPtr<IWindowProvider> window_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_WindowPatternId, &window_provider));
- ASSERT_NE(nullptr, window_provider.Get());
-
- BOOL is_modal;
- EXPECT_HRESULT_SUCCEEDED(window_provider->get_IsModal(&is_modal));
- ASSERT_TRUE(is_modal);
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAIWindowProviderInvalidArgument) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.AddBoolAttribute(ax::mojom::BoolAttribute::kModal, true);
- Init(root);
-
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetRootIRawElementProviderSimple();
- ComPtr<IWindowProvider> window_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_WindowPatternId, &window_provider));
- ASSERT_NE(nullptr, window_provider.Get());
-
- ASSERT_EQ(E_INVALIDARG, window_provider->WaitForInputIdle(0, nullptr));
- ASSERT_EQ(E_INVALIDARG, window_provider->get_CanMaximize(nullptr));
- ASSERT_EQ(E_INVALIDARG, window_provider->get_CanMinimize(nullptr));
- ASSERT_EQ(E_INVALIDARG, window_provider->get_IsModal(nullptr));
- ASSERT_EQ(E_INVALIDARG, window_provider->get_WindowVisualState(nullptr));
- ASSERT_EQ(E_INVALIDARG, window_provider->get_WindowInteractionState(nullptr));
- ASSERT_EQ(E_INVALIDARG, window_provider->get_IsTopmost(nullptr));
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAIWindowProviderNotSupported) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
- root.AddBoolAttribute(ax::mojom::BoolAttribute::kModal, true);
- Init(root);
-
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetRootIRawElementProviderSimple();
- ComPtr<IWindowProvider> window_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_WindowPatternId, &window_provider));
- ASSERT_NE(nullptr, window_provider.Get());
-
- BOOL bool_result;
- WindowVisualState window_visual_state_result;
- WindowInteractionState window_interaction_state_result;
-
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_NOTSUPPORTED),
- window_provider->SetVisualState(
- WindowVisualState::WindowVisualState_Normal));
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_NOTSUPPORTED), window_provider->Close());
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_NOTSUPPORTED),
- window_provider->WaitForInputIdle(0, &bool_result));
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_NOTSUPPORTED),
- window_provider->get_CanMaximize(&bool_result));
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_NOTSUPPORTED),
- window_provider->get_CanMinimize(&bool_result));
- ASSERT_EQ(
- static_cast<HRESULT>(UIA_E_NOTSUPPORTED),
- window_provider->get_WindowVisualState(&window_visual_state_result));
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_NOTSUPPORTED),
- window_provider->get_WindowInteractionState(
- &window_interaction_state_result));
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_NOTSUPPORTED),
- window_provider->get_IsTopmost(&bool_result));
-}
-
-TEST_F(AXPlatformNodeWinTest, UIANavigate) {
- AXNodeData root_data;
- root_data.id = 1;
-
- AXNodeData element1_data;
- element1_data.id = 2;
- root_data.child_ids.push_back(element1_data.id);
-
- AXNodeData element2_data;
- element2_data.id = 3;
- root_data.child_ids.push_back(element2_data.id);
-
- AXNodeData element3_data;
- element3_data.id = 4;
- element1_data.child_ids.push_back(element3_data.id);
-
- Init(root_data, element1_data, element2_data, element3_data);
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* element1_node = root_node->children()[0];
- AXNode* element2_node = root_node->children()[1];
- AXNode* element3_node = element1_node->children()[0];
-
- auto TestNavigate = [this](AXNode* element_node, AXNode* parent,
- AXNode* next_sibling, AXNode* prev_sibling,
- AXNode* first_child, AXNode* last_child) {
- ComPtr<IRawElementProviderFragment> element_provider =
- QueryInterfaceFromNode<IRawElementProviderFragment>(element_node);
-
- auto TestNavigateSingle = [&](NavigateDirection direction,
- AXNode* expected_node) {
- ComPtr<IRawElementProviderFragment> expected_provider =
- QueryInterfaceFromNode<IRawElementProviderFragment>(expected_node);
-
- ComPtr<IRawElementProviderFragment> navigated_to_fragment;
- EXPECT_HRESULT_SUCCEEDED(
- element_provider->Navigate(direction, &navigated_to_fragment));
- EXPECT_EQ(expected_provider.Get(), navigated_to_fragment.Get());
- };
-
- TestNavigateSingle(NavigateDirection_Parent, parent);
- TestNavigateSingle(NavigateDirection_NextSibling, next_sibling);
- TestNavigateSingle(NavigateDirection_PreviousSibling, prev_sibling);
- TestNavigateSingle(NavigateDirection_FirstChild, first_child);
- TestNavigateSingle(NavigateDirection_LastChild, last_child);
- };
-
- TestNavigate(root_node,
- nullptr, // Parent
- nullptr, // NextSibling
- nullptr, // PreviousSibling
- element1_node, // FirstChild
- element2_node); // LastChild
-
- TestNavigate(element1_node, root_node, element2_node, nullptr, element3_node,
- element3_node);
-
- TestNavigate(element2_node, root_node, nullptr, element1_node, nullptr,
- nullptr);
-
- TestNavigate(element3_node, element1_node, nullptr, nullptr, nullptr,
- nullptr);
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionProviderCanSelectMultipleDefault) {
- Init(BuildListBox(/*option_1_is_selected*/ false,
- /*option_2_is_selected*/ false,
- /*option_3_is_selected*/ false, {}));
-
- ComPtr<ISelectionProvider> selection_provider(
- QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
-
- BOOL multiple = TRUE;
- EXPECT_HRESULT_SUCCEEDED(
- selection_provider->get_CanSelectMultiple(&multiple));
- EXPECT_FALSE(multiple);
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionProviderCanSelectMultipleTrue) {
- const std::vector<ax::mojom::State> state = {
- ax::mojom::State::kMultiselectable, ax::mojom::State::kFocusable};
- Init(BuildListBox(/*option_1_is_selected*/ false,
- /*option_2_is_selected*/ false,
- /*option_3_is_selected*/ false,
- /*additional_state*/ state));
-
- ComPtr<ISelectionProvider> selection_provider(
- QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
-
- BOOL multiple = FALSE;
- EXPECT_HRESULT_SUCCEEDED(
- selection_provider->get_CanSelectMultiple(&multiple));
- EXPECT_TRUE(multiple);
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionProviderIsSelectionRequiredDefault) {
- Init(BuildListBox(/*option_1_is_selected*/ false,
- /*option_2_is_selected*/ false,
- /*option_3_is_selected*/ false,
- /*additional_state*/ {}));
-
- ComPtr<ISelectionProvider> selection_provider(
- QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
-
- BOOL selection_required = TRUE;
- EXPECT_HRESULT_SUCCEEDED(
- selection_provider->get_IsSelectionRequired(&selection_required));
- EXPECT_FALSE(selection_required);
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionProviderIsSelectionRequiredTrue) {
- Init(BuildListBox(/*option_1_is_selected*/ false,
- /*option_2_is_selected*/ false,
- /*option_3_is_selected*/ false,
- /*additional_state*/ {ax::mojom::State::kRequired}));
-
- ComPtr<ISelectionProvider> selection_provider(
- QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
-
- BOOL selection_required = FALSE;
- EXPECT_HRESULT_SUCCEEDED(
- selection_provider->get_IsSelectionRequired(&selection_required));
- EXPECT_TRUE(selection_required);
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionProviderGetSelectionNoneSelected) {
- Init(BuildListBox(/*option_1_is_selected*/ false,
- /*option_2_is_selected*/ false,
- /*option_3_is_selected*/ false,
- /*additional_state*/ {ax::mojom::State::kFocusable}));
-
- ComPtr<ISelectionProvider> selection_provider(
- QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
-
- base::win::ScopedSafearray selected_items;
- EXPECT_HRESULT_SUCCEEDED(
- selection_provider->GetSelection(selected_items.Receive()));
- EXPECT_NE(nullptr, selected_items.Get());
-
- LONG array_lower_bound;
- EXPECT_HRESULT_SUCCEEDED(
- ::SafeArrayGetLBound(selected_items.Get(), 1, &array_lower_bound));
- EXPECT_EQ(0, array_lower_bound);
-
- LONG array_upper_bound;
- EXPECT_HRESULT_SUCCEEDED(
- ::SafeArrayGetUBound(selected_items.Get(), 1, &array_upper_bound));
- EXPECT_EQ(-1, array_upper_bound);
-}
-
-TEST_F(AXPlatformNodeWinTest,
- ISelectionProviderGetSelectionSingleItemSelected) {
- Init(BuildListBox(/*option_1_is_selected*/ false,
- /*option_2_is_selected*/ true,
- /*option_3_is_selected*/ false,
- /*additional_state*/ {ax::mojom::State::kFocusable}));
-
- ComPtr<ISelectionProvider> selection_provider(
- QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
- ComPtr<IRawElementProviderSimple> option2_provider(
- QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetRootAsAXNode()->children()[1]));
-
- base::win::ScopedSafearray selected_items;
- EXPECT_HRESULT_SUCCEEDED(
- selection_provider->GetSelection(selected_items.Receive()));
- EXPECT_NE(nullptr, selected_items.Get());
-
- LONG array_lower_bound;
- EXPECT_HRESULT_SUCCEEDED(
- ::SafeArrayGetLBound(selected_items.Get(), 1, &array_lower_bound));
- EXPECT_EQ(0, array_lower_bound);
-
- LONG array_upper_bound;
- EXPECT_HRESULT_SUCCEEDED(
- ::SafeArrayGetUBound(selected_items.Get(), 1, &array_upper_bound));
- EXPECT_EQ(0, array_upper_bound);
-
- IRawElementProviderSimple** array_data;
- EXPECT_HRESULT_SUCCEEDED(::SafeArrayAccessData(
- selected_items.Get(), reinterpret_cast<void**>(&array_data)));
- EXPECT_EQ(option2_provider.Get(), array_data[0]);
- EXPECT_HRESULT_SUCCEEDED(::SafeArrayUnaccessData(selected_items.Get()));
-}
-
-TEST_F(AXPlatformNodeWinTest,
- ISelectionProviderGetSelectionMultipleItemsSelected) {
- const std::vector<ax::mojom::State> state = {
- ax::mojom::State::kMultiselectable, ax::mojom::State::kFocusable};
- Init(BuildListBox(/*option_1_is_selected*/ true,
- /*option_2_is_selected*/ true,
- /*option_3_is_selected*/ true,
- /*additional_state*/ state));
-
- ComPtr<ISelectionProvider> selection_provider(
- QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
- ComPtr<IRawElementProviderSimple> option1_provider(
- QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetRootAsAXNode()->children()[0]));
- ComPtr<IRawElementProviderSimple> option2_provider(
- QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetRootAsAXNode()->children()[1]));
- ComPtr<IRawElementProviderSimple> option3_provider(
- QueryInterfaceFromNode<IRawElementProviderSimple>(
- GetRootAsAXNode()->children()[2]));
-
- base::win::ScopedSafearray selected_items;
- EXPECT_HRESULT_SUCCEEDED(
- selection_provider->GetSelection(selected_items.Receive()));
- EXPECT_NE(nullptr, selected_items.Get());
-
- LONG array_lower_bound;
- EXPECT_HRESULT_SUCCEEDED(
- ::SafeArrayGetLBound(selected_items.Get(), 1, &array_lower_bound));
- EXPECT_EQ(0, array_lower_bound);
-
- LONG array_upper_bound;
- EXPECT_HRESULT_SUCCEEDED(
- ::SafeArrayGetUBound(selected_items.Get(), 1, &array_upper_bound));
- EXPECT_EQ(2, array_upper_bound);
-
- IRawElementProviderSimple** array_data;
- EXPECT_HRESULT_SUCCEEDED(::SafeArrayAccessData(
- selected_items.Get(), reinterpret_cast<void**>(&array_data)));
- EXPECT_EQ(option1_provider.Get(), array_data[0]);
- EXPECT_EQ(option2_provider.Get(), array_data[1]);
- EXPECT_EQ(option3_provider.Get(), array_data[2]);
-
- EXPECT_HRESULT_SUCCEEDED(::SafeArrayUnaccessData(selected_items.Get()));
-}
-
-TEST_F(AXPlatformNodeWinTest, ComputeUIAControlType) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
-
- AXNodeData child1;
- AXNode::AXID child1_id = 2;
- child1.id = child1_id;
- child1.role = ax::mojom::Role::kTable;
- root.child_ids.push_back(child1_id);
-
- AXNodeData child2;
- AXNode::AXID child2_id = 3;
- child2.id = child2_id;
- child2.role = ax::mojom::Role::kLayoutTable;
- root.child_ids.push_back(child2_id);
-
- AXNodeData child3;
- AXNode::AXID child3_id = 4;
- child3.id = child3_id;
- child3.role = ax::mojom::Role::kTextField;
- root.child_ids.push_back(child3_id);
-
- AXNodeData child4;
- AXNode::AXID child4_id = 5;
- child4.id = child4_id;
- child4.role = ax::mojom::Role::kSearchBox;
- root.child_ids.push_back(child4_id);
-
- Init(root, child1, child2, child3, child4);
-
- EXPECT_UIA_INT_EQ(
- QueryInterfaceFromNodeId<IRawElementProviderSimple>(child1_id),
- UIA_ControlTypePropertyId, int{UIA_TableControlTypeId});
- EXPECT_UIA_INT_EQ(
- QueryInterfaceFromNodeId<IRawElementProviderSimple>(child2_id),
- UIA_ControlTypePropertyId, int{UIA_TableControlTypeId});
- EXPECT_UIA_INT_EQ(
- QueryInterfaceFromNodeId<IRawElementProviderSimple>(child3_id),
- UIA_ControlTypePropertyId, int{UIA_EditControlTypeId});
- EXPECT_UIA_INT_EQ(
- QueryInterfaceFromNodeId<IRawElementProviderSimple>(child4_id),
- UIA_ControlTypePropertyId, int{UIA_EditControlTypeId});
-}
-
-TEST_F(AXPlatformNodeWinTest, UIALandmarkType) {
- auto TestLandmarkType = [this](ax::mojom::Role node_role,
- base::Optional<LONG> expected_landmark_type,
- const std::string& node_name = {}) {
- AXNodeData root_data;
- root_data.id = 1;
- root_data.role = node_role;
- if (!node_name.empty())
- root_data.SetName(node_name);
- Init(root_data);
-
- ComPtr<IRawElementProviderSimple> root_provider =
- GetRootIRawElementProviderSimple();
-
- if (expected_landmark_type) {
- EXPECT_UIA_INT_EQ(root_provider, UIA_LandmarkTypePropertyId,
- expected_landmark_type.value());
- } else {
- EXPECT_UIA_EMPTY(root_provider, UIA_LandmarkTypePropertyId);
- }
- };
-
- TestLandmarkType(ax::mojom::Role::kBanner, UIA_CustomLandmarkTypeId);
- TestLandmarkType(ax::mojom::Role::kComplementary, UIA_CustomLandmarkTypeId);
- TestLandmarkType(ax::mojom::Role::kContentInfo, UIA_CustomLandmarkTypeId);
- TestLandmarkType(ax::mojom::Role::kFooter, UIA_CustomLandmarkTypeId);
- TestLandmarkType(ax::mojom::Role::kMain, UIA_MainLandmarkTypeId);
- TestLandmarkType(ax::mojom::Role::kNavigation, UIA_NavigationLandmarkTypeId);
- TestLandmarkType(ax::mojom::Role::kSearch, UIA_SearchLandmarkTypeId);
-
- // Only named forms should be exposed as landmarks.
- TestLandmarkType(ax::mojom::Role::kForm, {});
- TestLandmarkType(ax::mojom::Role::kForm, UIA_FormLandmarkTypeId, "name");
-
- // Only named regions should be exposed as landmarks.
- TestLandmarkType(ax::mojom::Role::kRegion, {});
- TestLandmarkType(ax::mojom::Role::kRegion, UIA_CustomLandmarkTypeId, "name");
-
- TestLandmarkType(ax::mojom::Role::kGroup, {});
- TestLandmarkType(ax::mojom::Role::kHeading, {});
- TestLandmarkType(ax::mojom::Role::kList, {});
- TestLandmarkType(ax::mojom::Role::kTable, {});
-}
-
-TEST_F(AXPlatformNodeWinTest, UIALocalizedLandmarkType) {
- auto TestLocalizedLandmarkType =
- [this](ax::mojom::Role node_role,
- const std::wstring& expected_localized_landmark,
- const std::string& node_name = {}) {
- AXNodeData root_data;
- root_data.id = 1;
- root_data.role = node_role;
- if (!node_name.empty())
- root_data.SetName(node_name);
- Init(root_data);
-
- ComPtr<IRawElementProviderSimple> root_provider =
- GetRootIRawElementProviderSimple();
-
- if (expected_localized_landmark.empty()) {
- EXPECT_UIA_EMPTY(root_provider, UIA_LocalizedLandmarkTypePropertyId);
- } else {
- EXPECT_UIA_BSTR_EQ(root_provider, UIA_LocalizedLandmarkTypePropertyId,
- expected_localized_landmark.c_str());
- }
- };
-
- TestLocalizedLandmarkType(ax::mojom::Role::kBanner, L"banner");
- TestLocalizedLandmarkType(ax::mojom::Role::kComplementary, L"complementary");
- TestLocalizedLandmarkType(ax::mojom::Role::kContentInfo,
- L"content information");
- TestLocalizedLandmarkType(ax::mojom::Role::kFooter, L"content information");
-
- // Only named regions should be exposed as landmarks.
- TestLocalizedLandmarkType(ax::mojom::Role::kRegion, {});
- TestLocalizedLandmarkType(ax::mojom::Role::kRegion, L"region", "name");
-
- TestLocalizedLandmarkType(ax::mojom::Role::kForm, {});
- TestLocalizedLandmarkType(ax::mojom::Role::kGroup, {});
- TestLocalizedLandmarkType(ax::mojom::Role::kHeading, {});
- TestLocalizedLandmarkType(ax::mojom::Role::kList, {});
- TestLocalizedLandmarkType(ax::mojom::Role::kMain, {});
- TestLocalizedLandmarkType(ax::mojom::Role::kNavigation, {});
- TestLocalizedLandmarkType(ax::mojom::Role::kSearch, {});
- TestLocalizedLandmarkType(ax::mojom::Role::kTable, {});
-}
-
-TEST_F(AXPlatformNodeWinTest, IRawElementProviderSimple2ShowContextMenu) {
- AXNodeData root_data;
- root_data.id = 1;
-
- AXNodeData element1_data;
- element1_data.id = 2;
- root_data.child_ids.push_back(element1_data.id);
-
- AXNodeData element2_data;
- element2_data.id = 3;
- root_data.child_ids.push_back(element2_data.id);
-
- Init(root_data, element1_data, element2_data);
-
- AXNode* root_node = GetRootAsAXNode();
- AXNode* element1_node = root_node->children()[0];
- AXNode* element2_node = root_node->children()[1];
-
- ComPtr<IRawElementProviderSimple2> root_provider =
- QueryInterfaceFromNode<IRawElementProviderSimple2>(root_node);
- ComPtr<IRawElementProviderSimple2> element1_provider =
- QueryInterfaceFromNode<IRawElementProviderSimple2>(element1_node);
- ComPtr<IRawElementProviderSimple2> element2_provider =
- QueryInterfaceFromNode<IRawElementProviderSimple2>(element2_node);
-
- EXPECT_HRESULT_SUCCEEDED(element1_provider->ShowContextMenu());
- EXPECT_EQ(element1_node, TestAXNodeWrapper::GetNodeFromLastShowContextMenu());
- EXPECT_HRESULT_SUCCEEDED(element2_provider->ShowContextMenu());
- EXPECT_EQ(element2_node, TestAXNodeWrapper::GetNodeFromLastShowContextMenu());
- EXPECT_HRESULT_SUCCEEDED(root_provider->ShowContextMenu());
- EXPECT_EQ(root_node, TestAXNodeWrapper::GetNodeFromLastShowContextMenu());
-}
-
-TEST_F(AXPlatformNodeWinTest, UIAErrorHandling) {
- AXNodeData root;
- Init(root);
-
- ComPtr<IRawElementProviderSimple> simple_provider =
- GetRootIRawElementProviderSimple();
- ComPtr<IRawElementProviderSimple2> simple2_provider =
- QueryInterfaceFromNode<IRawElementProviderSimple2>(GetRootAsAXNode());
- ComPtr<IRawElementProviderFragment> fragment_provider =
- GetRootIRawElementProviderFragment();
- ComPtr<IGridItemProvider> grid_item_provider =
- QueryInterfaceFromNode<IGridItemProvider>(GetRootAsAXNode());
- ComPtr<IGridProvider> grid_provider =
- QueryInterfaceFromNode<IGridProvider>(GetRootAsAXNode());
- ComPtr<IScrollItemProvider> scroll_item_provider =
- QueryInterfaceFromNode<IScrollItemProvider>(GetRootAsAXNode());
- ComPtr<IScrollProvider> scroll_provider =
- QueryInterfaceFromNode<IScrollProvider>(GetRootAsAXNode());
- ComPtr<ISelectionItemProvider> selection_item_provider =
- QueryInterfaceFromNode<ISelectionItemProvider>(GetRootAsAXNode());
- ComPtr<ISelectionProvider> selection_provider =
- QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode());
- ComPtr<ITableItemProvider> table_item_provider =
- QueryInterfaceFromNode<ITableItemProvider>(GetRootAsAXNode());
- ComPtr<ITableProvider> table_provider =
- QueryInterfaceFromNode<ITableProvider>(GetRootAsAXNode());
- ComPtr<IExpandCollapseProvider> expand_collapse_provider =
- QueryInterfaceFromNode<IExpandCollapseProvider>(GetRootAsAXNode());
- ComPtr<IToggleProvider> toggle_provider =
- QueryInterfaceFromNode<IToggleProvider>(GetRootAsAXNode());
- ComPtr<IValueProvider> value_provider =
- QueryInterfaceFromNode<IValueProvider>(GetRootAsAXNode());
- ComPtr<IRangeValueProvider> range_value_provider =
- QueryInterfaceFromNode<IRangeValueProvider>(GetRootAsAXNode());
- ComPtr<IWindowProvider> window_provider =
- QueryInterfaceFromNode<IWindowProvider>(GetRootAsAXNode());
-
- // Create an empty tree.
- SetTree(std::make_unique<AXTree>());
-
- // IGridItemProvider
- int int_result = 0;
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- grid_item_provider->get_Column(&int_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- grid_item_provider->get_ColumnSpan(&int_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- grid_item_provider->get_Row(&int_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- grid_item_provider->get_RowSpan(&int_result));
-
- // IExpandCollapseProvider
- ExpandCollapseState expand_collapse_state;
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- expand_collapse_provider->Collapse());
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- expand_collapse_provider->Expand());
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- expand_collapse_provider->get_ExpandCollapseState(
- &expand_collapse_state));
-
- // IGridProvider
- ComPtr<IRawElementProviderSimple> temp_simple_provider;
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- grid_provider->GetItem(0, 0, &temp_simple_provider));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- grid_provider->get_RowCount(&int_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- grid_provider->get_ColumnCount(&int_result));
-
- // IScrollItemProvider
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- scroll_item_provider->ScrollIntoView());
-
- // IScrollProvider
- BOOL bool_result = TRUE;
- double double_result = 3.14;
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- scroll_provider->SetScrollPercent(0, 0));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- scroll_provider->get_HorizontallyScrollable(&bool_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- scroll_provider->get_HorizontalScrollPercent(&double_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- scroll_provider->get_HorizontalViewSize(&double_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- scroll_provider->get_VerticallyScrollable(&bool_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- scroll_provider->get_VerticalScrollPercent(&double_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- scroll_provider->get_VerticalViewSize(&double_result));
-
- // ISelectionItemProvider
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- selection_item_provider->AddToSelection());
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- selection_item_provider->RemoveFromSelection());
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- selection_item_provider->Select());
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- selection_item_provider->get_IsSelected(&bool_result));
- EXPECT_EQ(
- static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- selection_item_provider->get_SelectionContainer(&temp_simple_provider));
-
- // ISelectionProvider
- base::win::ScopedSafearray array_result;
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- selection_provider->GetSelection(array_result.Receive()));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- selection_provider->get_CanSelectMultiple(&bool_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- selection_provider->get_IsSelectionRequired(&bool_result));
-
- // ITableItemProvider
- RowOrColumnMajor row_or_column_major_result;
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- table_item_provider->GetColumnHeaderItems(array_result.Receive()));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- table_item_provider->GetRowHeaderItems(array_result.Receive()));
-
- // ITableProvider
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- table_provider->GetColumnHeaders(array_result.Receive()));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- table_provider->GetRowHeaders(array_result.Receive()));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- table_provider->get_RowOrColumnMajor(&row_or_column_major_result));
-
- // IRawElementProviderSimple
- ScopedVariant variant;
- ComPtr<IUnknown> unknown;
- ComPtr<IRawElementProviderSimple> host_provider;
- ProviderOptions options;
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- simple_provider->GetPatternProvider(UIA_WindowPatternId, &unknown));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- simple_provider->GetPropertyValue(UIA_FrameworkIdPropertyId,
- variant.Receive()));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- simple_provider->get_ProviderOptions(&options));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- simple_provider->get_HostRawElementProvider(&host_provider));
-
- // IRawElementProviderSimple2
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- simple2_provider->ShowContextMenu());
-
- // IRawElementProviderFragment
- ComPtr<IRawElementProviderFragment> navigated_to_fragment;
- base::win::ScopedSafearray safearray;
- UiaRect bounding_rectangle;
- ComPtr<IRawElementProviderFragmentRoot> fragment_root;
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- fragment_provider->Navigate(NavigateDirection_Parent,
- &navigated_to_fragment));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- fragment_provider->GetRuntimeId(safearray.Receive()));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- fragment_provider->get_BoundingRectangle(&bounding_rectangle));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- fragment_provider->GetEmbeddedFragmentRoots(safearray.Receive()));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- fragment_provider->get_FragmentRoot(&fragment_root));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- fragment_provider->SetFocus());
-
- // IValueProvider
- ScopedBstr bstr_value;
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- value_provider->SetValue(L"3.14"));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- value_provider->get_Value(bstr_value.Receive()));
-
- // IRangeValueProvider
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- range_value_provider->SetValue(double_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- range_value_provider->get_LargeChange(&double_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- range_value_provider->get_Maximum(&double_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- range_value_provider->get_Minimum(&double_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- range_value_provider->get_SmallChange(&double_result));
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- range_value_provider->get_Value(&double_result));
-
- // IToggleProvider
- ToggleState toggle_state;
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- toggle_provider->Toggle());
- EXPECT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- toggle_provider->get_ToggleState(&toggle_state));
-
- // IWindowProvider
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- window_provider->SetVisualState(
- WindowVisualState::WindowVisualState_Normal));
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- window_provider->Close());
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- window_provider->WaitForInputIdle(0, nullptr));
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- window_provider->get_CanMaximize(nullptr));
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- window_provider->get_CanMinimize(nullptr));
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- window_provider->get_IsModal(nullptr));
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- window_provider->get_WindowVisualState(nullptr));
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- window_provider->get_WindowInteractionState(nullptr));
- ASSERT_EQ(static_cast<HRESULT>(UIA_E_ELEMENTNOTAVAILABLE),
- window_provider->get_IsTopmost(nullptr));
-}
-
-TEST_F(AXPlatformNodeWinTest, GetPatternProviderSupportedPatterns) {
- constexpr AXNode::AXID root_id = 1;
- constexpr AXNode::AXID text_field_with_combo_box_id = 2;
- constexpr AXNode::AXID meter_id = 3;
- constexpr AXNode::AXID group_with_scroll_id = 4;
- constexpr AXNode::AXID checkbox_id = 5;
- constexpr AXNode::AXID link_id = 6;
- constexpr AXNode::AXID table_without_header_id = 7;
- constexpr AXNode::AXID table_without_header_cell_id = 8;
- constexpr AXNode::AXID table_with_header_id = 9;
- constexpr AXNode::AXID table_with_header_row_1_id = 10;
- constexpr AXNode::AXID table_with_header_column_header_id = 11;
- constexpr AXNode::AXID table_with_header_row_2_id = 12;
- constexpr AXNode::AXID table_with_header_cell_id = 13;
- constexpr AXNode::AXID grid_without_header_id = 14;
- constexpr AXNode::AXID grid_without_header_cell_id = 15;
- constexpr AXNode::AXID grid_with_header_id = 16;
- constexpr AXNode::AXID grid_with_header_row_1_id = 17;
- constexpr AXNode::AXID grid_with_header_column_header_id = 18;
- constexpr AXNode::AXID grid_with_header_row_2_id = 19;
- constexpr AXNode::AXID grid_with_header_cell_id = 20;
-
- AXTreeUpdate update;
- update.tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
- update.has_tree_data = true;
- update.root_id = root_id;
- update.nodes.resize(20);
- update.nodes[0].id = root_id;
- update.nodes[0].role = ax::mojom::Role::kRootWebArea;
- update.nodes[0].child_ids = {text_field_with_combo_box_id,
- meter_id,
- group_with_scroll_id,
- checkbox_id,
- link_id,
- table_without_header_id,
- table_with_header_id,
- grid_without_header_id,
- grid_with_header_id};
- update.nodes[1].id = text_field_with_combo_box_id;
- update.nodes[1].role = ax::mojom::Role::kTextFieldWithComboBox;
- update.nodes[2].id = meter_id;
- update.nodes[2].role = ax::mojom::Role::kMeter;
- update.nodes[3].id = group_with_scroll_id;
- update.nodes[3].role = ax::mojom::Role::kGroup;
- update.nodes[3].AddIntAttribute(ax::mojom::IntAttribute::kScrollXMin, 10);
- update.nodes[3].AddIntAttribute(ax::mojom::IntAttribute::kScrollXMax, 10);
- update.nodes[3].AddIntAttribute(ax::mojom::IntAttribute::kScrollX, 10);
- update.nodes[4].id = checkbox_id;
- update.nodes[4].role = ax::mojom::Role::kCheckBox;
- update.nodes[5].id = link_id;
- update.nodes[5].role = ax::mojom::Role::kLink;
- update.nodes[6].id = table_without_header_id;
- update.nodes[6].role = ax::mojom::Role::kTable;
- update.nodes[6].child_ids = {table_without_header_cell_id};
- update.nodes[7].id = table_without_header_cell_id;
- update.nodes[7].role = ax::mojom::Role::kCell;
- update.nodes[8].id = table_with_header_id;
- update.nodes[8].role = ax::mojom::Role::kTable;
- update.nodes[8].child_ids = {table_with_header_row_1_id,
- table_with_header_row_2_id};
- update.nodes[9].id = table_with_header_row_1_id;
- update.nodes[9].role = ax::mojom::Role::kRow;
- update.nodes[9].child_ids = {table_with_header_column_header_id};
- update.nodes[10].id = table_with_header_column_header_id;
- update.nodes[10].role = ax::mojom::Role::kColumnHeader;
- update.nodes[11].id = table_with_header_row_2_id;
- update.nodes[11].role = ax::mojom::Role::kRow;
- update.nodes[11].child_ids = {table_with_header_cell_id};
- update.nodes[12].id = table_with_header_cell_id;
- update.nodes[12].role = ax::mojom::Role::kCell;
- update.nodes[13].id = grid_without_header_id;
- update.nodes[13].role = ax::mojom::Role::kGrid;
- update.nodes[13].child_ids = {grid_without_header_cell_id};
- update.nodes[14].id = grid_without_header_cell_id;
- update.nodes[14].role = ax::mojom::Role::kCell;
- update.nodes[14].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
- update.nodes[15].id = grid_with_header_id;
- update.nodes[15].role = ax::mojom::Role::kGrid;
- update.nodes[15].child_ids = {grid_with_header_row_1_id,
- grid_with_header_row_2_id};
- update.nodes[16].id = grid_with_header_row_1_id;
- update.nodes[16].role = ax::mojom::Role::kRow;
- update.nodes[16].child_ids = {grid_with_header_column_header_id};
- update.nodes[17].id = grid_with_header_column_header_id;
- update.nodes[17].role = ax::mojom::Role::kColumnHeader;
- update.nodes[17].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
- update.nodes[18].id = grid_with_header_row_2_id;
- update.nodes[18].role = ax::mojom::Role::kRow;
- update.nodes[18].child_ids = {grid_with_header_cell_id};
- update.nodes[19].id = grid_with_header_cell_id;
- update.nodes[19].role = ax::mojom::Role::kCell;
- update.nodes[19].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
-
- Init(update);
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_TextEditPatternId,
- UIA_TextPatternId}),
- GetSupportedPatternsFromNodeId(root_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_ValuePatternId,
- UIA_ExpandCollapsePatternId, UIA_TextChildPatternId}),
- GetSupportedPatternsFromNodeId(text_field_with_combo_box_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_ValuePatternId,
- UIA_RangeValuePatternId, UIA_TextChildPatternId}),
- GetSupportedPatternsFromNodeId(meter_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_ScrollPatternId,
- UIA_TextChildPatternId}),
- GetSupportedPatternsFromNodeId(group_with_scroll_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_ValuePatternId,
- UIA_TextChildPatternId, UIA_TogglePatternId}),
- GetSupportedPatternsFromNodeId(checkbox_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_ValuePatternId,
- UIA_InvokePatternId, UIA_TextChildPatternId}),
- GetSupportedPatternsFromNodeId(link_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_GridPatternId,
- UIA_TextChildPatternId}),
- GetSupportedPatternsFromNodeId(table_without_header_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_GridItemPatternId,
- UIA_TextChildPatternId}),
- GetSupportedPatternsFromNodeId(table_without_header_cell_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_GridPatternId,
- UIA_TablePatternId, UIA_TextChildPatternId}),
- GetSupportedPatternsFromNodeId(table_with_header_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_GridItemPatternId,
- UIA_TableItemPatternId, UIA_TextChildPatternId}),
- GetSupportedPatternsFromNodeId(table_with_header_column_header_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_GridItemPatternId,
- UIA_TableItemPatternId, UIA_TextChildPatternId}),
- GetSupportedPatternsFromNodeId(table_with_header_cell_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_ValuePatternId,
- UIA_SelectionPatternId, UIA_GridPatternId,
- UIA_TextChildPatternId}),
- GetSupportedPatternsFromNodeId(grid_without_header_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_ValuePatternId,
- UIA_GridItemPatternId, UIA_TextChildPatternId,
- UIA_SelectionItemPatternId}),
- GetSupportedPatternsFromNodeId(grid_without_header_cell_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_ValuePatternId,
- UIA_SelectionPatternId, UIA_GridPatternId,
- UIA_TablePatternId, UIA_TextChildPatternId}),
- GetSupportedPatternsFromNodeId(grid_with_header_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_ValuePatternId,
- UIA_GridItemPatternId, UIA_TableItemPatternId,
- UIA_TextChildPatternId, UIA_SelectionItemPatternId}),
- GetSupportedPatternsFromNodeId(grid_with_header_column_header_id));
-
- EXPECT_EQ(PatternSet({UIA_ScrollItemPatternId, UIA_ValuePatternId,
- UIA_GridItemPatternId, UIA_TableItemPatternId,
- UIA_TextChildPatternId, UIA_SelectionItemPatternId}),
- GetSupportedPatternsFromNodeId(grid_with_header_cell_id));
-}
-
-TEST_F(AXPlatformNodeWinTest, GetPatternProviderExpandCollapsePattern) {
- ui::AXNodeData root;
- root.id = 1;
-
- ui::AXNodeData list_box;
- ui::AXNodeData list_item;
- ui::AXNodeData menu_item;
- ui::AXNodeData menu_list_option;
- ui::AXNodeData tree_item;
- ui::AXNodeData combo_box_grouping;
- ui::AXNodeData combo_box_menu_button;
- ui::AXNodeData disclosure_triangle;
- ui::AXNodeData text_field_with_combo_box;
-
- list_box.id = 2;
- list_item.id = 3;
- menu_item.id = 4;
- menu_list_option.id = 5;
- tree_item.id = 6;
- combo_box_grouping.id = 7;
- combo_box_menu_button.id = 8;
- disclosure_triangle.id = 9;
- text_field_with_combo_box.id = 10;
-
- root.child_ids.push_back(list_box.id);
- root.child_ids.push_back(list_item.id);
- root.child_ids.push_back(menu_item.id);
- root.child_ids.push_back(menu_list_option.id);
- root.child_ids.push_back(tree_item.id);
- root.child_ids.push_back(combo_box_grouping.id);
- root.child_ids.push_back(combo_box_menu_button.id);
- root.child_ids.push_back(disclosure_triangle.id);
- root.child_ids.push_back(text_field_with_combo_box.id);
-
- // list_box HasPopup set to false, does not support expand collapse.
- list_box.role = ax::mojom::Role::kListBoxOption;
- list_box.SetHasPopup(ax::mojom::HasPopup::kFalse);
-
- // list_item HasPopup set to true, supports expand collapse.
- list_item.role = ax::mojom::Role::kListItem;
- list_item.SetHasPopup(ax::mojom::HasPopup::kTrue);
-
- // menu_item has expanded state and supports expand collapse.
- menu_item.role = ax::mojom::Role::kMenuItem;
- menu_item.AddState(ax::mojom::State::kExpanded);
-
- // menu_list_option has collapsed state and supports expand collapse.
- menu_list_option.role = ax::mojom::Role::kMenuListOption;
- menu_list_option.AddState(ax::mojom::State::kCollapsed);
-
- // These roles by default supports expand collapse.
- tree_item.role = ax::mojom::Role::kTreeItem;
- combo_box_grouping.role = ax::mojom::Role::kComboBoxGrouping;
- combo_box_menu_button.role = ax::mojom::Role::kComboBoxMenuButton;
- disclosure_triangle.role = ax::mojom::Role::kDisclosureTriangle;
- text_field_with_combo_box.role = ax::mojom::Role::kTextFieldWithComboBox;
-
- Init(root, list_box, list_item, menu_item, menu_list_option, tree_item,
- combo_box_grouping, combo_box_menu_button, disclosure_triangle,
- text_field_with_combo_box);
-
- // list_box HasPopup set to false, does not support expand collapse.
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetIRawElementProviderSimpleFromChildIndex(0);
- ComPtr<IExpandCollapseProvider> expandcollapse_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- EXPECT_EQ(nullptr, expandcollapse_provider.Get());
-
- // list_item HasPopup set to true, supports expand collapse.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(1);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- EXPECT_NE(nullptr, expandcollapse_provider.Get());
-
- // menu_item has expanded state and supports expand collapse.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(2);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- EXPECT_NE(nullptr, expandcollapse_provider.Get());
-
- // menu_list_option has collapsed state and supports expand collapse.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(3);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- EXPECT_NE(nullptr, expandcollapse_provider.Get());
-
- // tree_item by default supports expand collapse.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(4);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- EXPECT_NE(nullptr, expandcollapse_provider.Get());
-
- // combo_box_grouping by default supports expand collapse.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(5);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- EXPECT_NE(nullptr, expandcollapse_provider.Get());
-
- // combo_box_menu_button by default supports expand collapse.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(6);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- EXPECT_NE(nullptr, expandcollapse_provider.Get());
-
- // disclosure_triangle by default supports expand collapse.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(7);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- EXPECT_NE(nullptr, expandcollapse_provider.Get());
-
- // text_field_with_combo_box by default supports expand collapse.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(8);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- EXPECT_NE(nullptr, expandcollapse_provider.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, GetPatternProviderInvokePattern) {
- ui::AXNodeData root;
- root.id = 1;
-
- ui::AXNodeData link;
- ui::AXNodeData generic_container;
- ui::AXNodeData combo_box_grouping;
- ui::AXNodeData check_box;
-
- link.id = 2;
- generic_container.id = 3;
- combo_box_grouping.id = 4;
- check_box.id = 5;
-
- root.child_ids.push_back(link.id);
- root.child_ids.push_back(generic_container.id);
- root.child_ids.push_back(combo_box_grouping.id);
- root.child_ids.push_back(check_box.id);
-
- // Role link is clickable and neither supports expand collapse nor supports
- // toggle. It should support invoke pattern.
- link.role = ax::mojom::Role::kLink;
-
- // Role generic container is not clickable. It should not support invoke
- // pattern.
- generic_container.role = ax::mojom::Role::kGenericContainer;
-
- // Role combo box grouping supports expand collapse. It should not support
- // invoke pattern.
- combo_box_grouping.role = ax::mojom::Role::kComboBoxGrouping;
-
- // Role check box supports toggle. It should not support invoke pattern.
- check_box.role = ax::mojom::Role::kCheckBox;
-
- Init(root, link, generic_container, combo_box_grouping, check_box);
-
- // Role link is clickable and neither supports expand collapse nor supports
- // toggle. It should support invoke pattern.
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetIRawElementProviderSimpleFromChildIndex(0);
- ComPtr<IInvokeProvider> invoke_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_InvokePatternId, &invoke_provider));
- EXPECT_NE(nullptr, invoke_provider.Get());
-
- // Role generic container is not clickable. It should not support invoke
- // pattern.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(1);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_InvokePatternId, &invoke_provider));
- EXPECT_EQ(nullptr, invoke_provider.Get());
-
- // Role combo box grouping supports expand collapse. It should not support
- // invoke pattern.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(2);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_InvokePatternId, &invoke_provider));
- EXPECT_EQ(nullptr, invoke_provider.Get());
-
- // Role check box supports toggle. It should not support invoke pattern.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(3);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_InvokePatternId, &invoke_provider));
- EXPECT_EQ(nullptr, invoke_provider.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, IExpandCollapsePatternProviderAction) {
- ui::AXNodeData root;
- root.id = 1;
-
- ui::AXNodeData combo_box_grouping_has_popup;
- ui::AXNodeData combo_box_grouping_expanded;
- ui::AXNodeData combo_box_grouping_collapsed;
- ui::AXNodeData combo_box_grouping_disabled;
- ui::AXNodeData button_has_popup_menu;
- ui::AXNodeData button_has_popup_menu_pressed;
- ui::AXNodeData button_has_popup_true;
- ui::AXNodeData generic_container_has_popup_menu;
-
- combo_box_grouping_has_popup.id = 2;
- combo_box_grouping_expanded.id = 3;
- combo_box_grouping_collapsed.id = 4;
- combo_box_grouping_disabled.id = 5;
- button_has_popup_menu.id = 6;
- button_has_popup_menu_pressed.id = 7;
- button_has_popup_true.id = 8;
- generic_container_has_popup_menu.id = 9;
-
- root.child_ids = {
- combo_box_grouping_has_popup.id, combo_box_grouping_expanded.id,
- combo_box_grouping_collapsed.id, combo_box_grouping_disabled.id,
- button_has_popup_menu.id, button_has_popup_menu_pressed.id,
- button_has_popup_true.id, generic_container_has_popup_menu.id};
-
- // combo_box_grouping HasPopup set to true, can collapse, can expand.
- // state is ExpandCollapseState_LeafNode.
- combo_box_grouping_has_popup.role = ax::mojom::Role::kComboBoxGrouping;
- combo_box_grouping_has_popup.SetHasPopup(ax::mojom::HasPopup::kTrue);
-
- // combo_box_grouping Expanded set, can collapse, cannot expand.
- // state is ExpandCollapseState_Expanded.
- combo_box_grouping_expanded.role = ax::mojom::Role::kComboBoxGrouping;
- combo_box_grouping_expanded.AddState(ax::mojom::State::kExpanded);
-
- // combo_box_grouping Collapsed set, can expand, cannot collapse.
- // state is ExpandCollapseState_Collapsed.
- combo_box_grouping_collapsed.role = ax::mojom::Role::kComboBoxGrouping;
- combo_box_grouping_collapsed.AddState(ax::mojom::State::kCollapsed);
-
- // combo_box_grouping is disabled, can neither expand nor collapse.
- // state is ExpandCollapseState_LeafNode.
- combo_box_grouping_disabled.role = ax::mojom::Role::kComboBoxGrouping;
- combo_box_grouping_disabled.SetRestriction(ax::mojom::Restriction::kDisabled);
-
- // button_has_popup_menu HasPopup set to kMenu and is not STATE_PRESSED.
- // state is ExpandCollapseState_Collapsed.
- button_has_popup_menu.role = ax::mojom::Role::kButton;
- button_has_popup_menu.SetHasPopup(ax::mojom::HasPopup::kMenu);
-
- // button_has_popup_menu_pressed HasPopup set to kMenu and is STATE_PRESSED.
- // state is ExpandCollapseState_Expanded.
- button_has_popup_menu_pressed.role = ax::mojom::Role::kButton;
- button_has_popup_menu_pressed.SetHasPopup(ax::mojom::HasPopup::kMenu);
- button_has_popup_menu_pressed.SetCheckedState(ax::mojom::CheckedState::kTrue);
-
- // button_has_popup_true HasPopup set to true but is not a menu.
- // state is ExpandCollapseState_LeafNode.
- button_has_popup_true.role = ax::mojom::Role::kButton;
- button_has_popup_true.SetHasPopup(ax::mojom::HasPopup::kTrue);
-
- // generic_container_has_popup_menu HasPopup set to menu but with no expand
- // state set.
- // state is ExpandCollapseState_LeafNode.
- generic_container_has_popup_menu.role = ax::mojom::Role::kGenericContainer;
- generic_container_has_popup_menu.SetHasPopup(ax::mojom::HasPopup::kMenu);
-
- Init(root, combo_box_grouping_has_popup, combo_box_grouping_disabled,
- combo_box_grouping_expanded, combo_box_grouping_collapsed,
- combo_box_grouping_disabled, button_has_popup_menu,
- button_has_popup_menu_pressed, button_has_popup_true,
- generic_container_has_popup_menu);
-
- // combo_box_grouping HasPopup set to true, can collapse, can expand.
- // state is ExpandCollapseState_LeafNode.
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetIRawElementProviderSimpleFromChildIndex(0);
- ComPtr<IExpandCollapseProvider> expandcollapse_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- ASSERT_NE(nullptr, expandcollapse_provider.Get());
- EXPECT_HRESULT_SUCCEEDED(expandcollapse_provider->Collapse());
- EXPECT_HRESULT_SUCCEEDED(expandcollapse_provider->Expand());
- ExpandCollapseState state;
- EXPECT_HRESULT_SUCCEEDED(
- expandcollapse_provider->get_ExpandCollapseState(&state));
- EXPECT_EQ(ExpandCollapseState_LeafNode, state);
-
- // combo_box_grouping Expanded set, can collapse, cannot expand.
- // state is ExpandCollapseState_Expanded.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(1);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- ASSERT_NE(nullptr, expandcollapse_provider.Get());
- EXPECT_HRESULT_SUCCEEDED(expandcollapse_provider->Collapse());
- EXPECT_HRESULT_FAILED(expandcollapse_provider->Expand());
- EXPECT_HRESULT_SUCCEEDED(
- expandcollapse_provider->get_ExpandCollapseState(&state));
- EXPECT_EQ(ExpandCollapseState_Expanded, state);
-
- // combo_box_grouping Collapsed set, can expand, cannot collapse.
- // state is ExpandCollapseState_Collapsed.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(2);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- ASSERT_NE(nullptr, expandcollapse_provider.Get());
- EXPECT_HRESULT_FAILED(expandcollapse_provider->Collapse());
- EXPECT_HRESULT_SUCCEEDED(expandcollapse_provider->Expand());
- EXPECT_HRESULT_SUCCEEDED(
- expandcollapse_provider->get_ExpandCollapseState(&state));
- EXPECT_EQ(ExpandCollapseState_Collapsed, state);
-
- // combo_box_grouping is disabled, can neither expand nor collapse.
- // state is ExpandCollapseState_LeafNode.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(3);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- ASSERT_NE(nullptr, expandcollapse_provider.Get());
- EXPECT_HRESULT_FAILED(expandcollapse_provider->Collapse());
- EXPECT_HRESULT_FAILED(expandcollapse_provider->Expand());
- EXPECT_HRESULT_SUCCEEDED(
- expandcollapse_provider->get_ExpandCollapseState(&state));
- EXPECT_EQ(ExpandCollapseState_LeafNode, state);
-
- // button_has_popup_menu HasPopup set to kMenu and is not STATE_PRESSED.
- // state is ExpandCollapseState_Collapsed.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(4);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- ASSERT_NE(nullptr, expandcollapse_provider.Get());
- EXPECT_HRESULT_SUCCEEDED(
- expandcollapse_provider->get_ExpandCollapseState(&state));
- EXPECT_EQ(ExpandCollapseState_Collapsed, state);
-
- // button_has_popup_menu_pressed HasPopup set to kMenu and is STATE_PRESSED.
- // state is ExpandCollapseState_Expanded.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(5);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- ASSERT_NE(nullptr, expandcollapse_provider.Get());
- EXPECT_HRESULT_SUCCEEDED(
- expandcollapse_provider->get_ExpandCollapseState(&state));
- EXPECT_EQ(ExpandCollapseState_Expanded, state);
-
- // button_has_popup_true HasPopup set to true but is not a menu.
- // state is ExpandCollapseState_LeafNode.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(6);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- ASSERT_NE(nullptr, expandcollapse_provider.Get());
- EXPECT_HRESULT_SUCCEEDED(
- expandcollapse_provider->get_ExpandCollapseState(&state));
- EXPECT_EQ(ExpandCollapseState_LeafNode, state);
-
- // generic_container_has_popup_menu HasPopup set to menu but with no expand
- // state set.
- // state is ExpandCollapseState_LeafNode.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(7);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_ExpandCollapsePatternId, &expandcollapse_provider));
- ASSERT_NE(nullptr, expandcollapse_provider.Get());
- EXPECT_HRESULT_SUCCEEDED(
- expandcollapse_provider->get_ExpandCollapseState(&state));
- EXPECT_EQ(ExpandCollapseState_LeafNode, state);
-}
-
-TEST_F(AXPlatformNodeWinTest, IInvokeProviderInvoke) {
- ui::AXNodeData root;
- root.id = 1;
-
- ui::AXNodeData button;
- ui::AXNodeData button_disabled;
-
- button.id = 2;
- button_disabled.id = 3;
-
- root.child_ids.push_back(button.id);
- root.child_ids.push_back(button_disabled.id);
-
- // generic button can be invoked.
- button.role = ax::mojom::Role::kButton;
-
- // disabled button, cannot be invoked.
- button_disabled.role = ax::mojom::Role::kButton;
- button_disabled.SetRestriction(ax::mojom::Restriction::kDisabled);
-
- Init(root, button, button_disabled);
- AXNode* button_node = GetRootAsAXNode()->children()[0];
-
- // generic button can be invoked.
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetIRawElementProviderSimpleFromChildIndex(0);
- ComPtr<IInvokeProvider> invoke_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_InvokePatternId, &invoke_provider));
- EXPECT_NE(nullptr, invoke_provider.Get());
- EXPECT_HRESULT_SUCCEEDED(invoke_provider->Invoke());
- EXPECT_EQ(button_node, TestAXNodeWrapper::GetNodeFromLastDefaultAction());
-
- // disabled button, cannot be invoked.
- raw_element_provider_simple = GetIRawElementProviderSimpleFromChildIndex(1);
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_InvokePatternId, &invoke_provider));
- EXPECT_NE(nullptr, invoke_provider.Get());
- EXPECT_UIA_ELEMENTNOTENABLED(invoke_provider->Invoke());
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionItemProviderNotSupported) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kNone;
-
- Init(root);
-
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetRootIRawElementProviderSimple();
- ComPtr<ISelectionItemProvider> selection_item_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_SelectionItemPatternId, &selection_item_provider));
- ASSERT_EQ(nullptr, selection_item_provider.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionItemProviderDisabled) {
- AXNodeData root;
- root.id = 1;
- root.AddIntAttribute(ax::mojom::IntAttribute::kRestriction,
- static_cast<int>(ax::mojom::Restriction::kDisabled));
- root.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
- root.role = ax::mojom::Role::kTab;
-
- Init(root);
-
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetRootIRawElementProviderSimple();
- ComPtr<ISelectionItemProvider> selection_item_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_SelectionItemPatternId, &selection_item_provider));
- ASSERT_NE(nullptr, selection_item_provider.Get());
-
- BOOL selected;
-
- EXPECT_UIA_ELEMENTNOTENABLED(selection_item_provider->AddToSelection());
- EXPECT_UIA_ELEMENTNOTENABLED(selection_item_provider->RemoveFromSelection());
- EXPECT_UIA_ELEMENTNOTENABLED(selection_item_provider->Select());
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionItemProviderNotSelectable) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTab;
-
- Init(root);
-
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetRootIRawElementProviderSimple();
- ComPtr<ISelectionItemProvider> selection_item_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_SelectionItemPatternId, &selection_item_provider));
- ASSERT_EQ(nullptr, selection_item_provider.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionItemProviderSimple) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kListBox;
-
- AXNodeData option1;
- option1.id = 2;
- option1.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
- option1.role = ax::mojom::Role::kListBoxOption;
- root.child_ids.push_back(option1.id);
-
- Init(root, option1);
-
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- GetIRawElementProviderSimpleFromChildIndex(0);
- ComPtr<ISelectionItemProvider> option1_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_SelectionItemPatternId, &option1_provider));
- ASSERT_NE(nullptr, option1_provider.Get());
-
- BOOL selected;
-
- // Note: TestAXNodeWrapper::AccessibilityPerformAction will
- // flip kSelected for kListBoxOption when the kDoDefault action is fired.
-
- // Initial State
- EXPECT_HRESULT_SUCCEEDED(option1_provider->get_IsSelected(&selected));
- EXPECT_FALSE(selected);
-
- // AddToSelection should fire event when not selected
- EXPECT_HRESULT_SUCCEEDED(option1_provider->AddToSelection());
- EXPECT_HRESULT_SUCCEEDED(option1_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-
- // AddToSelection should not fire event when selected
- EXPECT_HRESULT_SUCCEEDED(option1_provider->AddToSelection());
- EXPECT_HRESULT_SUCCEEDED(option1_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-
- // RemoveFromSelection should fire event when selected
- EXPECT_HRESULT_SUCCEEDED(option1_provider->RemoveFromSelection());
- EXPECT_HRESULT_SUCCEEDED(option1_provider->get_IsSelected(&selected));
- EXPECT_FALSE(selected);
-
- // RemoveFromSelection should not fire event when not selected
- EXPECT_HRESULT_SUCCEEDED(option1_provider->RemoveFromSelection());
- EXPECT_HRESULT_SUCCEEDED(option1_provider->get_IsSelected(&selected));
- EXPECT_FALSE(selected);
-
- // Select should fire event when not selected
- EXPECT_HRESULT_SUCCEEDED(option1_provider->Select());
- EXPECT_HRESULT_SUCCEEDED(option1_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-
- // Select should not fire event when selected
- EXPECT_HRESULT_SUCCEEDED(option1_provider->Select());
- EXPECT_HRESULT_SUCCEEDED(option1_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionItemProviderRadioButton) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRadioGroup;
-
- // CheckedState::kNone
- AXNodeData option1;
- option1.id = 2;
- option1.AddIntAttribute(ax::mojom::IntAttribute::kCheckedState,
- static_cast<int>(ax::mojom::CheckedState::kNone));
- option1.role = ax::mojom::Role::kRadioButton;
- root.child_ids.push_back(option1.id);
-
- // CheckedState::kFalse
- AXNodeData option2;
- option2.id = 3;
- option2.AddIntAttribute(ax::mojom::IntAttribute::kCheckedState,
- static_cast<int>(ax::mojom::CheckedState::kFalse));
- option2.role = ax::mojom::Role::kRadioButton;
- root.child_ids.push_back(option2.id);
-
- // CheckedState::kTrue
- AXNodeData option3;
- option3.id = 4;
- option3.AddIntAttribute(ax::mojom::IntAttribute::kCheckedState,
- static_cast<int>(ax::mojom::CheckedState::kTrue));
- option3.role = ax::mojom::Role::kRadioButton;
- root.child_ids.push_back(option3.id);
-
- // CheckedState::kMixed
- AXNodeData option4;
- option4.id = 5;
- option4.AddIntAttribute(ax::mojom::IntAttribute::kCheckedState,
- static_cast<int>(ax::mojom::CheckedState::kMixed));
- option4.role = ax::mojom::Role::kRadioButton;
- root.child_ids.push_back(option4.id);
-
- Init(root, option1, option2, option3, option4);
-
- BOOL selected;
-
- // Option 1, CheckedState::kNone, ISelectionItemProvider is not supported.
- ComPtr<ISelectionItemProvider> option1_provider;
- EXPECT_HRESULT_SUCCEEDED(
- GetIRawElementProviderSimpleFromChildIndex(0)->GetPatternProvider(
- UIA_SelectionItemPatternId, &option1_provider));
- ASSERT_EQ(nullptr, option1_provider.Get());
-
- // Option 2, CheckedState::kFalse.
- ComPtr<ISelectionItemProvider> option2_provider;
- EXPECT_HRESULT_SUCCEEDED(
- GetIRawElementProviderSimpleFromChildIndex(1)->GetPatternProvider(
- UIA_SelectionItemPatternId, &option2_provider));
- ASSERT_NE(nullptr, option2_provider.Get());
-
- EXPECT_HRESULT_SUCCEEDED(option2_provider->get_IsSelected(&selected));
- EXPECT_FALSE(selected);
-
- EXPECT_HRESULT_SUCCEEDED(option2_provider->Select());
- EXPECT_HRESULT_SUCCEEDED(option2_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-
- // Option 3, CheckedState::kTrue.
- ComPtr<ISelectionItemProvider> option3_provider;
- EXPECT_HRESULT_SUCCEEDED(
- GetIRawElementProviderSimpleFromChildIndex(2)->GetPatternProvider(
- UIA_SelectionItemPatternId, &option3_provider));
- ASSERT_NE(nullptr, option3_provider.Get());
-
- EXPECT_HRESULT_SUCCEEDED(option3_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-
- EXPECT_HRESULT_SUCCEEDED(option3_provider->RemoveFromSelection());
- EXPECT_HRESULT_SUCCEEDED(option3_provider->get_IsSelected(&selected));
- EXPECT_FALSE(selected);
-
- EXPECT_HRESULT_SUCCEEDED(option3_provider->AddToSelection());
- EXPECT_HRESULT_SUCCEEDED(option3_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-
- // Option 4, CheckedState::kMixed, ISelectionItemProvider is not supported.
- ComPtr<ISelectionItemProvider> option4_provider;
- EXPECT_HRESULT_SUCCEEDED(
- GetIRawElementProviderSimpleFromChildIndex(3)->GetPatternProvider(
- UIA_SelectionItemPatternId, &option4_provider));
- ASSERT_EQ(nullptr, option4_provider.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionItemProviderMenuItemRadio) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kMenu;
-
- // CheckedState::kNone
- AXNodeData option1;
- option1.id = 2;
- option1.AddIntAttribute(ax::mojom::IntAttribute::kCheckedState,
- static_cast<int>(ax::mojom::CheckedState::kNone));
- option1.role = ax::mojom::Role::kMenuItemRadio;
- root.child_ids.push_back(option1.id);
-
- // CheckedState::kFalse
- AXNodeData option2;
- option2.id = 3;
- option2.AddIntAttribute(ax::mojom::IntAttribute::kCheckedState,
- static_cast<int>(ax::mojom::CheckedState::kFalse));
- option2.role = ax::mojom::Role::kMenuItemRadio;
- root.child_ids.push_back(option2.id);
-
- // CheckedState::kTrue
- AXNodeData option3;
- option3.id = 4;
- option3.AddIntAttribute(ax::mojom::IntAttribute::kCheckedState,
- static_cast<int>(ax::mojom::CheckedState::kTrue));
- option3.role = ax::mojom::Role::kMenuItemRadio;
- root.child_ids.push_back(option3.id);
-
- // CheckedState::kMixed
- AXNodeData option4;
- option4.id = 5;
- option4.AddIntAttribute(ax::mojom::IntAttribute::kCheckedState,
- static_cast<int>(ax::mojom::CheckedState::kMixed));
- option4.role = ax::mojom::Role::kMenuItemRadio;
- root.child_ids.push_back(option4.id);
-
- Init(root, option1, option2, option3, option4);
-
- BOOL selected;
-
- // Option 1, CheckedState::kNone, ISelectionItemProvider is not supported.
- ComPtr<ISelectionItemProvider> option1_provider;
- EXPECT_HRESULT_SUCCEEDED(
- GetIRawElementProviderSimpleFromChildIndex(0)->GetPatternProvider(
- UIA_SelectionItemPatternId, &option1_provider));
- ASSERT_EQ(nullptr, option1_provider.Get());
-
- // Option 2, CheckedState::kFalse.
- ComPtr<ISelectionItemProvider> option2_provider;
- EXPECT_HRESULT_SUCCEEDED(
- GetIRawElementProviderSimpleFromChildIndex(1)->GetPatternProvider(
- UIA_SelectionItemPatternId, &option2_provider));
- ASSERT_NE(nullptr, option2_provider.Get());
-
- EXPECT_HRESULT_SUCCEEDED(option2_provider->get_IsSelected(&selected));
- EXPECT_FALSE(selected);
-
- EXPECT_HRESULT_SUCCEEDED(option2_provider->Select());
- EXPECT_HRESULT_SUCCEEDED(option2_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-
- // Option 3, CheckedState::kTrue.
- ComPtr<ISelectionItemProvider> option3_provider;
- EXPECT_HRESULT_SUCCEEDED(
- GetIRawElementProviderSimpleFromChildIndex(2)->GetPatternProvider(
- UIA_SelectionItemPatternId, &option3_provider));
- ASSERT_NE(nullptr, option3_provider.Get());
-
- EXPECT_HRESULT_SUCCEEDED(option3_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-
- EXPECT_HRESULT_SUCCEEDED(option3_provider->RemoveFromSelection());
- EXPECT_HRESULT_SUCCEEDED(option3_provider->get_IsSelected(&selected));
- EXPECT_FALSE(selected);
-
- EXPECT_HRESULT_SUCCEEDED(option3_provider->AddToSelection());
- EXPECT_HRESULT_SUCCEEDED(option3_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-
- // Option 4, CheckedState::kMixed, ISelectionItemProvider is not supported.
- ComPtr<ISelectionItemProvider> option4_provider;
- EXPECT_HRESULT_SUCCEEDED(
- GetIRawElementProviderSimpleFromChildIndex(3)->GetPatternProvider(
- UIA_SelectionItemPatternId, &option4_provider));
- ASSERT_EQ(nullptr, option4_provider.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionItemProviderTable) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTable;
-
- AXNodeData row1;
- row1.id = 2;
- row1.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row1.id);
-
- AXNodeData cell1;
- cell1.id = 3;
- cell1.role = ax::mojom::Role::kCell;
- cell1.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
- row1.child_ids.push_back(cell1.id);
-
- Init(root, row1, cell1);
-
- ComPtr<ISelectionItemProvider> selection_item_provider;
- EXPECT_HRESULT_SUCCEEDED(
- GetIRawElementProviderSimpleFromChildIndex(0)->GetPatternProvider(
- UIA_SelectionItemPatternId, &selection_item_provider));
- ASSERT_EQ(nullptr, selection_item_provider.Get());
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionItemProviderGrid) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kGrid;
-
- AXNodeData row1;
- row1.id = 2;
- row1.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row1.id);
-
- AXNodeData cell1;
- cell1.id = 3;
- cell1.role = ax::mojom::Role::kCell;
- cell1.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
- row1.child_ids.push_back(cell1.id);
-
- Init(root, row1, cell1);
-
- const auto* row = GetRootAsAXNode()->children()[0];
- ComPtr<IRawElementProviderSimple> raw_element_provider_simple =
- QueryInterfaceFromNode<IRawElementProviderSimple>(row->children()[0]);
-
- ComPtr<ISelectionItemProvider> selection_item_provider;
- EXPECT_HRESULT_SUCCEEDED(raw_element_provider_simple->GetPatternProvider(
- UIA_SelectionItemPatternId, &selection_item_provider));
- ASSERT_NE(nullptr, selection_item_provider.Get());
-
- BOOL selected;
-
- // Note: TestAXNodeWrapper::AccessibilityPerformAction will
- // flip kSelected for kCell when the kDoDefault action is fired.
-
- // Initial State
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->get_IsSelected(&selected));
- EXPECT_FALSE(selected);
-
- // AddToSelection should fire event when not selected
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->AddToSelection());
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-
- // AddToSelection should not fire event when selected
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->AddToSelection());
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-
- // RemoveFromSelection should fire event when selected
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->RemoveFromSelection());
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->get_IsSelected(&selected));
- EXPECT_FALSE(selected);
-
- // RemoveFromSelection should not fire event when not selected
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->RemoveFromSelection());
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->get_IsSelected(&selected));
- EXPECT_FALSE(selected);
-
- // Select should fire event when not selected
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->Select());
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-
- // Select should not fire event when selected
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->Select());
- EXPECT_HRESULT_SUCCEEDED(selection_item_provider->get_IsSelected(&selected));
- EXPECT_TRUE(selected);
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionItemProviderGetSelectionContainer) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kGrid;
-
- AXNodeData row1;
- row1.id = 2;
- row1.role = ax::mojom::Role::kRow;
- root.child_ids.push_back(row1.id);
-
- AXNodeData cell1;
- cell1.id = 3;
- cell1.role = ax::mojom::Role::kCell;
- cell1.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
- row1.child_ids.push_back(cell1.id);
-
- Init(root, row1, cell1);
-
- ComPtr<IRawElementProviderSimple> container_provider =
- GetRootIRawElementProviderSimple();
-
- const auto* row = GetRootAsAXNode()->children()[0];
- ComPtr<ISelectionItemProvider> item_provider =
- QueryInterfaceFromNode<ISelectionItemProvider>(row->children()[0]);
-
- ComPtr<IRawElementProviderSimple> container;
- EXPECT_HRESULT_SUCCEEDED(item_provider->get_SelectionContainer(&container));
- EXPECT_NE(nullptr, container);
- EXPECT_EQ(container, container_provider);
-}
-
-TEST_F(AXPlatformNodeWinTest, ISelectionItemProviderSelectFollowFocus) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kTabList;
-
- AXNodeData tab1;
- tab1.id = 2;
- tab1.role = ax::mojom::Role::kTab;
- tab1.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
- tab1.SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kClick);
- root.child_ids.push_back(tab1.id);
-
- Init(root, tab1);
-
- auto* tab1_node = GetRootAsAXNode()->children()[0];
- ComPtr<IRawElementProviderSimple> tab1_raw_element_provider_simple =
- QueryInterfaceFromNode<IRawElementProviderSimple>(tab1_node);
- ASSERT_NE(nullptr, tab1_raw_element_provider_simple.Get());
-
- ComPtr<IRawElementProviderFragment> tab1_raw_element_provider_fragment =
- IRawElementProviderFragmentFromNode(tab1_node);
- ASSERT_NE(nullptr, tab1_raw_element_provider_fragment.Get());
-
- ComPtr<ISelectionItemProvider> tab1_selection_item_provider;
- EXPECT_HRESULT_SUCCEEDED(tab1_raw_element_provider_simple->GetPatternProvider(
- UIA_SelectionItemPatternId, &tab1_selection_item_provider));
- ASSERT_NE(nullptr, tab1_selection_item_provider.Get());
-
- BOOL is_selected;
- // Before setting focus to "tab1", validate that "tab1" has selected=false.
- tab1_selection_item_provider->get_IsSelected(&is_selected);
- EXPECT_FALSE(is_selected);
-
- // Setting focus on "tab1" will result in selected=true.
- tab1_raw_element_provider_fragment->SetFocus();
- tab1_selection_item_provider->get_IsSelected(&is_selected);
- EXPECT_TRUE(is_selected);
-
- // Verify that we can still trigger action::kDoDefault through Select().
- EXPECT_HRESULT_SUCCEEDED(tab1_selection_item_provider->Select());
- tab1_selection_item_provider->get_IsSelected(&is_selected);
- EXPECT_TRUE(is_selected);
- EXPECT_EQ(tab1_node, TestAXNodeWrapper::GetNodeFromLastDefaultAction());
- // Verify that after Select(), "tab1" is still selected.
- tab1_selection_item_provider->get_IsSelected(&is_selected);
- EXPECT_TRUE(is_selected);
-
- // Since last Select() performed |action::kDoDefault|, which set
- // |kSelectedFromFocus| to false. Calling Select() again will not perform
- // |action::kDoDefault| again.
- TestAXNodeWrapper::SetNodeFromLastDefaultAction(nullptr);
- EXPECT_HRESULT_SUCCEEDED(tab1_selection_item_provider->Select());
- tab1_selection_item_provider->get_IsSelected(&is_selected);
- EXPECT_TRUE(is_selected);
- // Verify that after Select(),|action::kDoDefault| was not triggered on
- // "tab1".
- EXPECT_EQ(nullptr, TestAXNodeWrapper::GetNodeFromLastDefaultAction());
-}
-
-TEST_F(AXPlatformNodeWinTest, IValueProvider_GetValue) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kProgressIndicator;
- child1.AddFloatAttribute(ax::mojom::FloatAttribute::kValueForRange, 3.0f);
- root.child_ids.push_back(child1.id);
-
- AXNodeData child2;
- child2.id = 3;
- child2.role = ax::mojom::Role::kTextField;
- child2.AddState(ax::mojom::State::kEditable);
- child2.AddStringAttribute(ax::mojom::StringAttribute::kValue, "test");
- root.child_ids.push_back(child2.id);
-
- AXNodeData child3;
- child3.id = 4;
- child3.role = ax::mojom::Role::kTextField;
- child3.AddStringAttribute(ax::mojom::StringAttribute::kValue, "test");
- child3.AddIntAttribute(ax::mojom::IntAttribute::kRestriction,
- static_cast<int>(ax::mojom::Restriction::kReadOnly));
- root.child_ids.push_back(child3.id);
-
- Init(root, child1, child2, child3);
-
- ScopedBstr bstr_value;
-
- EXPECT_HRESULT_SUCCEEDED(
- QueryInterfaceFromNode<IValueProvider>(GetRootAsAXNode()->children()[0])
- ->get_Value(bstr_value.Receive()));
- EXPECT_STREQ(L"3", bstr_value.Get());
- bstr_value.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(
- QueryInterfaceFromNode<IValueProvider>(GetRootAsAXNode()->children()[1])
- ->get_Value(bstr_value.Receive()));
- EXPECT_STREQ(L"test", bstr_value.Get());
- bstr_value.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(
- QueryInterfaceFromNode<IValueProvider>(GetRootAsAXNode()->children()[2])
- ->get_Value(bstr_value.Receive()));
- EXPECT_STREQ(L"test", bstr_value.Get());
- bstr_value.Reset();
-}
-
-TEST_F(AXPlatformNodeWinTest, IAccessibleValue) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
-
- AXNodeData child;
- child.id = 2;
- child.role = ax::mojom::Role::kSlider;
- child.AddFloatAttribute(ax::mojom::FloatAttribute::kValueForRange, 3.0f);
- child.AddFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange, 1.0f);
- child.AddFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange, 9.0f);
- root.child_ids.push_back(child.id);
-
- Init(root, child);
-
- ScopedVariant value;
- EXPECT_HRESULT_SUCCEEDED(
- QueryInterfaceFromNode<IAccessibleValue>(GetRootAsAXNode()->children()[0])
- ->get_currentValue(value.Receive()));
- ASSERT_EQ(VT_R8, value.type());
- EXPECT_DOUBLE_EQ(3.0, V_R8(value.ptr()));
-}
-
-TEST_F(AXPlatformNodeWinTest, IValueProvider_SetValue) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kProgressIndicator;
- child1.AddFloatAttribute(ax::mojom::FloatAttribute::kValueForRange, 3.0f);
- root.child_ids.push_back(child1.id);
-
- AXNodeData child2;
- child2.id = 3;
- child2.role = ax::mojom::Role::kTextField;
- child2.AddStringAttribute(ax::mojom::StringAttribute::kValue, "test");
- root.child_ids.push_back(child2.id);
-
- AXNodeData child3;
- child3.id = 4;
- child3.role = ax::mojom::Role::kTextField;
- child3.AddStringAttribute(ax::mojom::StringAttribute::kValue, "test");
- child3.AddIntAttribute(ax::mojom::IntAttribute::kRestriction,
- static_cast<int>(ax::mojom::Restriction::kReadOnly));
- root.child_ids.push_back(child3.id);
-
- Init(root, child1, child2, child3);
-
- ComPtr<IValueProvider> root_provider =
- QueryInterfaceFromNode<IValueProvider>(GetRootAsAXNode());
- ComPtr<IValueProvider> provider1 =
- QueryInterfaceFromNode<IValueProvider>(GetRootAsAXNode()->children()[0]);
- ComPtr<IValueProvider> provider2 =
- QueryInterfaceFromNode<IValueProvider>(GetRootAsAXNode()->children()[1]);
- ComPtr<IValueProvider> provider3 =
- QueryInterfaceFromNode<IValueProvider>(GetRootAsAXNode()->children()[2]);
-
- ScopedBstr bstr_value;
-
- // Note: TestAXNodeWrapper::AccessibilityPerformAction will
- // modify the value when the kSetValue action is fired.
-
- EXPECT_UIA_ELEMENTNOTENABLED(provider1->SetValue(L"2"));
- EXPECT_HRESULT_SUCCEEDED(provider1->get_Value(bstr_value.Receive()));
- EXPECT_STREQ(L"3", bstr_value.Get());
- bstr_value.Reset();
-
- EXPECT_HRESULT_SUCCEEDED(provider2->SetValue(L"changed"));
- EXPECT_HRESULT_SUCCEEDED(provider2->get_Value(bstr_value.Receive()));
- EXPECT_STREQ(L"changed", bstr_value.Get());
- bstr_value.Reset();
-
- EXPECT_UIA_ELEMENTNOTENABLED(provider3->SetValue(L"changed"));
- EXPECT_HRESULT_SUCCEEDED(provider3->get_Value(bstr_value.Receive()));
- EXPECT_STREQ(L"test", bstr_value.Get());
- bstr_value.Reset();
-}
-
-TEST_F(AXPlatformNodeWinTest, IValueProvider_IsReadOnly) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kRootWebArea;
-
- AXNodeData child1;
- child1.id = 2;
- child1.role = ax::mojom::Role::kTextField;
- child1.AddState(ax::mojom::State::kEditable);
- root.child_ids.push_back(child1.id);
-
- AXNodeData child2;
- child2.id = 3;
- child2.role = ax::mojom::Role::kTextField;
- child2.AddIntAttribute(ax::mojom::IntAttribute::kRestriction,
- static_cast<int>(ax::mojom::Restriction::kReadOnly));
- root.child_ids.push_back(child2.id);
-
- AXNodeData child3;
- child3.id = 4;
- child3.role = ax::mojom::Role::kTextField;
- child3.AddIntAttribute(ax::mojom::IntAttribute::kRestriction,
- static_cast<int>(ax::mojom::Restriction::kDisabled));
- root.child_ids.push_back(child3.id);
-
- AXNodeData child4;
- child4.id = 5;
- child4.role = ax::mojom::Role::kLink;
- root.child_ids.push_back(child4.id);
-
- Init(root, child1, child2, child3, child4);
-
- BOOL is_readonly = false;
-
- EXPECT_HRESULT_SUCCEEDED(
- QueryInterfaceFromNode<IValueProvider>(GetRootAsAXNode()->children()[0])
- ->get_IsReadOnly(&is_readonly));
- EXPECT_FALSE(is_readonly);
-
- EXPECT_HRESULT_SUCCEEDED(
- QueryInterfaceFromNode<IValueProvider>(GetRootAsAXNode()->children()[1])
- ->get_IsReadOnly(&is_readonly));
- EXPECT_TRUE(is_readonly);
-
- EXPECT_HRESULT_SUCCEEDED(
- QueryInterfaceFromNode<IValueProvider>(GetRootAsAXNode()->children()[2])
- ->get_IsReadOnly(&is_readonly));
- EXPECT_TRUE(is_readonly);
-
- EXPECT_HRESULT_SUCCEEDED(
- QueryInterfaceFromNode<IValueProvider>(GetRootAsAXNode()->children()[3])
- ->get_IsReadOnly(&is_readonly));
- EXPECT_TRUE(is_readonly);
-}
-
-TEST_F(AXPlatformNodeWinTest, IScrollProviderSetScrollPercent) {
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kGenericContainer;
- root.AddIntAttribute(ax::mojom::IntAttribute::kScrollX, 0);
- root.AddIntAttribute(ax::mojom::IntAttribute::kScrollXMin, 0);
- root.AddIntAttribute(ax::mojom::IntAttribute::kScrollXMax, 100);
-
- root.AddIntAttribute(ax::mojom::IntAttribute::kScrollY, 60);
- root.AddIntAttribute(ax::mojom::IntAttribute::kScrollYMin, 10);
- root.AddIntAttribute(ax::mojom::IntAttribute::kScrollYMax, 60);
-
- Init(root);
-
- ComPtr<IScrollProvider> scroll_provider =
- QueryInterfaceFromNode<IScrollProvider>(GetRootAsAXNode());
- double x_scroll_percent;
- double y_scroll_percent;
-
- // Set x scroll percent: 0%, y scroll percent: 0%.
- // Expected x scroll percent: 0%, y scroll percent: 0%.
- EXPECT_HRESULT_SUCCEEDED(scroll_provider->SetScrollPercent(0, 0));
- EXPECT_HRESULT_SUCCEEDED(
- scroll_provider->get_HorizontalScrollPercent(&x_scroll_percent));
- EXPECT_EQ(x_scroll_percent, 0);
- EXPECT_HRESULT_SUCCEEDED(
- scroll_provider->get_VerticalScrollPercent(&y_scroll_percent));
- EXPECT_EQ(y_scroll_percent, 0);
-
- // Set x scroll percent: 100%, y scroll percent: 100%.
- // Expected x scroll percent: 100%, y scroll percent: 100%.
- EXPECT_HRESULT_SUCCEEDED(scroll_provider->SetScrollPercent(100, 100));
- EXPECT_HRESULT_SUCCEEDED(
- scroll_provider->get_HorizontalScrollPercent(&x_scroll_percent));
- EXPECT_EQ(x_scroll_percent, 100);
- EXPECT_HRESULT_SUCCEEDED(
- scroll_provider->get_VerticalScrollPercent(&y_scroll_percent));
- EXPECT_EQ(y_scroll_percent, 100);
-
- // Set x scroll percent: 500%, y scroll percent: 600%.
- // Expected x scroll percent: 100%, y scroll percent: 100%.
- EXPECT_HRESULT_SUCCEEDED(scroll_provider->SetScrollPercent(500, 600));
- EXPECT_HRESULT_SUCCEEDED(
- scroll_provider->get_HorizontalScrollPercent(&x_scroll_percent));
- EXPECT_EQ(x_scroll_percent, 100);
- EXPECT_HRESULT_SUCCEEDED(
- scroll_provider->get_VerticalScrollPercent(&y_scroll_percent));
- EXPECT_EQ(y_scroll_percent, 100);
-
- // Set x scroll percent: -100%, y scroll percent: -200%.
- // Expected x scroll percent: 0%, y scroll percent: 0%.
- EXPECT_HRESULT_SUCCEEDED(scroll_provider->SetScrollPercent(-100, -200));
- EXPECT_HRESULT_SUCCEEDED(
- scroll_provider->get_HorizontalScrollPercent(&x_scroll_percent));
- EXPECT_EQ(x_scroll_percent, 0);
- EXPECT_HRESULT_SUCCEEDED(
- scroll_provider->get_VerticalScrollPercent(&y_scroll_percent));
- EXPECT_EQ(y_scroll_percent, 0);
-
- // Set x scroll percent: 12%, y scroll percent: 34%.
- // Expected x scroll percent: 12%, y scroll percent: 34%.
- EXPECT_HRESULT_SUCCEEDED(scroll_provider->SetScrollPercent(12, 34));
- EXPECT_HRESULT_SUCCEEDED(
- scroll_provider->get_HorizontalScrollPercent(&x_scroll_percent));
- EXPECT_EQ(x_scroll_percent, 12);
- EXPECT_HRESULT_SUCCEEDED(
- scroll_provider->get_VerticalScrollPercent(&y_scroll_percent));
- EXPECT_EQ(y_scroll_percent, 34);
-}
-
-TEST_F(AXPlatformNodeWinTest, SanitizeStringAttributeForIA2) {
- std::string input("\\:=,;");
- std::string output;
- AXPlatformNodeWin::SanitizeStringAttributeForIA2(input, &output);
- EXPECT_EQ("\\\\\\:\\=\\,\\;", output);
-}
-
-//
-// IChromeAccessible tests
-//
-
-class TestIChromeAccessibleDelegate
- : public CComObjectRootEx<CComMultiThreadModel>,
- public IDispatchImpl<IChromeAccessibleDelegate> {
- using IDispatchImpl::Invoke;
-
- public:
- BEGIN_COM_MAP(TestIChromeAccessibleDelegate)
- COM_INTERFACE_ENTRY(IChromeAccessibleDelegate)
- END_COM_MAP()
-
- TestIChromeAccessibleDelegate() = default;
- ~TestIChromeAccessibleDelegate() = default;
-
- std::string WaitForBulkFetchResult(LONG expected_request_id) {
- if (bulk_fetch_result_.empty())
- WaitUsingRunLoop();
- CHECK_EQ(expected_request_id, request_id_);
- return bulk_fetch_result_;
- }
-
- IUnknown* WaitForHitTestResult(LONG expected_request_id) {
- if (!hit_test_result_)
- WaitUsingRunLoop();
- CHECK_EQ(expected_request_id, request_id_);
- return hit_test_result_.Get();
- }
-
- private:
- void WaitUsingRunLoop() {
- base::RunLoop run_loop;
- run_loop_quit_closure_ = run_loop.QuitClosure();
- run_loop.Run();
- }
-
- IFACEMETHODIMP put_bulkFetchResult(LONG request_id, BSTR result) override {
- bulk_fetch_result_ = base::WideToUTF8(result);
- request_id_ = request_id;
- if (run_loop_quit_closure_)
- run_loop_quit_closure_.Run();
- return S_OK;
- }
-
- IFACEMETHODIMP put_hitTestResult(LONG request_id, IUnknown* result) override {
- hit_test_result_ = result;
- request_id_ = request_id;
- if (run_loop_quit_closure_)
- run_loop_quit_closure_.Run();
- return S_OK;
- }
-
- std::string bulk_fetch_result_;
- ComPtr<IUnknown> hit_test_result_;
- LONG request_id_ = 0;
- base::RepeatingClosure run_loop_quit_closure_;
-};
-
-// http://crbug.com/1087206: failing on Win7 builders.
-TEST_F(AXPlatformNodeWinTest, DISABLED_BulkFetch) {
- base::test::SingleThreadTaskEnvironment task_environment;
- AXNodeData root;
- root.id = 1;
- root.role = ax::mojom::Role::kScrollBar;
-
- Init(root);
-
- ComPtr<IChromeAccessible> chrome_accessible =
- QueryInterfaceFromNode<IChromeAccessible>(GetRootAsAXNode());
-
- CComObject<TestIChromeAccessibleDelegate>* delegate = nullptr;
- ASSERT_HRESULT_SUCCEEDED(
- CComObject<TestIChromeAccessibleDelegate>::CreateInstance(&delegate));
- ScopedBstr input_bstr(L"Potato");
- chrome_accessible->get_bulkFetch(input_bstr.Get(), 99, delegate);
- std::string response = delegate->WaitForBulkFetchResult(99);
-
- // Note: base::JSONReader is fine for unit tests, but production code
- // that parses untrusted JSON should always use DataDecoder instead.
- base::Optional<base::Value> result =
- base::JSONReader::Read(response, base::JSON_ALLOW_TRAILING_COMMAS);
- ASSERT_TRUE(result);
- ASSERT_TRUE(result->FindKey("role"));
- ASSERT_EQ("scrollBar", result->FindKey("role")->GetString());
-}
-
-TEST_F(AXPlatformNodeWinTest, AsyncHitTest) {
- base::test::SingleThreadTaskEnvironment task_environment;
- AXNodeData root;
- root.id = 50;
- root.role = ax::mojom::Role::kArticle;
- root.relative_bounds.bounds = gfx::RectF(0, 0, 800, 600);
-
- Init(root);
-
- ComPtr<IChromeAccessible> chrome_accessible =
- QueryInterfaceFromNode<IChromeAccessible>(GetRootAsAXNode());
-
- CComObject<TestIChromeAccessibleDelegate>* delegate = nullptr;
- ASSERT_HRESULT_SUCCEEDED(
- CComObject<TestIChromeAccessibleDelegate>::CreateInstance(&delegate));
- ScopedBstr input_bstr(L"Potato");
- chrome_accessible->get_hitTest(400, 300, 12345, delegate);
- ComPtr<IUnknown> result = delegate->WaitForHitTestResult(12345);
- ComPtr<IAccessible2> accessible = ToIAccessible2(result);
- LONG result_unique_id = 0;
- ASSERT_HRESULT_SUCCEEDED(accessible->get_uniqueID(&result_unique_id));
- ComPtr<IAccessible2> root_accessible =
- QueryInterfaceFromNode<IAccessible2>(GetRootAsAXNode());
- LONG root_unique_id = 0;
- ASSERT_HRESULT_SUCCEEDED(root_accessible->get_uniqueID(&root_unique_id));
- ASSERT_EQ(root_unique_id, result_unique_id);
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_node_win_unittest.h b/third_party/accessibility/ax/platform/ax_platform_node_win_unittest.h
deleted file mode 100644
index 2d27271..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_node_win_unittest.h
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_WIN_UNITTEST_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_WIN_UNITTEST_H_
-
-#include "ui/accessibility/platform/ax_platform_node_unittest.h"
-
-#include <memory>
-#include <unordered_set>
-
-#include "base/test/scoped_feature_list.h"
-#include "ui/accessibility/platform/ax_fragment_root_delegate_win.h"
-#include "ui/base/win/accessibility_misc_utils.h"
-
-struct IAccessible;
-struct IAccessible2;
-struct IAccessible2_2;
-struct IAccessibleTableCell;
-struct IRawElementProviderFragment;
-struct IRawElementProviderFragmentRoot;
-struct IRawElementProviderSimple;
-struct IUnknown;
-
-namespace base {
-namespace win {
-class ScopedVariant;
-} // namespace win
-} // namespace base
-
-namespace ui {
-
-class AXFragmentRootWin;
-class AXPlatformNode;
-
-class TestFragmentRootDelegate : public AXFragmentRootDelegateWin {
- public:
- TestFragmentRootDelegate();
- virtual ~TestFragmentRootDelegate();
- gfx::NativeViewAccessible GetChildOfAXFragmentRoot() override;
- gfx::NativeViewAccessible GetParentOfAXFragmentRoot() override;
- bool IsAXFragmentRootAControlElement() override;
- gfx::NativeViewAccessible child_ = nullptr;
- gfx::NativeViewAccessible parent_ = nullptr;
- bool is_control_element_ = true;
-};
-
-class MockIRawElementProviderSimple
- : public CComObjectRootEx<CComMultiThreadModel>,
- public IRawElementProviderSimple {
- public:
- BEGIN_COM_MAP(MockIRawElementProviderSimple)
- COM_INTERFACE_ENTRY(IRawElementProviderSimple)
- END_COM_MAP()
-
- MockIRawElementProviderSimple();
- ~MockIRawElementProviderSimple();
-
- static HRESULT CreateMockIRawElementProviderSimple(
- IRawElementProviderSimple** provider);
-
- //
- // IRawElementProviderSimple methods.
- //
- IFACEMETHODIMP GetPatternProvider(PATTERNID pattern_id,
- IUnknown** result) override;
-
- IFACEMETHODIMP GetPropertyValue(PROPERTYID property_id,
- VARIANT* result) override;
-
- IFACEMETHODIMP
- get_ProviderOptions(enum ProviderOptions* ret) override;
-
- IFACEMETHODIMP
- get_HostRawElementProvider(IRawElementProviderSimple** provider) override;
-};
-
-class AXPlatformNodeWinTest : public AXPlatformNodeTest {
- public:
- AXPlatformNodeWinTest();
- ~AXPlatformNodeWinTest() override;
-
- void SetUp() override;
-
- void TearDown() override;
-
- protected:
- static const base::string16 kEmbeddedCharacterAsString;
-
- AXPlatformNode* AXPlatformNodeFromNode(AXNode* node);
- template <typename T>
- Microsoft::WRL::ComPtr<T> QueryInterfaceFromNodeId(AXNode::AXID id);
- template <typename T>
- Microsoft::WRL::ComPtr<T> QueryInterfaceFromNode(AXNode* node);
- Microsoft::WRL::ComPtr<IRawElementProviderSimple>
- GetRootIRawElementProviderSimple();
- Microsoft::WRL::ComPtr<IRawElementProviderSimple>
- GetIRawElementProviderSimpleFromChildIndex(int child_index);
- Microsoft::WRL::ComPtr<IRawElementProviderSimple>
- GetIRawElementProviderSimpleFromTree(const ui::AXTreeID tree_id,
- const AXNode::AXID node_id);
- Microsoft::WRL::ComPtr<IRawElementProviderFragment>
- GetRootIRawElementProviderFragment();
- Microsoft::WRL::ComPtr<IRawElementProviderFragment>
- IRawElementProviderFragmentFromNode(AXNode* node);
- Microsoft::WRL::ComPtr<IAccessible> IAccessibleFromNode(AXNode* node);
- Microsoft::WRL::ComPtr<IAccessible> GetRootIAccessible();
- Microsoft::WRL::ComPtr<IAccessible2> ToIAccessible2(
- Microsoft::WRL::ComPtr<IUnknown> unknown);
- Microsoft::WRL::ComPtr<IAccessible2> ToIAccessible2(
- Microsoft::WRL::ComPtr<IAccessible> accessible);
- Microsoft::WRL::ComPtr<IAccessible2_2> ToIAccessible2_2(
- Microsoft::WRL::ComPtr<IAccessible> accessible);
- void CheckVariantHasName(const base::win::ScopedVariant& variant,
- const wchar_t* expected_name);
- void CheckIUnknownHasName(Microsoft::WRL::ComPtr<IUnknown> unknown,
- const wchar_t* expected_name);
- Microsoft::WRL::ComPtr<IAccessibleTableCell> GetCellInTable();
-
- void InitFragmentRoot();
- AXFragmentRootWin* InitNodeAsFragmentRoot(AXNode* node,
- TestFragmentRootDelegate* delegate);
- Microsoft::WRL::ComPtr<IRawElementProviderFragmentRoot> GetFragmentRoot();
-
- using PatternSet = std::unordered_set<LONG>;
- PatternSet GetSupportedPatternsFromNodeId(AXNode::AXID id);
-
- std::unique_ptr<AXFragmentRootWin> ax_fragment_root_;
-
- std::unique_ptr<TestFragmentRootDelegate> test_fragment_root_delegate_;
-
- base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_WIN_UNITTEST_H_
diff --git a/third_party/accessibility/ax/platform/ax_platform_relation_win.cc b/third_party/accessibility/ax/platform/ax_platform_relation_win.cc
deleted file mode 100644
index eee92e3..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_relation_win.cc
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_platform_relation_win.h"
-
-#include <wrl/client.h>
-
-#include <algorithm>
-#include <vector>
-
-#include "base/lazy_instance.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/win/enum_variant.h"
-#include "base/win/scoped_variant.h"
-#include "third_party/iaccessible2/ia2_api_all.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_mode_observer.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_text_utils.h"
-#include "ui/accessibility/ax_tree_data.h"
-#include "ui/accessibility/platform/ax_platform_node_base.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
-#include "ui/accessibility/platform/ax_unique_id.h"
-#include "ui/base/win/atl_module.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-
-namespace ui {
-
-AXPlatformRelationWin::AXPlatformRelationWin() {
- win::CreateATLModuleIfNeeded();
-}
-
-AXPlatformRelationWin::~AXPlatformRelationWin() {}
-
-base::string16 GetIA2RelationFromIntAttr(ax::mojom::IntAttribute attribute) {
- switch (attribute) {
- case ax::mojom::IntAttribute::kMemberOfId:
- return IA2_RELATION_MEMBER_OF;
- case ax::mojom::IntAttribute::kErrormessageId:
- return IA2_RELATION_ERROR;
- case ax::mojom::IntAttribute::kPopupForId:
- // Map "popup for" to "controlled by".
- // Unlike ATK there is no special IA2 popup-for relationship, but it can
- // be exposed via the controlled by relation, which is also computed for
- // content as the reverse of the controls relationship.
- return IA2_RELATION_CONTROLLED_BY;
- default:
- break;
- }
- return base::string16();
-}
-
-base::string16 GetIA2RelationFromIntListAttr(
- ax::mojom::IntListAttribute attribute) {
- switch (attribute) {
- case ax::mojom::IntListAttribute::kControlsIds:
- return IA2_RELATION_CONTROLLER_FOR;
- case ax::mojom::IntListAttribute::kDescribedbyIds:
- return IA2_RELATION_DESCRIBED_BY;
- case ax::mojom::IntListAttribute::kDetailsIds:
- return IA2_RELATION_DETAILS;
- case ax::mojom::IntListAttribute::kFlowtoIds:
- return IA2_RELATION_FLOWS_TO;
- case ax::mojom::IntListAttribute::kLabelledbyIds:
- return IA2_RELATION_LABELLED_BY;
- default:
- break;
- }
- return base::string16();
-}
-
-base::string16 GetIA2ReverseRelationFromIntAttr(
- ax::mojom::IntAttribute attribute) {
- switch (attribute) {
- case ax::mojom::IntAttribute::kErrormessageId:
- return IA2_RELATION_ERROR_FOR;
- default:
- break;
- }
- return base::string16();
-}
-
-base::string16 GetIA2ReverseRelationFromIntListAttr(
- ax::mojom::IntListAttribute attribute) {
- switch (attribute) {
- case ax::mojom::IntListAttribute::kControlsIds:
- return IA2_RELATION_CONTROLLED_BY;
- case ax::mojom::IntListAttribute::kDescribedbyIds:
- return IA2_RELATION_DESCRIPTION_FOR;
- case ax::mojom::IntListAttribute::kDetailsIds:
- return IA2_RELATION_DETAILS_FOR;
- case ax::mojom::IntListAttribute::kFlowtoIds:
- return IA2_RELATION_FLOWS_FROM;
- case ax::mojom::IntListAttribute::kLabelledbyIds:
- return IA2_RELATION_LABEL_FOR;
- default:
- break;
- }
- return base::string16();
-}
-
-// static
-int AXPlatformRelationWin::EnumerateRelationships(
- AXPlatformNodeBase* node,
- int desired_index,
- const base::string16& desired_ia2_relation,
- base::string16* out_ia2_relation,
- std::set<AXPlatformNode*>* out_targets) {
- const AXNodeData& node_data = node->GetData();
- AXPlatformNodeDelegate* delegate = node->GetDelegate();
-
- // The first time this is called, populate vectors with all of the
- // int attributes and intlist attributes that have reverse relations
- // we care about on Windows. Computing these by calling
- // GetIA2ReverseRelationFrom{Int|IntList}Attr on every possible attribute
- // simplifies the work needed to support an additional relation
- // attribute in the future.
- static std::vector<ax::mojom::IntAttribute>
- int_attributes_with_reverse_relations;
- static std::vector<ax::mojom::IntListAttribute>
- intlist_attributes_with_reverse_relations;
- static bool first_time = true;
- if (first_time) {
- for (int32_t attr_index =
- static_cast<int32_t>(ax::mojom::IntAttribute::kNone);
- attr_index <= static_cast<int32_t>(ax::mojom::IntAttribute::kMaxValue);
- ++attr_index) {
- auto attr = static_cast<ax::mojom::IntAttribute>(attr_index);
- if (!GetIA2ReverseRelationFromIntAttr(attr).empty())
- int_attributes_with_reverse_relations.push_back(attr);
- }
- for (int32_t attr_index =
- static_cast<int32_t>(ax::mojom::IntListAttribute::kNone);
- attr_index <=
- static_cast<int32_t>(ax::mojom::IntListAttribute::kMaxValue);
- ++attr_index) {
- auto attr = static_cast<ax::mojom::IntListAttribute>(attr_index);
- if (!GetIA2ReverseRelationFromIntListAttr(attr).empty())
- intlist_attributes_with_reverse_relations.push_back(attr);
- }
- first_time = false;
- }
-
- // Enumerate all of the relations and reverse relations that
- // are exposed via IAccessible2 on Windows. We do this with a series
- // of loops. Every time we encounter one, we check if the caller
- // requested that particular relation by index, and return it.
- // Otherwise we build up and return the total number of relations found.
- int total_count = 0;
-
- // Iterate over all int attributes on this node to check the ones
- // that correspond to IAccessible2 relations.
- for (size_t i = 0; i < node_data.int_attributes.size(); ++i) {
- ax::mojom::IntAttribute int_attribute = node_data.int_attributes[i].first;
- base::string16 relation = GetIA2RelationFromIntAttr(int_attribute);
- if (!relation.empty() &&
- (desired_ia2_relation.empty() || desired_ia2_relation == relation)) {
- // Skip reflexive relations
- if (node_data.int_attributes[i].second == node_data.id)
- continue;
- if (desired_index == total_count) {
- *out_ia2_relation = relation;
- out_targets->insert(
- delegate->GetFromNodeID(node_data.int_attributes[i].second));
- return 1;
- }
- total_count++;
- }
- }
-
- // Iterate over all of the int attributes that have reverse relations
- // in IAccessible2, and query AXTree to see if the reverse relation exists.
- for (ax::mojom::IntAttribute int_attribute :
- int_attributes_with_reverse_relations) {
- base::string16 relation = GetIA2ReverseRelationFromIntAttr(int_attribute);
- std::set<AXPlatformNode*> targets =
- delegate->GetReverseRelations(int_attribute);
- // Erase reflexive relations.
- targets.erase(node);
- if (targets.size()) {
- if (!relation.empty() &&
- (desired_ia2_relation.empty() || desired_ia2_relation == relation)) {
- if (desired_index == total_count) {
- *out_ia2_relation = relation;
- *out_targets = targets;
- return 1;
- }
- total_count++;
- }
- }
- }
-
- // Iterate over all intlist attributes on this node to check the ones
- // that correspond to IAccessible2 relations.
- for (size_t i = 0; i < node_data.intlist_attributes.size(); ++i) {
- ax::mojom::IntListAttribute intlist_attribute =
- node_data.intlist_attributes[i].first;
- base::string16 relation = GetIA2RelationFromIntListAttr(intlist_attribute);
- if (!relation.empty() &&
- (desired_ia2_relation.empty() || desired_ia2_relation == relation)) {
- if (desired_index == total_count) {
- *out_ia2_relation = relation;
- for (int32_t target_id : node_data.intlist_attributes[i].second) {
- // Skip reflexive relations
- if (target_id == node_data.id)
- continue;
- out_targets->insert(delegate->GetFromNodeID(target_id));
- }
- if (out_targets->size() == 0)
- continue;
- return 1;
- }
- total_count++;
- }
- }
-
- // Iterate over all of the intlist attributes that have reverse relations
- // in IAccessible2, and query AXTree to see if the reverse relation exists.
- for (ax::mojom::IntListAttribute intlist_attribute :
- intlist_attributes_with_reverse_relations) {
- base::string16 relation =
- GetIA2ReverseRelationFromIntListAttr(intlist_attribute);
- std::set<AXPlatformNode*> targets =
- delegate->GetReverseRelations(intlist_attribute);
- // Erase reflexive relations.
- targets.erase(node);
- if (targets.size()) {
- if (!relation.empty() &&
- (desired_ia2_relation.empty() || desired_ia2_relation == relation)) {
- if (desired_index == total_count) {
- *out_ia2_relation = relation;
- *out_targets = targets;
- return 1;
- }
- total_count++;
- }
- }
- }
-
- return total_count;
-}
-
-void AXPlatformRelationWin::Initialize(const base::string16& type) {
- type_ = type;
-}
-
-void AXPlatformRelationWin::Invalidate() {
- targets_.clear();
-}
-
-void AXPlatformRelationWin::AddTarget(AXPlatformNodeWin* target) {
- targets_.push_back(target);
-}
-
-IFACEMETHODIMP AXPlatformRelationWin::get_relationType(BSTR* relation_type) {
- if (!relation_type)
- return E_INVALIDARG;
-
- *relation_type = SysAllocString(type_.c_str());
- DCHECK(*relation_type);
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformRelationWin::get_nTargets(LONG* n_targets) {
- if (!n_targets)
- return E_INVALIDARG;
-
- *n_targets = static_cast<LONG>(targets_.size());
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformRelationWin::get_target(LONG target_index,
- IUnknown** target) {
- if (!target)
- return E_INVALIDARG;
-
- if (target_index < 0 || target_index >= static_cast<LONG>(targets_.size())) {
- return E_INVALIDARG;
- }
-
- *target = static_cast<IAccessible*>(targets_[target_index].Get());
- (*target)->AddRef();
- return S_OK;
-}
-
-IFACEMETHODIMP AXPlatformRelationWin::get_targets(LONG max_targets,
- IUnknown** targets,
- LONG* n_targets) {
- if (!targets || !n_targets)
- return E_INVALIDARG;
-
- LONG count = static_cast<LONG>(targets_.size());
- if (count > max_targets)
- count = max_targets;
-
- *n_targets = count;
- if (count == 0)
- return S_FALSE;
-
- for (LONG i = 0; i < count; ++i) {
- HRESULT result = get_target(i, &targets[i]);
- if (result != S_OK)
- return result;
- }
-
- return S_OK;
-}
-
-IFACEMETHODIMP
-AXPlatformRelationWin::get_localizedRelationType(BSTR* relation_type) {
- return E_NOTIMPL;
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_platform_relation_win.h b/third_party/accessibility/ax/platform/ax_platform_relation_win.h
deleted file mode 100644
index dd8426f..0000000
--- a/third_party/accessibility/ax/platform/ax_platform_relation_win.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_RELATION_WIN_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_RELATION_WIN_H_
-
-#include <oleacc.h>
-#include <wrl/client.h>
-#include <set>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/observer_list.h"
-#include "base/win/atl.h"
-#include "third_party/iaccessible2/ia2_api_all.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_text_utils.h"
-#include "ui/accessibility/platform/ax_platform_node_win.h"
-
-namespace ui {
-
-//
-// AXPlatformRelationWin
-//
-// A simple implementation of IAccessibleRelation, used to represent a
-// relationship between one accessible node in the tree and
-// potentially multiple target nodes. Also contains a utility function
-// to compute all of the possible IAccessible2 relations and reverse
-// relations given the internal relation id attributes.
-class AXPlatformRelationWin : public CComObjectRootEx<CComMultiThreadModel>,
- public IAccessibleRelation {
- public:
- BEGIN_COM_MAP(AXPlatformRelationWin)
- COM_INTERFACE_ENTRY(IAccessibleRelation)
- END_COM_MAP()
-
- AXPlatformRelationWin();
- virtual ~AXPlatformRelationWin();
-
- // This is the main utility function that enumerates all of the possible
- // IAccessible2 relations between one node and any other node in the tree.
- // Forward relations come from the int_attributes and intlist_attributes
- // in node_data. Reverse relations come from querying |delegate| for the
- // reverse relations given |node_data.id|.
- //
- // If you pass -1 for |desired_index| and "" for |desired_ia2_relation|,
- // it will return a count of all relations.
- //
- // If you pass either an index in |desired_index| or a specific relation
- // in |desired_ia2_relation|, the first matching relation will be returned in
- // |out_ia2_relation| and |out_targets| (both of which must not be null),
- // and it will return 1 on success, and 0 if none were found matching that
- // criteria.
- static int EnumerateRelationships(AXPlatformNodeBase* node,
- int desired_index,
- const base::string16& desired_ia2_relation,
- base::string16* out_ia2_relation,
- std::set<AXPlatformNode*>* out_targets);
-
- void Initialize(const base::string16& type);
- void Invalidate();
- void AddTarget(AXPlatformNodeWin* target);
-
- // IAccessibleRelation methods.
- IFACEMETHODIMP get_relationType(BSTR* relation_type) override;
- IFACEMETHODIMP get_nTargets(LONG* n_targets) override;
- IFACEMETHODIMP get_target(LONG target_index, IUnknown** target) override;
- IFACEMETHODIMP get_targets(LONG max_targets,
- IUnknown** targets,
- LONG* n_targets) override;
- IFACEMETHODIMP get_localizedRelationType(BSTR* relation_type) override;
-
- private:
- base::string16 type_;
- std::vector<Microsoft::WRL::ComPtr<AXPlatformNodeWin>> targets_;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_RELATION_WIN_H_
diff --git a/third_party/accessibility/ax/platform/ax_platform_text_boundary.cc b/third_party/accessibility/ax/platform/ax_platform_text_boundary.cc
index 216f510..bd5dc76 100644
--- a/third_party/accessibility/ax/platform/ax_platform_text_boundary.cc
+++ b/third_party/accessibility/ax/platform/ax_platform_text_boundary.cc
@@ -2,52 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/platform/ax_platform_text_boundary.h"
+#include "ax_platform_text_boundary.h"
-#include "ui/accessibility/ax_enums.mojom.h"
+#include "ax/ax_enums.h"
namespace ui {
-#if BUILDFLAG(USE_ATK)
-ax::mojom::TextBoundary FromAtkTextBoundary(AtkTextBoundary boundary) {
- // These are listed in order of their definition in the ATK header.
- switch (boundary) {
- case ATK_TEXT_BOUNDARY_CHAR:
- return ax::mojom::TextBoundary::kCharacter;
- case ATK_TEXT_BOUNDARY_WORD_START:
- return ax::mojom::TextBoundary::kWordStart;
- case ATK_TEXT_BOUNDARY_WORD_END:
- return ax::mojom::TextBoundary::kWordEnd;
- case ATK_TEXT_BOUNDARY_SENTENCE_START:
- return ax::mojom::TextBoundary::kSentenceStart;
- case ATK_TEXT_BOUNDARY_SENTENCE_END:
- return ax::mojom::TextBoundary::kSentenceEnd;
- case ATK_TEXT_BOUNDARY_LINE_START:
- return ax::mojom::TextBoundary::kLineStart;
- case ATK_TEXT_BOUNDARY_LINE_END:
- return ax::mojom::TextBoundary::kLineEnd;
- }
-}
-
-#if ATK_CHECK_VERSION(2, 10, 0)
-ax::mojom::TextBoundary FromAtkTextGranularity(AtkTextGranularity granularity) {
- // These are listed in order of their definition in the ATK header.
- switch (granularity) {
- case ATK_TEXT_GRANULARITY_CHAR:
- return ax::mojom::TextBoundary::kCharacter;
- case ATK_TEXT_GRANULARITY_WORD:
- return ax::mojom::TextBoundary::kWordStart;
- case ATK_TEXT_GRANULARITY_SENTENCE:
- return ax::mojom::TextBoundary::kSentenceStart;
- case ATK_TEXT_GRANULARITY_LINE:
- return ax::mojom::TextBoundary::kLineStart;
- case ATK_TEXT_GRANULARITY_PARAGRAPH:
- return ax::mojom::TextBoundary::kParagraphStart;
- }
-}
-#endif // ATK_CHECK_VERSION(2, 10, 0)
-#endif // BUILDFLAG(USE_ATK)
-
#ifdef OS_WIN
ax::mojom::TextBoundary FromIA2TextBoundary(IA2TextBoundaryType boundary) {
switch (boundary) {
diff --git a/third_party/accessibility/ax/platform/ax_platform_text_boundary.h b/third_party/accessibility/ax/platform/ax_platform_text_boundary.h
index b2fdf46..ac30dc9 100644
--- a/third_party/accessibility/ax/platform/ax_platform_text_boundary.h
+++ b/third_party/accessibility/ax/platform/ax_platform_text_boundary.h
@@ -5,14 +5,9 @@
#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_TEXT_BOUNDARY_H_
#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_TEXT_BOUNDARY_H_
-#include "build/build_config.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/base/buildflags.h"
-
-#if BUILDFLAG(USE_ATK)
-#include <atk/atk.h>
-#endif // BUILDFLAG(USE_ATK)
+#include "ax/ax_enums.h"
+#include "ax/ax_export.h"
+#include "ax_build/build_config.h"
#ifdef OS_WIN
#include <oleacc.h>
@@ -23,17 +18,6 @@
namespace ui {
-#if BUILDFLAG(USE_ATK)
-// Converts from an ATK text boundary to an ax::mojom::TextBoundary.
-AX_EXPORT ax::mojom::TextBoundary FromAtkTextBoundary(AtkTextBoundary boundary);
-
-#if ATK_CHECK_VERSION(2, 10, 0)
-// Same as above, but for an older version of the API.
-AX_EXPORT ax::mojom::TextBoundary FromAtkTextGranularity(
- AtkTextGranularity granularity);
-#endif // ATK_CHECK_VERSION(2, 10, 0)
-#endif // BUILDFLAG(USE_ATK)
-
#ifdef OS_WIN
// Converts from an IAccessible2 text boundary to an ax::mojom::TextBoundary.
AX_EXPORT ax::mojom::TextBoundary FromIA2TextBoundary(
diff --git a/third_party/accessibility/ax/platform/ax_system_caret_win.cc b/third_party/accessibility/ax/platform/ax_system_caret_win.cc
deleted file mode 100644
index 4b7356a..0000000
--- a/third_party/accessibility/ax/platform/ax_system_caret_win.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/ax_system_caret_win.h"
-
-#include <windows.h>
-
-#include "base/check.h"
-#include "base/notreached.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/platform/ax_platform_node_win.h"
-#include "ui/display/win/screen_win.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/geometry/rect_f.h"
-
-namespace ui {
-
-AXSystemCaretWin::AXSystemCaretWin(gfx::AcceleratedWidget event_target)
- : event_target_(event_target) {
- caret_ = static_cast<AXPlatformNodeWin*>(AXPlatformNodeWin::Create(this));
- // The caret object is not part of the accessibility tree and so doesn't need
- // a node ID. A globally unique ID is used when firing Win events, retrieved
- // via |unique_id|.
- data_.id = -1;
- data_.role = ax::mojom::Role::kCaret;
- // |get_accState| should return 0 which means that the caret is visible.
- data_.state = 0;
- data_.AddState(ax::mojom::State::kInvisible);
- // According to MSDN, "Edit" should be the name of the caret object.
- data_.SetName(L"Edit");
- data_.relative_bounds.offset_container_id = -1;
-
- if (event_target_) {
- ::NotifyWinEvent(EVENT_OBJECT_CREATE, event_target_, OBJID_CARET,
- -caret_->GetUniqueId());
- }
-}
-
-AXSystemCaretWin::~AXSystemCaretWin() {
- if (event_target_) {
- ::NotifyWinEvent(EVENT_OBJECT_DESTROY, event_target_, OBJID_CARET,
- -caret_->GetUniqueId());
- }
- caret_->Destroy();
-}
-
-Microsoft::WRL::ComPtr<IAccessible> AXSystemCaretWin::GetCaret() const {
- Microsoft::WRL::ComPtr<IAccessible> caret_accessible;
- HRESULT hr = caret_->QueryInterface(IID_PPV_ARGS(&caret_accessible));
- DCHECK(SUCCEEDED(hr));
- return caret_accessible;
-}
-
-void AXSystemCaretWin::MoveCaretTo(const gfx::Rect& bounds_physical_pixels) {
- if (bounds_physical_pixels.IsEmpty())
- return;
-
- // If the caret has non-empty bounds, assume it has been made visible.
- bool newly_visible = false;
- if (data_.HasState(ax::mojom::State::kInvisible)) {
- newly_visible = true;
- data_.RemoveState(ax::mojom::State::kInvisible);
- }
-
- if (!event_target_)
- return;
-
- if (newly_visible) {
- ::NotifyWinEvent(EVENT_OBJECT_SHOW, event_target_, OBJID_CARET,
- -caret_->GetUniqueId());
- }
-
- gfx::RectF new_location(bounds_physical_pixels);
- // Avoid redundant caret move events (if the location stays the same), but
- // always fire when it's made visible again.
- if (data_.relative_bounds.bounds != new_location || newly_visible) {
- data_.relative_bounds.bounds = new_location;
- ::NotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, event_target_, OBJID_CARET,
- -caret_->GetUniqueId());
- }
-}
-
-void AXSystemCaretWin::Hide() {
- if (!data_.HasState(ax::mojom::State::kInvisible)) {
- data_.AddState(ax::mojom::State::kInvisible);
- data_.relative_bounds.bounds.set_width(0);
- if (event_target_) {
- ::NotifyWinEvent(EVENT_OBJECT_HIDE, event_target_, OBJID_CARET,
- -caret_->GetUniqueId());
- }
- }
-}
-
-const AXNodeData& AXSystemCaretWin::GetData() const {
- return data_;
-}
-
-gfx::NativeViewAccessible AXSystemCaretWin::GetParent() {
- if (!event_target_)
- return nullptr;
-
- gfx::NativeViewAccessible parent;
- HRESULT hr =
- ::AccessibleObjectFromWindow(event_target_, OBJID_WINDOW, IID_IAccessible,
- reinterpret_cast<void**>(&parent));
- if (SUCCEEDED(hr))
- return parent;
- return nullptr;
-}
-
-gfx::Rect AXSystemCaretWin::GetBoundsRect(
- const AXCoordinateSystem coordinate_system,
- const AXClippingBehavior clipping_behavior,
- AXOffscreenResult* offscreen_result) const {
- switch (coordinate_system) {
- case AXCoordinateSystem::kScreenPhysicalPixels:
- // We could optionally add clipping here if ever needed.
- return ToEnclosingRect(data_.relative_bounds.bounds);
- case AXCoordinateSystem::kScreenDIPs:
- return display::win::ScreenWin::ScreenToDIPRect(
- event_target_, ToEnclosingRect(data_.relative_bounds.bounds));
- case AXCoordinateSystem::kRootFrame:
- case AXCoordinateSystem::kFrame:
- NOTIMPLEMENTED();
- return gfx::Rect();
- }
-}
-
-gfx::AcceleratedWidget
-AXSystemCaretWin::GetTargetForNativeAccessibilityEvent() {
- return event_target_;
-}
-
-bool AXSystemCaretWin::ShouldIgnoreHoveredStateForTesting() {
- return false;
-}
-
-const ui::AXUniqueId& AXSystemCaretWin::GetUniqueId() const {
- return unique_id_;
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_system_caret_win.h b/third_party/accessibility/ax/platform/ax_system_caret_win.h
deleted file mode 100644
index a0d1b51..0000000
--- a/third_party/accessibility/ax/platform/ax_system_caret_win.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_AX_SYSTEM_CARET_WIN_H_
-#define UI_ACCESSIBILITY_PLATFORM_AX_SYSTEM_CARET_WIN_H_
-
-#include <oleacc.h>
-#include <wrl/client.h>
-
-#include "base/macros.h"
-#include "ui/accessibility/ax_export.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/ax_tree_data.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate_base.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace ui {
-
-class AXPlatformNodeWin;
-
-// A class representing the position of the caret to assistive software on
-// Windows. This is required because Chrome doesn't use the standard system
-// caret and because some assistive software still relies on specific
-// accessibility APIs to retrieve the caret position.
-class AX_EXPORT AXSystemCaretWin : private AXPlatformNodeDelegateBase {
- public:
- explicit AXSystemCaretWin(gfx::AcceleratedWidget event_target);
- ~AXSystemCaretWin() override;
-
- Microsoft::WRL::ComPtr<IAccessible> GetCaret() const;
- void MoveCaretTo(const gfx::Rect& bounds_physical_pixels);
- void Hide();
-
- private:
- // |AXPlatformNodeDelegate| members.
- const AXNodeData& GetData() const override;
- gfx::NativeViewAccessible GetParent() override;
- gfx::Rect GetBoundsRect(const AXCoordinateSystem coordinate_system,
- const AXClippingBehavior clipping_behavior,
- AXOffscreenResult* offscreen_result) const override;
- gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
- bool ShouldIgnoreHoveredStateForTesting() override;
- const ui::AXUniqueId& GetUniqueId() const override;
-
- AXPlatformNodeWin* caret_;
- gfx::AcceleratedWidget event_target_;
- AXNodeData data_;
- ui::AXUniqueId unique_id_;
-
- friend class AXPlatformNodeWin;
-
- DISALLOW_COPY_AND_ASSIGN(AXSystemCaretWin);
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_AX_SYSTEM_CARET_WIN_H_
diff --git a/third_party/accessibility/ax/platform/ax_unique_id.cc b/third_party/accessibility/ax/platform/ax_unique_id.cc
index 163fcdc..75e3184 100644
--- a/third_party/accessibility/ax/platform/ax_unique_id.cc
+++ b/third_party/accessibility/ax/platform/ax_unique_id.cc
@@ -2,21 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/platform/ax_unique_id.h"
+#include "ax_unique_id.h"
#include <memory>
#include <unordered_set>
-#include "base/lazy_instance.h"
+#include "base/container_utils.h"
#include "base/logging.h"
-#include "base/stl_util.h"
namespace ui {
namespace {
-base::LazyInstance<std::unordered_set<int32_t>>::Leaky g_assigned_ids =
- LAZY_INSTANCE_INITIALIZER;
+std::unordered_set<int32_t> g_assigned_ids;
} // namespace
@@ -25,7 +23,7 @@
AXUniqueId::AXUniqueId(const int32_t max_id) : id_(GetNextAXUniqueId(max_id)) {}
AXUniqueId::~AXUniqueId() {
- g_assigned_ids.Get().erase(id_);
+ g_assigned_ids.erase(id_);
}
bool AXUniqueId::operator==(const AXUniqueId& other) const {
@@ -37,7 +35,7 @@
}
bool AXUniqueId::IsAssigned(const int32_t id) const {
- return base::Contains(g_assigned_ids.Get(), id);
+ return base::Contains(g_assigned_ids, id);
}
int32_t AXUniqueId::GetNextAXUniqueId(const int32_t max_id) {
@@ -53,7 +51,7 @@
++current_id;
}
if (current_id == prev_id) {
- LOG(FATAL) << "There are over 2 billion available IDs, so the newly "
+ BASE_LOG() << "There are over 2 billion available IDs, so the newly "
"created ID cannot be equal to the most recently created "
"ID.";
}
@@ -61,7 +59,7 @@
// unassigned ID.
} while (has_wrapped && IsAssigned(current_id));
- g_assigned_ids.Get().insert(current_id);
+ g_assigned_ids.insert(current_id);
return current_id;
}
diff --git a/third_party/accessibility/ax/platform/ax_unique_id.h b/third_party/accessibility/ax/platform/ax_unique_id.h
index 0f3853f..ea89d44 100644
--- a/third_party/accessibility/ax/platform/ax_unique_id.h
+++ b/third_party/accessibility/ax/platform/ax_unique_id.h
@@ -8,7 +8,8 @@
#include <stdint.h>
#include "base/macros.h"
-#include "ui/accessibility/ax_export.h"
+
+#include "ax/ax_export.h"
namespace ui {
@@ -44,7 +45,7 @@
int32_t id_;
- DISALLOW_COPY_AND_ASSIGN(AXUniqueId);
+ BASE_DISALLOW_COPY_AND_ASSIGN(AXUniqueId);
};
} // namespace ui
diff --git a/third_party/accessibility/ax/platform/ax_unique_id_unittest.cc b/third_party/accessibility/ax/platform/ax_unique_id_unittest.cc
index d6fdb58..0274aca 100644
--- a/third_party/accessibility/ax/platform/ax_unique_id_unittest.cc
+++ b/third_party/accessibility/ax/platform/ax_unique_id_unittest.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/platform/ax_unique_id.h"
+#include "ax_unique_id.h"
#include <memory>
-#include "testing/gtest/include/gtest/gtest.h"
+#include "gtest/gtest.h"
namespace ui {
@@ -25,7 +25,7 @@
private:
friend class AXUniqueId;
- DISALLOW_COPY_AND_ASSIGN(AXTestSmallBankUniqueId);
+ BASE_DISALLOW_COPY_AND_ASSIGN(AXTestSmallBankUniqueId);
};
AXTestSmallBankUniqueId::AXTestSmallBankUniqueId() : AXUniqueId(kMaxId) {}
@@ -43,7 +43,8 @@
}
static int kIdToReplace = 10;
- int32_t expected_id = ids[kIdToReplace]->Get();
+ std::unique_ptr<AXTestSmallBankUniqueId>& unique = ids[kIdToReplace];
+ int32_t expected_id = unique->Get();
// Delete one of the ids and replace with a new one.
ids[kIdToReplace] = nullptr;
diff --git a/third_party/accessibility/ax/platform/compute_attributes.cc b/third_party/accessibility/ax/platform/compute_attributes.cc
index b5adf3d..86d5bff 100644
--- a/third_party/accessibility/ax/platform/compute_attributes.cc
+++ b/third_party/accessibility/ax/platform/compute_attributes.cc
@@ -2,19 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/platform/compute_attributes.h"
+#include "compute_attributes.h"
#include <cstddef>
-#include "base/optional.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node_data.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate.h"
+#include "ax/ax_enums.h"
+#include "ax/ax_node_data.h"
+#include "ax_platform_node_delegate.h"
namespace ui {
namespace {
-base::Optional<int32_t> GetCellAttribute(
+std::optional<int32_t> GetCellAttribute(
const ui::AXPlatformNodeDelegate* delegate,
ax::mojom::IntAttribute attribute) {
switch (attribute) {
@@ -31,20 +30,20 @@
case ax::mojom::IntAttribute::kTableCellRowSpan:
return delegate->GetTableCellRowSpan();
default:
- return base::nullopt;
+ return std::nullopt;
}
}
-base::Optional<int32_t> GetRowAttribute(
+std::optional<int32_t> GetRowAttribute(
const ui::AXPlatformNodeDelegate* delegate,
ax::mojom::IntAttribute attribute) {
if (attribute == ax::mojom::IntAttribute::kTableRowIndex) {
return delegate->GetTableRowRowIndex();
}
- return base::nullopt;
+ return std::nullopt;
}
-base::Optional<int32_t> GetTableAttribute(
+std::optional<int32_t> GetTableAttribute(
const ui::AXPlatformNodeDelegate* delegate,
ax::mojom::IntAttribute attribute) {
switch (attribute) {
@@ -57,11 +56,11 @@
case ax::mojom::IntAttribute::kAriaRowCount:
return delegate->GetTableAriaRowCount();
default:
- return base::nullopt;
+ return std::nullopt;
}
}
-base::Optional<int> GetOrderedSetItemAttribute(
+std::optional<int> GetOrderedSetItemAttribute(
const ui::AXPlatformNodeDelegate* delegate,
ax::mojom::IntAttribute attribute) {
switch (attribute) {
@@ -70,36 +69,36 @@
case ax::mojom::IntAttribute::kSetSize:
return delegate->GetSetSize();
default:
- return base::nullopt;
+ return std::nullopt;
}
}
-base::Optional<int> GetOrderedSetAttribute(
+std::optional<int> GetOrderedSetAttribute(
const ui::AXPlatformNodeDelegate* delegate,
ax::mojom::IntAttribute attribute) {
switch (attribute) {
case ax::mojom::IntAttribute::kSetSize:
return delegate->GetSetSize();
default:
- return base::nullopt;
+ return std::nullopt;
}
}
-base::Optional<int32_t> GetFromData(const ui::AXPlatformNodeDelegate* delegate,
- ax::mojom::IntAttribute attribute) {
+std::optional<int32_t> GetFromData(const ui::AXPlatformNodeDelegate* delegate,
+ ax::mojom::IntAttribute attribute) {
int32_t value;
if (delegate->GetData().GetIntAttribute(attribute, &value)) {
return value;
}
- return base::nullopt;
+ return std::nullopt;
}
} // namespace
-base::Optional<int32_t> ComputeAttribute(
+std::optional<int32_t> ComputeAttribute(
const ui::AXPlatformNodeDelegate* delegate,
ax::mojom::IntAttribute attribute) {
- base::Optional<int32_t> maybe_value = base::nullopt;
+ std::optional<int32_t> maybe_value = std::nullopt;
// Table-related nodes.
if (delegate->IsTableCellOrHeader())
maybe_value = GetCellAttribute(delegate, attribute);
diff --git a/third_party/accessibility/ax/platform/compute_attributes.h b/third_party/accessibility/ax/platform/compute_attributes.h
index f0e82a0..30f5f4d 100644
--- a/third_party/accessibility/ax/platform/compute_attributes.h
+++ b/third_party/accessibility/ax/platform/compute_attributes.h
@@ -6,10 +6,10 @@
#define UI_ACCESSIBILITY_PLATFORM_COMPUTE_ATTRIBUTES_H_
#include <cstddef>
+#include <optional>
-#include "base/optional.h"
-#include "ui/accessibility/ax_enums.mojom-forward.h"
-#include "ui/accessibility/ax_export.h"
+#include "ax/ax_enums.h"
+#include "ax/ax_export.h"
namespace ui {
@@ -17,7 +17,7 @@
// Compute the attribute value instead of returning the "raw" attribute value
// for those attributes that have computation methods.
-AX_EXPORT base::Optional<int32_t> ComputeAttribute(
+AX_EXPORT std::optional<int32_t> ComputeAttribute(
const ui::AXPlatformNodeDelegate* delegate,
ax::mojom::IntAttribute attribute);
diff --git a/third_party/accessibility/ax/platform/ichromeaccessible.idl b/third_party/accessibility/ax/platform/ichromeaccessible.idl
deleted file mode 100644
index f3567d1..0000000
--- a/third_party/accessibility/ax/platform/ichromeaccessible.idl
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import "objidl.idl";
-import "oaidl.idl";
-
-const long DISPID_CHROME_BULK_FETCH = -1600;
-const long DISPID_CHROME_ON_BULK_FETCH_RESULT = -1601;
-const long DISPID_CHROME_HIT_TEST = -1602;
-const long DISPID_CHROME_ON_HIT_TEST_RESULT = -1603;
-
-// Interface to be implemented by the client that calls IChromeAccessible.
-// For every method in IChromeAccessible, there's a corresponding response
-// method in IChromeAccessibleDelegate.
-[object, uuid(0e3edc14-79f4-413f-b854-d3b6860d74a2), pointer_default(unique)]
-interface IChromeAccessibleDelegate : IUnknown
-{
- [propput, id(DISPID_CHROME_ON_BULK_FETCH_RESULT)] HRESULT bulkFetchResult(
- [in] LONG requestID,
- [in] BSTR resultJson
- );
-
- [propput, id(DISPID_CHROME_ON_HIT_TEST_RESULT)] HRESULT hitTestResult(
- [in] LONG requestID,
- [in] IUnknown* result
- );
-};
-
-// Chrome-specific interface exposed on every IAccessible object.
-//
-// This interface is EXPERIMENTAL and only available behind a flag.
-// Run Chrome with --enable-features=IChromeAccessible to use it.
-//
-// Do not depend on this interface remaining stable! It's only designed
-// for prototyping ideas, and anything that's stabilized should move to
-// an open standard API.
-[object, uuid(6175bd95-3b2e-4ebc-bc51-9cab782bec92), pointer_default(unique)]
-interface IChromeAccessible : IUnknown
-{
- // TODO(crbug.com/1083834): Fully document this interface.
- // Fetch multiple accessibility properties of one or more accessibility
- // nodes as JSON. This method is asynchronous; the result is returned
- // by calling put_bulkFetchResult on |delegate|. The client can pass any
- // valid LONG as requestID and the same value will be passed to
- // put_bulkFetchResult to enable matching of requests and responses.
- [propget, id(DISPID_CHROME_BULK_FETCH)] HRESULT bulkFetch(
- [in] BSTR inputJson,
- [in] LONG requestID,
- [in] IChromeAccessibleDelegate* delegate
- );
-
- // Hit-test the given pixel in screen physical pixel coordinates.
- // This method is asynchronous; the result is returned
- // by calling put_hitTestResult on |delegate|. The client can pass any
- // valid LONG as requestID and the same value will be passed to
- // put_hitTestResult to enable matching of requests and responses.
- [propget, id(DISPID_CHROME_HIT_TEST)] HRESULT hitTest(
- [in] LONG screenPhysicalPixelX,
- [in] LONG screenPhysicalPixelY,
- [in] LONG requestID,
- [in] IChromeAccessibleDelegate* delegate
- );
-};
diff --git a/third_party/accessibility/ax/platform/test_ax_node_wrapper.cc b/third_party/accessibility/ax/platform/test_ax_node_wrapper.cc
index ee40863..04513c6 100644
--- a/third_party/accessibility/ax/platform/test_ax_node_wrapper.cc
+++ b/third_party/accessibility/ax/platform/test_ax_node_wrapper.cc
@@ -2,19 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/platform/test_ax_node_wrapper.h"
+#include "test_ax_node_wrapper.h"
#include <map>
#include <utility>
+#include "ax/ax_action_data.h"
+#include "ax/ax_role_properties.h"
+#include "ax/ax_table_info.h"
+#include "ax/ax_tree_observer.h"
#include "base/numerics/ranges.h"
-#include "base/stl_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_table_info.h"
-#include "ui/accessibility/ax_tree_observer.h"
-#include "ui/gfx/geometry/rect_conversions.h"
+#include "base/string_utils.h"
+#include "gfx/geometry/rect_conversions.h"
namespace ui {
@@ -190,7 +189,7 @@
}
case AXCoordinateSystem::kRootFrame:
case AXCoordinateSystem::kFrame:
- NOTIMPLEMENTED();
+ BASE_UNREACHABLE();
return gfx::Rect();
}
}
@@ -235,7 +234,7 @@
}
case AXCoordinateSystem::kRootFrame:
case AXCoordinateSystem::kFrame:
- NOTIMPLEMENTED();
+ BASE_UNREACHABLE();
return gfx::Rect();
}
}
@@ -259,7 +258,7 @@
}
case AXCoordinateSystem::kRootFrame:
case AXCoordinateSystem::kFrame:
- NOTIMPLEMENTED();
+ BASE_UNREACHABLE();
return gfx::Rect();
}
}
@@ -348,12 +347,12 @@
int32_t id) {
// TestAXNodeWrapper only supports one accessibility tree.
// Additional work would need to be done to support multiple trees.
- CHECK_EQ(GetTreeData().tree_id, ax_tree_id);
+ BASE_CHECK(GetTreeData().tree_id == ax_tree_id);
return GetFromNodeID(id);
}
int TestAXNodeWrapper::GetIndexInParent() {
- return node_ ? int{node_->GetUnignoredIndexInParent()} : -1;
+ return node_ ? static_cast<int>(node_->GetUnignoredIndexInParent()) : -1;
}
void TestAXNodeWrapper::ReplaceIntAttribute(int32_t node_id,
@@ -370,8 +369,9 @@
std::vector<std::pair<ax::mojom::IntAttribute, int32_t>>& attributes =
new_data.int_attributes;
- base::EraseIf(attributes,
- [attribute](auto& pair) { return pair.first == attribute; });
+ attributes.erase(std::remove_if(
+ attributes.begin(), attributes.end(),
+ [attribute](auto& pair) { return pair.first == attribute; }));
new_data.AddIntAttribute(attribute, value);
node->SetData(new_data);
@@ -384,8 +384,9 @@
std::vector<std::pair<ax::mojom::FloatAttribute, float>>& attributes =
new_data.float_attributes;
- base::EraseIf(attributes,
- [attribute](auto& pair) { return pair.first == attribute; });
+ attributes.erase(std::remove_if(
+ attributes.begin(), attributes.end(),
+ [attribute](auto& pair) { return pair.first == attribute; }));
new_data.AddFloatAttribute(attribute, value);
node_->SetData(new_data);
@@ -397,8 +398,9 @@
std::vector<std::pair<ax::mojom::BoolAttribute, bool>>& attributes =
new_data.bool_attributes;
- base::EraseIf(attributes,
- [attribute](auto& pair) { return pair.first == attribute; });
+ attributes.erase(std::remove_if(
+ attributes.begin(), attributes.end(),
+ [attribute](auto& pair) { return pair.first == attribute; }));
new_data.AddBoolAttribute(attribute, value);
node_->SetData(new_data);
@@ -411,8 +413,9 @@
std::vector<std::pair<ax::mojom::StringAttribute, std::string>>& attributes =
new_data.string_attributes;
- base::EraseIf(attributes,
- [attribute](auto& pair) { return pair.first == attribute; });
+ attributes.erase(std::remove_if(
+ attributes.begin(), attributes.end(),
+ [attribute](auto& pair) { return pair.first == attribute; }));
new_data.AddStringAttribute(attribute, value);
node_->SetData(new_data);
@@ -438,27 +441,27 @@
return node_->IsTable();
}
-base::Optional<int> TestAXNodeWrapper::GetTableRowCount() const {
+std::optional<int> TestAXNodeWrapper::GetTableRowCount() const {
return node_->GetTableRowCount();
}
-base::Optional<int> TestAXNodeWrapper::GetTableColCount() const {
+std::optional<int> TestAXNodeWrapper::GetTableColCount() const {
return node_->GetTableColCount();
}
-base::Optional<int> TestAXNodeWrapper::GetTableAriaRowCount() const {
+std::optional<int> TestAXNodeWrapper::GetTableAriaRowCount() const {
return node_->GetTableAriaRowCount();
}
-base::Optional<int> TestAXNodeWrapper::GetTableAriaColCount() const {
+std::optional<int> TestAXNodeWrapper::GetTableAriaColCount() const {
return node_->GetTableAriaColCount();
}
-base::Optional<int> TestAXNodeWrapper::GetTableCellCount() const {
+std::optional<int> TestAXNodeWrapper::GetTableCellCount() const {
return node_->GetTableCellCount();
}
-base::Optional<bool> TestAXNodeWrapper::GetTableHasColumnOrRowHeaderNode()
+std::optional<bool> TestAXNodeWrapper::GetTableHasColumnOrRowHeaderNode()
const {
return node_->GetTableHasColumnOrRowHeaderNode();
}
@@ -485,7 +488,7 @@
return node_->IsTableRow();
}
-base::Optional<int> TestAXNodeWrapper::GetTableRowRowIndex() const {
+std::optional<int> TestAXNodeWrapper::GetTableRowRowIndex() const {
return node_->GetTableRowRowIndex();
}
@@ -493,39 +496,39 @@
return node_->IsTableCellOrHeader();
}
-base::Optional<int> TestAXNodeWrapper::GetTableCellIndex() const {
+std::optional<int> TestAXNodeWrapper::GetTableCellIndex() const {
return node_->GetTableCellIndex();
}
-base::Optional<int> TestAXNodeWrapper::GetTableCellColIndex() const {
+std::optional<int> TestAXNodeWrapper::GetTableCellColIndex() const {
return node_->GetTableCellColIndex();
}
-base::Optional<int> TestAXNodeWrapper::GetTableCellRowIndex() const {
+std::optional<int> TestAXNodeWrapper::GetTableCellRowIndex() const {
return node_->GetTableCellRowIndex();
}
-base::Optional<int> TestAXNodeWrapper::GetTableCellColSpan() const {
+std::optional<int> TestAXNodeWrapper::GetTableCellColSpan() const {
return node_->GetTableCellColSpan();
}
-base::Optional<int> TestAXNodeWrapper::GetTableCellRowSpan() const {
+std::optional<int> TestAXNodeWrapper::GetTableCellRowSpan() const {
return node_->GetTableCellRowSpan();
}
-base::Optional<int> TestAXNodeWrapper::GetTableCellAriaColIndex() const {
+std::optional<int> TestAXNodeWrapper::GetTableCellAriaColIndex() const {
return node_->GetTableCellAriaColIndex();
}
-base::Optional<int> TestAXNodeWrapper::GetTableCellAriaRowIndex() const {
+std::optional<int> TestAXNodeWrapper::GetTableCellAriaRowIndex() const {
return node_->GetTableCellAriaRowIndex();
}
-base::Optional<int32_t> TestAXNodeWrapper::GetCellId(int row_index,
- int col_index) const {
+std::optional<int32_t> TestAXNodeWrapper::GetCellId(int row_index,
+ int col_index) const {
AXNode* cell = node_->GetTableCellFromCoords(row_index, col_index);
if (!cell)
- return base::nullopt;
+ return std::nullopt;
return cell->id();
}
@@ -534,10 +537,10 @@
return native_event_target_;
}
-base::Optional<int32_t> TestAXNodeWrapper::CellIndexToId(int cell_index) const {
+std::optional<int32_t> TestAXNodeWrapper::CellIndexToId(int cell_index) const {
AXNode* cell = node_->GetTableCellFromIndex(cell_index);
if (!cell)
- return base::nullopt;
+ return std::nullopt;
return cell->id();
}
@@ -666,12 +669,12 @@
}
}
-base::string16 TestAXNodeWrapper::GetLocalizedRoleDescriptionForUnlabeledImage()
+std::u16string TestAXNodeWrapper::GetLocalizedRoleDescriptionForUnlabeledImage()
const {
return base::ASCIIToUTF16("Unlabeled image");
}
-base::string16 TestAXNodeWrapper::GetLocalizedStringForLandmarkType() const {
+std::u16string TestAXNodeWrapper::GetLocalizedStringForLandmarkType() const {
const AXNodeData& data = GetData();
switch (data.role) {
case ax::mojom::Role::kBanner:
@@ -689,14 +692,13 @@
case ax::mojom::Role::kSection:
if (data.HasStringAttribute(ax::mojom::StringAttribute::kName))
return base::ASCIIToUTF16("region");
- FALLTHROUGH;
default:
return {};
}
}
-base::string16 TestAXNodeWrapper::GetLocalizedStringForRoleDescription() const {
+std::u16string TestAXNodeWrapper::GetLocalizedStringForRoleDescription() const {
const AXNodeData& data = GetData();
switch (data.role) {
@@ -793,7 +795,7 @@
}
}
-base::string16 TestAXNodeWrapper::GetLocalizedStringForImageAnnotationStatus(
+std::u16string TestAXNodeWrapper::GetLocalizedStringForImageAnnotationStatus(
ax::mojom::ImageAnnotationStatus status) const {
switch (status) {
case ax::mojom::ImageAnnotationStatus::kEligibleForAnnotation:
@@ -812,14 +814,14 @@
case ax::mojom::ImageAnnotationStatus::kIneligibleForAnnotation:
case ax::mojom::ImageAnnotationStatus::kSilentlyEligibleForAnnotation:
case ax::mojom::ImageAnnotationStatus::kAnnotationSucceeded:
- return base::string16();
+ return std::u16string();
}
- NOTREACHED();
- return base::string16();
+ BASE_UNREACHABLE();
+ return std::u16string();
}
-base::string16 TestAXNodeWrapper::GetStyleNameAttributeAsLocalizedString()
+std::u16string TestAXNodeWrapper::GetStyleNameAttributeAsLocalizedString()
const {
AXNode* current_node = node_;
while (current_node) {
@@ -827,7 +829,7 @@
return base::ASCIIToUTF16("mark");
current_node = current_node->parent();
}
- return base::string16();
+ return std::u16string();
}
bool TestAXNodeWrapper::ShouldIgnoreHoveredStateForTesting() {
@@ -857,13 +859,13 @@
std::set<AXPlatformNode*> TestAXNodeWrapper::GetReverseRelations(
ax::mojom::IntAttribute attr) {
- DCHECK(IsNodeIdIntAttribute(attr));
+ BASE_DCHECK(IsNodeIdIntAttribute(attr));
return GetNodesForNodeIds(tree_->GetReverseRelations(attr, GetData().id));
}
std::set<AXPlatformNode*> TestAXNodeWrapper::GetReverseRelations(
ax::mojom::IntListAttribute attr) {
- DCHECK(IsNodeIdIntListAttribute(attr));
+ BASE_DCHECK(IsNodeIdIntListAttribute(attr));
return GetNodesForNodeIds(tree_->GetReverseRelations(attr, GetData().id));
}
@@ -888,11 +890,11 @@
return node_->IsOrderedSet();
}
-base::Optional<int> TestAXNodeWrapper::GetPosInSet() const {
+std::optional<int> TestAXNodeWrapper::GetPosInSet() const {
return node_->GetPosInSet();
}
-base::Optional<int> TestAXNodeWrapper::GetSetSize() const {
+std::optional<int> TestAXNodeWrapper::GetSetSize() const {
return node_->GetSetSize();
}
@@ -901,13 +903,14 @@
}
int TestAXNodeWrapper::InternalChildCount() const {
- return int{node_->GetUnignoredChildCount()};
+ return static_cast<int>(node_->GetUnignoredChildCount());
}
TestAXNodeWrapper* TestAXNodeWrapper::InternalGetChild(int index) const {
- CHECK_GE(index, 0);
- CHECK_LT(index, InternalChildCount());
- return GetOrCreate(tree_, node_->GetUnignoredChildAtIndex(size_t{index}));
+ BASE_CHECK(index >= 0);
+ BASE_CHECK(index < InternalChildCount());
+ return GetOrCreate(
+ tree_, node_->GetUnignoredChildAtIndex(static_cast<size_t>(index)));
}
// Recursive helper function for GetUIADescendants. Aggregates all of the
@@ -957,7 +960,8 @@
gfx::RectF TestAXNodeWrapper::GetInlineTextRect(const int start_offset,
const int end_offset) const {
- DCHECK(start_offset >= 0 && end_offset >= 0 && start_offset <= end_offset);
+ BASE_DCHECK(start_offset >= 0 && end_offset >= 0 &&
+ start_offset <= end_offset);
const std::vector<int32_t>& character_offsets = GetData().GetIntListAttribute(
ax::mojom::IntListAttribute::kCharacterOffsets);
gfx::RectF location = GetLocation();
@@ -978,7 +982,7 @@
break;
}
default:
- NOTIMPLEMENTED();
+ BASE_UNREACHABLE();
}
return bounds;
}
diff --git a/third_party/accessibility/ax/platform/test_ax_node_wrapper.h b/third_party/accessibility/ax/platform/test_ax_node_wrapper.h
index 4cd51d5..fc0581c 100644
--- a/third_party/accessibility/ax/platform/test_ax_node_wrapper.h
+++ b/third_party/accessibility/ax/platform/test_ax_node_wrapper.h
@@ -9,12 +9,12 @@
#include <string>
#include <vector>
+#include "ax/ax_node.h"
+#include "ax/ax_tree.h"
+#include "ax_build/build_config.h"
+#include "ax_platform_node.h"
+#include "ax_platform_node_delegate_base.h"
#include "base/auto_reset.h"
-#include "build/build_config.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_tree.h"
-#include "ui/accessibility/platform/ax_platform_node.h"
-#include "ui/accessibility/platform/ax_platform_node_delegate_base.h"
#if defined(OS_WIN)
namespace gfx {
@@ -101,39 +101,38 @@
int32_t id) override;
int GetIndexInParent() override;
bool IsTable() const override;
- base::Optional<int> GetTableRowCount() const override;
- base::Optional<int> GetTableColCount() const override;
- base::Optional<int> GetTableAriaColCount() const override;
- base::Optional<int> GetTableAriaRowCount() const override;
- base::Optional<int> GetTableCellCount() const override;
- base::Optional<bool> GetTableHasColumnOrRowHeaderNode() const override;
+ std::optional<int> GetTableRowCount() const override;
+ std::optional<int> GetTableColCount() const override;
+ std::optional<int> GetTableAriaColCount() const override;
+ std::optional<int> GetTableAriaRowCount() const override;
+ std::optional<int> GetTableCellCount() const override;
+ std::optional<bool> GetTableHasColumnOrRowHeaderNode() const override;
std::vector<int32_t> GetColHeaderNodeIds() const override;
std::vector<int32_t> GetColHeaderNodeIds(int col_index) const override;
std::vector<int32_t> GetRowHeaderNodeIds() const override;
std::vector<int32_t> GetRowHeaderNodeIds(int row_index) const override;
bool IsTableRow() const override;
- base::Optional<int> GetTableRowRowIndex() const override;
+ std::optional<int> GetTableRowRowIndex() const override;
bool IsTableCellOrHeader() const override;
- base::Optional<int> GetTableCellIndex() const override;
- base::Optional<int> GetTableCellColIndex() const override;
- base::Optional<int> GetTableCellRowIndex() const override;
- base::Optional<int> GetTableCellColSpan() const override;
- base::Optional<int> GetTableCellRowSpan() const override;
- base::Optional<int> GetTableCellAriaColIndex() const override;
- base::Optional<int> GetTableCellAriaRowIndex() const override;
- base::Optional<int32_t> GetCellId(int row_index,
- int col_index) const override;
- base::Optional<int32_t> CellIndexToId(int cell_index) const override;
+ std::optional<int> GetTableCellIndex() const override;
+ std::optional<int> GetTableCellColIndex() const override;
+ std::optional<int> GetTableCellRowIndex() const override;
+ std::optional<int> GetTableCellColSpan() const override;
+ std::optional<int> GetTableCellRowSpan() const override;
+ std::optional<int> GetTableCellAriaColIndex() const override;
+ std::optional<int> GetTableCellAriaRowIndex() const override;
+ std::optional<int32_t> GetCellId(int row_index, int col_index) const override;
+ std::optional<int32_t> CellIndexToId(int cell_index) const override;
bool IsCellOrHeaderOfARIATable() const override;
bool IsCellOrHeaderOfARIAGrid() const override;
gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
bool AccessibilityPerformAction(const AXActionData& data) override;
- base::string16 GetLocalizedRoleDescriptionForUnlabeledImage() const override;
- base::string16 GetLocalizedStringForLandmarkType() const override;
- base::string16 GetLocalizedStringForRoleDescription() const override;
- base::string16 GetLocalizedStringForImageAnnotationStatus(
+ std::u16string GetLocalizedRoleDescriptionForUnlabeledImage() const override;
+ std::u16string GetLocalizedStringForLandmarkType() const override;
+ std::u16string GetLocalizedStringForRoleDescription() const override;
+ std::u16string GetLocalizedStringForImageAnnotationStatus(
ax::mojom::ImageAnnotationStatus status) const override;
- base::string16 GetStyleNameAttributeAsLocalizedString() const override;
+ std::u16string GetStyleNameAttributeAsLocalizedString() const override;
bool ShouldIgnoreHoveredStateForTesting() override;
const ui::AXUniqueId& GetUniqueId() const override;
bool HasVisibleCaretOrSelection() const override;
@@ -143,8 +142,8 @@
ax::mojom::IntListAttribute attr) override;
bool IsOrderedSetItem() const override;
bool IsOrderedSet() const override;
- base::Optional<int> GetPosInSet() const override;
- base::Optional<int> GetSetSize() const override;
+ std::optional<int> GetPosInSet() const override;
+ std::optional<int> GetSetSize() const override;
const std::vector<gfx::NativeViewAccessible> GetUIADescendants()
const override;
gfx::RectF GetLocation() const;
diff --git a/third_party/accessibility/ax/platform/uia_registrar_win.cc b/third_party/accessibility/ax/platform/uia_registrar_win.cc
deleted file mode 100644
index bd6ca8f..0000000
--- a/third_party/accessibility/ax/platform/uia_registrar_win.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/platform/uia_registrar_win.h"
-#include <wrl/implements.h>
-#include "base/stl_util.h"
-
-namespace ui {
-
-UiaRegistrarWin::UiaRegistrarWin() {
- // Create the registrar object and get the IUIAutomationRegistrar
- // interface pointer.
- Microsoft::WRL::ComPtr<IUIAutomationRegistrar> registrar;
- if (FAILED(CoCreateInstance(CLSID_CUIAutomationRegistrar, nullptr,
- CLSCTX_INPROC_SERVER, IID_IUIAutomationRegistrar,
- ®istrar)))
- return;
-
- // Register the custom UIA property that represents the unique id of an UIA
- // element which also matches its corresponding IA2 element's unique id.
- UIAutomationPropertyInfo unique_id_property_info = {
- kUiaPropertyUniqueIdGuid, L"UniqueId", UIAutomationType_String};
- registrar->RegisterProperty(&unique_id_property_info,
- &uia_unique_id_property_id_);
-
- // Register the custom UIA event that represents the test end event for the
- // UIA test suite.
- UIAutomationEventInfo test_complete_event_info = {
- kUiaEventTestCompleteSentinelGuid, L"kUiaTestCompleteSentinel"};
- registrar->RegisterEvent(&test_complete_event_info,
- &uia_test_complete_event_id_);
-}
-
-UiaRegistrarWin::~UiaRegistrarWin() = default;
-
-PROPERTYID UiaRegistrarWin::GetUiaUniqueIdPropertyId() const {
- return uia_unique_id_property_id_;
-}
-
-EVENTID UiaRegistrarWin::GetUiaTestCompleteEventId() const {
- return uia_test_complete_event_id_;
-}
-
-const UiaRegistrarWin& UiaRegistrarWin::GetInstance() {
- static base::NoDestructor<UiaRegistrarWin> instance;
- return *instance;
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/platform/uia_registrar_win.h b/third_party/accessibility/ax/platform/uia_registrar_win.h
deleted file mode 100644
index 53c8da4..0000000
--- a/third_party/accessibility/ax/platform/uia_registrar_win.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_PLATFORM_UIA_REGISTRAR_WIN_H_
-#define UI_ACCESSIBILITY_PLATFORM_UIA_REGISTRAR_WIN_H_
-
-#include <objbase.h>
-#include <uiautomation.h>
-#include "base/macros.h"
-#include "base/no_destructor.h"
-#include "ui/accessibility/ax_export.h"
-
-namespace ui {
-// {3761326A-34B2-465A-835D-7A3D8F4EFB92}
-static const GUID kUiaEventTestCompleteSentinelGuid = {
- 0x3761326a,
- 0x34b2,
- 0x465a,
- {0x83, 0x5d, 0x7a, 0x3d, 0x8f, 0x4e, 0xfb, 0x92}};
-
-// {cc7eeb32-4b62-4f4c-aff6-1c2e5752ad8e}
-static const GUID kUiaPropertyUniqueIdGuid = {
- 0xcc7eeb32,
- 0x4b62,
- 0x4f4c,
- {0xaf, 0xf6, 0x1c, 0x2e, 0x57, 0x52, 0xad, 0x8e}};
-
-class AX_EXPORT UiaRegistrarWin {
- public:
- UiaRegistrarWin();
- ~UiaRegistrarWin();
- PROPERTYID GetUiaUniqueIdPropertyId() const;
- EVENTID GetUiaTestCompleteEventId() const;
-
- static const UiaRegistrarWin& GetInstance();
-
- private:
- PROPERTYID uia_unique_id_property_id_ = 0;
- EVENTID uia_test_complete_event_id_ = 0;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_PLATFORM_UIA_REGISTRAR_WIN_H_
diff --git a/third_party/accessibility/ax/run_all_unittests.cc b/third_party/accessibility/ax/run_all_unittests.cc
deleted file mode 100644
index ae25b61..0000000
--- a/third_party/accessibility/ax/run_all_unittests.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/bind.h"
-#include "base/test/launcher/unit_test_launcher.h"
-#include "base/test/test_suite.h"
-#include "build/build_config.h"
-#include "mojo/core/embedder/embedder.h"
-
-int main(int argc, char** argv) {
- mojo::core::Init();
-
- base::TestSuite test_suite(argc, argv);
- return base::LaunchUnitTests(
- argc, argv,
- base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite)));
-}
diff --git a/third_party/accessibility/ax/test_ax_node_helper.cc b/third_party/accessibility/ax/test_ax_node_helper.cc
index a2cfcf0..4c53f84 100644
--- a/third_party/accessibility/ax/test_ax_node_helper.cc
+++ b/third_party/accessibility/ax/test_ax_node_helper.cc
@@ -2,19 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/test_ax_node_helper.h"
+#include "test_ax_node_helper.h"
#include <map>
#include <utility>
+#include "ax_action_data.h"
+#include "ax_role_properties.h"
+#include "ax_table_info.h"
+#include "ax_tree_observer.h"
#include "base/numerics/ranges.h"
-#include "base/stl_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_role_properties.h"
-#include "ui/accessibility/ax_table_info.h"
-#include "ui/accessibility/ax_tree_observer.h"
-#include "ui/gfx/geometry/rect_conversions.h"
+#include "gfx/geometry/rect_conversions.h"
namespace ui {
@@ -84,7 +82,7 @@
}
case AXCoordinateSystem::kRootFrame:
case AXCoordinateSystem::kFrame:
- NOTIMPLEMENTED();
+ BASE_UNREACHABLE();
return gfx::Rect();
}
}
@@ -127,7 +125,7 @@
}
case AXCoordinateSystem::kRootFrame:
case AXCoordinateSystem::kFrame:
- NOTIMPLEMENTED();
+ BASE_UNREACHABLE();
return gfx::Rect();
}
}
@@ -141,18 +139,20 @@
}
int TestAXNodeHelper::InternalChildCount() const {
- return int{node_->GetUnignoredChildCount()};
+ return static_cast<int>(node_->GetUnignoredChildCount());
}
TestAXNodeHelper* TestAXNodeHelper::InternalGetChild(int index) const {
- CHECK_GE(index, 0);
- CHECK_LT(index, InternalChildCount());
- return GetOrCreate(tree_, node_->GetUnignoredChildAtIndex(size_t{index}));
+ BASE_CHECK(index >= 0);
+ BASE_CHECK(index < InternalChildCount());
+ return GetOrCreate(
+ tree_, node_->GetUnignoredChildAtIndex(static_cast<size_t>(index)));
}
gfx::RectF TestAXNodeHelper::GetInlineTextRect(const int start_offset,
const int end_offset) const {
- DCHECK(start_offset >= 0 && end_offset >= 0 && start_offset <= end_offset);
+ BASE_DCHECK(start_offset >= 0 && end_offset >= 0 &&
+ start_offset <= end_offset);
const std::vector<int32_t>& character_offsets = GetData().GetIntListAttribute(
ax::mojom::IntListAttribute::kCharacterOffsets);
gfx::RectF location = GetLocation();
@@ -173,7 +173,7 @@
break;
}
default:
- NOTIMPLEMENTED();
+ BASE_UNREACHABLE();
}
return bounds;
}
@@ -201,4 +201,5 @@
}
return AXOffscreenResult::kOnscreen;
}
+
} // namespace ui
diff --git a/third_party/accessibility/ax/test_ax_node_helper.h b/third_party/accessibility/ax/test_ax_node_helper.h
index a303b81..042ce55 100644
--- a/third_party/accessibility/ax/test_ax_node_helper.h
+++ b/third_party/accessibility/ax/test_ax_node_helper.h
@@ -5,11 +5,11 @@
#ifndef UI_ACCESSIBILITY_TEST_AX_NODE_HELPER_H_
#define UI_ACCESSIBILITY_TEST_AX_NODE_HELPER_H_
-#include "ui/accessibility/ax_clipping_behavior.h"
-#include "ui/accessibility/ax_coordinate_system.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_offscreen_result.h"
-#include "ui/accessibility/ax_tree.h"
+#include "ax_clipping_behavior.h"
+#include "ax_coordinate_system.h"
+#include "ax_node.h"
+#include "ax_offscreen_result.h"
+#include "ax_tree.h"
namespace ui {
diff --git a/third_party/accessibility/ax/test_ax_tree_manager.cc b/third_party/accessibility/ax/test_ax_tree_manager.cc
index e699a87..16c0837 100644
--- a/third_party/accessibility/ax/test_ax_tree_manager.cc
+++ b/third_party/accessibility/ax/test_ax_tree_manager.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/accessibility/test_ax_tree_manager.h"
+#include "test_ax_tree_manager.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_tree_data.h"
-#include "ui/accessibility/ax_tree_manager_map.h"
+#include "ax_node.h"
+#include "ax_tree_data.h"
+#include "ax_tree_manager_map.h"
namespace ui {
@@ -31,7 +31,10 @@
}
AXTree* TestAXTreeManager::GetTree() const {
- DCHECK(tree_) << "Did you forget to call SetTree?";
+ if (!tree_) {
+ BASE_LOG() << "Did you forget to call SetTree?";
+ BASE_UNREACHABLE();
+ }
return tree_.get();
}
diff --git a/third_party/accessibility/ax/test_ax_tree_manager.h b/third_party/accessibility/ax/test_ax_tree_manager.h
index 958761d..b5a6c49 100644
--- a/third_party/accessibility/ax/test_ax_tree_manager.h
+++ b/third_party/accessibility/ax/test_ax_tree_manager.h
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_ACCESSIBILITY_TEST_AX_TREE_MANAGER_H_
-#define UI_ACCESSIBILITY_TEST_AX_TREE_MANAGER_H_
+#ifndef ACCESSIBILITY_TEST_AX_AX_TREE_MANAGER_H_
+#define ACCESSIBILITY_TEST_AX_AX_TREE_MANAGER_H_
#include <memory>
-#include "ui/accessibility/ax_tree.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/accessibility/ax_tree_manager.h"
+#include "ax_tree.h"
+#include "ax_tree_id.h"
+#include "ax_tree_manager.h"
namespace ui {
@@ -54,4 +54,4 @@
} // namespace ui
-#endif // UI_ACCESSIBILITY_TEST_AX_TREE_MANAGER_H_
+#endif // ACCESSIBILITY_TEST_AX_AX_TREE_MANAGER_H_
diff --git a/third_party/accessibility/ax/tree_generator.cc b/third_party/accessibility/ax/tree_generator.cc
deleted file mode 100644
index 01fb37d..0000000
--- a/third_party/accessibility/ax/tree_generator.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/accessibility/tree_generator.h"
-
-#include "ui/accessibility/ax_serializable_tree.h"
-#include "ui/accessibility/ax_tree.h"
-
-namespace ui {
-
-static int UniqueTreeCountForNodeCount(int node_count, bool permutations) {
- int unique_tree_count = 1;
-
- // (n-1)! for the possible trees.
- for (int i = 2; i < node_count; ++i)
- unique_tree_count *= i;
-
- // n! for the permutations of ids.
- if (permutations)
- unique_tree_count = unique_tree_count * unique_tree_count * node_count;
-
- return unique_tree_count;
-}
-
-TreeGenerator::TreeGenerator(int max_node_count, bool permutations)
- : max_node_count_(max_node_count),
- permutations_(permutations),
- total_unique_tree_count_(0) {
- unique_tree_count_by_size_.push_back(0);
- for (int i = 1; i <= max_node_count; ++i) {
- int unique_tree_count = UniqueTreeCountForNodeCount(i, permutations);
- unique_tree_count_by_size_.push_back(unique_tree_count);
- total_unique_tree_count_ += unique_tree_count;
- }
-}
-
-TreeGenerator::~TreeGenerator() {}
-
-int TreeGenerator::UniqueTreeCount() const {
- return total_unique_tree_count_;
-}
-
-void TreeGenerator::BuildUniqueTree(int tree_index, AXTree* out_tree) const {
- AXTreeUpdate update;
- BuildUniqueTreeUpdate(tree_index, &update);
- CHECK(out_tree->Unserialize(update)) << out_tree->error();
-}
-
-int TreeGenerator::IgnoredPermutationCountPerUniqueTree(int tree_index) const {
- int unique_tree_count_so_far = 0;
- for (int node_count = 1; node_count <= max_node_count_; ++node_count) {
- int unique_tree_count = unique_tree_count_by_size_[node_count];
- if (tree_index - unique_tree_count_so_far < unique_tree_count) {
- // Each node other than the root can be either ignored or not,
- // so return 2 ^ (node_count - 1)
- return 1 << (node_count - 1);
- }
- unique_tree_count_so_far += unique_tree_count;
- }
-
- NOTREACHED();
- return 0;
-}
-
-void TreeGenerator::BuildUniqueTreeWithIgnoredNodes(int tree_index,
- int ignored_index,
- AXTree* out_tree) const {
- AXTreeUpdate update;
- BuildUniqueTreeUpdate(tree_index, &update);
-
- int node_count = int{update.nodes.size()};
- CHECK_GE(ignored_index, 0);
- CHECK_LT(ignored_index, 1 << (node_count - 1));
-
- for (int i = 0; i < node_count - 1; i++) {
- if (ignored_index & (1 << i))
- update.nodes[i + 1].AddState(ax::mojom::State::kIgnored);
- }
- CHECK(out_tree->Unserialize(update)) << out_tree->error();
-}
-
-void TreeGenerator::BuildUniqueTreeUpdate(int tree_index,
- AXTreeUpdate* out_update) const {
- CHECK_LT(tree_index, total_unique_tree_count_);
-
- int unique_tree_count_so_far = 0;
- for (int node_count = 1; node_count <= max_node_count_; ++node_count) {
- int unique_tree_count = unique_tree_count_by_size_[node_count];
- if (tree_index - unique_tree_count_so_far < unique_tree_count) {
- BuildUniqueTreeUpdateWithSize(
- node_count, tree_index - unique_tree_count_so_far, out_update);
- return;
- }
- unique_tree_count_so_far += unique_tree_count;
- }
-}
-
-void TreeGenerator::BuildUniqueTreeUpdateWithSize(
- int node_count,
- int tree_index,
- AXTreeUpdate* out_update) const {
- std::vector<int> indices;
- std::vector<int> permuted;
- int unique_tree_count = unique_tree_count_by_size_[node_count];
- CHECK_LT(tree_index, unique_tree_count);
-
- if (permutations_) {
- // Use the first few bits of |tree_index| to permute the indices.
- for (int i = 0; i < node_count; ++i)
- indices.push_back(i + 1);
- for (int i = 0; i < node_count; ++i) {
- int p = (node_count - i);
- int index = tree_index % p;
- tree_index /= p;
- permuted.push_back(indices[index]);
- indices.erase(indices.begin() + index);
- }
- } else {
- for (int i = 0; i < node_count; ++i)
- permuted.push_back(i + 1);
- }
-
- // Build an AXTreeUpdate. The first two nodes of the tree always
- // go in the same place.
- out_update->root_id = permuted[0];
- out_update->nodes.resize(node_count);
- out_update->nodes[0].id = permuted[0];
- if (node_count > 1) {
- out_update->nodes[0].child_ids.push_back(permuted[1]);
- out_update->nodes[1].id = permuted[1];
- }
-
- // The remaining nodes are assigned based on their parent
- // selected from the next bits from |tree_index|.
- for (int i = 2; i < node_count; ++i) {
- out_update->nodes[i].id = permuted[i];
- int parent_index = (tree_index % i);
- tree_index /= i;
- out_update->nodes[parent_index].child_ids.push_back(permuted[i]);
- }
-}
-
-} // namespace ui
diff --git a/third_party/accessibility/ax/tree_generator.h b/third_party/accessibility/ax/tree_generator.h
deleted file mode 100644
index 509cd21..0000000
--- a/third_party/accessibility/ax/tree_generator.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_ACCESSIBILITY_TREE_GENERATOR_H_
-#define UI_ACCESSIBILITY_TREE_GENERATOR_H_
-
-#include <vector>
-
-#include "ui/accessibility/ax_tree_update_forward.h"
-
-namespace ui {
-
-class AXTree;
-
-// A class to create all possible trees with up to <n> nodes and the
-// ids [1...n].
-//
-// There are two parts to the algorithm:
-//
-// The tree structure is formed as follows: without loss of generality,
-// the first node becomes the root and the second node becomes its
-// child. Thereafter, choose every possible parent for every other node.
-//
-// So for node i in (3...n), there are (i - 1) possible choices for its
-// parent, for a total of (n-1)! (n minus 1 factorial) possible trees.
-//
-// The second optional part is the assignment of ids to the nodes in the tree.
-// There are exactly n! (n factorial) permutations of the sequence 1...n,
-// and each of these is assigned to every node in every possible tree.
-//
-// The total number of trees for a given <n>, including permutations of ids, is
-// n! * (n-1)!
-//
-// n = 2: 2 trees
-// n = 3: 12 trees
-// n = 4: 144 trees
-// n = 5: 2880 trees
-//
-// Note that the generator returns all trees with sizes *up to* <n>, which
-// is a bit larger.
-//
-// This grows really fast! Still, it's very helpful for exhaustively testing
-// tree code on smaller trees at least.
-class TreeGenerator {
- public:
- // Will generate all trees with up to |max_node_count| nodes.
- // If |permutations| is true, will return every possible permutation of
- // ids, otherwise the root will always have id 1, and so on.
- TreeGenerator(int max_node_count, bool permutations);
- ~TreeGenerator();
-
- // Build all unique trees (no nodes ignored).
- int UniqueTreeCount() const;
- void BuildUniqueTree(int tree_index, AXTree* out_tree) const;
-
- // Support for returning every permutation of ignored nodes
- // (other than the root, which is never ignored) per unique tree.
- int IgnoredPermutationCountPerUniqueTree(int tree_index) const;
- void BuildUniqueTreeWithIgnoredNodes(int tree_index,
- int ignored_index,
- AXTree* out_tree) const;
-
- private:
- void BuildUniqueTreeUpdate(int tree_index,
- AXTreeUpdate* out_tree_update) const;
- void BuildUniqueTreeUpdateWithSize(int node_count,
- int tree_index,
- AXTreeUpdate* out_tree_update) const;
-
- int max_node_count_;
- bool permutations_;
- int total_unique_tree_count_;
- std::vector<int> unique_tree_count_by_size_;
-};
-
-} // namespace ui
-
-#endif // UI_ACCESSIBILITY_TREE_GENERATOR_H_
diff --git a/third_party/accessibility/ax_build/BUILD.gn b/third_party/accessibility/ax_build/BUILD.gn
new file mode 100644
index 0000000..8764c36
--- /dev/null
+++ b/third_party/accessibility/ax_build/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2013 The Flutter Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("ax_build") {
+ visibility = [ "//flutter/third_party/accessibility/*" ]
+ include_dirs = [ "//flutter/third_party/accessibility" ]
+
+ sources = [ "build_config.h" ]
+}
diff --git a/third_party/accessibility/ax_build/build_config.h b/third_party/accessibility/ax_build/build_config.h
index 2c3e81e..9d2ffed 100644
--- a/third_party/accessibility/ax_build/build_config.h
+++ b/third_party/accessibility/ax_build/build_config.h
@@ -33,8 +33,8 @@
// ARCH_CPU_31_BITS / ARCH_CPU_32_BITS / ARCH_CPU_64_BITS
// ARCH_CPU_BIG_ENDIAN / ARCH_CPU_LITTLE_ENDIAN
-#ifndef BUILD_BUILD_CONFIG_H_
-#define BUILD_BUILD_CONFIG_H_
+#ifndef UI_ACCESSIBILITY_BUILD_BUILD_CONFIG_H_
+#define UI_ACCESSIBILITY_BUILD_BUILD_CONFIG_H_
// A set of macros to use for platform detection.
#if defined(__native_client__)
@@ -220,9 +220,9 @@
// The compiler thinks std::string::const_iterator and "const char*" are
// equivalent types.
#define STD_STRING_ITERATOR_IS_CHAR_POINTER
-// The compiler thinks base::string16::const_iterator and "char16*" are
+// The compiler thinks std::u16string::const_iterator and "char16*" are
// equivalent types.
#define BASE_STRING16_ITERATOR_IS_CHAR16_POINTER
#endif
-#endif // BUILD_BUILD_CONFIG_H_
+#endif // UI_ACCESSIBILITY_BUILD_BUILD_CONFIG_H_
diff --git a/third_party/accessibility/base/BUILD.gn b/third_party/accessibility/base/BUILD.gn
new file mode 100644
index 0000000..86fa04d
--- /dev/null
+++ b/third_party/accessibility/base/BUILD.gn
@@ -0,0 +1,37 @@
+# Copyright 2013 The Flutter Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//flutter/common/config.gni")
+
+source_set("base") {
+ visibility = [ "//flutter/third_party/accessibility/*" ]
+ include_dirs = [ "//flutter/third_party/accessibility" ]
+
+ sources = [
+ "auto_reset.h",
+ "color_utils.h",
+ "compiler_specific.h",
+ "container_utils.h",
+ "logging.cc",
+ "logging.h",
+ "macros.h",
+ "no_destructor.h",
+ "simple_token.cc",
+ "simple_token.h",
+ "string_utils.cc",
+ "string_utils.h",
+ ]
+
+ if (is_mac) {
+ sources += [
+ "platform/darwin/scoped_nsobject.h",
+ "platform/darwin/scoped_nsobject.mm",
+ ]
+ }
+
+ public_deps = [
+ "numerics",
+ "//flutter/third_party/accessibility/ax_build",
+ ]
+}
diff --git a/third_party/accessibility/base/auto_reset.h b/third_party/accessibility/base/auto_reset.h
index d8ce87b..293620b 100644
--- a/third_party/accessibility/base/auto_reset.h
+++ b/third_party/accessibility/base/auto_reset.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef BASE_AUTO_RESET_H_
-#define BASE_AUTO_RESET_H_
+#ifndef ACCESSIBILITY_BASE_AUTO_RESET_H_
+#define ACCESSIBILITY_BASE_AUTO_RESET_H_
#include <utility>
@@ -49,4 +49,4 @@
} // namespace base
-#endif // BASE_AUTO_RESET_H_
+#endif // ACCESSIBILITY_BASE_AUTO_RESET_H_
diff --git a/third_party/accessibility/base/color_utils.h b/third_party/accessibility/base/color_utils.h
new file mode 100644
index 0000000..c1118f1
--- /dev/null
+++ b/third_party/accessibility/base/color_utils.h
@@ -0,0 +1,24 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_COLOR_UTILS_H_
+#define BASE_COLOR_UTILS_H_
+
+/** Returns alpha byte from color value.
+ */
+#define ColorGetA(color) (((color) >> 24) & 0xFF)
+
+/** Returns red component of color, from zero to 255.
+ */
+#define ColorGetR(color) (((color) >> 16) & 0xFF)
+
+/** Returns green component of color, from zero to 255.
+ */
+#define ColorGetG(color) (((color) >> 8) & 0xFF)
+
+/** Returns blue component of color, from zero to 255.
+ */
+#define ColorGetB(color) (((color) >> 0) & 0xFF)
+
+#endif // BASE_COLOR_UTILS_H_
diff --git a/third_party/accessibility/base/compiler_specific.h b/third_party/accessibility/base/compiler_specific.h
index 6943b0c..c1c10c2 100644
--- a/third_party/accessibility/base/compiler_specific.h
+++ b/third_party/accessibility/base/compiler_specific.h
@@ -1,14 +1,12 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef BASE_COMPILER_SPECIFIC_H_
-#define BASE_COMPILER_SPECIFIC_H_
+#ifndef ACCESSIBILITY_BASE_COMPILER_SPECIFIC_H_
+#define ACCESSIBILITY_BASE_COMPILER_SPECIFIC_H_
-#include "build/build_config.h"
-
-#if defined(COMPILER_MSVC) && !defined(__clang__)
-#error "Only clang-cl is supported on Windows, see https://crbug.com/988071"
+#if !defined(__GNUC__) && !defined(__clang__) && !defined(_MSC_VER)
+#error Unsupported compiler.
#endif
// Annotate a variable indicating it's ok if the variable is not used.
@@ -16,293 +14,16 @@
// is important for some other reason.)
// Use like:
// int x = ...;
-// ALLOW_UNUSED_LOCAL(x);
-#define ALLOW_UNUSED_LOCAL(x) (void)x
+// BASE_ALLOW_UNUSED_LOCAL(x);
+#define BASE_ALLOW_UNUSED_LOCAL(x) false ? (void)x : (void)0
// Annotate a typedef or function indicating it's ok if it's not used.
// Use like:
// typedef Foo Bar ALLOW_UNUSED_TYPE;
-#if defined(COMPILER_GCC) || defined(__clang__)
-#define ALLOW_UNUSED_TYPE __attribute__((unused))
+#if defined(__GNUC__) || defined(__clang__)
+#define BASE_ALLOW_UNUSED_TYPE __attribute__((unused))
#else
-#define ALLOW_UNUSED_TYPE
+#define BASE_ALLOW_UNUSED_TYPE
#endif
-// Annotate a function indicating it should not be inlined.
-// Use like:
-// NOINLINE void DoStuff() { ... }
-#if defined(COMPILER_GCC)
-#define NOINLINE __attribute__((noinline))
-#elif defined(COMPILER_MSVC)
-#define NOINLINE __declspec(noinline)
-#else
-#define NOINLINE
-#endif
-
-#if defined(COMPILER_GCC) && defined(NDEBUG)
-#define ALWAYS_INLINE inline __attribute__((__always_inline__))
-#elif defined(COMPILER_MSVC) && defined(NDEBUG)
-#define ALWAYS_INLINE __forceinline
-#else
-#define ALWAYS_INLINE inline
-#endif
-
-// Annotate a function indicating it should never be tail called. Useful to make
-// sure callers of the annotated function are never omitted from call-stacks.
-// To provide the complementary behavior (prevent the annotated function from
-// being omitted) look at NOINLINE. Also note that this doesn't prevent code
-// folding of multiple identical caller functions into a single signature. To
-// prevent code folding, see base::debug::Alias.
-// Use like:
-// void NOT_TAIL_CALLED FooBar();
-#if defined(__clang__) && __has_attribute(not_tail_called)
-#define NOT_TAIL_CALLED __attribute__((not_tail_called))
-#else
-#define NOT_TAIL_CALLED
-#endif
-
-// Specify memory alignment for structs, classes, etc.
-// Use like:
-// class ALIGNAS(16) MyClass { ... }
-// ALIGNAS(16) int array[4];
-//
-// In most places you can use the C++11 keyword "alignas", which is preferred.
-//
-// But compilers have trouble mixing __attribute__((...)) syntax with
-// alignas(...) syntax.
-//
-// Doesn't work in clang or gcc:
-// struct alignas(16) __attribute__((packed)) S { char c; };
-// Works in clang but not gcc:
-// struct __attribute__((packed)) alignas(16) S2 { char c; };
-// Works in clang and gcc:
-// struct alignas(16) S3 { char c; } __attribute__((packed));
-//
-// There are also some attributes that must be specified *before* a class
-// definition: visibility (used for exporting functions/classes) is one of
-// these attributes. This means that it is not possible to use alignas() with a
-// class that is marked as exported.
-#if defined(COMPILER_MSVC)
-#define ALIGNAS(byte_alignment) __declspec(align(byte_alignment))
-#elif defined(COMPILER_GCC)
-#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
-#endif
-
-// Annotate a function indicating the caller must examine the return value.
-// Use like:
-// int foo() WARN_UNUSED_RESULT;
-// To explicitly ignore a result, see |ignore_result()| in base/macros.h.
-#undef WARN_UNUSED_RESULT
-#if defined(COMPILER_GCC) || defined(__clang__)
-#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
-#else
-#define WARN_UNUSED_RESULT
-#endif
-
-// Tell the compiler a function is using a printf-style format string.
-// |format_param| is the one-based index of the format string parameter;
-// |dots_param| is the one-based index of the "..." parameter.
-// For v*printf functions (which take a va_list), pass 0 for dots_param.
-// (This is undocumented but matches what the system C headers do.)
-// For member functions, the implicit this parameter counts as index 1.
-#if defined(COMPILER_GCC) || defined(__clang__)
-#define PRINTF_FORMAT(format_param, dots_param) \
- __attribute__((format(printf, format_param, dots_param)))
-#else
-#define PRINTF_FORMAT(format_param, dots_param)
-#endif
-
-// WPRINTF_FORMAT is the same, but for wide format strings.
-// This doesn't appear to yet be implemented in any compiler.
-// See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38308 .
-#define WPRINTF_FORMAT(format_param, dots_param)
-// If available, it would look like:
-// __attribute__((format(wprintf, format_param, dots_param)))
-
-// Sanitizers annotations.
-#if defined(__has_attribute)
-#if __has_attribute(no_sanitize)
-#define NO_SANITIZE(what) __attribute__((no_sanitize(what)))
-#endif
-#endif
-#if !defined(NO_SANITIZE)
-#define NO_SANITIZE(what)
-#endif
-
-// MemorySanitizer annotations.
-#if defined(MEMORY_SANITIZER) && !defined(OS_NACL)
-#include <sanitizer/msan_interface.h>
-
-// Mark a memory region fully initialized.
-// Use this to annotate code that deliberately reads uninitialized data, for
-// example a GC scavenging root set pointers from the stack.
-#define MSAN_UNPOISON(p, size) __msan_unpoison(p, size)
-
-// Check a memory region for initializedness, as if it was being used here.
-// If any bits are uninitialized, crash with an MSan report.
-// Use this to sanitize data which MSan won't be able to track, e.g. before
-// passing data to another process via shared memory.
-#define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) \
- __msan_check_mem_is_initialized(p, size)
-#else // MEMORY_SANITIZER
-#define MSAN_UNPOISON(p, size)
-#define MSAN_CHECK_MEM_IS_INITIALIZED(p, size)
-#endif // MEMORY_SANITIZER
-
-// DISABLE_CFI_PERF -- Disable Control Flow Integrity for perf reasons.
-#if !defined(DISABLE_CFI_PERF)
-#if defined(__clang__) && defined(OFFICIAL_BUILD)
-#define DISABLE_CFI_PERF __attribute__((no_sanitize("cfi")))
-#else
-#define DISABLE_CFI_PERF
-#endif
-#endif
-
-// DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks.
-#if !defined(DISABLE_CFI_ICALL)
-#if defined(OS_WIN)
-// Windows also needs __declspec(guard(nocf)).
-#define DISABLE_CFI_ICALL NO_SANITIZE("cfi-icall") __declspec(guard(nocf))
-#else
-#define DISABLE_CFI_ICALL NO_SANITIZE("cfi-icall")
-#endif
-#endif
-#if !defined(DISABLE_CFI_ICALL)
-#define DISABLE_CFI_ICALL
-#endif
-
-// Macro useful for writing cross-platform function pointers.
-#if !defined(CDECL)
-#if defined(OS_WIN)
-#define CDECL __cdecl
-#else // defined(OS_WIN)
-#define CDECL
-#endif // defined(OS_WIN)
-#endif // !defined(CDECL)
-
-// Macro for hinting that an expression is likely to be false.
-#if !defined(UNLIKELY)
-#if defined(COMPILER_GCC) || defined(__clang__)
-#define UNLIKELY(x) __builtin_expect(!!(x), 0)
-#else
-#define UNLIKELY(x) (x)
-#endif // defined(COMPILER_GCC)
-#endif // !defined(UNLIKELY)
-
-#if !defined(LIKELY)
-#if defined(COMPILER_GCC) || defined(__clang__)
-#define LIKELY(x) __builtin_expect(!!(x), 1)
-#else
-#define LIKELY(x) (x)
-#endif // defined(COMPILER_GCC)
-#endif // !defined(LIKELY)
-
-// Compiler feature-detection.
-// clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension
-#if defined(__has_feature)
-#define HAS_FEATURE(FEATURE) __has_feature(FEATURE)
-#else
-#define HAS_FEATURE(FEATURE) 0
-#endif
-
-// Macro for telling -Wimplicit-fallthrough that a fallthrough is intentional.
-#if defined(__clang__)
-#define FALLTHROUGH [[clang::fallthrough]]
-#else
-#define FALLTHROUGH
-#endif
-
-#if defined(COMPILER_GCC)
-#define PRETTY_FUNCTION __PRETTY_FUNCTION__
-#elif defined(COMPILER_MSVC)
-#define PRETTY_FUNCTION __FUNCSIG__
-#else
-// See https://en.cppreference.com/w/c/language/function_definition#func
-#define PRETTY_FUNCTION __func__
-#endif
-
-#if !defined(CPU_ARM_NEON)
-#if defined(__arm__)
-#if !defined(__ARMEB__) && !defined(__ARM_EABI__) && !defined(__EABI__) && \
- !defined(__VFP_FP__) && !defined(_WIN32_WCE) && !defined(ANDROID)
-#error Chromium does not support middle endian architecture
-#endif
-#if defined(__ARM_NEON__)
-#define CPU_ARM_NEON 1
-#endif
-#endif // defined(__arm__)
-#endif // !defined(CPU_ARM_NEON)
-
-#if !defined(HAVE_MIPS_MSA_INTRINSICS)
-#if defined(__mips_msa) && defined(__mips_isa_rev) && (__mips_isa_rev >= 5)
-#define HAVE_MIPS_MSA_INTRINSICS 1
-#endif
-#endif
-
-#if defined(__clang__) && __has_attribute(uninitialized)
-// Attribute "uninitialized" disables -ftrivial-auto-var-init=pattern for
-// the specified variable.
-// Library-wide alternative is
-// 'configs -= [ "//build/config/compiler:default_init_stack_vars" ]' in .gn
-// file.
-//
-// See "init_stack_vars" in build/config/compiler/BUILD.gn and
-// http://crbug.com/977230
-// "init_stack_vars" is enabled for non-official builds and we hope to enable it
-// in official build in 2020 as well. The flag writes fixed pattern into
-// uninitialized parts of all local variables. In rare cases such initialization
-// is undesirable and attribute can be used:
-// 1. Degraded performance
-// In most cases compiler is able to remove additional stores. E.g. if memory is
-// never accessed or properly initialized later. Preserved stores mostly will
-// not affect program performance. However if compiler failed on some
-// performance critical code we can get a visible regression in a benchmark.
-// 2. memset, memcpy calls
-// Compiler may replaces some memory writes with memset or memcpy calls. This is
-// not -ftrivial-auto-var-init specific, but it can happen more likely with the
-// flag. It can be a problem if code is not linked with C run-time library.
-//
-// Note: The flag is security risk mitigation feature. So in future the
-// attribute uses should be avoided when possible. However to enable this
-// mitigation on the most of the code we need to be less strict now and minimize
-// number of exceptions later. So if in doubt feel free to use attribute, but
-// please document the problem for someone who is going to cleanup it later.
-// E.g. platform, bot, benchmark or test name in patch description or next to
-// the attribute.
-#define STACK_UNINITIALIZED __attribute__((uninitialized))
-#else
-#define STACK_UNINITIALIZED
-#endif
-
-// The ANALYZER_ASSUME_TRUE(bool arg) macro adds compiler-specific hints
-// to Clang which control what code paths are statically analyzed,
-// and is meant to be used in conjunction with assert & assert-like functions.
-// The expression is passed straight through if analysis isn't enabled.
-//
-// ANALYZER_SKIP_THIS_PATH() suppresses static analysis for the current
-// codepath and any other branching codepaths that might follow.
-#if defined(__clang_analyzer__)
-
-inline constexpr bool AnalyzerNoReturn() __attribute__((analyzer_noreturn)) {
- return false;
-}
-
-inline constexpr bool AnalyzerAssumeTrue(bool arg) {
- // AnalyzerNoReturn() is invoked and analysis is terminated if |arg| is
- // false.
- return arg || AnalyzerNoReturn();
-}
-
-#define ANALYZER_ASSUME_TRUE(arg) ::AnalyzerAssumeTrue(!!(arg))
-#define ANALYZER_SKIP_THIS_PATH() static_cast<void>(::AnalyzerNoReturn())
-#define ANALYZER_ALLOW_UNUSED(var) static_cast<void>(var);
-
-#else // !defined(__clang_analyzer__)
-
-#define ANALYZER_ASSUME_TRUE(arg) (arg)
-#define ANALYZER_SKIP_THIS_PATH()
-#define ANALYZER_ALLOW_UNUSED(var) static_cast<void>(var);
-
-#endif // defined(__clang_analyzer__)
-
-#endif // BASE_COMPILER_SPECIFIC_H_
+#endif // ACCESSIBILITY_BASE_COMPILER_SPECIFIC_H_
diff --git a/third_party/accessibility/base/container_utils.h b/third_party/accessibility/base/container_utils.h
new file mode 100644
index 0000000..3636731
--- /dev/null
+++ b/third_party/accessibility/base/container_utils.h
@@ -0,0 +1,34 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_CONTAINER_UTILS_H_
+#define BASE_CONTAINER_UTILS_H_
+
+#include <set>
+#include <vector>
+
+namespace base {
+
+template <class T, class Allocator, class Predicate>
+size_t EraseIf(std::vector<T, Allocator>& container, Predicate pred) {
+ auto it = std::remove_if(container.begin(), container.end(), pred);
+ size_t removed = std::distance(it, container.end());
+ container.erase(it, container.end());
+ return removed;
+}
+
+template <typename Container, typename Value>
+bool Contains(const Container& container, const Value& value) {
+ return container.find(value) != container.end();
+}
+
+template <typename T>
+bool Contains(const std::vector<T>& container, const T& value) {
+ return std::find(container.begin(), container.end(), value) !=
+ container.end();
+}
+
+} // namespace base
+
+#endif // BASE_CONTAINER_UTILS_H_
diff --git a/third_party/accessibility/base/logging.cc b/third_party/accessibility/base/logging.cc
new file mode 100644
index 0000000..a86eb23
--- /dev/null
+++ b/third_party/accessibility/base/logging.cc
@@ -0,0 +1,65 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "logging.h"
+
+#include <algorithm>
+#include <iostream>
+
+#include "ax_build/build_config.h"
+// #include "log_settings.h"
+
+#if defined(OS_ANDROID)
+#include <android/log.h>
+#elif defined(OS_IOS)
+#include <syslog.h>
+#endif
+
+namespace base {
+
+namespace {
+
+const char* StripPath(const char* path) {
+ auto* p = strrchr(path, '/');
+ if (p) {
+ return p + 1;
+ }
+ return path;
+}
+
+} // namespace
+
+LogMessage::LogMessage(const char* file,
+ int line,
+ const char* condition,
+ bool killProcess)
+ : file_(file), line_(line), killProcess_(killProcess) {
+ stream_ << "[ERROR:" << StripPath(file_) << "(" << line_ << ")] ";
+
+ if (condition) {
+ stream_ << "Check failed: " << condition << ". ";
+ }
+}
+
+LogMessage::~LogMessage() {
+ stream_ << std::endl;
+
+#if defined(OS_ANDROID)
+ android_LogPriority priority = ANDROID_LOG_ERROR __android_log_write(
+ priority, "flutter", stream_.str().c_str());
+#elif defined(OS_IOS)
+ syslog(LOG_ALERT, "%s", stream_.str().c_str());
+#else
+ std::cerr << stream_.str();
+ std::cerr.flush();
+#endif
+ if (killProcess_)
+ KillProcess();
+}
+
+void KillProcess() {
+ abort();
+}
+
+} // namespace base
diff --git a/third_party/accessibility/base/logging.h b/third_party/accessibility/base/logging.h
new file mode 100644
index 0000000..32187eb
--- /dev/null
+++ b/third_party/accessibility/base/logging.h
@@ -0,0 +1,75 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ACCESSIBILITY_BASE_LOGGING_H_
+#define ACCESSIBILITY_BASE_LOGGING_H_
+
+#include <sstream>
+
+#include "macros.h"
+
+namespace base {
+
+class LogMessageVoidify {
+ public:
+ void operator&(std::ostream&) {}
+};
+
+class LogMessage {
+ public:
+ LogMessage(const char* file,
+ int line,
+ const char* condition,
+ bool killProcess);
+ ~LogMessage();
+
+ std::ostream& stream() { return stream_; }
+
+ private:
+ std::ostringstream stream_;
+ const char* file_;
+ const int line_;
+ const bool killProcess_;
+
+ BASE_DISALLOW_COPY_AND_ASSIGN(LogMessage);
+};
+
+[[noreturn]] void KillProcess();
+
+} // namespace base
+
+#define BASE_LOG_STREAM() \
+ ::base::LogMessage(__FILE__, __LINE__, nullptr, false).stream()
+
+#define BASE_LAZY_STREAM(stream, condition) \
+ !(condition) ? (void)0 : ::base::LogMessageVoidify() & (stream)
+
+#define BASE_EAT_STREAM_PARAMETERS(ignored) \
+ true || (ignored) \
+ ? (void)0 \
+ : ::base::LogMessageVoidify() & \
+ ::base::LogMessage(0, 0, nullptr, !(ignored)).stream()
+
+#define BASE_LOG() BASE_LAZY_STREAM(BASE_LOG_STREAM(), true)
+
+#define BASE_CHECK(condition) \
+ BASE_LAZY_STREAM( \
+ ::base::LogMessage(__FILE__, __LINE__, #condition, true).stream(), \
+ !(condition))
+
+#ifndef NDEBUG
+#define BASE_DLOG() BASE_LOG()
+#define BASE_DCHECK(condition) BASE_CHECK(condition)
+#else
+#define BASE_DLOG() BASE_EAT_STREAM_PARAMETERS(true)
+#define BASE_DCHECK(condition) BASE_EAT_STREAM_PARAMETERS(condition)
+#endif
+
+#define BASE_UNREACHABLE() \
+ { \
+ BASE_LOG() << "Reached unreachable code."; \
+ ::base::KillProcess(); \
+ }
+
+#endif // ACCESSIBILITY_BASE_LOGGING_H_
diff --git a/third_party/accessibility/base/logging_unittests.cc b/third_party/accessibility/base/logging_unittests.cc
new file mode 100644
index 0000000..87ea984
--- /dev/null
+++ b/third_party/accessibility/base/logging_unittests.cc
@@ -0,0 +1,32 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gtest/gtest.h"
+#include "logging.h"
+
+namespace base {
+namespace testing {
+
+int UnreachableScopeWithoutReturnDoesNotMakeCompilerMad() {
+ KillProcess();
+ // return 0; <--- Missing but compiler is fine.
+}
+
+int UnreachableScopeWithMacroWithoutReturnDoesNotMakeCompilerMad() {
+ BASE_UNREACHABLE();
+ // return 0; <--- Missing but compiler is fine.
+}
+
+TEST(LoggingTest, UnreachableKillProcess) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_DEATH(KillProcess(), "");
+}
+
+TEST(LoggingTest, UnreachableKillProcessWithMacro) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_DEATH({ BASE_UNREACHABLE(); }, "");
+}
+
+} // namespace testing
+} // namespace base
diff --git a/third_party/accessibility/base/macros.h b/third_party/accessibility/base/macros.h
new file mode 100644
index 0000000..71b1e57
--- /dev/null
+++ b/third_party/accessibility/base/macros.h
@@ -0,0 +1,12 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ACCESSIBILITY_BASE_MACROS_H_
+#define ACCESSIBILITY_BASE_MACROS_H_
+
+#define BASE_DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&) = delete; \
+ TypeName& operator=(const TypeName&) = delete
+
+#endif // ACCESSIBILITY_BASE_MACROS_H_
diff --git a/third_party/accessibility/base/no_destructor.h b/third_party/accessibility/base/no_destructor.h
index 21cfef8..464bdc9 100644
--- a/third_party/accessibility/base/no_destructor.h
+++ b/third_party/accessibility/base/no_destructor.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef BASE_NO_DESTRUCTOR_H_
-#define BASE_NO_DESTRUCTOR_H_
+#ifndef ACCESSIBILITY_BASE_NO_DESTRUCTOR_H_
+#define ACCESSIBILITY_BASE_NO_DESTRUCTOR_H_
#include <new>
#include <utility>
@@ -95,4 +95,4 @@
} // namespace base
-#endif // BASE_NO_DESTRUCTOR_H_
+#endif // ACCESSIBILITY_BASE_NO_DESTRUCTOR_H_
diff --git a/third_party/accessibility/base/numerics/BUILD.gn b/third_party/accessibility/base/numerics/BUILD.gn
index 0bb8dd1..74fe392 100644
--- a/third_party/accessibility/base/numerics/BUILD.gn
+++ b/third_party/accessibility/base/numerics/BUILD.gn
@@ -6,8 +6,8 @@
# way to facilitate pulling it into various third-party projects. So, this
# file is here to protect against accidentally introducing external
# dependencies or depending on internal implementation details.
-source_set("base_numerics") {
- visibility = [ "//base/*" ]
+source_set("numerics") {
+ visibility = [ "//flutter/third_party/accessibility/*" ]
sources = [
"checked_math_impl.h",
"clamped_math_impl.h",
diff --git a/third_party/accessibility/base/platform/darwin/scoped_nsobject.h b/third_party/accessibility/base/platform/darwin/scoped_nsobject.h
new file mode 100644
index 0000000..410904e
--- /dev/null
+++ b/third_party/accessibility/base/platform/darwin/scoped_nsobject.h
@@ -0,0 +1,156 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ACCESSIBILITY_BASE_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
+#define ACCESSIBILITY_BASE_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
+
+// Include NSObject.h directly because Foundation.h pulls in many dependencies.
+// (Approx 100k lines of code versus 1.5k for NSObject.h). scoped_nsobject gets
+// singled out because it is most typically included from other header files.
+#import <Foundation/NSObject.h>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+
+@class NSAutoreleasePool;
+
+namespace base {
+
+// scoped_nsobject<> is patterned after scoped_ptr<>, but maintains ownership
+// of an NSObject subclass object. Style deviations here are solely for
+// compatibility with scoped_ptr<>'s interface, with which everyone is already
+// familiar.
+//
+// scoped_nsobject<> takes ownership of an object (in the constructor or in
+// reset()) by taking over the caller's existing ownership claim. The caller
+// must own the object it gives to scoped_nsobject<>, and relinquishes an
+// ownership claim to that object. scoped_nsobject<> does not call -retain,
+// callers have to call this manually if appropriate.
+//
+// scoped_nsprotocol<> has the same behavior as scoped_nsobject, but can be used
+// with protocols.
+//
+// scoped_nsobject<> is not to be used for NSAutoreleasePools. For
+// NSAutoreleasePools use ScopedNSAutoreleasePool from
+// scoped_nsautorelease_pool.h instead.
+// We check for bad uses of scoped_nsobject and NSAutoreleasePool at compile
+// time with a template specialization (see below).
+
+template <typename NST>
+class scoped_nsprotocol {
+ public:
+ explicit scoped_nsprotocol(NST object = nil) : object_(object) {}
+
+ scoped_nsprotocol(const scoped_nsprotocol<NST>& that) : object_([that.object_ retain]) {}
+
+ template <typename NSU>
+ scoped_nsprotocol(const scoped_nsprotocol<NSU>& that) : object_([that.get() retain]) {}
+
+ ~scoped_nsprotocol() { [object_ release]; }
+
+ scoped_nsprotocol& operator=(const scoped_nsprotocol<NST>& that) {
+ reset([that.get() retain]);
+ return *this;
+ }
+
+ void reset(NST object = nil) {
+ // We intentionally do not check that object != object_ as the caller must
+ // either already have an ownership claim over whatever it passes to this
+ // method, or call it with the |RETAIN| policy which will have ensured that
+ // the object is retained once more when reaching this point.
+ [object_ release];
+ object_ = object;
+ }
+
+ bool operator==(NST that) const { return object_ == that; }
+ bool operator!=(NST that) const { return object_ != that; }
+
+ operator NST() const { return object_; }
+
+ NST get() const { return object_; }
+
+ void swap(scoped_nsprotocol& that) {
+ NST temp = that.object_;
+ that.object_ = object_;
+ object_ = temp;
+ }
+
+ // Shift reference to the autorelease pool to be released later.
+ NST autorelease() { return [release() autorelease]; }
+
+ private:
+ NST object_;
+
+ // scoped_nsprotocol<>::release() is like scoped_ptr<>::release. It is NOT a
+ // wrapper for [object_ release]. To force a scoped_nsprotocol<> to call
+ // [object_ release], use scoped_nsprotocol<>::reset().
+ [[nodiscard]] NST release() {
+ NST temp = object_;
+ object_ = nil;
+ return temp;
+ }
+};
+
+// Free functions
+template <class C>
+void swap(scoped_nsprotocol<C>& p1, scoped_nsprotocol<C>& p2) {
+ p1.swap(p2);
+}
+
+template <class C>
+bool operator==(C p1, const scoped_nsprotocol<C>& p2) {
+ return p1 == p2.get();
+}
+
+template <class C>
+bool operator!=(C p1, const scoped_nsprotocol<C>& p2) {
+ return p1 != p2.get();
+}
+
+template <typename NST>
+class scoped_nsobject : public scoped_nsprotocol<NST*> {
+ public:
+ explicit scoped_nsobject(NST* object = nil) : scoped_nsprotocol<NST*>(object) {}
+
+ scoped_nsobject(const scoped_nsobject<NST>& that) : scoped_nsprotocol<NST*>(that) {}
+
+ template <typename NSU>
+ scoped_nsobject(const scoped_nsobject<NSU>& that) : scoped_nsprotocol<NST*>(that) {}
+
+ scoped_nsobject& operator=(const scoped_nsobject<NST>& that) {
+ scoped_nsprotocol<NST*>::operator=(that);
+ return *this;
+ }
+};
+
+// Specialization to make scoped_nsobject<id> work.
+template <>
+class scoped_nsobject<id> : public scoped_nsprotocol<id> {
+ public:
+ explicit scoped_nsobject(id object = nil) : scoped_nsprotocol<id>(object) {}
+
+ scoped_nsobject(const scoped_nsobject<id>& that) : scoped_nsprotocol<id>(that) {}
+
+ template <typename NSU>
+ scoped_nsobject(const scoped_nsobject<NSU>& that) : scoped_nsprotocol<id>(that) {}
+
+ scoped_nsobject& operator=(const scoped_nsobject<id>& that) {
+ scoped_nsprotocol<id>::operator=(that);
+ return *this;
+ }
+};
+
+// Do not use scoped_nsobject for NSAutoreleasePools, use
+// ScopedNSAutoreleasePool instead. This is a compile time check. See details
+// at top of header.
+template <>
+class scoped_nsobject<NSAutoreleasePool> {
+ private:
+ explicit scoped_nsobject(NSAutoreleasePool* object = nil);
+ BASE_DISALLOW_COPY_AND_ASSIGN(scoped_nsobject);
+};
+
+} // namespace base
+
+#endif // FLUTTER_BASE_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
diff --git a/third_party/accessibility/base/platform/darwin/scoped_nsobject.mm b/third_party/accessibility/base/platform/darwin/scoped_nsobject.mm
new file mode 100644
index 0000000..991f6b8
--- /dev/null
+++ b/third_party/accessibility/base/platform/darwin/scoped_nsobject.mm
@@ -0,0 +1,11 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/platform/darwin/scoped_nsobject.h"
+
+namespace base {
+
+//
+
+} // namespace base
diff --git a/third_party/accessibility/base/simple_token.cc b/third_party/accessibility/base/simple_token.cc
new file mode 100644
index 0000000..3208f09
--- /dev/null
+++ b/third_party/accessibility/base/simple_token.cc
@@ -0,0 +1,47 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "simple_token.h"
+
+#include <ostream>
+#include <random>
+
+namespace base {
+
+constexpr size_t kRandomTokenLength = 10;
+
+SimpleToken::SimpleToken(const std::string& token) : token_(token) {}
+
+// static
+SimpleToken SimpleToken::Create() {
+ const char charset[] =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+ const size_t max_index = (sizeof(charset) - 1);
+
+ std::string str;
+ for (size_t i = 0; i < kRandomTokenLength; i++) {
+ str.push_back(charset[rand() % max_index]);
+ }
+ return SimpleToken(str);
+}
+
+std::ostream& operator<<(std::ostream& out, const SimpleToken& token) {
+ return out << "(" << token.ToString() << ")";
+}
+
+std::optional<base::SimpleToken> ValueToSimpleToken(std::string str) {
+ return std::make_optional<base::SimpleToken>(str);
+}
+
+std::string SimpleTokenToValue(const SimpleToken& token) {
+ return token.ToString();
+}
+
+size_t SimpleTokenHash(const SimpleToken& SimpleToken) {
+ return std::hash<std::string>()(SimpleToken.ToString());
+}
+
+} // namespace base
diff --git a/third_party/accessibility/base/simple_token.h b/third_party/accessibility/base/simple_token.h
new file mode 100644
index 0000000..d4cc0a7
--- /dev/null
+++ b/third_party/accessibility/base/simple_token.h
@@ -0,0 +1,58 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_SIMPLE_TOKEN_H_
+#define BASE_SIMPLE_TOKEN_H_
+
+#include <functional>
+#include <optional>
+#include <string>
+
+namespace base {
+
+// A simple string wrapping token.
+class SimpleToken {
+ public:
+ // Create a random SimpleToken.
+ static SimpleToken Create();
+
+ // Creates an empty SimpleToken.
+ // Assign to it with Create() before using it.
+ SimpleToken() = default;
+ ~SimpleToken() = default;
+ // Creates an token that wrapps the input string.
+ SimpleToken(const std::string& token);
+
+ // Hex representation of the unguessable token.
+ std::string ToString() const { return token_; }
+
+ explicit constexpr operator bool() const { return !token_.empty(); }
+
+ constexpr bool operator<(const SimpleToken& other) const {
+ return token_.compare(other.token_) < 0;
+ }
+
+ constexpr bool operator==(const SimpleToken& other) const {
+ return token_.compare(other.token_) == 0;
+ }
+
+ constexpr bool operator!=(const SimpleToken& other) const {
+ return !(*this == other);
+ }
+
+ private:
+ std::string token_;
+};
+
+std::ostream& operator<<(std::ostream& out, const SimpleToken& token);
+
+std::optional<base::SimpleToken> ValueToSimpleToken(std::string str);
+
+std::string SimpleTokenToValue(const SimpleToken& token);
+
+size_t SimpleTokenHash(const SimpleToken& SimpleToken);
+
+} // namespace base
+
+#endif // BASE_SIMPLE_TOKEN_H_
diff --git a/third_party/accessibility/base/string_utils.cc b/third_party/accessibility/base/string_utils.cc
new file mode 100644
index 0000000..94cfb5d
--- /dev/null
+++ b/third_party/accessibility/base/string_utils.cc
@@ -0,0 +1,101 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "string_utils.h"
+
+#include <codecvt>
+#include <locale>
+#include <regex>
+#include <sstream>
+
+#include "no_destructor.h"
+
+namespace base {
+
+std::u16string ASCIIToUTF16(std::string src) {
+ return std::u16string(src.begin(), src.end());
+}
+
+std::u16string UTF8ToUTF16(std::string src) {
+ std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
+ return convert.from_bytes(src);
+}
+
+std::string UTF16ToUTF8(std::u16string src) {
+ std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
+ return convert.to_bytes(src);
+}
+
+std::u16string NumberToString16(float number) {
+ return ASCIIToUTF16(NumberToString(number));
+}
+
+std::string NumberToString(int32_t number) {
+ return std::to_string(number);
+}
+
+std::string NumberToString(unsigned int number) {
+ return std::to_string(number);
+}
+
+std::string NumberToString(float number) {
+ return std::to_string(number);
+}
+
+std::string JoinString(std::vector<std::string> tokens, std::string delimiter) {
+ std::ostringstream imploded;
+ for (size_t i = 0; i < tokens.size(); i++) {
+ if (i == tokens.size() - 1) {
+ imploded << tokens[i];
+ } else {
+ imploded << tokens[i] << delimiter;
+ }
+ }
+ return imploded.str();
+}
+
+void ReplaceChars(std::string in,
+ std::string from,
+ std::string to,
+ std::string* out) {
+ size_t pos = in.find(from);
+ while (pos != std::string::npos) {
+ in.replace(pos, from.size(), to);
+ pos = in.find(from, pos + to.size());
+ }
+ *out = in;
+}
+
+const std::string& EmptyString() {
+ static const base::NoDestructor<std::string> s;
+ return *s;
+}
+
+std::string ToUpperASCII(std::string str) {
+ std::string ret;
+ ret.reserve(str.size());
+ for (size_t i = 0; i < str.size(); i++)
+ ret.push_back(std::toupper(str[i]));
+ return ret;
+}
+
+std::string ToLowerASCII(std::string str) {
+ std::string ret;
+ ret.reserve(str.size());
+ for (size_t i = 0; i < str.size(); i++)
+ ret.push_back(std::tolower(str[i]));
+ return ret;
+}
+
+bool LowerCaseEqualsASCII(std::string a, std::string b) {
+ std::string lower_a = ToLowerASCII(a);
+ return lower_a.compare(ToLowerASCII(b)) == 0;
+}
+
+bool ContainsOnlyChars(std::u16string str, char16_t ch) {
+ return std::find_if(str.begin(), str.end(),
+ [ch](char16_t c) { return c != ch; }) == str.end();
+}
+
+} // namespace base
diff --git a/third_party/accessibility/base/string_utils.h b/third_party/accessibility/base/string_utils.h
new file mode 100644
index 0000000..227c651
--- /dev/null
+++ b/third_party/accessibility/base/string_utils.h
@@ -0,0 +1,50 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_STRING_UTILS_H_
+#define BASE_STRING_UTILS_H_
+
+#include <string>
+#include <vector>
+
+namespace base {
+
+constexpr char16_t kWhitespaceUTF16 = u' ';
+
+// Return a C++ string given printf-like input.
+template <typename... Args>
+std::string StringPrintf(const std::string& format, Args... args) {
+ // Calculate the buffer size.
+ int size = snprintf(nullptr, 0, format.c_str(), args...) + 1;
+ std::unique_ptr<char[]> buf(new char[size]);
+ snprintf(buf.get(), size, format.c_str(), args...);
+ return std::string(buf.get(), buf.get() + size - 1);
+}
+
+std::u16string ASCIIToUTF16(std::string src);
+std::u16string UTF8ToUTF16(std::string src);
+std::string UTF16ToUTF8(std::u16string src);
+
+std::u16string NumberToString16(float number);
+std::string NumberToString(unsigned int number);
+std::string NumberToString(int32_t number);
+std::string NumberToString(float number);
+
+std::string ToUpperASCII(std::string str);
+std::string ToLowerASCII(std::string str);
+
+std::string JoinString(std::vector<std::string> tokens, std::string delimiter);
+void ReplaceChars(std::string in,
+ std::string from,
+ std::string to,
+ std::string* out);
+
+bool LowerCaseEqualsASCII(std::string a, std::string b);
+bool ContainsOnlyChars(std::u16string str, char16_t ch);
+
+const std::string& EmptyString();
+
+} // namespace base
+
+#endif // BASE_STRING_UTILS_H_
diff --git a/third_party/accessibility/base/string_utils_unittest.cc b/third_party/accessibility/base/string_utils_unittest.cc
new file mode 100644
index 0000000..dad910e
--- /dev/null
+++ b/third_party/accessibility/base/string_utils_unittest.cc
@@ -0,0 +1,58 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "string_utils.h"
+
+#include <errno.h>
+#include <stddef.h>
+
+#include "base/logging.h"
+#include "gtest/gtest.h"
+
+namespace base {
+
+TEST(StringUtilsTest, StringPrintfEmpty) {
+ EXPECT_EQ("", base::StringPrintf("%s", ""));
+}
+
+TEST(StringUtilsTest, StringPrintfMisc) {
+ EXPECT_EQ("123hello w", StringPrintf("%3d%2s %1c", 123, "hello", 'w'));
+}
+// Test that StringPrintf and StringAppendV do not change errno.
+TEST(StringUtilsTest, StringPrintfErrno) {
+ errno = 1;
+ EXPECT_EQ("", StringPrintf("%s", ""));
+ EXPECT_EQ(1, errno);
+}
+
+TEST(StringUtilsTest, canASCIIToUTF16) {
+ std::string ascii = "abcdefg";
+ EXPECT_EQ(ASCIIToUTF16(ascii).compare(u"abcdefg"), 0);
+}
+
+TEST(StringUtilsTest, canUTF8ToUTF16) {
+ std::string utf8 = "äåè";
+ EXPECT_EQ(UTF8ToUTF16(utf8).compare(u"äåè"), 0);
+}
+
+TEST(StringUtilsTest, canUTF16ToUTF8) {
+ std::u16string utf16 = u"äåè";
+ EXPECT_EQ(UTF16ToUTF8(utf16).compare("äåè"), 0);
+}
+
+TEST(StringUtilsTest, canNumberToString16) {
+ float number = 1.123;
+ EXPECT_EQ(NumberToString16(number).compare(u"1.123000"), 0);
+}
+
+TEST(StringUtilsTest, canNumberToString) {
+ float f = 1.123;
+ EXPECT_EQ(NumberToString(f).compare("1.123000"), 0);
+ unsigned int s = 11;
+ EXPECT_EQ(NumberToString(s).compare("11"), 0);
+ int32_t i = -23;
+ EXPECT_EQ(NumberToString(i).compare("-23"), 0);
+}
+
+} // namespace base
diff --git a/third_party/accessibility/build.gn b/third_party/accessibility/build.gn
new file mode 100644
index 0000000..08fc552
--- /dev/null
+++ b/third_party/accessibility/build.gn
@@ -0,0 +1,90 @@
+# Copyright 2013 The Flutter Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//flutter/common/config.gni")
+import("//flutter/testing/testing.gni")
+
+config("accessibility_config") {
+ visibility = [ ":*" ]
+ include_dirs = [ "//flutter/third_party/accessibility" ]
+}
+
+source_set("accessibility") {
+ defines = []
+
+ public_deps = [
+ "ax",
+ "ax_build",
+ "base",
+ "gfx",
+ ]
+
+ public_configs = [ ":accessibility_config" ]
+
+ if (is_mac) {
+ libs = [
+ "AppKit.framework",
+ "CoreFoundation.framework",
+ "CoreGraphics.framework",
+ "CoreText.framework",
+ "IOSurface.framework",
+ ]
+ }
+}
+
+if (enable_unittests) {
+ test_fixtures("accessibility_fixtures") {
+ fixtures = []
+ }
+
+ executable("accessibility_unittests") {
+ testonly = true
+
+ sources = [
+ "ax/ax_enum_util_unittest.cc",
+ "ax/ax_event_generator_unittest.cc",
+ "ax/ax_node_data_unittest.cc",
+ "ax/ax_node_position_unittest.cc",
+ "ax/ax_range_unittest.cc",
+ "ax/ax_role_properties_unittest.cc",
+ "ax/ax_table_info_unittest.cc",
+ "ax/ax_tree_unittest.cc",
+ "ax/test_ax_node_helper.cc",
+ "ax/test_ax_node_helper.h",
+ "ax/test_ax_tree_manager.cc",
+ "ax/test_ax_tree_manager.h",
+ ]
+
+ sources += [
+ "ax/platform/ax_platform_node_base_unittest.cc",
+ "ax/platform/ax_platform_node_unittest.cc",
+ "ax/platform/ax_platform_node_unittest.h",
+ "ax/platform/ax_unique_id_unittest.cc",
+ "ax/platform/test_ax_node_wrapper.cc",
+ "ax/platform/test_ax_node_wrapper.h",
+ ]
+
+ sources += [
+ "base/logging_unittests.cc",
+ "base/string_utils_unittest.cc",
+ ]
+
+ sources += [
+ "gfx/geometry/insets_unittest.cc",
+ "gfx/geometry/point_unittest.cc",
+ "gfx/geometry/rect_unittest.cc",
+ "gfx/geometry/size_unittest.cc",
+ "gfx/geometry/vector2d_unittest.cc",
+ "gfx/test/gfx_util.cc",
+ "gfx/test/gfx_util.h",
+ ]
+
+ deps = [
+ ":accessibility",
+ ":accessibility_fixtures",
+ "//flutter/testing",
+ "//flutter/testing:dart",
+ ]
+ }
+}
diff --git a/third_party/accessibility/gfx/BUILD.gn b/third_party/accessibility/gfx/BUILD.gn
new file mode 100644
index 0000000..df88fec
--- /dev/null
+++ b/third_party/accessibility/gfx/BUILD.gn
@@ -0,0 +1,57 @@
+# Copyright 2013 The Flutter Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//flutter/common/config.gni")
+
+source_set("gfx") {
+ visibility = [ "//flutter/third_party/accessibility/*" ]
+ include_dirs = [ "//flutter/third_party/accessibility" ]
+
+ sources = [
+ "geometry/insets.cc",
+ "geometry/insets.h",
+ "geometry/insets_f.cc",
+ "geometry/insets_f.h",
+ "geometry/point.cc",
+ "geometry/point.h",
+ "geometry/point_conversions.cc",
+ "geometry/point_conversions.h",
+ "geometry/point_f.cc",
+ "geometry/point_f.h",
+ "geometry/rect.cc",
+ "geometry/rect.h",
+ "geometry/rect_conversions.cc",
+ "geometry/rect_conversions.h",
+ "geometry/rect_f.cc",
+ "geometry/rect_f.h",
+ "geometry/size.cc",
+ "geometry/size.h",
+ "geometry/size_conversions.cc",
+ "geometry/size_conversions.h",
+ "geometry/size_f.cc",
+ "geometry/size_f.h",
+ "geometry/vector2d.cc",
+ "geometry/vector2d.h",
+ "geometry/vector2d_conversions.cc",
+ "geometry/vector2d_conversions.h",
+ "geometry/vector2d_f.cc",
+ "geometry/vector2d_f.h",
+ "gfx_export.h",
+ "native_widget_types.h",
+ "transform.cc",
+ "transform.h",
+ ]
+
+ if (is_mac) {
+ sources += [
+ "mac/coordinate_conversion.h",
+ "mac/coordinate_conversion.mm",
+ ]
+ }
+
+ deps = [
+ "//flutter/third_party/accessibility/ax_build",
+ "//flutter/third_party/accessibility/base",
+ ]
+}
diff --git a/third_party/accessibility/gfx/geometry/insets.cc b/third_party/accessibility/gfx/geometry/insets.cc
index 75a216c..33bb9ad 100644
--- a/third_party/accessibility/gfx/geometry/insets.cc
+++ b/third_party/accessibility/gfx/geometry/insets.cc
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/insets.h"
+#include "insets.h"
-#include "base/strings/stringprintf.h"
-#include "ui/gfx/geometry/vector2d.h"
+#include "base/string_utils.h"
+#include "vector2d.h"
namespace gfx {
diff --git a/third_party/accessibility/gfx/geometry/insets.h b/third_party/accessibility/gfx/geometry/insets.h
index 58ab1b7..d9aa779 100644
--- a/third_party/accessibility/gfx/geometry/insets.h
+++ b/third_party/accessibility/gfx/geometry/insets.h
@@ -7,10 +7,9 @@
#include <string>
-#include "base/numerics/clamped_math.h"
-#include "ui/gfx/geometry/geometry_export.h"
-#include "ui/gfx/geometry/insets_f.h"
-#include "ui/gfx/geometry/size.h"
+#include "gfx/gfx_export.h"
+#include "insets_f.h"
+#include "size.h"
namespace gfx {
@@ -23,7 +22,7 @@
// This can be used to represent a space within a rectangle, by "shrinking" the
// rectangle by the inset amount on all four sides. Alternatively, it can
// represent a border that has a different thickness on each side.
-class GEOMETRY_EXPORT Insets {
+class GFX_EXPORT Insets {
public:
constexpr Insets() : top_(0), left_(0), bottom_(0), right_(0) {}
constexpr explicit Insets(int all)
@@ -135,7 +134,7 @@
int bottom_;
int right_;
- // See ui/gfx/geometry/rect.h
+ // See rect.h
// Returns true iff a+b would overflow max int.
static constexpr bool AddWouldOverflow(int a, int b) {
// In this function, GCC tries to make optimizations that would only work if
diff --git a/third_party/accessibility/gfx/geometry/insets_f.cc b/third_party/accessibility/gfx/geometry/insets_f.cc
index efaebc3..30929c4 100644
--- a/third_party/accessibility/gfx/geometry/insets_f.cc
+++ b/third_party/accessibility/gfx/geometry/insets_f.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/insets_f.h"
+#include "insets_f.h"
-#include "base/strings/stringprintf.h"
+#include "base/string_utils.h"
namespace gfx {
diff --git a/third_party/accessibility/gfx/geometry/insets_f.h b/third_party/accessibility/gfx/geometry/insets_f.h
index bae68dd..2a85fb5 100644
--- a/third_party/accessibility/gfx/geometry/insets_f.h
+++ b/third_party/accessibility/gfx/geometry/insets_f.h
@@ -7,12 +7,12 @@
#include <string>
-#include "ui/gfx/geometry/geometry_export.h"
+#include "gfx/gfx_export.h"
namespace gfx {
// A floating point version of gfx::Insets.
-class GEOMETRY_EXPORT InsetsF {
+class GFX_EXPORT InsetsF {
public:
constexpr InsetsF() : top_(0.f), left_(0.f), bottom_(0.f), right_(0.f) {}
constexpr explicit InsetsF(float all)
diff --git a/third_party/accessibility/gfx/geometry/insets_unittest.cc b/third_party/accessibility/gfx/geometry/insets_unittest.cc
index eb49c17..4e17f30 100644
--- a/third_party/accessibility/gfx/geometry/insets_unittest.cc
+++ b/third_party/accessibility/gfx/geometry/insets_unittest.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/insets.h"
+#include "insets.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/insets_f.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/geometry/vector2d.h"
+#include "gtest/gtest.h"
+#include "insets_f.h"
+#include "rect.h"
+#include "size.h"
+#include "vector2d.h"
TEST(InsetsTest, InsetsDefault) {
gfx::Insets insets;
diff --git a/third_party/accessibility/gfx/geometry/point.cc b/third_party/accessibility/gfx/geometry/point.cc
index 522bbfd..8c8e8e9 100644
--- a/third_party/accessibility/gfx/geometry/point.cc
+++ b/third_party/accessibility/gfx/geometry/point.cc
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/point.h"
+#include "point.h"
-#include "base/strings/stringprintf.h"
-#include "build/build_config.h"
-#include "ui/gfx/geometry/point_conversions.h"
-#include "ui/gfx/geometry/point_f.h"
+#include "ax_build/build_config.h"
+#include "base/string_utils.h"
+#include "point_conversions.h"
+#include "point_f.h"
#if defined(OS_WIN)
#include <windows.h>
diff --git a/third_party/accessibility/gfx/geometry/point.h b/third_party/accessibility/gfx/geometry/point.h
index 06cb71b..1f865ea 100644
--- a/third_party/accessibility/gfx/geometry/point.h
+++ b/third_party/accessibility/gfx/geometry/point.h
@@ -9,10 +9,10 @@
#include <string>
#include <tuple>
+#include "ax_build/build_config.h"
#include "base/numerics/clamped_math.h"
-#include "build/build_config.h"
-#include "ui/gfx/geometry/geometry_export.h"
-#include "ui/gfx/geometry/vector2d.h"
+#include "gfx/gfx_export.h"
+#include "vector2d.h"
#if defined(OS_WIN)
typedef unsigned long DWORD;
@@ -24,7 +24,7 @@
namespace gfx {
// A point has an x and y coordinate.
-class GEOMETRY_EXPORT Point {
+class GFX_EXPORT Point {
public:
constexpr Point() : x_(0), y_(0) {}
constexpr Point(int x, int y) : x_(x), y_(y) {}
@@ -127,12 +127,12 @@
void PrintTo(const Point& point, ::std::ostream* os);
// Helper methods to scale a gfx::Point to a new gfx::Point.
-GEOMETRY_EXPORT Point ScaleToCeiledPoint(const Point& point, float x_scale, float y_scale);
-GEOMETRY_EXPORT Point ScaleToCeiledPoint(const Point& point, float x_scale);
-GEOMETRY_EXPORT Point ScaleToFlooredPoint(const Point& point, float x_scale, float y_scale);
-GEOMETRY_EXPORT Point ScaleToFlooredPoint(const Point& point, float x_scale);
-GEOMETRY_EXPORT Point ScaleToRoundedPoint(const Point& point, float x_scale, float y_scale);
-GEOMETRY_EXPORT Point ScaleToRoundedPoint(const Point& point, float x_scale);
+GFX_EXPORT Point ScaleToCeiledPoint(const Point& point, float x_scale, float y_scale);
+GFX_EXPORT Point ScaleToCeiledPoint(const Point& point, float x_scale);
+GFX_EXPORT Point ScaleToFlooredPoint(const Point& point, float x_scale, float y_scale);
+GFX_EXPORT Point ScaleToFlooredPoint(const Point& point, float x_scale);
+GFX_EXPORT Point ScaleToRoundedPoint(const Point& point, float x_scale, float y_scale);
+GFX_EXPORT Point ScaleToRoundedPoint(const Point& point, float x_scale);
} // namespace gfx
diff --git a/third_party/accessibility/gfx/geometry/point_conversions.cc b/third_party/accessibility/gfx/geometry/point_conversions.cc
index 42fb2f6..9f5e702 100644
--- a/third_party/accessibility/gfx/geometry/point_conversions.cc
+++ b/third_party/accessibility/gfx/geometry/point_conversions.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/point_conversions.h"
+#include "point_conversions.h"
#include "base/numerics/safe_conversions.h"
diff --git a/third_party/accessibility/gfx/geometry/point_conversions.h b/third_party/accessibility/gfx/geometry/point_conversions.h
index 894272c..8c97e13 100644
--- a/third_party/accessibility/gfx/geometry/point_conversions.h
+++ b/third_party/accessibility/gfx/geometry/point_conversions.h
@@ -5,19 +5,19 @@
#ifndef UI_GFX_GEOMETRY_POINT_CONVERSIONS_H_
#define UI_GFX_GEOMETRY_POINT_CONVERSIONS_H_
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/point_f.h"
+#include "point.h"
+#include "point_f.h"
namespace gfx {
// Returns a Point with each component from the input PointF floored.
-GEOMETRY_EXPORT Point ToFlooredPoint(const PointF& point);
+GFX_EXPORT Point ToFlooredPoint(const PointF& point);
// Returns a Point with each component from the input PointF ceiled.
-GEOMETRY_EXPORT Point ToCeiledPoint(const PointF& point);
+GFX_EXPORT Point ToCeiledPoint(const PointF& point);
// Returns a Point with each component from the input PointF rounded.
-GEOMETRY_EXPORT Point ToRoundedPoint(const PointF& point);
+GFX_EXPORT Point ToRoundedPoint(const PointF& point);
} // namespace gfx
diff --git a/third_party/accessibility/gfx/geometry/point_f.cc b/third_party/accessibility/gfx/geometry/point_f.cc
index 211fd7d..03caccb 100644
--- a/third_party/accessibility/gfx/geometry/point_f.cc
+++ b/third_party/accessibility/gfx/geometry/point_f.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/point_f.h"
+#include "point_f.h"
-#include "base/strings/stringprintf.h"
+#include "base/string_utils.h"
namespace gfx {
diff --git a/third_party/accessibility/gfx/geometry/point_f.h b/third_party/accessibility/gfx/geometry/point_f.h
index e2bff33..cec1a17 100644
--- a/third_party/accessibility/gfx/geometry/point_f.h
+++ b/third_party/accessibility/gfx/geometry/point_f.h
@@ -9,14 +9,14 @@
#include <string>
#include <tuple>
-#include "ui/gfx/geometry/geometry_export.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/vector2d_f.h"
+#include "gfx/gfx_export.h"
+#include "point.h"
+#include "vector2d_f.h"
namespace gfx {
// A floating version of gfx::Point.
-class GEOMETRY_EXPORT PointF {
+class GFX_EXPORT PointF {
public:
constexpr PointF() : x_(0.f), y_(0.f) {}
constexpr PointF(float x, float y) : x_(x), y_(y) {}
@@ -108,9 +108,7 @@
return PointF(offset_from_origin.x(), offset_from_origin.y());
}
-GEOMETRY_EXPORT PointF ScalePoint(const PointF& p,
- float x_scale,
- float y_scale);
+GFX_EXPORT PointF ScalePoint(const PointF& p, float x_scale, float y_scale);
inline PointF ScalePoint(const PointF& p, float scale) {
return ScalePoint(p, scale, scale);
diff --git a/third_party/accessibility/gfx/geometry/point_unittest.cc b/third_party/accessibility/gfx/geometry/point_unittest.cc
index b60800f..0057a6b 100644
--- a/third_party/accessibility/gfx/geometry/point_unittest.cc
+++ b/third_party/accessibility/gfx/geometry/point_unittest.cc
@@ -4,11 +4,10 @@
#include <stddef.h>
-#include "base/stl_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/point_conversions.h"
-#include "ui/gfx/geometry/point_f.h"
+#include "gtest/gtest.h"
+#include "point.h"
+#include "point_conversions.h"
+#include "point_f.h"
namespace gfx {
@@ -55,7 +54,7 @@
{Point(12, 1), a + v1 - v2},
{Point(-10, 9), a - v1 + v2}};
- for (size_t i = 0; i < base::size(tests); ++i)
+ for (size_t i = 0; i < 7; ++i)
EXPECT_EQ(tests[i].expected.ToString(), tests[i].actual.ToString());
}
diff --git a/third_party/accessibility/gfx/geometry/rect.cc b/third_party/accessibility/gfx/geometry/rect.cc
index f4e190a..4b90d7f 100644
--- a/third_party/accessibility/gfx/geometry/rect.cc
+++ b/third_party/accessibility/gfx/geometry/rect.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/rect.h"
+#include "rect.h"
#include <algorithm>
@@ -14,11 +14,11 @@
#include <ApplicationServices/ApplicationServices.h>
#endif
-#include "base/check.h"
+#include "ax_build/build_config.h"
+#include "base/logging.h"
#include "base/numerics/clamped_math.h"
-#include "base/strings/stringprintf.h"
-#include "build/build_config.h"
-#include "ui/gfx/geometry/insets.h"
+#include "base/string_utils.h"
+#include "insets.h"
namespace gfx {
@@ -258,8 +258,8 @@
}
void Rect::SplitVertically(Rect* left_half, Rect* right_half) const {
- DCHECK(left_half);
- DCHECK(right_half);
+ BASE_DCHECK(left_half);
+ BASE_DCHECK(right_half);
left_half->SetRect(x(), y(), width() / 2, height());
right_half->SetRect(left_half->right(), y(), width() - left_half->width(),
diff --git a/third_party/accessibility/gfx/geometry/rect.h b/third_party/accessibility/gfx/geometry/rect.h
index 5d600ad..f1d82f7 100644
--- a/third_party/accessibility/gfx/geometry/rect.h
+++ b/third_party/accessibility/gfx/geometry/rect.h
@@ -16,12 +16,12 @@
#include <iosfwd>
#include <string>
-#include "base/check.h"
+#include "ax_build/build_config.h"
+#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
-#include "build/build_config.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/geometry/vector2d.h"
+#include "point.h"
+#include "size.h"
+#include "vector2d.h"
#if defined(OS_WIN)
typedef struct tagRECT RECT;
@@ -33,7 +33,7 @@
class Insets;
-class GEOMETRY_EXPORT Rect {
+class GFX_EXPORT Rect {
public:
constexpr Rect() = default;
constexpr Rect(int width, int height) : size_(width, height) {}
@@ -244,16 +244,16 @@
return !(lhs == rhs);
}
-GEOMETRY_EXPORT Rect operator+(const Rect& lhs, const Vector2d& rhs);
-GEOMETRY_EXPORT Rect operator-(const Rect& lhs, const Vector2d& rhs);
+GFX_EXPORT Rect operator+(const Rect& lhs, const Vector2d& rhs);
+GFX_EXPORT Rect operator-(const Rect& lhs, const Vector2d& rhs);
inline Rect operator+(const Vector2d& lhs, const Rect& rhs) {
return rhs + lhs;
}
-GEOMETRY_EXPORT Rect IntersectRects(const Rect& a, const Rect& b);
-GEOMETRY_EXPORT Rect UnionRects(const Rect& a, const Rect& b);
-GEOMETRY_EXPORT Rect SubtractRects(const Rect& a, const Rect& b);
+GFX_EXPORT Rect IntersectRects(const Rect& a, const Rect& b);
+GFX_EXPORT Rect UnionRects(const Rect& a, const Rect& b);
+GFX_EXPORT Rect SubtractRects(const Rect& a, const Rect& b);
// Constructs a rectangle with |p1| and |p2| as opposite corners.
//
@@ -261,7 +261,7 @@
// points", except that we consider points on the right/bottom edges of the
// rect to be outside the rect. So technically one or both points will not be
// contained within the rect, because they will appear on one of these edges.
-GEOMETRY_EXPORT Rect BoundingRect(const Point& p1, const Point& p2);
+GFX_EXPORT Rect BoundingRect(const Point& p1, const Point& p2);
// Scales the rect and returns the enclosing rect. Use this only the inputs are
// known to not overflow. Use ScaleToEnclosingRectSafe if the inputs are
@@ -273,10 +273,10 @@
// we haven't checked to ensure that the clamping behavior of the helper
// functions doesn't degrade performance, and callers shouldn't be passing
// values that cause overflow anyway.
- DCHECK(base::IsValueInRangeForNumericType<int>(std::floor(rect.x() * x_scale)));
- DCHECK(base::IsValueInRangeForNumericType<int>(std::floor(rect.y() * y_scale)));
- DCHECK(base::IsValueInRangeForNumericType<int>(std::ceil(rect.right() * x_scale)));
- DCHECK(base::IsValueInRangeForNumericType<int>(std::ceil(rect.bottom() * y_scale)));
+ BASE_DCHECK(base::IsValueInRangeForNumericType<int>(std::floor(rect.x() * x_scale)));
+ BASE_DCHECK(base::IsValueInRangeForNumericType<int>(std::floor(rect.y() * y_scale)));
+ BASE_DCHECK(base::IsValueInRangeForNumericType<int>(std::ceil(rect.right() * x_scale)));
+ BASE_DCHECK(base::IsValueInRangeForNumericType<int>(std::ceil(rect.bottom() * y_scale)));
int x = static_cast<int>(std::floor(rect.x() * x_scale));
int y = static_cast<int>(std::floor(rect.y() * y_scale));
int r = rect.width() == 0 ? x : static_cast<int>(std::ceil(rect.right() * x_scale));
@@ -309,10 +309,10 @@
inline Rect ScaleToEnclosedRect(const Rect& rect, float x_scale, float y_scale) {
if (x_scale == 1.f && y_scale == 1.f)
return rect;
- DCHECK(base::IsValueInRangeForNumericType<int>(std::ceil(rect.x() * x_scale)));
- DCHECK(base::IsValueInRangeForNumericType<int>(std::ceil(rect.y() * y_scale)));
- DCHECK(base::IsValueInRangeForNumericType<int>(std::floor(rect.right() * x_scale)));
- DCHECK(base::IsValueInRangeForNumericType<int>(std::floor(rect.bottom() * y_scale)));
+ BASE_DCHECK(base::IsValueInRangeForNumericType<int>(std::ceil(rect.x() * x_scale)));
+ BASE_DCHECK(base::IsValueInRangeForNumericType<int>(std::ceil(rect.y() * y_scale)));
+ BASE_DCHECK(base::IsValueInRangeForNumericType<int>(std::floor(rect.right() * x_scale)));
+ BASE_DCHECK(base::IsValueInRangeForNumericType<int>(std::floor(rect.bottom() * y_scale)));
int x = static_cast<int>(std::ceil(rect.x() * x_scale));
int y = static_cast<int>(std::ceil(rect.y() * y_scale));
int r = rect.width() == 0 ? x : static_cast<int>(std::floor(rect.right() * x_scale));
@@ -334,10 +334,10 @@
if (x_scale == 1.f && y_scale == 1.f)
return rect;
- DCHECK(base::IsValueInRangeForNumericType<int>(std::round(rect.x() * x_scale)));
- DCHECK(base::IsValueInRangeForNumericType<int>(std::round(rect.y() * y_scale)));
- DCHECK(base::IsValueInRangeForNumericType<int>(std::round(rect.right() * x_scale)));
- DCHECK(base::IsValueInRangeForNumericType<int>(std::round(rect.bottom() * y_scale)));
+ BASE_DCHECK(base::IsValueInRangeForNumericType<int>(std::round(rect.x() * x_scale)));
+ BASE_DCHECK(base::IsValueInRangeForNumericType<int>(std::round(rect.y() * y_scale)));
+ BASE_DCHECK(base::IsValueInRangeForNumericType<int>(std::round(rect.right() * x_scale)));
+ BASE_DCHECK(base::IsValueInRangeForNumericType<int>(std::round(rect.bottom() * y_scale)));
int x = static_cast<int>(std::round(rect.x() * x_scale));
int y = static_cast<int>(std::round(rect.y() * y_scale));
diff --git a/third_party/accessibility/gfx/geometry/rect_conversions.cc b/third_party/accessibility/gfx/geometry/rect_conversions.cc
index 212318b..249a547 100644
--- a/third_party/accessibility/gfx/geometry/rect_conversions.cc
+++ b/third_party/accessibility/gfx/geometry/rect_conversions.cc
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/rect_conversions.h"
+#include "rect_conversions.h"
#include <algorithm>
#include <cmath>
-#include "base/check.h"
+#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
namespace gfx {
@@ -80,10 +80,10 @@
// If these DCHECKs fail, you're using the wrong method, consider using
// ToEnclosingRect or ToEnclosedRect instead.
- DCHECK(std::abs(min_x - float_min_x) < 0.01f);
- DCHECK(std::abs(min_y - float_min_y) < 0.01f);
- DCHECK(std::abs(max_x - float_max_x) < 0.01f);
- DCHECK(std::abs(max_y - float_max_y) < 0.01f);
+ BASE_DCHECK(std::abs(min_x - float_min_x) < 0.01f);
+ BASE_DCHECK(std::abs(min_y - float_min_y) < 0.01f);
+ BASE_DCHECK(std::abs(max_x - float_max_x) < 0.01f);
+ BASE_DCHECK(std::abs(max_y - float_max_y) < 0.01f);
Rect result;
result.SetByBounds(min_x, min_y, max_x, max_y);
diff --git a/third_party/accessibility/gfx/geometry/rect_conversions.h b/third_party/accessibility/gfx/geometry/rect_conversions.h
index 3460dcc..f24f7b2 100644
--- a/third_party/accessibility/gfx/geometry/rect_conversions.h
+++ b/third_party/accessibility/gfx/geometry/rect_conversions.h
@@ -5,50 +5,48 @@
#ifndef UI_GFX_GEOMETRY_RECT_CONVERSIONS_H_
#define UI_GFX_GEOMETRY_RECT_CONVERSIONS_H_
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/rect_f.h"
+#include "rect.h"
+#include "rect_f.h"
namespace gfx {
// Returns the smallest Rect that encloses the given RectF.
-GEOMETRY_EXPORT Rect ToEnclosingRect(const RectF& rect);
+GFX_EXPORT Rect ToEnclosingRect(const RectF& rect);
// Similar to ToEnclosingRect(), but for each edge, if the distance between the
// edge and the nearest integer grid is smaller than |error|, the edge is
// snapped to the integer grid. Unlike ToNearestRect() which only accepts
// integer rect with or without floating point error, this function also accepts
// non-integer rect.
-GEOMETRY_EXPORT Rect ToEnclosingRectIgnoringError(const RectF& rect,
- float error);
+GFX_EXPORT Rect ToEnclosingRectIgnoringError(const RectF& rect, float error);
// Returns the largest Rect that is enclosed by the given RectF.
-GEOMETRY_EXPORT Rect ToEnclosedRect(const RectF& rect);
+GFX_EXPORT Rect ToEnclosedRect(const RectF& rect);
// Similar to ToEnclosedRect(), but for each edge, if the distance between the
// edge and the nearest integer grid is smaller than |error|, the edge is
// snapped to the integer grid. Unlike ToNearestRect() which only accepts
// integer rect with or without floating point error, this function also accepts
// non-integer rect.
-GEOMETRY_EXPORT Rect ToEnclosedRectIgnoringError(const RectF& rect,
- float error);
+GFX_EXPORT Rect ToEnclosedRectIgnoringError(const RectF& rect, float error);
// Returns the Rect after snapping the corners of the RectF to an integer grid.
// This should only be used when the RectF you provide is expected to be an
// integer rect with floating point error. If it is an arbitrary RectF, then
// you should use a different method.
-GEOMETRY_EXPORT Rect ToNearestRect(const RectF& rect);
+GFX_EXPORT Rect ToNearestRect(const RectF& rect);
// Returns true if the Rect produced after snapping the corners of the RectF
// to an integer grid is withing |distance|.
-GEOMETRY_EXPORT bool IsNearestRectWithinDistance(const gfx::RectF& rect,
- float distance);
+GFX_EXPORT bool IsNearestRectWithinDistance(const gfx::RectF& rect,
+ float distance);
// Returns the Rect after rounding the corners of the RectF to an integer grid.
-GEOMETRY_EXPORT gfx::Rect ToRoundedRect(const gfx::RectF& rect);
+GFX_EXPORT gfx::Rect ToRoundedRect(const gfx::RectF& rect);
// Returns a Rect obtained by flooring the values of the given RectF.
// Please prefer the previous two functions in new code.
-GEOMETRY_EXPORT Rect ToFlooredRectDeprecated(const RectF& rect);
+GFX_EXPORT Rect ToFlooredRectDeprecated(const RectF& rect);
} // namespace gfx
diff --git a/third_party/accessibility/gfx/geometry/rect_f.cc b/third_party/accessibility/gfx/geometry/rect_f.cc
index fc26eea..71a7c31 100644
--- a/third_party/accessibility/gfx/geometry/rect_f.cc
+++ b/third_party/accessibility/gfx/geometry/rect_f.cc
@@ -2,16 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/rect_f.h"
+#include "rect_f.h"
#include <algorithm>
#include <limits>
-#include "base/check.h"
+#include "ax_build/build_config.h"
+#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "build/build_config.h"
-#include "ui/gfx/geometry/insets_f.h"
+#include "base/string_utils.h"
+#include "insets_f.h"
#if defined(OS_IOS)
#include <CoreGraphics/CoreGraphics.h>
@@ -185,8 +185,8 @@
}
void RectF::SplitVertically(RectF* left_half, RectF* right_half) const {
- DCHECK(left_half);
- DCHECK(right_half);
+ BASE_DCHECK(left_half);
+ BASE_DCHECK(right_half);
left_half->SetRect(x(), y(), width() / 2, height());
right_half->SetRect(left_half->right(), y(), width() - left_half->width(),
diff --git a/third_party/accessibility/gfx/geometry/rect_f.h b/third_party/accessibility/gfx/geometry/rect_f.h
index cf41fc4..bb48df4 100644
--- a/third_party/accessibility/gfx/geometry/rect_f.h
+++ b/third_party/accessibility/gfx/geometry/rect_f.h
@@ -8,11 +8,11 @@
#include <iosfwd>
#include <string>
-#include "build/build_config.h"
-#include "ui/gfx/geometry/point_f.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size_f.h"
-#include "ui/gfx/geometry/vector2d_f.h"
+#include "ax_build/build_config.h"
+#include "point_f.h"
+#include "rect.h"
+#include "size_f.h"
+#include "vector2d_f.h"
#if defined(OS_APPLE)
typedef struct CGRect CGRect;
@@ -23,7 +23,7 @@
class InsetsF;
// A floating version of gfx::Rect.
-class GEOMETRY_EXPORT RectF {
+class GFX_EXPORT RectF {
public:
constexpr RectF() = default;
constexpr RectF(float width, float height) : size_(width, height) {}
@@ -212,9 +212,9 @@
return rhs + lhs;
}
-GEOMETRY_EXPORT RectF IntersectRects(const RectF& a, const RectF& b);
-GEOMETRY_EXPORT RectF UnionRects(const RectF& a, const RectF& b);
-GEOMETRY_EXPORT RectF SubtractRects(const RectF& a, const RectF& b);
+GFX_EXPORT RectF IntersectRects(const RectF& a, const RectF& b);
+GFX_EXPORT RectF UnionRects(const RectF& a, const RectF& b);
+GFX_EXPORT RectF SubtractRects(const RectF& a, const RectF& b);
inline RectF ScaleRect(const RectF& r, float x_scale, float y_scale) {
return RectF(r.x() * x_scale, r.y() * y_scale, r.width() * x_scale, r.height() * y_scale);
@@ -230,7 +230,7 @@
// points", except that we consider points on the right/bottom edges of the
// rect to be outside the rect. So technically one or both points will not be
// contained within the rect, because they will appear on one of these edges.
-GEOMETRY_EXPORT RectF BoundingRect(const PointF& p1, const PointF& p2);
+GFX_EXPORT RectF BoundingRect(const PointF& p1, const PointF& p2);
// This is declared here for use in gtest-based unit tests but is defined in
// the //ui/gfx:test_support target. Depend on that to use this in your unit
diff --git a/third_party/accessibility/gfx/geometry/rect_unittest.cc b/third_party/accessibility/gfx/geometry/rect_unittest.cc
index 699d4d1..0f91a98 100644
--- a/third_party/accessibility/gfx/geometry/rect_unittest.cc
+++ b/third_party/accessibility/gfx/geometry/rect_unittest.cc
@@ -6,12 +6,11 @@
#include <stddef.h>
-#include "base/stl_util.h"
-#include "build/build_config.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/test/gfx_util.h"
+#include "ax_build/build_config.h"
+#include "gfx/test/gfx_util.h"
+#include "gtest/gtest.h"
+#include "rect.h"
+#include "rect_conversions.h"
#if defined(OS_WIN)
#include <windows.h>
@@ -19,6 +18,11 @@
namespace gfx {
+template <typename T, size_t N>
+constexpr size_t size(const T (&array)[N]) noexcept {
+ return N;
+}
+
TEST(RectTest, Contains) {
static const struct ContainsCase {
int rect_x;
@@ -40,7 +44,7 @@
{0, 0, -10, -10, 0, 0, false},
#endif
};
- for (size_t i = 0; i < base::size(contains_cases); ++i) {
+ for (size_t i = 0; i < size(contains_cases); ++i) {
const ContainsCase& value = contains_cases[i];
Rect rect(value.rect_x, value.rect_y, value.rect_width, value.rect_height);
EXPECT_EQ(value.contained, rect.Contains(value.point_x, value.point_y));
@@ -68,7 +72,7 @@
{10, 10, 10, 10, 15, 15, 10, 10, true},
{10, 10, 10, 10, 20, 15, 10, 10, false},
{10, 10, 10, 10, 21, 15, 10, 10, false}};
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < size(tests); ++i) {
Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
EXPECT_EQ(tests[i].intersects, r1.Intersects(r2));
@@ -102,7 +106,7 @@
3, 1, 4, 2, 3, 1, 1, 2},
{3, 0, 2, 2, // gap
0, 0, 2, 2, 0, 0, 0, 0}};
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < size(tests); ++i) {
Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3);
@@ -137,7 +141,7 @@
0, 0, 2, 2, 0, 0, 5, 5},
{0, 0, 0, 0, // union with empty rect
2, 2, 2, 2, 2, 2, 2, 2}};
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < size(tests); ++i) {
Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3);
@@ -177,7 +181,7 @@
{-1, -1, 5, 5, 0, 0, 4, 4, 0, 0, 4, 4},
{2, 2, 4, 4, 0, 0, 3, 3, 0, 0, 3, 3},
{2, 2, 1, 1, 0, 0, 3, 3, 2, 2, 1, 1}};
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < size(tests); ++i) {
Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3);
@@ -416,7 +420,7 @@
std::numeric_limits<float>::max(), std::numeric_limits<float>::max(),
std::numeric_limits<float>::max(), std::numeric_limits<float>::max()}};
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < size(tests); ++i) {
RectF r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
RectF r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
@@ -460,7 +464,7 @@
{{1.9999f, 2.0001f, 6.0002f, 5.9998f}, {2, 3, 6, 4}},
{{1.9998f, 2.0002f, 6.0001f, 5.9999f}, {2, 3, 5, 5}}};
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < size(tests); ++i) {
RectF source(tests[i].in.x, tests[i].in.y, tests[i].in.width,
tests[i].in.height);
Rect enclosed = ToEnclosedRect(source);
@@ -523,7 +527,7 @@
{{1.9999f, 2.0001f, 6.0002f, 5.9998f}, {1, 2, 8, 6}},
{{1.9998f, 2.0002f, 6.0001f, 5.9999f}, {1, 2, 7, 7}}};
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < size(tests); ++i) {
RectF source(tests[i].in.x, tests[i].in.y, tests[i].in.width,
tests[i].in.height);
@@ -585,7 +589,7 @@
{{1.9999f, 2.0001f, 6.0002f, 5.9998f}, {2, 2, 6, 6}},
{{1.9998f, 2.0002f, 6.0001f, 5.9999f}, {2, 2, 6, 6}}};
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < size(tests); ++i) {
RectF source(tests[i].in.x, tests[i].in.y, tests[i].in.width,
tests[i].in.height);
@@ -625,7 +629,7 @@
{20000.5f, 20000.5f, 0.5f, 0.5f, 20000, 20000, 0, 0},
};
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < size(tests); ++i) {
RectF r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
@@ -678,7 +682,7 @@
Rect(-1, -3, 0, 0),
}};
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < size(tests); ++i) {
Rect result =
ScaleToEnclosedRect(tests[i].input_rect, tests[i].input_scale);
EXPECT_EQ(tests[i].expected_rect, result);
@@ -726,7 +730,7 @@
Rect(-2, -3, 0, 0),
}};
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < size(tests); ++i) {
Rect result =
ScaleToEnclosingRect(tests[i].input_rect, tests[i].input_scale);
EXPECT_EQ(tests[i].expected_rect, result);
@@ -777,7 +781,7 @@
{Point(-4, 6), Point(6, -4), Rect(-4, -4, 10, 10)},
};
- for (size_t i = 0; i < base::size(int_tests); ++i) {
+ for (size_t i = 0; i < size(int_tests); ++i) {
Rect actual = BoundingRect(int_tests[i].a, int_tests[i].b);
EXPECT_EQ(int_tests[i].expected, actual);
}
@@ -805,7 +809,7 @@
{PointF(-4.2f, 6.8f), PointF(6.8f, -4.2f),
RectF(-4.2f, -4.2f, 11.0f, 11.0f)}};
- for (size_t i = 0; i < base::size(float_tests); ++i) {
+ for (size_t i = 0; i < size(float_tests); ++i) {
RectF actual = BoundingRect(float_tests[i].a, float_tests[i].b);
EXPECT_RECTF_EQ(float_tests[i].expected, actual);
}
diff --git a/third_party/accessibility/gfx/geometry/size.cc b/third_party/accessibility/gfx/geometry/size.cc
index 761b246..8e95fe8 100644
--- a/third_party/accessibility/gfx/geometry/size.cc
+++ b/third_party/accessibility/gfx/geometry/size.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/size.h"
+#include "size.h"
#if defined(OS_WIN)
#include <windows.h>
@@ -12,11 +12,11 @@
#include <ApplicationServices/ApplicationServices.h>
#endif
+#include "ax_build/build_config.h"
#include "base/numerics/clamped_math.h"
#include "base/numerics/safe_math.h"
-#include "base/strings/stringprintf.h"
-#include "build/build_config.h"
-#include "ui/gfx/geometry/size_conversions.h"
+#include "base/string_utils.h"
+#include "size_conversions.h"
namespace gfx {
diff --git a/third_party/accessibility/gfx/geometry/size.h b/third_party/accessibility/gfx/geometry/size.h
index 7866834..d5162b0 100644
--- a/third_party/accessibility/gfx/geometry/size.h
+++ b/third_party/accessibility/gfx/geometry/size.h
@@ -9,10 +9,10 @@
#include <iosfwd>
#include <string>
+#include "ax_build/build_config.h"
#include "base/compiler_specific.h"
#include "base/numerics/safe_math.h"
-#include "build/build_config.h"
-#include "ui/gfx/geometry/geometry_export.h"
+#include "gfx/gfx_export.h"
#if defined(OS_WIN)
typedef struct tagSIZE SIZE;
@@ -23,7 +23,7 @@
namespace gfx {
// A size has width and height values.
-class GEOMETRY_EXPORT Size {
+class GFX_EXPORT Size {
public:
constexpr Size() : width_(0), height_(0) {}
constexpr Size(int width, int height)
@@ -100,12 +100,12 @@
void PrintTo(const Size& size, ::std::ostream* os);
// Helper methods to scale a gfx::Size to a new gfx::Size.
-GEOMETRY_EXPORT Size ScaleToCeiledSize(const Size& size, float x_scale, float y_scale);
-GEOMETRY_EXPORT Size ScaleToCeiledSize(const Size& size, float scale);
-GEOMETRY_EXPORT Size ScaleToFlooredSize(const Size& size, float x_scale, float y_scale);
-GEOMETRY_EXPORT Size ScaleToFlooredSize(const Size& size, float scale);
-GEOMETRY_EXPORT Size ScaleToRoundedSize(const Size& size, float x_scale, float y_scale);
-GEOMETRY_EXPORT Size ScaleToRoundedSize(const Size& size, float scale);
+GFX_EXPORT Size ScaleToCeiledSize(const Size& size, float x_scale, float y_scale);
+GFX_EXPORT Size ScaleToCeiledSize(const Size& size, float scale);
+GFX_EXPORT Size ScaleToFlooredSize(const Size& size, float x_scale, float y_scale);
+GFX_EXPORT Size ScaleToFlooredSize(const Size& size, float scale);
+GFX_EXPORT Size ScaleToRoundedSize(const Size& size, float x_scale, float y_scale);
+GFX_EXPORT Size ScaleToRoundedSize(const Size& size, float scale);
} // namespace gfx
diff --git a/third_party/accessibility/gfx/geometry/size_conversions.cc b/third_party/accessibility/gfx/geometry/size_conversions.cc
index 0c995ca..75be628 100644
--- a/third_party/accessibility/gfx/geometry/size_conversions.cc
+++ b/third_party/accessibility/gfx/geometry/size_conversions.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/size_conversions.h"
+#include "size_conversions.h"
#include "base/numerics/safe_conversions.h"
diff --git a/third_party/accessibility/gfx/geometry/size_conversions.h b/third_party/accessibility/gfx/geometry/size_conversions.h
index 6bc74c0..c138544 100644
--- a/third_party/accessibility/gfx/geometry/size_conversions.h
+++ b/third_party/accessibility/gfx/geometry/size_conversions.h
@@ -5,19 +5,19 @@
#ifndef UI_GFX_GEOMETRY_SIZE_CONVERSIONS_H_
#define UI_GFX_GEOMETRY_SIZE_CONVERSIONS_H_
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/geometry/size_f.h"
+#include "size.h"
+#include "size_f.h"
namespace gfx {
// Returns a Size with each component from the input SizeF floored.
-GEOMETRY_EXPORT Size ToFlooredSize(const SizeF& size);
+GFX_EXPORT Size ToFlooredSize(const SizeF& size);
// Returns a Size with each component from the input SizeF ceiled.
-GEOMETRY_EXPORT Size ToCeiledSize(const SizeF& size);
+GFX_EXPORT Size ToCeiledSize(const SizeF& size);
// Returns a Size with each component from the input SizeF rounded.
-GEOMETRY_EXPORT Size ToRoundedSize(const SizeF& size);
+GFX_EXPORT Size ToRoundedSize(const SizeF& size);
} // namespace gfx
diff --git a/third_party/accessibility/gfx/geometry/size_f.cc b/third_party/accessibility/gfx/geometry/size_f.cc
index 6d08e18..6e38bf0 100644
--- a/third_party/accessibility/gfx/geometry/size_f.cc
+++ b/third_party/accessibility/gfx/geometry/size_f.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/size_f.h"
+#include "size_f.h"
-#include "base/strings/stringprintf.h"
+#include "base/string_utils.h"
namespace gfx {
diff --git a/third_party/accessibility/gfx/geometry/size_f.h b/third_party/accessibility/gfx/geometry/size_f.h
index 21e5950..b1f3337 100644
--- a/third_party/accessibility/gfx/geometry/size_f.h
+++ b/third_party/accessibility/gfx/geometry/size_f.h
@@ -9,18 +9,13 @@
#include <string>
#include "base/compiler_specific.h"
-#include "base/gtest_prod_util.h"
-#include "ui/gfx/geometry/geometry_export.h"
-#include "ui/gfx/geometry/size.h"
+#include "gfx/gfx_export.h"
+#include "size.h"
namespace gfx {
-FORWARD_DECLARE_TEST(SizeTest, TrivialDimensionTests);
-FORWARD_DECLARE_TEST(SizeTest, ClampsToZero);
-FORWARD_DECLARE_TEST(SizeTest, ConsistentClamping);
-
// A floating version of gfx::Size.
-class GEOMETRY_EXPORT SizeF {
+class GFX_EXPORT SizeF {
public:
constexpr SizeF() : width_(0.f), height_(0.f) {}
constexpr SizeF(float width, float height)
@@ -59,10 +54,6 @@
std::string ToString() const;
private:
- FRIEND_TEST_ALL_PREFIXES(SizeTest, TrivialDimensionTests);
- FRIEND_TEST_ALL_PREFIXES(SizeTest, ClampsToZero);
- FRIEND_TEST_ALL_PREFIXES(SizeTest, ConsistentClamping);
-
static constexpr float kTrivial = 8.f * std::numeric_limits<float>::epsilon();
static constexpr float clamp(float f) { return f > kTrivial ? f : 0.f; }
@@ -79,7 +70,7 @@
return !(lhs == rhs);
}
-GEOMETRY_EXPORT SizeF ScaleSize(const SizeF& p, float x_scale, float y_scale);
+GFX_EXPORT SizeF ScaleSize(const SizeF& p, float x_scale, float y_scale);
inline SizeF ScaleSize(const SizeF& p, float scale) {
return ScaleSize(p, scale, scale);
diff --git a/third_party/accessibility/gfx/geometry/size_unittest.cc b/third_party/accessibility/gfx/geometry/size_unittest.cc
index 46958db..e025482 100644
--- a/third_party/accessibility/gfx/geometry/size_unittest.cc
+++ b/third_party/accessibility/gfx/geometry/size_unittest.cc
@@ -2,15 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/size.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/size_conversions.h"
-#include "ui/gfx/geometry/size_f.h"
+#include "size.h"
+#include "gtest/gtest.h"
+#include "size_conversions.h"
+#include "size_f.h"
namespace gfx {
namespace {
+static constexpr float kTrivial = 8.f * std::numeric_limits<float>::epsilon();
+
int TestSizeF(const SizeF& s) {
return s.width();
}
@@ -155,7 +157,7 @@
// This checks that we set IsEmpty appropriately.
TEST(SizeTest, TrivialDimensionTests) {
- const float clearly_trivial = SizeF::kTrivial / 2.f;
+ const float clearly_trivial = kTrivial / 2.f;
const float massize_dimension = 4e13f;
// First, using the constructor.
@@ -199,8 +201,8 @@
// These are the ramifications of the decision to keep the recorded size
// at zero for trivial sizes.
TEST(SizeTest, ClampsToZero) {
- const float clearly_trivial = SizeF::kTrivial / 2.f;
- const float nearly_trivial = SizeF::kTrivial * 1.5f;
+ const float clearly_trivial = kTrivial / 2.f;
+ const float nearly_trivial = kTrivial * 1.5f;
SizeF test(clearly_trivial, 1.f);
@@ -235,11 +237,11 @@
TEST(SizeTest, ConsistentClamping) {
SizeF resized;
- resized.SetSize(SizeF::kTrivial, 0.f);
- EXPECT_EQ(SizeF(SizeF::kTrivial, 0.f), resized);
+ resized.SetSize(kTrivial, 0.f);
+ EXPECT_EQ(SizeF(kTrivial, 0.f), resized);
- resized.SetSize(0.f, SizeF::kTrivial);
- EXPECT_EQ(SizeF(0.f, SizeF::kTrivial), resized);
+ resized.SetSize(0.f, kTrivial);
+ EXPECT_EQ(SizeF(0.f, kTrivial), resized);
}
// Let's make sure we don't unexpectedly grow the struct by adding constants.
diff --git a/third_party/accessibility/gfx/geometry/vector2d.cc b/third_party/accessibility/gfx/geometry/vector2d.cc
index 0ce3b20..6dbf41e 100644
--- a/third_party/accessibility/gfx/geometry/vector2d.cc
+++ b/third_party/accessibility/gfx/geometry/vector2d.cc
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/vector2d.h"
+#include "vector2d.h"
#include <cmath>
#include "base/numerics/clamped_math.h"
-#include "base/strings/stringprintf.h"
+#include "base/string_utils.h"
namespace gfx {
diff --git a/third_party/accessibility/gfx/geometry/vector2d.h b/third_party/accessibility/gfx/geometry/vector2d.h
index 3d9c60d..64f6ffb 100644
--- a/third_party/accessibility/gfx/geometry/vector2d.h
+++ b/third_party/accessibility/gfx/geometry/vector2d.h
@@ -15,12 +15,12 @@
#include <iosfwd>
#include <string>
-#include "ui/gfx/geometry/geometry_export.h"
-#include "ui/gfx/geometry/vector2d_f.h"
+#include "gfx/gfx_export.h"
+#include "vector2d_f.h"
namespace gfx {
-class GEOMETRY_EXPORT Vector2d {
+class GFX_EXPORT Vector2d {
public:
constexpr Vector2d() : x_(0), y_(0) {}
constexpr Vector2d(int x, int y) : x_(x), y_(y) {}
diff --git a/third_party/accessibility/gfx/geometry/vector2d_conversions.cc b/third_party/accessibility/gfx/geometry/vector2d_conversions.cc
index a7c5b42..6a2e7f3 100644
--- a/third_party/accessibility/gfx/geometry/vector2d_conversions.cc
+++ b/third_party/accessibility/gfx/geometry/vector2d_conversions.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/vector2d_conversions.h"
+#include "vector2d_conversions.h"
#include "base/numerics/safe_conversions.h"
diff --git a/third_party/accessibility/gfx/geometry/vector2d_conversions.h b/third_party/accessibility/gfx/geometry/vector2d_conversions.h
index 055ebd0..0e0d88e 100644
--- a/third_party/accessibility/gfx/geometry/vector2d_conversions.h
+++ b/third_party/accessibility/gfx/geometry/vector2d_conversions.h
@@ -5,19 +5,19 @@
#ifndef UI_GFX_GEOMETRY_VECTOR2D_CONVERSIONS_H_
#define UI_GFX_GEOMETRY_VECTOR2D_CONVERSIONS_H_
-#include "ui/gfx/geometry/vector2d.h"
-#include "ui/gfx/geometry/vector2d_f.h"
+#include "vector2d.h"
+#include "vector2d_f.h"
namespace gfx {
// Returns a Vector2d with each component from the input Vector2dF floored.
-GEOMETRY_EXPORT Vector2d ToFlooredVector2d(const Vector2dF& vector2d);
+GFX_EXPORT Vector2d ToFlooredVector2d(const Vector2dF& vector2d);
// Returns a Vector2d with each component from the input Vector2dF ceiled.
-GEOMETRY_EXPORT Vector2d ToCeiledVector2d(const Vector2dF& vector2d);
+GFX_EXPORT Vector2d ToCeiledVector2d(const Vector2dF& vector2d);
// Returns a Vector2d with each component from the input Vector2dF rounded.
-GEOMETRY_EXPORT Vector2d ToRoundedVector2d(const Vector2dF& vector2d);
+GFX_EXPORT Vector2d ToRoundedVector2d(const Vector2dF& vector2d);
} // namespace gfx
diff --git a/third_party/accessibility/gfx/geometry/vector2d_f.cc b/third_party/accessibility/gfx/geometry/vector2d_f.cc
index f59cdd5..3cb7d0a 100644
--- a/third_party/accessibility/gfx/geometry/vector2d_f.cc
+++ b/third_party/accessibility/gfx/geometry/vector2d_f.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/geometry/vector2d_f.h"
+#include "vector2d_f.h"
#include <cmath>
-#include "base/strings/stringprintf.h"
+#include "base/string_utils.h"
namespace gfx {
diff --git a/third_party/accessibility/gfx/geometry/vector2d_f.h b/third_party/accessibility/gfx/geometry/vector2d_f.h
index 28128bd..3d56789 100644
--- a/third_party/accessibility/gfx/geometry/vector2d_f.h
+++ b/third_party/accessibility/gfx/geometry/vector2d_f.h
@@ -13,11 +13,11 @@
#include <iosfwd>
#include <string>
-#include "ui/gfx/geometry/geometry_export.h"
+#include "gfx/gfx_export.h"
namespace gfx {
-class GEOMETRY_EXPORT Vector2dF {
+class GFX_EXPORT Vector2dF {
public:
constexpr Vector2dF() : x_(0), y_(0) {}
constexpr Vector2dF(float x, float y) : x_(x), y_(y) {}
@@ -92,16 +92,16 @@
}
// Return the cross product of two vectors.
-GEOMETRY_EXPORT double CrossProduct(const Vector2dF& lhs, const Vector2dF& rhs);
+GFX_EXPORT double CrossProduct(const Vector2dF& lhs, const Vector2dF& rhs);
// Return the dot product of two vectors.
-GEOMETRY_EXPORT double DotProduct(const Vector2dF& lhs, const Vector2dF& rhs);
+GFX_EXPORT double DotProduct(const Vector2dF& lhs, const Vector2dF& rhs);
// Return a vector that is |v| scaled by the given scale factors along each
// axis.
-GEOMETRY_EXPORT Vector2dF ScaleVector2d(const Vector2dF& v,
- float x_scale,
- float y_scale);
+GFX_EXPORT Vector2dF ScaleVector2d(const Vector2dF& v,
+ float x_scale,
+ float y_scale);
// Return a vector that is |v| scaled by the given scale factor.
inline Vector2dF ScaleVector2d(const Vector2dF& v, float scale) {
diff --git a/third_party/accessibility/gfx/geometry/vector2d_unittest.cc b/third_party/accessibility/gfx/geometry/vector2d_unittest.cc
index 286ec35..db1cd01 100644
--- a/third_party/accessibility/gfx/geometry/vector2d_unittest.cc
+++ b/third_party/accessibility/gfx/geometry/vector2d_unittest.cc
@@ -7,13 +7,17 @@
#include <cmath>
#include <limits>
-#include "base/stl_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/vector2d.h"
-#include "ui/gfx/geometry/vector2d_f.h"
+#include "gtest/gtest.h"
+#include "vector2d.h"
+#include "vector2d_f.h"
namespace gfx {
+template <typename T, size_t N>
+constexpr size_t size(const T (&array)[N]) noexcept {
+ return N;
+}
+
TEST(Vector2dTest, ConversionToFloat) {
Vector2d i(3, 4);
Vector2dF f = i;
@@ -43,7 +47,7 @@
{Vector2d(3 + 4, 5 - 1), i1 + i2},
{Vector2d(3 - 4, 5 + 1), i1 - i2}};
- for (size_t i = 0; i < base::size(int_tests); ++i)
+ for (size_t i = 0; i < size(int_tests); ++i)
EXPECT_EQ(int_tests[i].expected.ToString(), int_tests[i].actual.ToString());
Vector2dF f1(3.1f, 5.1f);
@@ -57,7 +61,7 @@
{Vector2dF(3.1f + 4.3f, 5.1f - 1.3f), f1 + f2},
{Vector2dF(3.1f - 4.3f, 5.1f + 1.3f), f1 - f2}};
- for (size_t i = 0; i < base::size(float_tests); ++i)
+ for (size_t i = 0; i < size(float_tests); ++i)
EXPECT_EQ(float_tests[i].expected.ToString(),
float_tests[i].actual.ToString());
}
@@ -72,7 +76,7 @@
{Vector2d(-3, 3), -Vector2d(3, -3)},
{Vector2d(3, -3), -Vector2d(-3, 3)}};
- for (size_t i = 0; i < base::size(int_tests); ++i)
+ for (size_t i = 0; i < size(int_tests); ++i)
EXPECT_EQ(int_tests[i].expected.ToString(), int_tests[i].actual.ToString());
const struct {
@@ -84,7 +88,7 @@
{Vector2dF(-0.3f, 0.3f), -Vector2dF(0.3f, -0.3f)},
{Vector2dF(0.3f, -0.3f), -Vector2dF(-0.3f, 0.3f)}};
- for (size_t i = 0; i < base::size(float_tests); ++i)
+ for (size_t i = 0; i < size(float_tests); ++i)
EXPECT_EQ(float_tests[i].expected.ToString(),
float_tests[i].actual.ToString());
}
@@ -97,7 +101,7 @@
{-4.5f, 1.2f, 3.3f, 0}, {4.5f, 0, 3.3f, 5.6f},
{0, 1.2f, 3.3f, 5.6f}};
- for (size_t i = 0; i < base::size(double_values); ++i) {
+ for (size_t i = 0; i < size(double_values); ++i) {
Vector2dF v(double_values[i][0], double_values[i][1]);
v.Scale(double_values[i][2], double_values[i][3]);
EXPECT_EQ(v.x(), double_values[i][0] * double_values[i][2]);
@@ -115,7 +119,7 @@
{4.5f, 1.2f, -3.3f}, {-4.5f, 1.2f, 3.3f}, {-4.5f, 1.2f, 0},
{-4.5f, 1.2f, 3.3f}, {4.5f, 0, 3.3f}, {0, 1.2f, 3.3f}};
- for (size_t i = 0; i < base::size(single_values); ++i) {
+ for (size_t i = 0; i < size(single_values); ++i) {
Vector2dF v(single_values[i][0], single_values[i][1]);
v.Scale(single_values[i][2]);
EXPECT_EQ(v.x(), single_values[i][0] * single_values[i][2]);
@@ -134,7 +138,7 @@
{0, 0}, {10, 20}, {20, 10}, {-10, -20}, {-20, 10}, {10, -20},
};
- for (size_t i = 0; i < base::size(int_values); ++i) {
+ for (size_t i = 0; i < size(int_values); ++i) {
int v0 = int_values[i][0];
int v1 = int_values[i][1];
double length_squared =
@@ -158,7 +162,7 @@
335890352589839028212313231225425134332.38123f},
};
- for (size_t i = 0; i < base::size(float_values); ++i) {
+ for (size_t i = 0; i < size(float_values); ++i) {
double v0 = float_values[i][0];
double v1 = float_values[i][1];
double length_squared =
diff --git a/third_party/accessibility/gfx/mac/coordinate_conversion.h b/third_party/accessibility/gfx/mac/coordinate_conversion.h
index 3b75485..15b7f40 100644
--- a/third_party/accessibility/gfx/mac/coordinate_conversion.h
+++ b/third_party/accessibility/gfx/mac/coordinate_conversion.h
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_GFX_MAC_COORDINATE_CONVERSION_H_
-#define UI_GFX_MAC_COORDINATE_CONVERSION_H_
+#ifndef ACCESSIBILITY_GFX_MAC_COORDINATE_CONVERSION_H_
+#define ACCESSIBILITY_GFX_MAC_COORDINATE_CONVERSION_H_
#import <Foundation/Foundation.h>
-#include "ui/gfx/gfx_export.h"
+#include "gfx/gfx_export.h"
namespace gfx {
@@ -17,19 +17,16 @@
// Convert a gfx::Rect specified with the origin at the top left of the primary
// display into AppKit secreen coordinates (origin at the bottom left).
GFX_EXPORT NSRect ScreenRectToNSRect(const Rect& rect);
-
// Convert an AppKit NSRect with origin in the bottom left of the primary
// display into a gfx::Rect with origin at the top left of the primary display.
GFX_EXPORT Rect ScreenRectFromNSRect(const NSRect& point);
-
// Convert a gfx::Point specified with the origin at the top left of the primary
// display into AppKit screen coordinates (origin at the bottom left).
GFX_EXPORT NSPoint ScreenPointToNSPoint(const Point& point);
-
// Convert an AppKit NSPoint with origin in the bottom left of the primary
// display into a gfx::Point with origin at the top left of the primary display.
GFX_EXPORT Point ScreenPointFromNSPoint(const NSPoint& point);
} // namespace gfx
-#endif // UI_GFX_MAC_COORDINATE_CONVERSION_H_
+#endif // ACCESSIBILITY_GFX_MAC_COORDINATE_CONVERSION_H_
diff --git a/third_party/accessibility/gfx/mac/coordinate_conversion.mm b/third_party/accessibility/gfx/mac/coordinate_conversion.mm
index 916bb5d..04080a5 100644
--- a/third_party/accessibility/gfx/mac/coordinate_conversion.mm
+++ b/third_party/accessibility/gfx/mac/coordinate_conversion.mm
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#import "ui/gfx/mac/coordinate_conversion.h"
+#import "coordinate_conversion.h"
#import <Cocoa/Cocoa.h>
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/rect.h"
+#include "gfx/geometry/point.h"
+#include "gfx/geometry/rect.h"
namespace gfx {
diff --git a/third_party/accessibility/gfx/native_widget_types.h b/third_party/accessibility/gfx/native_widget_types.h
index f823bb3..8c54797 100644
--- a/third_party/accessibility/gfx/native_widget_types.h
+++ b/third_party/accessibility/gfx/native_widget_types.h
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_GFX_NATIVE_WIDGET_TYPES_H_
-#define UI_GFX_NATIVE_WIDGET_TYPES_H_
+#ifndef ACCESSIBILITY_GFX_NATIVE_WIDGET_TYPES_H_
+#define ACCESSIBILITY_GFX_NATIVE_WIDGET_TYPES_H_
#include <stdint.h>
-#include "build/build_config.h"
-#include "ui/gfx/gfx_export.h"
+#include "ax_build/build_config.h"
+#include "gfx/gfx_export.h"
#if defined(OS_ANDROID)
#include "base/android/scoped_java_ref.h"
@@ -182,8 +182,8 @@
private:
NSWindow* ns_window_ = nullptr;
};
-constexpr NativeView kNullNativeView = NativeView(nullptr);
-constexpr NativeWindow kNullNativeWindow = NativeWindow(nullptr);
+const NativeView kNullNativeView = NativeView(nullptr);
+const NativeWindow kNullNativeWindow = NativeWindow(nullptr);
#elif defined(OS_ANDROID)
typedef void* NativeCursor;
typedef ui::ViewAndroid* NativeView;
@@ -251,4 +251,4 @@
} // namespace gfx
-#endif // UI_GFX_NATIVE_WIDGET_TYPES_H_
+#endif // ACCESSIBILITY_GFX_NATIVE_WIDGET_TYPES_H_
diff --git a/third_party/accessibility/gfx/test/gfx_util.cc b/third_party/accessibility/gfx/test/gfx_util.cc
new file mode 100644
index 0000000..05d9793b
--- /dev/null
+++ b/third_party/accessibility/gfx/test/gfx_util.cc
@@ -0,0 +1,110 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gfx/test/gfx_util.h"
+
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include "gfx/geometry/point.h"
+#include "gfx/geometry/point_f.h"
+#include "gfx/geometry/rect.h"
+#include "gfx/geometry/rect_f.h"
+#include "gfx/geometry/size.h"
+#include "gfx/geometry/size_f.h"
+#include "gfx/geometry/vector2d.h"
+#include "gfx/geometry/vector2d_f.h"
+#include "gfx/transform.h"
+
+namespace gfx {
+
+namespace {
+
+bool FloatAlmostEqual(float a, float b) {
+ // FloatLE is the gtest predicate for less than or almost equal to.
+ return ::testing::FloatLE("a", "b", a, b) &&
+ ::testing::FloatLE("b", "a", b, a);
+}
+
+} // namespace
+
+::testing::AssertionResult AssertPointFloatEqual(const char* lhs_expr,
+ const char* rhs_expr,
+ const PointF& lhs,
+ const PointF& rhs) {
+ if (FloatAlmostEqual(lhs.x(), rhs.x()) &&
+ FloatAlmostEqual(lhs.y(), rhs.y())) {
+ return ::testing::AssertionSuccess();
+ }
+ return ::testing::AssertionFailure()
+ << "Value of: " << rhs_expr << "\n Actual: " << rhs.ToString()
+ << "\nExpected: " << lhs_expr << "\nWhich is: " << lhs.ToString();
+}
+
+::testing::AssertionResult AssertRectFloatEqual(const char* lhs_expr,
+ const char* rhs_expr,
+ const RectF& lhs,
+ const RectF& rhs) {
+ if (FloatAlmostEqual(lhs.x(), rhs.x()) &&
+ FloatAlmostEqual(lhs.y(), rhs.y()) &&
+ FloatAlmostEqual(lhs.width(), rhs.width()) &&
+ FloatAlmostEqual(lhs.height(), rhs.height())) {
+ return ::testing::AssertionSuccess();
+ }
+ return ::testing::AssertionFailure()
+ << "Value of: " << rhs_expr << "\n Actual: " << rhs.ToString()
+ << "\nExpected: " << lhs_expr << "\nWhich is: " << lhs.ToString();
+}
+
+::testing::AssertionResult AssertSizeFFloatEqual(const char* lhs_expr,
+ const char* rhs_expr,
+ const SizeF& lhs,
+ const SizeF& rhs) {
+ if (FloatAlmostEqual(lhs.width(), rhs.width()) &&
+ FloatAlmostEqual(lhs.height(), rhs.height())) {
+ return ::testing::AssertionSuccess();
+ }
+ return ::testing::AssertionFailure()
+ << "Value of: " << rhs_expr << "\n Actual: " << rhs.ToString()
+ << "\nExpected: " << lhs_expr << "\nWhich is: " << lhs.ToString();
+}
+
+void PrintTo(const Point& point, ::std::ostream* os) {
+ *os << point.ToString();
+}
+
+void PrintTo(const PointF& point, ::std::ostream* os) {
+ *os << point.ToString();
+}
+
+void PrintTo(const Rect& rect, ::std::ostream* os) {
+ *os << rect.ToString();
+}
+
+void PrintTo(const RectF& rect, ::std::ostream* os) {
+ *os << rect.ToString();
+}
+
+void PrintTo(const Size& size, ::std::ostream* os) {
+ *os << size.ToString();
+}
+
+void PrintTo(const SizeF& size, ::std::ostream* os) {
+ *os << size.ToString();
+}
+
+void PrintTo(const Transform& transform, ::std::ostream* os) {
+ *os << transform.ToString();
+}
+
+void PrintTo(const Vector2d& vector, ::std::ostream* os) {
+ *os << vector.ToString();
+}
+
+void PrintTo(const Vector2dF& vector, ::std::ostream* os) {
+ *os << vector.ToString();
+}
+
+} // namespace gfx
diff --git a/third_party/accessibility/gfx/test/gfx_util.h b/third_party/accessibility/gfx/test/gfx_util.h
new file mode 100644
index 0000000..71307b6
--- /dev/null
+++ b/third_party/accessibility/gfx/test/gfx_util.h
@@ -0,0 +1,63 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_TEST_GFX_UTIL_H_
+#define UI_GFX_TEST_GFX_UTIL_H_
+
+#include <iosfwd>
+#include <string>
+
+#include "gtest/gtest.h"
+
+namespace gfx {
+
+class AxisTransform2d;
+class BoxF;
+class PointF;
+class RectF;
+class SizeF;
+
+#define EXPECT_AXIS_TRANSFORM2D_EQ(a, b) \
+ EXPECT_PRED_FORMAT2(::gfx::AssertAxisTransform2dFloatEqual, a, b)
+
+::testing::AssertionResult AssertAxisTransform2dFloatEqual(
+ const char* lhs_expr,
+ const char* rhs_expr,
+ const AxisTransform2d& lhs,
+ const AxisTransform2d& rhs);
+
+#define EXPECT_BOXF_EQ(a, b) \
+ EXPECT_PRED_FORMAT2(::gfx::AssertBoxFloatEqual, a, b)
+
+::testing::AssertionResult AssertBoxFloatEqual(const char* lhs_expr,
+ const char* rhs_expr,
+ const BoxF& lhs,
+ const BoxF& rhs);
+
+#define EXPECT_POINTF_EQ(a, b) \
+ EXPECT_PRED_FORMAT2(::gfx::AssertPointFloatEqual, a, b)
+
+::testing::AssertionResult AssertPointFloatEqual(const char* lhs_expr,
+ const char* rhs_expr,
+ const PointF& lhs,
+ const PointF& rhs);
+
+#define EXPECT_RECTF_EQ(a, b) \
+ EXPECT_PRED_FORMAT2(::gfx::AssertRectFloatEqual, a, b)
+
+::testing::AssertionResult AssertRectFloatEqual(const char* lhs_expr,
+ const char* rhs_expr,
+ const RectF& lhs,
+ const RectF& rhs);
+
+#define EXPECT_SIZEF_EQ(a, b) \
+ EXPECT_PRED_FORMAT2(::gfx::AssertSizeFFloatEqual, a, b)
+
+::testing::AssertionResult AssertSizeFFloatEqual(const char* lhs_expr,
+ const char* rhs_expr,
+ const SizeF& lhs,
+ const SizeF& rhs);
+} // namespace gfx
+
+#endif // UI_GFX_TEST_GFX_UTIL_H_
diff --git a/third_party/accessibility/gfx/transform.cc b/third_party/accessibility/gfx/transform.cc
index 2ca5fff..1de3a6a 100644
--- a/third_party/accessibility/gfx/transform.cc
+++ b/third_party/accessibility/gfx/transform.cc
@@ -1,594 +1,76 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/transform.h"
+#include "transform.h"
-#include "base/check_op.h"
-#include "base/strings/stringprintf.h"
-#include "ui/gfx/geometry/angle_conversions.h"
-#include "ui/gfx/geometry/box_f.h"
-#include "ui/gfx/geometry/point3_f.h"
-#include "ui/gfx/geometry/point_conversions.h"
-#include "ui/gfx/geometry/quaternion.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/vector3d_f.h"
-#include "ui/gfx/rrect_f.h"
-#include "ui/gfx/skia_util.h"
-#include "ui/gfx/transform_util.h"
+#include "base/string_utils.h"
namespace gfx {
-namespace {
+Transform::Transform()
+ : matrix_{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1},
+ is_identity_(true) {}
-const SkScalar kEpsilon = std::numeric_limits<float>::epsilon();
-
-SkScalar TanDegrees(double degrees) {
- return SkDoubleToScalar(std::tan(gfx::DegToRad(degrees)));
+Transform::Transform(float col1row1,
+ float col2row1,
+ float col3row1,
+ float col4row1,
+ float col1row2,
+ float col2row2,
+ float col3row2,
+ float col4row2,
+ float col1row3,
+ float col2row3,
+ float col3row3,
+ float col4row3,
+ float col1row4,
+ float col2row4,
+ float col3row4,
+ float col4row4)
+ : matrix_{col1row1, col2row1, col3row1, col4row1, col1row2, col2row2,
+ col3row2, col4row2, col1row3, col2row3, col3row3, col4row3,
+ col4row4, col2row4, col3row4, col4row4} {
+ UpdateIdentity();
}
-inline bool ApproximatelyZero(SkScalar x, SkScalar tolerance) {
- return std::abs(x) <= tolerance;
+Transform::Transform(float col1row1,
+ float col2row1,
+ float col1row2,
+ float col2row2,
+ float x_translation,
+ float y_translation)
+ : matrix_{col1row1,
+ col2row1,
+ x_translation,
+ 0,
+ col1row2,
+ col2row2,
+ y_translation,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1} {
+ UpdateIdentity();
}
-inline bool ApproximatelyOne(SkScalar x, SkScalar tolerance) {
- return std::abs(x - 1) <= tolerance;
+bool Transform::operator==(const Transform& rhs) const {
+ return matrix_[0] == rhs[0] && matrix_[1] == rhs[1] && matrix_[2] == rhs[2] &&
+ matrix_[3] == rhs[3] && matrix_[4] == rhs[4] && matrix_[5] == rhs[5] &&
+ matrix_[6] == rhs[6] && matrix_[7] == rhs[7] && matrix_[8] == rhs[8] &&
+ matrix_[9] == rhs[9] && matrix_[10] == rhs[10] &&
+ matrix_[11] == rhs[11] && matrix_[12] == rhs[12] &&
+ matrix_[13] == rhs[13] && matrix_[14] == rhs[14] &&
+ matrix_[15] == rhs[15];
}
-} // namespace
-
-Transform::Transform(SkScalar col1row1,
- SkScalar col2row1,
- SkScalar col3row1,
- SkScalar col4row1,
- SkScalar col1row2,
- SkScalar col2row2,
- SkScalar col3row2,
- SkScalar col4row2,
- SkScalar col1row3,
- SkScalar col2row3,
- SkScalar col3row3,
- SkScalar col4row3,
- SkScalar col1row4,
- SkScalar col2row4,
- SkScalar col3row4,
- SkScalar col4row4)
- : matrix_(SkMatrix44::kUninitialized_Constructor) {
- matrix_.set4x4(col1row1, col1row2, col1row3, col1row4, col2row1, col2row2,
- col2row3, col2row4, col3row1, col3row2, col3row3, col3row4,
- col4row1, col4row2, col4row3, col4row4);
-}
-
-Transform::Transform(SkScalar col1row1,
- SkScalar col2row1,
- SkScalar col1row2,
- SkScalar col2row2,
- SkScalar x_translation,
- SkScalar y_translation)
- : matrix_(SkMatrix44::kIdentity_Constructor) {
- matrix_.set(0, 0, col1row1);
- matrix_.set(1, 0, col1row2);
- matrix_.set(0, 1, col2row1);
- matrix_.set(1, 1, col2row2);
- matrix_.set(0, 3, x_translation);
- matrix_.set(1, 3, y_translation);
-}
-
-Transform::Transform(const Quaternion& q)
- : matrix_(SkMatrix44::kUninitialized_Constructor) {
- double x = q.x();
- double y = q.y();
- double z = q.z();
- double w = q.w();
-
- // Implicitly calls matrix.setIdentity()
- matrix_.set3x3(SkDoubleToScalar(1.0 - 2.0 * (y * y + z * z)),
- SkDoubleToScalar(2.0 * (x * y + z * w)),
- SkDoubleToScalar(2.0 * (x * z - y * w)),
- SkDoubleToScalar(2.0 * (x * y - z * w)),
- SkDoubleToScalar(1.0 - 2.0 * (x * x + z * z)),
- SkDoubleToScalar(2.0 * (y * z + x * w)),
- SkDoubleToScalar(2.0 * (x * z + y * w)),
- SkDoubleToScalar(2.0 * (y * z - x * w)),
- SkDoubleToScalar(1.0 - 2.0 * (x * x + y * y)));
-}
-
-void Transform::RotateAboutXAxis(double degrees) {
- double radians = gfx::DegToRad(degrees);
- SkScalar cosTheta = SkDoubleToScalar(std::cos(radians));
- SkScalar sinTheta = SkDoubleToScalar(std::sin(radians));
- if (matrix_.isIdentity()) {
- matrix_.set3x3(1, 0, 0, 0, cosTheta, sinTheta, 0, -sinTheta, cosTheta);
- } else {
- SkMatrix44 rot(SkMatrix44::kUninitialized_Constructor);
- rot.set3x3(1, 0, 0, 0, cosTheta, sinTheta, 0, -sinTheta, cosTheta);
- matrix_.preConcat(rot);
- }
-}
-
-void Transform::RotateAboutYAxis(double degrees) {
- double radians = gfx::DegToRad(degrees);
- SkScalar cosTheta = SkDoubleToScalar(std::cos(radians));
- SkScalar sinTheta = SkDoubleToScalar(std::sin(radians));
- if (matrix_.isIdentity()) {
- // Note carefully the placement of the -sinTheta for rotation about
- // y-axis is different than rotation about x-axis or z-axis.
- matrix_.set3x3(cosTheta, 0, -sinTheta, 0, 1, 0, sinTheta, 0, cosTheta);
- } else {
- SkMatrix44 rot(SkMatrix44::kUninitialized_Constructor);
- rot.set3x3(cosTheta, 0, -sinTheta, 0, 1, 0, sinTheta, 0, cosTheta);
- matrix_.preConcat(rot);
- }
-}
-
-void Transform::RotateAboutZAxis(double degrees) {
- double radians = gfx::DegToRad(degrees);
- SkScalar cosTheta = SkDoubleToScalar(std::cos(radians));
- SkScalar sinTheta = SkDoubleToScalar(std::sin(radians));
- if (matrix_.isIdentity()) {
- matrix_.set3x3(cosTheta, sinTheta, 0, -sinTheta, cosTheta, 0, 0, 0, 1);
- } else {
- SkMatrix44 rot(SkMatrix44::kUninitialized_Constructor);
- rot.set3x3(cosTheta, sinTheta, 0, -sinTheta, cosTheta, 0, 0, 0, 1);
- matrix_.preConcat(rot);
- }
-}
-
-void Transform::RotateAbout(const Vector3dF& axis, double degrees) {
- if (matrix_.isIdentity()) {
- matrix_.setRotateDegreesAbout(axis.x(), axis.y(), axis.z(),
- SkDoubleToScalar(degrees));
- } else {
- SkMatrix44 rot(SkMatrix44::kUninitialized_Constructor);
- rot.setRotateDegreesAbout(axis.x(), axis.y(), axis.z(),
- SkDoubleToScalar(degrees));
- matrix_.preConcat(rot);
- }
-}
-
-void Transform::Scale(SkScalar x, SkScalar y) {
- matrix_.preScale(x, y, 1);
-}
-
-void Transform::PostScale(SkScalar x, SkScalar y) {
- matrix_.postScale(x, y, 1);
-}
-
-void Transform::Scale3d(SkScalar x, SkScalar y, SkScalar z) {
- matrix_.preScale(x, y, z);
-}
-
-void Transform::Translate(const Vector2dF& offset) {
- Translate(offset.x(), offset.y());
-}
-
-void Transform::Translate(SkScalar x, SkScalar y) {
- matrix_.preTranslate(x, y, 0);
-}
-
-void Transform::PostTranslate(const Vector2dF& offset) {
- PostTranslate(offset.x(), offset.y());
-}
-
-void Transform::PostTranslate(SkScalar x, SkScalar y) {
- matrix_.postTranslate(x, y, 0);
-}
-
-void Transform::Translate3d(const Vector3dF& offset) {
- Translate3d(offset.x(), offset.y(), offset.z());
-}
-
-void Transform::Translate3d(SkScalar x, SkScalar y, SkScalar z) {
- matrix_.preTranslate(x, y, z);
-}
-
-void Transform::Skew(double angle_x, double angle_y) {
- if (matrix_.isIdentity()) {
- matrix_.set(0, 1, TanDegrees(angle_x));
- matrix_.set(1, 0, TanDegrees(angle_y));
- } else {
- SkMatrix44 skew(SkMatrix44::kIdentity_Constructor);
- skew.set(0, 1, TanDegrees(angle_x));
- skew.set(1, 0, TanDegrees(angle_y));
- matrix_.preConcat(skew);
- }
-}
-
-void Transform::ApplyPerspectiveDepth(SkScalar depth) {
- if (depth == 0)
- return;
- if (matrix_.isIdentity()) {
- matrix_.set(3, 2, -SK_Scalar1 / depth);
- } else {
- SkMatrix44 m(SkMatrix44::kIdentity_Constructor);
- m.set(3, 2, -SK_Scalar1 / depth);
- matrix_.preConcat(m);
- }
-}
-
-void Transform::PreconcatTransform(const Transform& transform) {
- matrix_.preConcat(transform.matrix_);
-}
-
-void Transform::ConcatTransform(const Transform& transform) {
- matrix_.postConcat(transform.matrix_);
-}
-
-bool Transform::IsApproximatelyIdentityOrTranslation(SkScalar tolerance) const {
- DCHECK_GE(tolerance, 0);
- return ApproximatelyOne(matrix_.get(0, 0), tolerance) &&
- ApproximatelyZero(matrix_.get(1, 0), tolerance) &&
- ApproximatelyZero(matrix_.get(2, 0), tolerance) &&
- matrix_.get(3, 0) == 0 &&
- ApproximatelyZero(matrix_.get(0, 1), tolerance) &&
- ApproximatelyOne(matrix_.get(1, 1), tolerance) &&
- ApproximatelyZero(matrix_.get(2, 1), tolerance) &&
- matrix_.get(3, 1) == 0 &&
- ApproximatelyZero(matrix_.get(0, 2), tolerance) &&
- ApproximatelyZero(matrix_.get(1, 2), tolerance) &&
- ApproximatelyOne(matrix_.get(2, 2), tolerance) &&
- matrix_.get(3, 2) == 0 && matrix_.get(3, 3) == 1;
-}
-
-bool Transform::IsApproximatelyIdentityOrIntegerTranslation(
- SkScalar tolerance) const {
- if (!IsApproximatelyIdentityOrTranslation(tolerance))
- return false;
-
- for (float t : {matrix_.get(0, 3), matrix_.get(1, 3), matrix_.get(2, 3)}) {
- if (!base::IsValueInRangeForNumericType<int>(t) ||
- std::abs(std::round(t) - t) > tolerance)
- return false;
- }
- return true;
-}
-
-bool Transform::IsIdentityOrIntegerTranslation() const {
- if (!IsIdentityOrTranslation())
- return false;
-
- for (float t : {matrix_.get(0, 3), matrix_.get(1, 3), matrix_.get(2, 3)}) {
- if (!base::IsValueInRangeForNumericType<int>(t) || static_cast<int>(t) != t)
- return false;
- }
- return true;
-}
-
-bool Transform::IsBackFaceVisible() const {
- // Compute whether a layer with a forward-facing normal of (0, 0, 1, 0)
- // would have its back face visible after applying the transform.
- if (matrix_.isIdentity())
- return false;
-
- // This is done by transforming the normal and seeing if the resulting z
- // value is positive or negative. However, note that transforming a normal
- // actually requires using the inverse-transpose of the original transform.
- //
- // We can avoid inverting and transposing the matrix since we know we want
- // to transform only the specific normal vector (0, 0, 1, 0). In this case,
- // we only need the 3rd row, 3rd column of the inverse-transpose. We can
- // calculate only the 3rd row 3rd column element of the inverse, skipping
- // everything else.
- //
- // For more information, refer to:
- // http://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution
- //
-
- double determinant = matrix_.determinant();
-
- // If matrix was not invertible, then just assume back face is not visible.
- if (determinant == 0)
- return false;
-
- // Compute the cofactor of the 3rd row, 3rd column.
- double cofactor_part_1 =
- matrix_.get(0, 0) * matrix_.get(1, 1) * matrix_.get(3, 3);
-
- double cofactor_part_2 =
- matrix_.get(0, 1) * matrix_.get(1, 3) * matrix_.get(3, 0);
-
- double cofactor_part_3 =
- matrix_.get(0, 3) * matrix_.get(1, 0) * matrix_.get(3, 1);
-
- double cofactor_part_4 =
- matrix_.get(0, 0) * matrix_.get(1, 3) * matrix_.get(3, 1);
-
- double cofactor_part_5 =
- matrix_.get(0, 1) * matrix_.get(1, 0) * matrix_.get(3, 3);
-
- double cofactor_part_6 =
- matrix_.get(0, 3) * matrix_.get(1, 1) * matrix_.get(3, 0);
-
- double cofactor33 = cofactor_part_1 + cofactor_part_2 + cofactor_part_3 -
- cofactor_part_4 - cofactor_part_5 - cofactor_part_6;
-
- // Technically the transformed z component is cofactor33 / determinant. But
- // we can avoid the costly division because we only care about the resulting
- // +/- sign; we can check this equivalently by multiplication.
- return cofactor33 * determinant < -kEpsilon;
-}
-
-bool Transform::GetInverse(Transform* transform) const {
- if (!matrix_.invert(&transform->matrix_)) {
- // Initialize the return value to identity if this matrix turned
- // out to be un-invertible.
- transform->MakeIdentity();
- return false;
- }
-
- return true;
-}
-
-bool Transform::Preserves2dAxisAlignment() const {
- // Check whether an axis aligned 2-dimensional rect would remain axis-aligned
- // after being transformed by this matrix (and implicitly projected by
- // dropping any non-zero z-values).
- //
- // The 4th column can be ignored because translations don't affect axis
- // alignment. The 3rd column can be ignored because we are assuming 2d
- // inputs, where z-values will be zero. The 3rd row can also be ignored
- // because we are assuming 2d outputs, and any resulting z-value is dropped
- // anyway. For the inner 2x2 portion, the only effects that keep a rect axis
- // aligned are (1) swapping axes and (2) scaling axes. This can be checked by
- // verifying only 1 element of every column and row is non-zero. Degenerate
- // cases that project the x or y dimension to zero are considered to preserve
- // axis alignment.
- //
- // If the matrix does have perspective component that is affected by x or y
- // values: The current implementation conservatively assumes that axis
- // alignment is not preserved.
-
- bool has_x_or_y_perspective =
- matrix_.get(3, 0) != 0 || matrix_.get(3, 1) != 0;
-
- int num_non_zero_in_row_0 = 0;
- int num_non_zero_in_row_1 = 0;
- int num_non_zero_in_col_0 = 0;
- int num_non_zero_in_col_1 = 0;
-
- if (std::abs(matrix_.get(0, 0)) > kEpsilon) {
- num_non_zero_in_row_0++;
- num_non_zero_in_col_0++;
- }
-
- if (std::abs(matrix_.get(0, 1)) > kEpsilon) {
- num_non_zero_in_row_0++;
- num_non_zero_in_col_1++;
- }
-
- if (std::abs(matrix_.get(1, 0)) > kEpsilon) {
- num_non_zero_in_row_1++;
- num_non_zero_in_col_0++;
- }
-
- if (std::abs(matrix_.get(1, 1)) > kEpsilon) {
- num_non_zero_in_row_1++;
- num_non_zero_in_col_1++;
- }
-
- return num_non_zero_in_row_0 <= 1 && num_non_zero_in_row_1 <= 1 &&
- num_non_zero_in_col_0 <= 1 && num_non_zero_in_col_1 <= 1 &&
- !has_x_or_y_perspective;
-}
-
-void Transform::Transpose() {
- matrix_.transpose();
-}
-
-void Transform::FlattenTo2d() {
- float tmp[16];
- matrix_.asColMajorf(tmp);
- tmp[2] = 0.0;
- tmp[6] = 0.0;
- tmp[8] = 0.0;
- tmp[9] = 0.0;
- tmp[10] = 1.0;
- tmp[11] = 0.0;
- tmp[14] = 0.0;
- matrix_.setColMajorf(tmp);
-}
-
-bool Transform::IsFlat() const {
- return matrix_.get(2, 0) == 0.0 && matrix_.get(2, 1) == 0.0 &&
- matrix_.get(0, 2) == 0.0 && matrix_.get(1, 2) == 0.0 &&
- matrix_.get(2, 2) == 1.0 && matrix_.get(3, 2) == 0.0 &&
- matrix_.get(2, 3) == 0.0;
-}
-
-Vector2dF Transform::To2dTranslation() const {
- return gfx::Vector2dF(SkScalarToFloat(matrix_.get(0, 3)),
- SkScalarToFloat(matrix_.get(1, 3)));
-}
-
-void Transform::TransformPoint(Point* point) const {
- DCHECK(point);
- TransformPointInternal(matrix_, point);
-}
-
-void Transform::TransformPoint(PointF* point) const {
- DCHECK(point);
- TransformPointInternal(matrix_, point);
-}
-
-void Transform::TransformPoint(Point3F* point) const {
- DCHECK(point);
- TransformPointInternal(matrix_, point);
-}
-
-void Transform::TransformVector(Vector3dF* vector) const {
- DCHECK(vector);
- TransformVectorInternal(matrix_, vector);
-}
-
-bool Transform::TransformPointReverse(Point* point) const {
- DCHECK(point);
-
- // TODO(sad): Try to avoid trying to invert the matrix.
- SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor);
- if (!matrix_.invert(&inverse))
- return false;
-
- TransformPointInternal(inverse, point);
- return true;
-}
-
-bool Transform::TransformPointReverse(Point3F* point) const {
- DCHECK(point);
-
- // TODO(sad): Try to avoid trying to invert the matrix.
- SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor);
- if (!matrix_.invert(&inverse))
- return false;
-
- TransformPointInternal(inverse, point);
- return true;
-}
-
-void Transform::TransformRect(RectF* rect) const {
- if (matrix_.isIdentity())
- return;
-
- SkRect src = RectFToSkRect(*rect);
- SkMatrix(matrix_).mapRect(&src);
- *rect = SkRectToRectF(src);
-}
-
-bool Transform::TransformRectReverse(RectF* rect) const {
- if (matrix_.isIdentity())
- return true;
-
- SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor);
- if (!matrix_.invert(&inverse))
- return false;
-
- SkRect src = RectFToSkRect(*rect);
- SkMatrix(inverse).mapRect(&src);
- *rect = SkRectToRectF(src);
- return true;
-}
-
-bool Transform::TransformRRectF(RRectF* rrect) const {
- SkRRect result;
- if (!SkRRect(*rrect).transform(SkMatrix(matrix_), &result))
- return false;
- *rrect = gfx::RRectF(result);
- return true;
-}
-
-void Transform::TransformBox(BoxF* box) const {
- BoxF bounds;
- bool first_point = true;
- for (int corner = 0; corner < 8; ++corner) {
- gfx::Point3F point = box->origin();
- point += gfx::Vector3dF(corner & 1 ? box->width() : 0.f,
- corner & 2 ? box->height() : 0.f,
- corner & 4 ? box->depth() : 0.f);
- TransformPoint(&point);
- if (first_point) {
- bounds.set_origin(point);
- first_point = false;
- } else {
- bounds.ExpandTo(point);
- }
- }
- *box = bounds;
-}
-
-bool Transform::TransformBoxReverse(BoxF* box) const {
- gfx::Transform inverse = *this;
- if (!GetInverse(&inverse))
- return false;
- inverse.TransformBox(box);
- return true;
-}
-
-bool Transform::Blend(const Transform& from, double progress) {
- DecomposedTransform to_decomp;
- DecomposedTransform from_decomp;
- if (!DecomposeTransform(&to_decomp, *this) ||
- !DecomposeTransform(&from_decomp, from))
- return false;
-
- to_decomp = BlendDecomposedTransforms(to_decomp, from_decomp, progress);
-
- matrix_ = ComposeTransform(to_decomp).matrix();
- return true;
-}
-
-void Transform::RoundTranslationComponents() {
- matrix_.set(0, 3, std::round(matrix_.get(0, 3)));
- matrix_.set(1, 3, std::round(matrix_.get(1, 3)));
-}
-
-void Transform::TransformPointInternal(const SkMatrix44& xform,
- Point3F* point) const {
- if (xform.isIdentity())
- return;
-
- SkScalar p[4] = {point->x(), point->y(), point->z(), 1};
-
- xform.mapScalars(p);
-
- if (p[3] != SK_Scalar1 && p[3] != 0.f) {
- float w_inverse = SK_Scalar1 / p[3];
- point->SetPoint(p[0] * w_inverse, p[1] * w_inverse, p[2] * w_inverse);
- } else {
- point->SetPoint(p[0], p[1], p[2]);
- }
-}
-
-void Transform::TransformVectorInternal(const SkMatrix44& xform,
- Vector3dF* vector) const {
- if (xform.isIdentity())
- return;
-
- SkScalar p[4] = {vector->x(), vector->y(), vector->z(), 0};
-
- xform.mapScalars(p);
-
- vector->set_x(p[0]);
- vector->set_y(p[1]);
- vector->set_z(p[2]);
-}
-
-void Transform::TransformPointInternal(const SkMatrix44& xform,
- PointF* point) const {
- if (xform.isIdentity())
- return;
-
- SkScalar p[4] = {SkIntToScalar(point->x()), SkIntToScalar(point->y()), 0, 1};
-
- xform.mapScalars(p);
-
- point->SetPoint(p[0], p[1]);
-}
-
-void Transform::TransformPointInternal(const SkMatrix44& xform,
- Point* point) const {
- PointF point_float(*point);
- TransformPointInternal(xform, &point_float);
- *point = ToRoundedPoint(point_float);
-}
-
-bool Transform::ApproximatelyEqual(const gfx::Transform& transform) const {
- static const float component_tolerance = 0.1f;
-
- // We may have a larger discrepancy in the scroll components due to snapping
- // (floating point error might round the other way).
- static const float translation_tolerance = 1.f;
-
- for (int row = 0; row < 4; row++) {
- for (int col = 0; col < 4; col++) {
- const float delta =
- std::abs(matrix().get(row, col) - transform.matrix().get(row, col));
- const float tolerance =
- col == 3 && row < 3 ? translation_tolerance : component_tolerance;
- if (delta > tolerance)
- return false;
- }
- }
-
- return true;
+bool Transform::IsIdentity() const {
+ return is_identity_;
}
std::string Transform::ToString() const {
@@ -597,12 +79,56 @@
" %+0.4f %+0.4f %+0.4f %+0.4f \n"
" %+0.4f %+0.4f %+0.4f %+0.4f \n"
" %+0.4f %+0.4f %+0.4f %+0.4f ]\n",
- matrix_.get(0, 0), matrix_.get(0, 1), matrix_.get(0, 2),
- matrix_.get(0, 3), matrix_.get(1, 0), matrix_.get(1, 1),
- matrix_.get(1, 2), matrix_.get(1, 3), matrix_.get(2, 0),
- matrix_.get(2, 1), matrix_.get(2, 2), matrix_.get(2, 3),
- matrix_.get(3, 0), matrix_.get(3, 1), matrix_.get(3, 2),
- matrix_.get(3, 3));
+ matrix_[0], matrix_[1], matrix_[2], matrix_[3], matrix_[4], matrix_[5],
+ matrix_[6], matrix_[7], matrix_[8], matrix_[9], matrix_[10], matrix_[11],
+ matrix_[12], matrix_[13], matrix_[14], matrix_[15]);
+}
+
+void Transform::Scale(float x, float y) {
+ matrix_[0] *= x;
+ matrix_[5] *= y;
+ UpdateIdentity();
+}
+
+void Transform::TransformRect(RectF* rect) const {
+ if (IsIdentity())
+ return;
+ PointF origin = rect->origin();
+ PointF top_right = rect->top_right();
+ PointF bottom_left = rect->bottom_left();
+ TransformPoint(&origin);
+ TransformPoint(&top_right);
+ TransformPoint(&bottom_left);
+ rect->set_origin(origin);
+ rect->set_width(top_right.x() - origin.x());
+ rect->set_height(bottom_left.y() - origin.y());
+}
+
+void Transform::TransformPoint(PointF* point) const {
+ if (IsIdentity())
+ return;
+ float x = point->x();
+ float y = point->y();
+ point->SetPoint(x * matrix_[0] + y * matrix_[1] + matrix_[2],
+ x * matrix_[4] + y * matrix_[5] + matrix_[6]);
+ return;
+}
+
+void Transform::UpdateIdentity() {
+ for (size_t i = 0; i < 16; i++) {
+ if (i == 0 || i == 5 || i == 10 || i == 15) {
+ if (matrix_[i] != 1) {
+ is_identity_ = false;
+ return;
+ }
+ } else {
+ if (matrix_[i] != 0) {
+ is_identity_ = false;
+ return;
+ }
+ }
+ }
+ is_identity_ = true;
}
} // namespace gfx
diff --git a/third_party/accessibility/gfx/transform.h b/third_party/accessibility/gfx/transform.h
index 4e8b5da..1281bab 100644
--- a/third_party/accessibility/gfx/transform.h
+++ b/third_party/accessibility/gfx/transform.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,298 +8,76 @@
#include <iosfwd>
#include <string>
-#include "base/compiler_specific.h"
-#include "third_party/skia/include/core/SkMatrix44.h"
-#include "ui/gfx/geometry/vector2d_f.h"
-#include "ui/gfx/geometry_skia_export.h"
+#include "geometry/rect_f.h"
+#include "gfx_export.h"
namespace gfx {
-class BoxF;
class RectF;
-class RRectF;
-class Point;
-class PointF;
-class Point3F;
-class Quaternion;
-class Vector3dF;
// 4x4 transformation matrix. Transform is cheap and explicitly allows
// copy/assign.
-class GEOMETRY_SKIA_EXPORT Transform {
+class GFX_EXPORT Transform {
public:
- enum SkipInitialization { kSkipInitialization };
+ Transform();
- constexpr Transform() : matrix_(SkMatrix44::kIdentity_Constructor) {}
-
- // Skips initializing this matrix to avoid overhead, when we know it will be
- // initialized before use.
- Transform(SkipInitialization)
- : matrix_(SkMatrix44::kUninitialized_Constructor) {}
- Transform(const Transform& rhs) : matrix_(rhs.matrix_) {}
- // Initialize with the concatenation of lhs * rhs.
- Transform(const Transform& lhs, const Transform& rhs)
- : matrix_(lhs.matrix_, rhs.matrix_) {}
- explicit Transform(const SkMatrix44& matrix) : matrix_(matrix) {}
- // Constructs a transform from explicit 16 matrix elements. Elements
- // should be given in row-major order.
- Transform(SkScalar col1row1,
- SkScalar col2row1,
- SkScalar col3row1,
- SkScalar col4row1,
- SkScalar col1row2,
- SkScalar col2row2,
- SkScalar col3row2,
- SkScalar col4row2,
- SkScalar col1row3,
- SkScalar col2row3,
- SkScalar col3row3,
- SkScalar col4row3,
- SkScalar col1row4,
- SkScalar col2row4,
- SkScalar col3row4,
- SkScalar col4row4);
+ Transform(float col1row1,
+ float col2row1,
+ float col3row1,
+ float col4row1,
+ float col1row2,
+ float col2row2,
+ float col3row2,
+ float col4row2,
+ float col1row3,
+ float col2row3,
+ float col3row3,
+ float col4row3,
+ float col1row4,
+ float col2row4,
+ float col3row4,
+ float col4row4);
// Constructs a transform from explicit 2d elements. All other matrix
// elements remain the same as the corresponding elements of an identity
// matrix.
- Transform(SkScalar col1row1,
- SkScalar col2row1,
- SkScalar col1row2,
- SkScalar col2row2,
- SkScalar x_translation,
- SkScalar y_translation);
+ Transform(float col1row1,
+ float col2row1,
+ float col1row2,
+ float col2row2,
+ float x_translation,
+ float y_translation);
- // Constructs a transform corresponding to the given quaternion.
- explicit Transform(const Quaternion& q);
+ bool operator==(const Transform& rhs) const;
+ bool operator!=(const Transform& rhs) const { return !(*this == rhs); };
- bool operator==(const Transform& rhs) const { return matrix_ == rhs.matrix_; }
- bool operator!=(const Transform& rhs) const { return matrix_ != rhs.matrix_; }
+ float operator[](int index) const {
+ BASE_DCHECK((unsigned)index < 16);
+ return matrix_[index];
+ }
- // Resets this transform to the identity transform.
- void MakeIdentity() { matrix_.setIdentity(); }
-
- // Applies the current transformation on a 2d rotation and assigns the result
- // to |this|.
- void Rotate(double degrees) { RotateAboutZAxis(degrees); }
-
- // Applies the current transformation on an axis-angle rotation and assigns
- // the result to |this|.
- void RotateAboutXAxis(double degrees);
- void RotateAboutYAxis(double degrees);
- void RotateAboutZAxis(double degrees);
- void RotateAbout(const Vector3dF& axis, double degrees);
+ // Returns true if this is the identity matrix.
+ bool IsIdentity() const;
// Applies the current transformation on a scaling and assigns the result
// to |this|.
- void Scale(SkScalar x, SkScalar y);
- void Scale3d(SkScalar x, SkScalar y, SkScalar z);
- gfx::Vector2dF Scale2d() const {
- return gfx::Vector2dF(matrix_.get(0, 0), matrix_.get(1, 1));
- }
-
- // Applies a scale to the current transformation and assigns the result to
- // |this|.
- void PostScale(SkScalar x, SkScalar y);
-
- // Applies the current transformation on a translation and assigns the result
- // to |this|.
- void Translate(const Vector2dF& offset);
- void Translate(SkScalar x, SkScalar y);
- void Translate3d(const Vector3dF& offset);
- void Translate3d(SkScalar x, SkScalar y, SkScalar z);
-
- // Applies a translation to the current transformation and assigns the result
- // to |this|.
- void PostTranslate(const Vector2dF& offset);
- void PostTranslate(SkScalar x, SkScalar y);
-
- // Applies the current transformation on a skew and assigns the result
- // to |this|.
- void Skew(double angle_x, double angle_y);
-
- // Applies the current transformation on a perspective transform and assigns
- // the result to |this|.
- void ApplyPerspectiveDepth(SkScalar depth);
-
- // Applies a transformation on the current transformation
- // (i.e. 'this = this * transform;').
- void PreconcatTransform(const Transform& transform);
-
- // Applies a transformation on the current transformation
- // (i.e. 'this = transform * this;').
- void ConcatTransform(const Transform& transform);
-
- // Returns true if this is the identity matrix.
- // This function modifies a mutable variable in |matrix_|.
- bool IsIdentity() const { return matrix_.isIdentity(); }
-
- // Returns true if the matrix is either identity or pure translation.
- bool IsIdentityOrTranslation() const { return matrix_.isTranslate(); }
-
- // Returns true if the matrix is either the identity or a 2d translation.
- bool IsIdentityOr2DTranslation() const {
- return matrix_.isTranslate() && matrix_.get(2, 3) == 0;
- }
-
- // Returns true if the matrix is either identity or pure translation,
- // allowing for an amount of inaccuracy as specified by the parameter.
- bool IsApproximatelyIdentityOrTranslation(SkScalar tolerance) const;
- bool IsApproximatelyIdentityOrIntegerTranslation(SkScalar tolerance) const;
-
- // Returns true if the matrix is either a positive scale and/or a translation.
- bool IsPositiveScaleOrTranslation() const {
- if (!IsScaleOrTranslation())
- return false;
- return matrix_.get(0, 0) > 0.0 && matrix_.get(1, 1) > 0.0 &&
- matrix_.get(2, 2) > 0.0;
- }
-
- // Returns true if the matrix is identity or, if the matrix consists only
- // of a translation whose components can be represented as integers. Returns
- // false if the translation contains a fractional component or is too large to
- // fit in an integer.
- bool IsIdentityOrIntegerTranslation() const;
-
- // Returns true if the matrix had only scaling components.
- bool IsScale2d() const { return matrix_.isScale(); }
-
- // Returns true if the matrix is has only scaling and translation components.
- bool IsScaleOrTranslation() const { return matrix_.isScaleTranslate(); }
-
- // Returns true if axis-aligned 2d rects will remain axis-aligned after being
- // transformed by this matrix.
- bool Preserves2dAxisAlignment() const;
-
- // Returns true if the matrix has any perspective component that would
- // change the w-component of a homogeneous point.
- bool HasPerspective() const { return matrix_.hasPerspective(); }
-
- // Returns true if this transform is non-singular.
- bool IsInvertible() const { return matrix_.invert(NULL); }
-
- // Returns true if a layer with a forward-facing normal of (0, 0, 1) would
- // have its back side facing frontwards after applying the transform.
- bool IsBackFaceVisible() const;
-
- // Inverts the transform which is passed in. Returns true if successful, or
- // sets |transform| to the identify matrix on failure.
- bool GetInverse(Transform* transform) const WARN_UNUSED_RESULT;
-
- // Transposes this transform in place.
- void Transpose();
-
- // Set 3rd row and 3rd colum to (0, 0, 1, 0). Note that this flattening
- // operation is not quite the same as an orthographic projection and is
- // technically not a linear operation.
- //
- // One useful interpretation of doing this operation:
- // - For x and y values, the new transform behaves effectively like an
- // orthographic projection was added to the matrix sequence.
- // - For z values, the new transform overrides any effect that the transform
- // had on z, and instead it preserves the z value for any points that are
- // transformed.
- // - Because of linearity of transforms, this flattened transform also
- // preserves the effect that any subsequent (multiplied from the right)
- // transforms would have on z values.
- //
- void FlattenTo2d();
-
- // Returns true if the 3rd row and 3rd column are both (0, 0, 1, 0).
- bool IsFlat() const;
-
- // Returns the x and y translation components of the matrix.
- Vector2dF To2dTranslation() const;
-
- // Applies the transformation to the point.
- void TransformPoint(Point3F* point) const;
-
- // Applies the transformation to the point.
- void TransformPoint(PointF* point) const;
-
- // Applies the transformation to the point.
- void TransformPoint(Point* point) const;
-
- // Applies the transformation to the vector.
- void TransformVector(Vector3dF* vector) const;
-
- // Applies the reverse transformation on the point. Returns true if the
- // transformation can be inverted.
- bool TransformPointReverse(Point3F* point) const;
-
- // Applies the reverse transformation on the point. Returns true if the
- // transformation can be inverted. Rounds the result to the nearest point.
- bool TransformPointReverse(Point* point) const;
+ void Scale(float x, float y);
// Applies transformation on the given rect. After the function completes,
// |rect| will be the smallest axis aligned bounding rect containing the
// transformed rect.
void TransformRect(RectF* rect) const;
- // Applies the reverse transformation on the given rect. After the function
- // completes, |rect| will be the smallest axis aligned bounding rect
- // containing the transformed rect. Returns false if the matrix cannot be
- // inverted.
- bool TransformRectReverse(RectF* rect) const;
-
- // Applies transformation on the given |rrect|. Returns false if the transform
- // matrix cannot be applied to rrect.
- bool TransformRRectF(RRectF* rrect) const;
-
- // Applies transformation on the given box. After the function completes,
- // |box| will be the smallest axis aligned bounding box containing the
- // transformed box.
- void TransformBox(BoxF* box) const;
-
- // Applies the reverse transformation on the given box. After the function
- // completes, |box| will be the smallest axis aligned bounding box
- // containing the transformed box. Returns false if the matrix cannot be
- // inverted.
- bool TransformBoxReverse(BoxF* box) const;
-
- // Decomposes |this| and |from|, interpolates the decomposed values, and
- // sets |this| to the reconstituted result. Returns false if either matrix
- // can't be decomposed. Uses routines described in this spec:
- // http://www.w3.org/TR/css3-3d-transforms/.
- //
- // Note: this call is expensive since we need to decompose the transform. If
- // you're going to be calling this rapidly (e.g., in an animation) you should
- // decompose once using gfx::DecomposeTransforms and reuse your
- // DecomposedTransform.
- bool Blend(const Transform& from, double progress);
-
- void RoundTranslationComponents();
-
- // Returns |this| * |other|.
- Transform operator*(const Transform& other) const {
- return Transform(*this, other);
- }
-
- // Sets |this| = |this| * |other|
- Transform& operator*=(const Transform& other) {
- PreconcatTransform(other);
- return *this;
- }
-
- // Returns the underlying matrix.
- const SkMatrix44& matrix() const { return matrix_; }
- SkMatrix44& matrix() { return matrix_; }
- bool ApproximatelyEqual(const gfx::Transform& transform) const;
+ // Applies transformation on the given point
+ void TransformPoint(PointF* point) const;
std::string ToString() const;
private:
- void TransformPointInternal(const SkMatrix44& xform, Point* point) const;
+ // Row-major array
+ float matrix_[16];
+ bool is_identity_;
- void TransformPointInternal(const SkMatrix44& xform, PointF* point) const;
-
- void TransformPointInternal(const SkMatrix44& xform, Point3F* point) const;
-
- void TransformVectorInternal(const SkMatrix44& xform,
- Vector3dF* vector) const;
-
- SkMatrix44 matrix_;
-
- // copy/assign are allowed.
+ void UpdateIdentity();
};
// This is declared here for use in gtest-based unit tests but is defined in