Skip to content

Commit

Permalink
[A11y] Stable ids for AXObjects with DOM nodes
Browse files Browse the repository at this point in the history
Use the DOM node for the AXID for any AXObject with a DOM node. Other AXObjects will still generate their AXID, but in their own numerical namespace. For now, any AXID < 0 will be a generated ID.

Role changes and alerts required some new browser-side code, because rather than the object being destroyed and created with a new id, the ID now stays the same.

In some cases, test results have improved, e.g. rather than an object being destroyed and created with a different ID, it retains the same ID and a change event is fired for it.

Benefits:
- Removes over 100 lines of implementation code
- Use less memory: removes ids_in_use_ (set) and node_object_mapping_ (map).
- Reduce map lookups when an AXObject is removed -- based on the ID value, we can determine whether it has a DOM node and if it doesn't, we already know it cannot be in some of the maps
- Make it easier for screen readers to maintain the user's point of regard within content, even when the layout or role changes. Users sometimes lose their place, as the screen reader may move the user to the top. A hope is that this will reduce the occurrences of that happening.
- Enable the follow-ups listed below.

Follow-up work:
- Refactor content-visibility: auto change handling in a11y (crbug.com/1380449).
- See if the dom_node_id field in AXNodeData is needed anymore now that any id >0 is the same as the dom node id.
- Look at simplifying or removing reparenting computations in AXTreeSerializer. Maybe we can get rid of expensive AnyDescendantIsReparented().

Bug: none
Change-Id: I321320b02c5608cf5a2748c0b36eead1c67a7f05
Cq-Do-Not-Cancel-Tryjobs: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4027071
Reviewed-by: Daniel Hosseinian <dhoss@chromium.org>
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
Reviewed-by: Benjamin Beaudry <benjamin.beaudry@microsoft.com>
Reviewed-by: David Tseng <dtseng@chromium.org>
Reviewed-by: Mason Freed <masonf@chromium.org>
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1085033}
  • Loading branch information
aleventhal authored and Chromium LUCI CQ committed Dec 19, 2022
1 parent ead5db8 commit 742a07c
Show file tree
Hide file tree
Showing 68 changed files with 492 additions and 574 deletions.
Expand Up @@ -24,6 +24,8 @@ AccessibilityExtensionRecoveryStrategyTest = class extends CommonE2ETestBase {
};


// TODO(https://issuetracker.google.com/issues/263127143) Recovery can likely be
// simplified now that most ids are stable.
AX_TEST_F(
'AccessibilityExtensionRecoveryStrategyTest', 'ReparentedRecovery',
async function() {
Expand Down Expand Up @@ -54,30 +56,21 @@ AX_TEST_F(
assertFalse(
bAncestryRecovery.requiresRecovery(),
'bAncestryRecovery.requiresRecovery');
assertTrue(
assertFalse(
pAncestryRecovery.requiresRecovery(),
'pAncestryRecovery.requiresRecovery()');
assertTrue(
assertFalse(
sAncestryRecovery.requiresRecovery(),
'sAncestryRecovery.requiresRecovery()');
assertFalse(
bTreePathRecovery.requiresRecovery(),
'bTreePathRecovery.requiresRecovery()');
assertTrue(
assertFalse(
pTreePathRecovery.requiresRecovery(),
'pTreePathRecovery.requiresRecovery()');
assertTrue(
assertFalse(
sTreePathRecovery.requiresRecovery(),
'sTreePathRecovery.requiresRecovery()');

assertEquals(RoleType.BUTTON, bAncestryRecovery.node.role);
assertEquals(root, pAncestryRecovery.node);
assertEquals(root, sAncestryRecovery.node);

assertEquals(b, bTreePathRecovery.node);
assertEquals(b, pTreePathRecovery.node);
assertEquals(b, sTreePathRecovery.node);

assertFalse(
bAncestryRecovery.requiresRecovery(),
'bAncestryRecovery.requiresRecovery()');
Expand Down
Expand Up @@ -9,10 +9,8 @@ var allTests = [
rootNode.addEventListener('focus', (evt) => {
// The underlying DOM button has not changed, but its layout has. This
// listener ensures we at least get a focus event on a new valid
// accessibility object. Once display none nodes are in the tree, it's
// likely that |node| == |evt.target|.
assertFalse(evt.target == node);
assertEq(undefined, node.role);
// accessibility object.
assertEq(evt.target, node);
assertEq('button', evt.target.role);
chrome.test.succeed();
});
Expand Down
8 changes: 3 additions & 5 deletions components/pdf/renderer/pdf_accessibility_tree.cc
Expand Up @@ -1661,13 +1661,11 @@ PdfAccessibilityTree::GetRenderAccessibilityIfEnabled() {
// we shouldn't use it. This can happen if Blink accessibility is disabled
// after we started generating the accessible PDF.
base::WeakPtr<PdfAccessibilityTree> weak_this = GetWeakPtr();
if (render_accessibility->GenerateAXID() <= 0)
if (!render_accessibility->HasActiveDocument()) {
return nullptr;
}

// GenerateAXID() above can cause self deletion. Returning nullptr will cause
// callers to stop doing work.
if (!weak_this)
return nullptr;
DCHECK(weak_this);

return render_accessibility;
}
Expand Down
Expand Up @@ -2590,18 +2590,19 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
EXPECT_UIA_TEXTRANGE_EQ(text_range_provider,
L"Before frame\nText in iframe\nAfter frame");

// Traversing by word should include trailing whitespace.
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*/ -1,
/*expected_text*/ L"frame",
/*expected_text*/ L"frame\n",
/*expected_count*/ -1);
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character,
/*count*/ 2,
/*expected_text*/ L"frame\nT",
/*expected_text*/ L"frame\nTe",
/*expected_count*/ 2);
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Character,
/*count*/ 7,
Expand Down
3 changes: 3 additions & 0 deletions content/browser/accessibility/browser_accessibility.cc
Expand Up @@ -892,6 +892,9 @@ const ui::AXUniqueId& BrowserAccessibility::GetUniqueId() const {
// This is not the same as GetData().id which comes from Blink, because
// those ids are only unique within the Blink process. We need one that is
// unique for the browser process.
// TODO(accessibility) We should be able to get rid of this, because node IDs
// are actually unique within their renderer process, and each renderer
// process has its own OS-level window, which is all the uniqueness we need.
return unique_id_;
}

Expand Down
3 changes: 3 additions & 0 deletions content/browser/accessibility/browser_accessibility.h
Expand Up @@ -556,6 +556,9 @@ class CONTENT_EXPORT BrowserAccessibility : public ui::AXPlatformNodeDelegate {
static bool HasInvalidAttribute(const ui::TextAttributeList& attributes);

// A unique ID, since node IDs are frame-local.
// TODO(accessibility) We should be able to get rid of this, because node IDs
// are actually local to the renderer process, and each renderer process has
// its own OS-level window, which is all the uniqueness we need.
ui::AXUniqueId unique_id_;
};

Expand Down
Expand Up @@ -128,7 +128,7 @@ AccessibilityNotificationWaiter value_waiter(shell()->web_contents(),

EXPECT_EQ(
ui::AXTextMarkerToAXPosition(text_edit.edit_text_marker)->ToString(),
"TextPosition anchor_id=4 text_offset=1 affinity=downstream "
"TextPosition anchor_id=7 text_offset=1 affinity=downstream "
"annotated_text=B<>");
}

Expand Down
Expand Up @@ -314,6 +314,8 @@ void BrowserAccessibilityManagerAndroid::FireGeneratedEvent(
if (android_node->IsSlider())
wcax->HandleSliderChanged(android_node->unique_id());
break;
case ui::AXEventGenerator::Event::ROLE_CHANGED:
break;
case ui::AXEventGenerator::Event::SCROLL_HORIZONTAL_POSITION_CHANGED:
case ui::AXEventGenerator::Event::SCROLL_VERTICAL_POSITION_CHANGED:
wcax->HandleScrollPositionChanged(android_node->unique_id());
Expand Down Expand Up @@ -393,7 +395,6 @@ void BrowserAccessibilityManagerAndroid::FireGeneratedEvent(
case ui::AXEventGenerator::Event::READONLY_CHANGED:
case ui::AXEventGenerator::Event::RELATED_NODE_CHANGED:
case ui::AXEventGenerator::Event::REQUIRED_STATE_CHANGED:
case ui::AXEventGenerator::Event::ROLE_CHANGED:
case ui::AXEventGenerator::Event::ROW_COUNT_CHANGED:
case ui::AXEventGenerator::Event::SELECTED_CHANGED:
case ui::AXEventGenerator::Event::SELECTED_CHILDREN_CHANGED:
Expand Down
Expand Up @@ -276,9 +276,19 @@ void BrowserAccessibilityManagerAuraLinux::FireGeneratedEvent(
FireReadonlyChangedEvent(wrapper);
break;
case ui::AXEventGenerator::Event::RANGE_VALUE_CHANGED:
DCHECK(wrapper->GetData().IsRangeValueSupported());
FireEvent(wrapper, ax::mojom::Event::kValueChanged);
if (wrapper->GetData().IsRangeValueSupported()) {
FireEvent(wrapper, ax::mojom::Event::kValueChanged);
}
break;
case ui::AXEventGenerator::Event::ALERT:
case ui::AXEventGenerator::Event::ROLE_CHANGED: {
// Manually fire removal and addition of the object.
ui::AXPlatformNodeAuraLinux* platform_node =
ToBrowserAccessibilityAuraLinux(wrapper)->GetNode();
platform_node->OnSubtreeWillBeDeleted();
platform_node->OnSubtreeCreated();
break;
}
case ui::AXEventGenerator::Event::SELECTED_CHILDREN_CHANGED:
FireEvent(wrapper, ax::mojom::Event::kSelectedChildrenChanged);
break;
Expand Down Expand Up @@ -307,7 +317,6 @@ void BrowserAccessibilityManagerAuraLinux::FireGeneratedEvent(
// Currently unused events on this platform.
case ui::AXEventGenerator::Event::NONE:
case ui::AXEventGenerator::Event::ACCESS_KEY_CHANGED:
case ui::AXEventGenerator::Event::ALERT:
case ui::AXEventGenerator::Event::ATOMIC_CHANGED:
case ui::AXEventGenerator::Event::AUTO_COMPLETE_CHANGED:
case ui::AXEventGenerator::Event::CARET_BOUNDS_CHANGED:
Expand Down Expand Up @@ -348,7 +357,6 @@ void BrowserAccessibilityManagerAuraLinux::FireGeneratedEvent(
case ui::AXEventGenerator::Event::RANGE_VALUE_STEP_CHANGED:
case ui::AXEventGenerator::Event::RELATED_NODE_CHANGED:
case ui::AXEventGenerator::Event::REQUIRED_STATE_CHANGED:
case ui::AXEventGenerator::Event::ROLE_CHANGED:
case ui::AXEventGenerator::Event::ROW_COUNT_CHANGED:
case ui::AXEventGenerator::Event::SCROLL_HORIZONTAL_POSITION_CHANGED:
case ui::AXEventGenerator::Event::SCROLL_VERTICAL_POSITION_CHANGED:
Expand Down
Expand Up @@ -423,6 +423,7 @@ void BrowserAccessibilityManagerWin::FireGeneratedEvent(
HandleAriaPropertiesChangedEvent(*wrapper);
break;
case ui::AXEventGenerator::Event::ROLE_CHANGED:
FireWinAccessibilityEvent(IA2_EVENT_ROLE_CHANGED, wrapper);
FireUiaPropertyChangedEvent(UIA_AriaRolePropertyId, wrapper);
break;
case ui::AXEventGenerator::Event::SCROLL_HORIZONTAL_POSITION_CHANGED:
Expand Down
Expand Up @@ -984,6 +984,11 @@ IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
RunEventTest(FILE_PATH_LITERAL("remove-hidden-attribute-subtree.html"));
}

IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
AccessibilityEventsRoleChanged) {
RunEventTest(FILE_PATH_LITERAL("role-changed.html"));
}

IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
AccessibilityEventsSamePageLinkNavigation) {
#if BUILDFLAG(IS_WIN)
Expand Down
Expand Up @@ -612,7 +612,7 @@ public void test_cssDisplayDescendants() {
@Test
@SmallTest
public void test_cssDisplay() {
performTest("css-display.html", EMPTY_EXPECTATIONS_FILE);
performTest("css-display.html", "css-display-expected-android.txt");
}

@Test
Expand Down Expand Up @@ -968,6 +968,12 @@ public void test_reportValidityInvalidField() {
"report-validity-invalid-field-expected-android.txt");
}

@Test
@SmallTest
public void test_roleChanged() {
performTest("role-changed.html", "role-changed-expected-android.txt");
}

@Test
@SmallTest
public void test_samePageLinkNavigation() {
Expand Down
1 change: 1 addition & 0 deletions content/public/renderer/render_accessibility.h
Expand Up @@ -21,6 +21,7 @@ namespace content {
// This interface exposes the accessibility tree for one RenderFrame.
class CONTENT_EXPORT RenderAccessibility {
public:
virtual bool HasActiveDocument() const = 0;
virtual int GenerateAXID() = 0;

// These APIs allow a page with a single EMBED element to graft an
Expand Down
16 changes: 9 additions & 7 deletions content/renderer/accessibility/render_accessibility_impl.cc
Expand Up @@ -518,8 +518,7 @@ void RenderAccessibilityImpl::HandleAXEvent(const ui::AXEvent& event) {
DCHECK(!document.IsNull());

auto obj = WebAXObject::FromWebDocumentByID(document, event.id);
if (obj.IsDetached())
return;
DCHECK(!obj.IsDetached());

#if BUILDFLAG(IS_ANDROID)
// Inline text boxes are needed to support moving by character/word/line.
Expand All @@ -539,11 +538,9 @@ void RenderAccessibilityImpl::HandleAXEvent(const ui::AXEvent& event) {
if (IsImmediateProcessingRequiredForEvent(event))
event_schedule_mode_ = EventScheduleMode::kProcessEventsImmediately;

if (!obj.IsDetached()) {
MarkWebAXObjectDirty(obj, /* subtree= */ false, event.event_from,
event.event_from_action, event.event_intents,
event.event_type);
}
MarkWebAXObjectDirty(obj, /* subtree= */ false, event.event_from,
event.event_from_action, event.event_intents,
event.event_type);

ScheduleSendPendingAccessibilityEvents();
}
Expand Down Expand Up @@ -732,6 +729,11 @@ void RenderAccessibilityImpl::ScheduleSendPendingAccessibilityEvents(
delay);
}

bool RenderAccessibilityImpl::HasActiveDocument() const {
DCHECK(ax_context_);
return ax_context_->HasActiveDocument();
}

int RenderAccessibilityImpl::GenerateAXID() {
DCHECK(ax_context_);
return ax_context_->GenerateAXID();
Expand Down
1 change: 1 addition & 0 deletions content/renderer/accessibility/render_accessibility_impl.h
Expand Up @@ -94,6 +94,7 @@ class CONTENT_EXPORT RenderAccessibilityImpl : public RenderAccessibility,
ui::AXMode GetAccessibilityMode() { return accessibility_mode_; }

// RenderAccessibility implementation.
bool HasActiveDocument() const override;
int GenerateAXID() override;
ui::AXTreeID GetTreeIDForPluginHost() const override;
void SetPluginTreeSource(PluginAXTreeSource* source) override;
Expand Down
Expand Up @@ -2,4 +2,4 @@ AXLiveRegionChanged on AXGroup AXSubrole=AXApplicationAlert AXDescription='Foo'
=== Start Continuation ===
AXLiveRegionChanged on AXGroup AXSubrole=AXApplicationAlert AXDescription='Bar'
=== Start Continuation ===
AXLiveRegionChanged on AXGroup AXSubrole=AXApplicationAlert AXDescription='Baz'
AXLiveRegionChanged on AXGroup AXSubrole=AXApplicationAlert AXDescription='Baz'
@@ -0,0 +1,2 @@
CHILDREN-CHANGED:ADD index:0 CHILD:(role=ROLE_NOTIFICATION) role=ROLE_DOCUMENT_WEB ENABLED,FOCUSABLE,FOCUSED,SENSITIVE,SHOWING,VISIBLE
CHILDREN-CHANGED:REMOVE index:0 CHILD:(role=ROLE_NOTIFICATION) role=ROLE_DOCUMENT_WEB ENABLED,FOCUSABLE,FOCUSED,SENSITIVE,SHOWING,VISIBLE
@@ -1,3 +1,3 @@
EVENT_OBJECT_HIDE on <div#item3> role=ROLE_SYSTEM_LISTITEM name="Item 3" level=1 PosInSet=3 SetSize=3
EVENT_OBJECT_HIDE on <div> role=ROLE_SYSTEM_LISTITEM INVISIBLE
EVENT_OBJECT_REORDER on <div> role=ROLE_SYSTEM_LIST SetSize=2
IA2_EVENT_TEXT_REMOVED on <div> role=ROLE_SYSTEM_LIST SetSize=2 old_text={'<obj>' start=2 end=3}
@@ -1,3 +1,3 @@
EVENT_OBJECT_HIDE on <li#item3> role=ROLE_SYSTEM_LISTITEM level=1 PosInSet=3 SetSize=3
EVENT_OBJECT_HIDE on <li> role=ROLE_SYSTEM_GROUPING INVISIBLE
EVENT_OBJECT_REORDER on <ul> role=ROLE_SYSTEM_LIST SetSize=2
IA2_EVENT_TEXT_REMOVED on <ul> role=ROLE_SYSTEM_LIST SetSize=2 old_text={'<obj>' start=2 end=3}
@@ -0,0 +1 @@
TYPE_WINDOW_CONTENT_CHANGED - [contentTypes=64]
@@ -1,7 +1,7 @@
CHILDREN-CHANGED:ADD index:0 CHILD:(role=ROLE_TOGGLE_BUTTON) role=ROLE_SECTION ENABLED,SENSITIVE,SHOWING,VISIBLE
CHILDREN-CHANGED:REMOVE index:0 CHILD:(role=ROLE_PUSH_BUTTON) role=ROLE_SECTION ENABLED,SENSITIVE,SHOWING,VISIBLE
STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT
CHILDREN-CHANGED:REMOVE index:0 CHILD:(role=ROLE_TOGGLE_BUTTON) role=ROLE_SECTION ENABLED,SENSITIVE,SHOWING,VISIBLE
STATE-CHANGE:PRESSED:TRUE role=ROLE_TOGGLE_BUTTON name='(null)' ENABLED,FOCUSABLE,PRESSED,SENSITIVE,SHOWING,VISIBLE
=== Start Continuation ===
CHILDREN-CHANGED:ADD index:0 CHILD:(role=ROLE_PUSH_BUTTON) role=ROLE_SECTION ENABLED,SENSITIVE,SHOWING,VISIBLE
CHILDREN-CHANGED:REMOVE index:0 CHILD:(role=ROLE_TOGGLE_BUTTON) role=ROLE_SECTION ENABLED,SENSITIVE,SHOWING,VISIBLE
STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT
CHILDREN-CHANGED:REMOVE index:0 CHILD:(role=ROLE_PUSH_BUTTON) role=ROLE_SECTION ENABLED,SENSITIVE,SHOWING,VISIBLE
STATE-CHANGE:PRESSED:TRUE role=ROLE_PUSH_BUTTON name='(null)' ENABLED,FOCUSABLE,SENSITIVE,SHOWING,VISIBLE
@@ -1 +1,3 @@
AXValueChanged on AXCheckBox AXSubrole=AXToggleButton AXValue=1
=== Start Continuation ===
AXValueChanged on AXButton
@@ -1,7 +1,7 @@
StructureChanged/ChildAdded on role=button
StructureChanged/ChildRemoved on role=document
StructureChanged/ChildrenReordered on role=document
AriaProperties changed on role=button
AriaRole changed on role=button
ToggleToggleState changed on role=button
=== Start Continuation ===
StructureChanged/ChildAdded on role=button
StructureChanged/ChildRemoved on role=document
StructureChanged/ChildrenReordered on role=document
AriaProperties changed on role=button
AriaRole changed on role=button
ToggleToggleState changed on role=button
@@ -1,11 +1,5 @@
EVENT_OBJECT_HIDE on <button#test> role=ROLE_SYSTEM_PUSHBUTTON FOCUSABLE
EVENT_OBJECT_REORDER on <body> role=ROLE_SYSTEM_GROUPING
EVENT_OBJECT_SHOW on <button#test> role=ROLE_SYSTEM_PUSHBUTTON PRESSED,FOCUSABLE
IA2_EVENT_TEXT_INSERTED on <body> role=ROLE_SYSTEM_GROUPING new_text={'<obj>' start=0 end=1}
IA2_EVENT_TEXT_REMOVED on <body> role=ROLE_SYSTEM_GROUPING old_text={'<obj>' start=0 end=1}
EVENT_OBJECT_STATECHANGE on <button#test> role=ROLE_SYSTEM_PUSHBUTTON PRESSED,FOCUSABLE
IA2_EVENT_ROLE_CHANGED on <button#test> role=ROLE_SYSTEM_PUSHBUTTON PRESSED,FOCUSABLE
=== Start Continuation ===
EVENT_OBJECT_HIDE on <button#test> role=ROLE_SYSTEM_PUSHBUTTON PRESSED,FOCUSABLE
EVENT_OBJECT_REORDER on <body> role=ROLE_SYSTEM_GROUPING
EVENT_OBJECT_SHOW on <button#test> role=ROLE_SYSTEM_PUSHBUTTON FOCUSABLE
IA2_EVENT_TEXT_INSERTED on <body> role=ROLE_SYSTEM_GROUPING new_text={'<obj>' start=0 end=1}
IA2_EVENT_TEXT_REMOVED on <body> role=ROLE_SYSTEM_GROUPING old_text={'<obj>' start=0 end=1}
EVENT_OBJECT_STATECHANGE on <button#test> role=ROLE_SYSTEM_PUSHBUTTON FOCUSABLE
IA2_EVENT_ROLE_CHANGED on <button#test> role=ROLE_SYSTEM_PUSHBUTTON FOCUSABLE
Expand Up @@ -4,5 +4,4 @@ CHILDREN-CHANGED:REMOVE index:1 CHILD:(role=ROLE_PUSH_BUTTON) role=ROLE_ENTRY EN
=== Start Continuation ===
CHILDREN-CHANGED:REMOVE index:1 CHILD:(role=ROLE_PUSH_BUTTON) role=ROLE_ENTRY EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT
=== Start Continuation ===
CHILDREN-CHANGED:ADD index:1 CHILD:(role=ROLE_PUSH_BUTTON) role=ROLE_ENTRY ENABLED,SENSITIVE,SHOWING,SINGLE-LINE,VISIBLE,SELECTABLE-TEXT
CHILDREN-CHANGED:REMOVE index:4 CHILD:(role=ROLE_PUSH_BUTTON) role=ROLE_DOCUMENT_WEB ENABLED,FOCUSABLE,FOCUSED,SENSITIVE,SHOWING,VISIBLE
PARENT-CHANGED PARENT:(role=ROLE_ENTRY name='role only, plain') role=ROLE_PUSH_BUTTON name='ok' ENABLED,FOCUSABLE,SENSITIVE,SHOWING,VISIBLE
Expand Up @@ -7,6 +7,4 @@ EVENT_OBJECT_VALUECHANGE on <div> role=ROLE_SYSTEM_TEXT name="focusable" value="
EVENT_OBJECT_HIDE on <button#btn3> role=ROLE_SYSTEM_PUSHBUTTON name="ok" FOCUSABLE IA2_STATE_EDITABLE
EVENT_OBJECT_VALUECHANGE on <div> role=ROLE_SYSTEM_TEXT name="editable" value="foo" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT
=== Start Continuation ===
EVENT_OBJECT_HIDE on <button#btn4> role=ROLE_SYSTEM_PUSHBUTTON name="ok" FOCUSABLE
EVENT_OBJECT_SHOW on <button#btn4> role=ROLE_SYSTEM_PUSHBUTTON name="ok" FOCUSABLE
EVENT_OBJECT_VALUECHANGE on <div#txt4> role=ROLE_SYSTEM_TEXT name="role only, plain" value="foook" IA2_STATE_SELECTABLE_TEXT,IA2_STATE_SINGLE_LINE
@@ -1,3 +1,3 @@
EVENT_OBJECT_HIDE on <div#heading-root.a> role=ROLE_SYSTEM_GROUPING name="Heading" level=2
EVENT_OBJECT_HIDE on <div.a> role=ROLE_SYSTEM_GROUPING INVISIBLE
EVENT_OBJECT_REORDER on <div> role=ROLE_SYSTEM_TOOLBAR IA2_STATE_HORIZONTAL
EVENT_OBJECT_SHOW on <div#banner-root.b> role=ROLE_SYSTEM_GROUPING name="Banner"
@@ -0,0 +1 @@

@@ -1,4 +1,4 @@
EVENT_OBJECT_HIDE on <div.a> role=ROLE_SYSTEM_GROUPING name="Heading" level=2
EVENT_OBJECT_HIDE on <div.a> role=ROLE_SYSTEM_GROUPING INVISIBLE
EVENT_OBJECT_REORDER on <div> role=ROLE_SYSTEM_TOOLBAR IA2_STATE_HORIZONTAL
EVENT_OBJECT_SHOW on <div.b> role=ROLE_SYSTEM_GROUPING name="Banner"
IA2_EVENT_TEXT_INSERTED on <div> role=ROLE_SYSTEM_TOOLBAR IA2_STATE_HORIZONTAL new_text={'<obj>' start=1 end=2}
Expand Down
Expand Up @@ -2,6 +2,3 @@ CHILDREN-CHANGED:REMOVE index:0 CHILD:(role=ROLE_PANEL) role=ROLE_LANDMARK ENABL
CHILDREN-CHANGED:REMOVE index:1 CHILD:(role=ROLE_PANEL) role=ROLE_LANDMARK ENABLED,SENSITIVE,SHOWING,VISIBLE
PARENT-CHANGED PARENT:(role=ROLE_LANDMARK name='(null)') role=ROLE_LINK name='1' ENABLED,SENSITIVE,SHOWING,VISIBLE
PARENT-CHANGED PARENT:(role=ROLE_LANDMARK name='(null)') role=ROLE_STATIC name='2' ENABLED,SENSITIVE,SHOWING,VISIBLE
STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT
STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT
STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT
Expand Up @@ -5,7 +5,5 @@ CHILDREN-CHANGED:ADD index:0 CHILD:(role=ROLE_MENU) role=ROLE_MENU_ITEM ENABLED,
STATE-CHANGE:SHOWING:TRUE role=ROLE_MENU name='(null)' ENABLED,SENSITIVE,SHOWING,VERTICAL,VISIBLE
=== Start Continuation ===
CHILDREN-CHANGED:REMOVE index:0 CHILD:(role=ROLE_MENU) role=ROLE_MENU_ITEM ENABLED,FOCUSABLE,SENSITIVE,SHOWING,VISIBLE
STATE-CHANGE:SHOWING:FALSE role=ROLE_MENU name='(null)' ENABLED,SENSITIVE,SHOWING,VERTICAL,VISIBLE
=== Start Continuation ===
CHILDREN-CHANGED:REMOVE index:0 CHILD:(role=ROLE_MENU) role=ROLE_DOCUMENT_WEB ENABLED,FOCUSABLE,FOCUSED,SENSITIVE,SHOWING,VISIBLE
STATE-CHANGE:SHOWING:FALSE role=ROLE_MENU name='menu' ENABLED,SENSITIVE,SHOWING,VERTICAL,VISIBLE
CHILDREN-CHANGED:REMOVE index:0 CHILD:(role=ROLE_MENU) role=ROLE_DOCUMENT_WEB ENABLED,FOCUSABLE,FOCUSED,SENSITIVE,SHOWING,VISIBLE
Expand Up @@ -2,6 +2,4 @@ AXMenuOpened on AXMenu AXDescription='menu'
=== Start Continuation ===
AXMenuOpened on AXMenu
=== Start Continuation ===
AXMenuClosed on AXWebArea
=== Start Continuation ===
AXMenuClosed on AXWebArea
=== Start Continuation ===

0 comments on commit 742a07c

Please sign in to comment.