summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/accessibility/browser_accessibility.h6
-rw-r--r--content/browser/accessibility/browser_accessibility_manager.cc9
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_win.cc40
-rw-r--r--content/browser/accessibility/browser_accessibility_win.cc209
-rw-r--r--content/browser/accessibility/browser_accessibility_win.h42
-rw-r--r--content/browser/accessibility/browser_accessibility_win_unittest.cc4
-rw-r--r--content/browser/accessibility/dump_accessibility_events_browsertest.cc5
-rw-r--r--content/test/data/accessibility/event/add-child-expected-win.txt2
-rw-r--r--content/test/data/accessibility/event/add-subtree-expected-win.txt3
-rw-r--r--content/test/data/accessibility/event/css-display-expected-win.txt2
-rw-r--r--content/test/data/accessibility/event/css-visibility-expected-win.txt2
-rw-r--r--content/test/data/accessibility/event/inner-html-change-expected-mac.txt1
-rw-r--r--content/test/data/accessibility/event/inner-html-change-expected-win.txt6
-rw-r--r--content/test/data/accessibility/event/inner-html-change.html15
-rw-r--r--content/test/data/accessibility/event/remove-hidden-attribute-expected-win.txt2
-rw-r--r--content/test/data/accessibility/event/remove-hidden-attribute-subtree-expected-win.txt3
-rw-r--r--content/test/data/accessibility/event/text-changed-expected-win.txt2
17 files changed, 216 insertions, 137 deletions
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h
index e8a7d38..47f19b7 100644
--- a/content/browser/accessibility/browser_accessibility.h
+++ b/content/browser/accessibility/browser_accessibility.h
@@ -58,14 +58,8 @@ class CONTENT_EXPORT BrowserAccessibility {
// its data changes.
virtual void OnDataChanged() {}
- // Called after an atomic update to the tree finished and this object
- // was created or changed in this update.
- virtual void OnUpdateFinished() {}
-
virtual void OnSubtreeWillBeDeleted() {}
- virtual void OnSubtreeCreationFinished() {}
-
// Called when the location changed.
virtual void OnLocationChanged() {}
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index 781eadd..6049901 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -433,15 +433,6 @@ void BrowserAccessibilityManager::OnNodeChanged(ui::AXNode* node) {
void BrowserAccessibilityManager::OnAtomicUpdateFinished(
bool root_changed,
const std::vector<ui::AXTreeDelegate::Change>& changes) {
- for (size_t i = 0; i < changes.size(); ++i) {
- BrowserAccessibility* obj = GetFromAXNode(changes[i].node);
- if (!obj)
- continue;
-
- obj->OnUpdateFinished();
- if (changes[i].type == AXTreeDelegate::SUBTREE_CREATED)
- GetFromAXNode(changes[i].node)->OnSubtreeCreationFinished();
- }
}
BrowserAccessibilityDelegate*
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index 8b9f30e..ae4f089 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -306,17 +306,39 @@ void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished(
OnWindowFocused();
}
- // BrowserAccessibilityManager::OnAtomicUpdateFinished calls
- // OnUpdateFinished() on each node in |changes|. However, the
- // IAccessibleText text for a node is a concatenatenation of all of its child
- // text nodes, so we can't compute a node's IAccessibleText in
- // OnUpdateFinished because its children may not have been updated yet.
- //
- // So we make a second pass here to update IAccessibleText.
+ // Do a sequence of Windows-specific updates on each node. Each one is
+ // done in a single pass that must complete before the next step starts.
+ // The first step moves win_attributes_ to old_win_attributes_ and then
+ // recomputes all of win_attributes_ other than IAccessibleText.
for (size_t i = 0; i < changes.size(); ++i) {
BrowserAccessibility* obj = GetFromAXNode(changes[i].node);
- if (obj && obj->IsNative())
- obj->ToBrowserAccessibilityWin()->UpdateIAccessibleText();
+ if (obj && obj->IsNative() && !obj->PlatformIsChildOfLeaf())
+ obj->ToBrowserAccessibilityWin()->UpdateStep1ComputeWinAttributes();
+ }
+
+ // The next step updates the hypertext of each node, which is a
+ // concatenation of all of its child text nodes, so it can't run until
+ // the text of all of the nodes was computed in the previous step.
+ for (size_t i = 0; i < changes.size(); ++i) {
+ BrowserAccessibility* obj = GetFromAXNode(changes[i].node);
+ if (obj && obj->IsNative() && !obj->PlatformIsChildOfLeaf())
+ obj->ToBrowserAccessibilityWin()->UpdateStep2ComputeHypertext();
+ }
+
+ // The third step fires events on nodes based on what's changed - like
+ // if the name, value, or description changed, or if the hypertext had
+ // text inserted or removed. It's able to figure out exactly what changed
+ // because we still have old_win_attributes_ populated.
+ // This step has to run after the previous two steps complete because the
+ // client may walk the tree when it receives any of these events.
+ // At the end, it deletes old_win_attributes_ since they're not needed
+ // anymore.
+ for (size_t i = 0; i < changes.size(); ++i) {
+ BrowserAccessibility* obj = GetFromAXNode(changes[i].node);
+ if (obj && obj->IsNative() && !obj->PlatformIsChildOfLeaf()) {
+ obj->ToBrowserAccessibilityWin()->UpdateStep3FireEvents(
+ changes[i].type == AXTreeDelegate::SUBTREE_CREATED);
+ }
}
}
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc
index 71534a4..e4d2f37 100644
--- a/content/browser/accessibility/browser_accessibility_win.cc
+++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -35,7 +35,7 @@ const GUID GUID_IAccessibleContentDocument = {
0xa5d8e1f3, 0x3571, 0x4d8f,
0x95, 0x21, 0x07, 0xed, 0x28, 0xfb, 0x07, 0x2e};
-const base::char16 BrowserAccessibilityWin::kEmbeddedCharacter[] = L"\xfffc";
+const base::char16 BrowserAccessibilityWin::kEmbeddedCharacter = L'\xfffc';
// static
LONG BrowserAccessibilityWin::next_unique_id_win_ =
@@ -2174,12 +2174,15 @@ STDMETHODIMP BrowserAccessibilityWin::get_newText(IA2TextSegment* new_text) {
if (!new_text)
return E_INVALIDARG;
+ if (!old_win_attributes_)
+ return E_FAIL;
+
int start, old_len, new_len;
ComputeHypertextRemovedAndInserted(&start, &old_len, &new_len);
if (new_len == 0)
return E_FAIL;
- base::string16 substr = hypertext_.substr(start, new_len);
+ base::string16 substr = hypertext().substr(start, new_len);
new_text->text = SysAllocString(substr.c_str());
new_text->start = static_cast<long>(start);
new_text->end = static_cast<long>(start + new_len);
@@ -2193,12 +2196,16 @@ STDMETHODIMP BrowserAccessibilityWin::get_oldText(IA2TextSegment* old_text) {
if (!old_text)
return E_INVALIDARG;
+ if (!old_win_attributes_)
+ return E_FAIL;
+
int start, old_len, new_len;
ComputeHypertextRemovedAndInserted(&start, &old_len, &new_len);
if (old_len == 0)
return E_FAIL;
- base::string16 substr = old_hypertext_.substr(start, old_len);
+ base::string16 old_hypertext = old_win_attributes_->hypertext;
+ base::string16 substr = old_hypertext.substr(start, old_len);
old_text->text = SysAllocString(substr.c_str());
old_text->start = static_cast<long>(start);
old_text->end = static_cast<long>(start + old_len);
@@ -2302,7 +2309,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nHyperlinks(long* hyperlink_count) {
if (!hyperlink_count)
return E_INVALIDARG;
- *hyperlink_count = hyperlink_offset_to_index_.size();
+ *hyperlink_count = hyperlink_offset_to_index().size();
return S_OK;
}
@@ -2314,14 +2321,19 @@ STDMETHODIMP BrowserAccessibilityWin::get_hyperlink(
if (!hyperlink ||
index < 0 ||
- index >= static_cast<long>(hyperlinks_.size())) {
+ index >= static_cast<long>(hyperlinks().size())) {
return E_INVALIDARG;
}
+ int32 id = hyperlinks()[index];
BrowserAccessibilityWin* child =
- InternalGetChild(hyperlinks_[index])->ToBrowserAccessibilityWin();
- *hyperlink = static_cast<IAccessibleHyperlink*>(child->NewReference());
- return S_OK;
+ manager()->GetFromID(id)->ToBrowserAccessibilityWin();
+ if (child) {
+ *hyperlink = static_cast<IAccessibleHyperlink*>(child->NewReference());
+ return S_OK;
+ }
+
+ return E_FAIL;
}
STDMETHODIMP BrowserAccessibilityWin::get_hyperlinkIndex(
@@ -2336,13 +2348,13 @@ STDMETHODIMP BrowserAccessibilityWin::get_hyperlinkIndex(
*hyperlink_index = -1;
if (char_index < 0 ||
- char_index >= static_cast<long>(hypertext_.size())) {
+ char_index >= static_cast<long>(hypertext().size())) {
return E_INVALIDARG;
}
std::map<int32, int32>::iterator it =
- hyperlink_offset_to_index_.find(char_index);
- if (it == hyperlink_offset_to_index_.end())
+ hyperlink_offset_to_index().find(char_index);
+ if (it == hyperlink_offset_to_index().end())
return E_FAIL;
*hyperlink_index = it->second;
@@ -2943,21 +2955,10 @@ HRESULT WINAPI BrowserAccessibilityWin::InternalQueryInterface(
// Private methods.
//
-// Called every time this node's data changes, while the tree update is
-// still in progress.
-void BrowserAccessibilityWin::OnDataChanged() {
- BrowserAccessibility::OnDataChanged();
-}
-
-// Called every time this node's data changes, after an atomic tree update.
-void BrowserAccessibilityWin::OnUpdateFinished() {
- BrowserAccessibility::OnUpdateFinished();
-
- if (PlatformIsChildOfLeaf())
- return;
-
- bool is_new_object = ia_role() == 0 && role_name().empty();
-
+void BrowserAccessibilityWin::UpdateStep1ComputeWinAttributes() {
+ // Swap win_attributes_ to old_win_attributes_, allowing us to see
+ // exactly what changed and fire appropriate events. Note that
+ // old_win_attributes_ is cleared at the end of UpdateStep3FireEvents.
old_win_attributes_.swap(win_attributes_);
win_attributes_.reset(new WinAttributes());
@@ -3195,7 +3196,31 @@ void BrowserAccessibilityWin::OnUpdateFinished() {
win_attributes_->ia_role = ROLE_SYSTEM_GROUPING;
win_attributes_->ia2_role = ROLE_SYSTEM_GROUPING;
}
+}
+void BrowserAccessibilityWin::UpdateStep2ComputeHypertext() {
+ // Construct the hypertext for this node, which contains the concatenation
+ // of all of the static text of this node's children and an embedded object
+ // character for all non-static-text children. Build up a map from the
+ // character index of each embedded object character to the id of the
+ // child object it points to.
+ for (unsigned int i = 0; i < PlatformChildCount(); ++i) {
+ BrowserAccessibilityWin* child =
+ PlatformGetChild(i)->ToBrowserAccessibilityWin();
+ if (child->GetRole() == ui::AX_ROLE_STATIC_TEXT) {
+ win_attributes_->hypertext += child->name();
+ } else {
+ int32 char_offset = hypertext().size();
+ int32 child_id = child->GetId();
+ int32 index = hyperlinks().size();
+ win_attributes_->hyperlink_offset_to_index[char_offset] = index;
+ win_attributes_->hyperlinks.push_back(child_id);
+ win_attributes_->hypertext += kEmbeddedCharacter;
+ }
+ }
+}
+
+void BrowserAccessibilityWin::UpdateStep3FireEvents(bool is_subtree_creation) {
BrowserAccessibilityManagerWin* manager =
this->manager()->ToBrowserAccessibilityManagerWin();
@@ -3205,22 +3230,24 @@ void BrowserAccessibilityWin::OnUpdateFinished() {
manager->NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, this);
}
- // Fire an event if the name, description, help, or value changes.
- if (!is_new_object) {
- if (name != old_win_attributes_->name)
+ // Fire an event when a new subtree is created.
+ if (is_subtree_creation)
+ manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SHOW, this);
+
+ // The rest of the events only fire on changes, not on new objects.
+ if (old_win_attributes_->ia_role != 0 ||
+ !old_win_attributes_->role_name.empty()) {
+ // Fire an event if the name, description, help, or value changes.
+ if (name() != old_win_attributes_->name)
manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, this);
- if (description != old_win_attributes_->description)
+ if (description() != old_win_attributes_->description)
manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_DESCRIPTIONCHANGE, this);
- if (help != old_win_attributes_->help)
+ if (help() != old_win_attributes_->help)
manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_HELPCHANGE, this);
- if (value != old_win_attributes_->value)
+ if (value() != old_win_attributes_->value)
manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_VALUECHANGE, this);
- if (ia_state() != old_win_attributes_->ia_state) {
- LOG(INFO) << "State change:"
- << " from " << old_win_attributes_->ia_state
- << " to " << ia_state();
+ if (ia_state() != old_win_attributes_->ia_state)
manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_STATECHANGE, this);
- }
// Normally focus events are handled elsewhere, however
// focus for managed descendants is platform-specific.
@@ -3256,57 +3283,32 @@ void BrowserAccessibilityWin::OnUpdateFinished() {
}
// Changing a static text node can affect the IAccessibleText hypertext
- // of the parent node, so force it to be recomputed here.
- if (GetParent() &&
+ // of the parent node, so force an update on the parent.
+ BrowserAccessibilityWin* parent = GetParent()->ToBrowserAccessibilityWin();
+ if (parent &&
GetRole() == ui::AX_ROLE_STATIC_TEXT &&
- name != old_win_attributes_->name) {
- GetParent()->ToBrowserAccessibilityWin()->UpdateIAccessibleText();
- }
- }
-
- old_win_attributes_.reset(nullptr);
-}
-
-void BrowserAccessibilityWin::UpdateIAccessibleText() {
- old_hypertext_ = hypertext_;
- hypertext_.clear();
-
- // Construct the hypertext for this node.
- hyperlink_offset_to_index_.clear();
- hyperlinks_.clear();
- for (unsigned int i = 0; i < PlatformChildCount(); ++i) {
- BrowserAccessibilityWin* child =
- PlatformGetChild(i)->ToBrowserAccessibilityWin();
- if (child->GetRole() == ui::AX_ROLE_STATIC_TEXT) {
- hypertext_ += child->name();
- } else {
- hyperlink_offset_to_index_[hypertext_.size()] =
- hyperlinks_.size();
- hypertext_ += kEmbeddedCharacter;
- hyperlinks_.push_back(i);
+ name() != old_win_attributes_->name) {
+ parent->UpdateStep1ComputeWinAttributes();
+ parent->UpdateStep2ComputeHypertext();
+ parent->UpdateStep3FireEvents(false);
}
- }
- DCHECK_EQ(hyperlink_offset_to_index_.size(), hyperlinks_.size());
-
- if (hypertext_ != old_hypertext_) {
- BrowserAccessibilityManagerWin* manager =
- this->manager()->ToBrowserAccessibilityManagerWin();
+ // Fire hypertext-related events.
int start, old_len, new_len;
ComputeHypertextRemovedAndInserted(&start, &old_len, &new_len);
- if (old_len) {
+ if (old_len > 0) {
// In-process screen readers may call IAccessibleText::get_oldText
- // to retrieve the text that was removed.
+ // in reaction to this event to retrieve the text that was removed.
manager->MaybeCallNotifyWinEvent(IA2_EVENT_TEXT_REMOVED, this);
}
- if (new_len) {
+ if (new_len > 0) {
// In-process screen readers may call IAccessibleText::get_newText
- // to retrieve the text that was inserted.
+ // in reaction to this event to retrieve the text that was inserted.
manager->MaybeCallNotifyWinEvent(IA2_EVENT_TEXT_INSERTED, this);
}
}
- old_hypertext_.clear();
+ old_win_attributes_.reset(nullptr);
}
void BrowserAccessibilityWin::OnSubtreeWillBeDeleted() {
@@ -3314,11 +3316,6 @@ void BrowserAccessibilityWin::OnSubtreeWillBeDeleted() {
EVENT_OBJECT_HIDE, this);
}
-void BrowserAccessibilityWin::OnSubtreeCreationFinished() {
- manager()->ToBrowserAccessibilityManagerWin()->MaybeCallNotifyWinEvent(
- EVENT_OBJECT_SHOW, this);
-}
-
void BrowserAccessibilityWin::NativeAddReference() {
AddRef();
}
@@ -3433,30 +3430,70 @@ base::string16 BrowserAccessibilityWin::GetValueText() {
base::string16 BrowserAccessibilityWin::TextForIAccessibleText() {
if (IsEditableText())
return value();
- return (GetRole() == ui::AX_ROLE_STATIC_TEXT) ? name() : hypertext_;
+ return (GetRole() == ui::AX_ROLE_STATIC_TEXT) ? name() : hypertext();
+}
+
+bool BrowserAccessibilityWin::IsSameHypertextCharacter(size_t old_char_index,
+ size_t new_char_index) {
+ CHECK(old_win_attributes_);
+
+ // For anything other than the "embedded character", we just compare the
+ // characters directly.
+ base::char16 old_ch = old_win_attributes_->hypertext[old_char_index];
+ base::char16 new_ch = win_attributes_->hypertext[new_char_index];
+ if (old_ch != new_ch)
+ return false;
+ if (old_ch == new_ch && new_ch != kEmbeddedCharacter)
+ return true;
+
+ // If it's an embedded character, they're only identical if the child id
+ // the hyperlink points to is the same.
+ std::map<int32, int32>& old_offset_to_index =
+ old_win_attributes_->hyperlink_offset_to_index;
+ std::vector<int32>& old_hyperlinks = old_win_attributes_->hyperlinks;
+ int32 old_hyperlinks_count = static_cast<int32>(old_hyperlinks.size());
+ std::map<int32, int32>::iterator iter;
+ iter = old_offset_to_index.find(old_char_index);
+ int old_index = (iter != old_offset_to_index.end()) ? iter->second : -1;
+ int old_child_id = (old_index >= 0 && old_index < old_hyperlinks_count) ?
+ old_hyperlinks[old_index] : -1;
+
+ std::map<int32, int32>& new_offset_to_index =
+ win_attributes_->hyperlink_offset_to_index;
+ std::vector<int32>& new_hyperlinks = win_attributes_->hyperlinks;
+ int32 new_hyperlinks_count = static_cast<int32>(new_hyperlinks.size());
+ iter = new_offset_to_index.find(new_char_index);
+ int new_index = (iter != new_offset_to_index.end()) ? iter->second : -1;
+ int new_child_id = (new_index >= 0 && new_index < new_hyperlinks_count) ?
+ new_hyperlinks[new_index] : -1;
+
+ return old_child_id == new_child_id;
}
void BrowserAccessibilityWin::ComputeHypertextRemovedAndInserted(
int* start, int* old_len, int* new_len) {
+ CHECK(old_win_attributes_);
+
*start = 0;
*old_len = 0;
*new_len = 0;
- const base::string16& old_text = old_hypertext_;
- const base::string16& new_text = hypertext_;
+ const base::string16& old_text = old_win_attributes_->hypertext;
+ const base::string16& new_text = hypertext();
size_t common_prefix = 0;
while (common_prefix < old_text.size() &&
common_prefix < new_text.size() &&
- old_text[common_prefix] == new_text[common_prefix]) {
+ IsSameHypertextCharacter(common_prefix, common_prefix)) {
++common_prefix;
}
size_t common_suffix = 0;
while (common_prefix + common_suffix < old_text.size() &&
common_prefix + common_suffix < new_text.size() &&
- old_text[old_text.size() - common_suffix - 1] ==
- new_text[new_text.size() - common_suffix - 1]) {
+ IsSameHypertextCharacter(
+ old_text.size() - common_suffix - 1,
+ new_text.size() - common_suffix - 1)) {
++common_suffix;
}
diff --git a/content/browser/accessibility/browser_accessibility_win.h b/content/browser/accessibility/browser_accessibility_win.h
index 305daba..c5da608 100644
--- a/content/browser/accessibility/browser_accessibility_win.h
+++ b/content/browser/accessibility/browser_accessibility_win.h
@@ -82,7 +82,7 @@ BrowserAccessibilityWin
// Represents a non-static text node in IAccessibleHypertext. This character
// is embedded in the response to IAccessibleText::get_text, indicating the
// position where a non-static text child object appears.
- CONTENT_EXPORT static const base::char16 kEmbeddedCharacter[];
+ CONTENT_EXPORT static const base::char16 kEmbeddedCharacter;
// Mappings from roles and states to human readable strings. Initialize
// with |InitializeStringMaps|.
@@ -97,15 +97,18 @@ BrowserAccessibilityWin
// like NotifyWinEvent, and as the unique ID for IAccessible2 and ISimpleDOM.
LONG unique_id_win() const { return unique_id_win_; }
- CONTENT_EXPORT void UpdateIAccessibleText();
+ // Called after an atomic tree update completes. See
+ // BrowserAccessibilityManagerWin::OnAtomicUpdateFinished for more
+ // details on what these do.
+ CONTENT_EXPORT void UpdateStep1ComputeWinAttributes();
+ CONTENT_EXPORT void UpdateStep2ComputeHypertext();
+ CONTENT_EXPORT void UpdateStep3FireEvents(bool is_subtree_creation);
+ CONTENT_EXPORT void UpdateStep4DeleteOldWinAttributes();
//
// BrowserAccessibility methods.
//
- CONTENT_EXPORT virtual void OnDataChanged() override;
- CONTENT_EXPORT virtual void OnUpdateFinished() override;
CONTENT_EXPORT virtual void OnSubtreeWillBeDeleted() override;
- CONTENT_EXPORT virtual void OnSubtreeCreationFinished() override;
CONTENT_EXPORT virtual void NativeAddReference() override;
CONTENT_EXPORT virtual void NativeReleaseReference() override;
CONTENT_EXPORT virtual bool IsNative() const override;
@@ -791,6 +794,11 @@ BrowserAccessibilityWin
base::string16 description() const { return win_attributes_->description; }
base::string16 help() const { return win_attributes_->help; }
base::string16 value() const { return win_attributes_->value; }
+ base::string16 hypertext() const { return win_attributes_->hypertext; }
+ std::map<int32, int32>& hyperlink_offset_to_index() const {
+ return win_attributes_->hyperlink_offset_to_index;
+ }
+ std::vector<int32>& hyperlinks() const { return win_attributes_->hyperlinks; }
private:
// Add one to the reference count and return the same object. Always
@@ -842,6 +850,7 @@ BrowserAccessibilityWin
// be the name, it may be the value, etc. depending on the role.
base::string16 TextForIAccessibleText();
+ bool IsSameHypertextCharacter(size_t old_char_index, size_t new_char_index);
void ComputeHypertextRemovedAndInserted(
int* start, int* old_len, int* new_len);
@@ -889,6 +898,16 @@ BrowserAccessibilityWin
// IAccessible2 attributes.
std::vector<base::string16> ia2_attributes;
+
+ // Hypertext.
+ base::string16 hypertext;
+
+ // Maps the |hypertext_| embedded character offset to an index in
+ // |hyperlinks_|.
+ std::map<int32, int32> hyperlink_offset_to_index;
+
+ // The id of a BrowserAccessibilityWin for each hyperlink.
+ std::vector<int32> hyperlinks;
};
scoped_ptr<WinAttributes> win_attributes_;
@@ -900,19 +919,6 @@ BrowserAccessibilityWin
// Relationships between this node and other nodes.
std::vector<BrowserAccessibilityRelation*> relations_;
- // IAccessibleText text of this node including
- // embedded hyperlink characters.
- base::string16 old_hypertext_;
- base::string16 hypertext_;
-
- // Maps the |hypertext_| embedded character offset to an index in
- // |hyperlinks_|.
- std::map<int32, int32> hyperlink_offset_to_index_;
-
- // Collection of non-static text child indicies, each of which corresponds to
- // a hyperlink.
- std::vector<int32> hyperlinks_;
-
// The previous scroll position, so we can tell if this object scrolled.
int previous_scroll_x_;
int previous_scroll_y_;
diff --git a/content/browser/accessibility/browser_accessibility_win_unittest.cc b/content/browser/accessibility/browser_accessibility_win_unittest.cc
index 7b830d2..e1a3ac1 100644
--- a/content/browser/accessibility/browser_accessibility_win_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -442,7 +442,7 @@ TEST_F(BrowserAccessibilityTest, TestSimpleHypertext) {
CountedBrowserAccessibility::reset();
scoped_ptr<BrowserAccessibilityManager> manager(
BrowserAccessibilityManager::Create(
- MakeAXTreeUpdate(root, root, text1, text2),
+ MakeAXTreeUpdate(root, text1, text2),
NULL, new CountedBrowserAccessibilityFactory()));
ASSERT_EQ(3, CountedBrowserAccessibility::num_instances());
@@ -547,7 +547,7 @@ TEST_F(BrowserAccessibilityTest, TestComplexHypertext) {
base::win::ScopedBstr text;
ASSERT_EQ(S_OK, root_obj->get_text(0, text_len, text.Receive()));
const std::string embed = base::UTF16ToUTF8(
- BrowserAccessibilityWin::kEmbeddedCharacter);
+ base::string16(1, BrowserAccessibilityWin::kEmbeddedCharacter));
EXPECT_EQ(text1_name + embed + text2_name + embed,
base::UTF16ToUTF8(base::string16(text)));
text.Reset();
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
index 5247dd9..6d198fb 100644
--- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -195,6 +195,11 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
+ AccessibilityEventsInnerHtmlChange) {
+ RunEventTest(FILE_PATH_LITERAL("inner-html-change.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
AccessibilityEventsInputTypeTextValueChanged) {
RunEventTest(FILE_PATH_LITERAL("input-type-text-value-changed.html"));
}
diff --git a/content/test/data/accessibility/event/add-child-expected-win.txt b/content/test/data/accessibility/event/add-child-expected-win.txt
index 77d1194..5a2f0a8 100644
--- a/content/test/data/accessibility/event/add-child-expected-win.txt
+++ b/content/test/data/accessibility/event/add-child-expected-win.txt
@@ -1,3 +1,3 @@
-EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_LISTITEM name="Item 3"
IA2_EVENT_TEXT_INSERTED on role=ROLE_SYSTEM_LIST new_text={'<obj>' start=2 end=3}
+EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_LISTITEM name="Item 3"
EVENT_OBJECT_REORDER on role=ROLE_SYSTEM_LIST
diff --git a/content/test/data/accessibility/event/add-subtree-expected-win.txt b/content/test/data/accessibility/event/add-subtree-expected-win.txt
index d169afc..5a2f0a8 100644
--- a/content/test/data/accessibility/event/add-subtree-expected-win.txt
+++ b/content/test/data/accessibility/event/add-subtree-expected-win.txt
@@ -1,4 +1,3 @@
-EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_LISTITEM name="Item 3"
IA2_EVENT_TEXT_INSERTED on role=ROLE_SYSTEM_LIST new_text={'<obj>' start=2 end=3}
-IA2_EVENT_TEXT_INSERTED on role=ROLE_SYSTEM_LISTITEM name="Item 3" new_text={'<obj>Item 3' start=0 end=7}
+EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_LISTITEM name="Item 3"
EVENT_OBJECT_REORDER on role=ROLE_SYSTEM_LIST
diff --git a/content/test/data/accessibility/event/css-display-expected-win.txt b/content/test/data/accessibility/event/css-display-expected-win.txt
index 169dda2..8b623f2 100644
--- a/content/test/data/accessibility/event/css-display-expected-win.txt
+++ b/content/test/data/accessibility/event/css-display-expected-win.txt
@@ -1,3 +1,5 @@
EVENT_OBJECT_HIDE on role=div name="Heading"
+IA2_EVENT_TEXT_REMOVED on role=ROLE_SYSTEM_TOOLBAR old_text={'<obj>' start=0 end=1}
+IA2_EVENT_TEXT_INSERTED on role=ROLE_SYSTEM_TOOLBAR new_text={'<obj>' start=0 end=1}
EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_GROUPING name="Banner"
EVENT_OBJECT_REORDER on role=ROLE_SYSTEM_TOOLBAR
diff --git a/content/test/data/accessibility/event/css-visibility-expected-win.txt b/content/test/data/accessibility/event/css-visibility-expected-win.txt
index 169dda2..8b623f2 100644
--- a/content/test/data/accessibility/event/css-visibility-expected-win.txt
+++ b/content/test/data/accessibility/event/css-visibility-expected-win.txt
@@ -1,3 +1,5 @@
EVENT_OBJECT_HIDE on role=div name="Heading"
+IA2_EVENT_TEXT_REMOVED on role=ROLE_SYSTEM_TOOLBAR old_text={'<obj>' start=0 end=1}
+IA2_EVENT_TEXT_INSERTED on role=ROLE_SYSTEM_TOOLBAR new_text={'<obj>' start=0 end=1}
EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_GROUPING name="Banner"
EVENT_OBJECT_REORDER on role=ROLE_SYSTEM_TOOLBAR
diff --git a/content/test/data/accessibility/event/inner-html-change-expected-mac.txt b/content/test/data/accessibility/event/inner-html-change-expected-mac.txt
new file mode 100644
index 0000000..81e1652
--- /dev/null
+++ b/content/test/data/accessibility/event/inner-html-change-expected-mac.txt
@@ -0,0 +1 @@
+#<skip -- need to generate>
diff --git a/content/test/data/accessibility/event/inner-html-change-expected-win.txt b/content/test/data/accessibility/event/inner-html-change-expected-win.txt
new file mode 100644
index 0000000..69e831bdf
--- /dev/null
+++ b/content/test/data/accessibility/event/inner-html-change-expected-win.txt
@@ -0,0 +1,6 @@
+EVENT_OBJECT_HIDE on role=h1 name="A"
+EVENT_OBJECT_HIDE on role=P
+IA2_EVENT_TEXT_REMOVED on role=ROLE_SYSTEM_GROUPING old_text={'<obj><obj>' start=0 end=2}
+IA2_EVENT_TEXT_INSERTED on role=ROLE_SYSTEM_GROUPING new_text={'<obj><obj>' start=0 end=2}
+EVENT_OBJECT_SHOW on role=h1 name="C"
+EVENT_OBJECT_SHOW on role=P
diff --git a/content/test/data/accessibility/event/inner-html-change.html b/content/test/data/accessibility/event/inner-html-change.html
new file mode 100644
index 0000000..ba2c2ff
--- /dev/null
+++ b/content/test/data/accessibility/event/inner-html-change.html
@@ -0,0 +1,15 @@
+<!--
+The children changed / reorder event is fired an unpredictable number of times.
+@WIN-DENY:EVENT_OBJECT_REORDER*
+-->
+<!DOCTYPE html>
+<html>
+<body>
+<div role="group" id="main"><h1>A</h1><p>B</p></div>
+<script>
+ function go() {
+ document.querySelector('#main').innerHTML = '<h1>C</h1><p>D</p>';
+ }
+</script>
+</body>
+</html>
diff --git a/content/test/data/accessibility/event/remove-hidden-attribute-expected-win.txt b/content/test/data/accessibility/event/remove-hidden-attribute-expected-win.txt
index 77d1194..5a2f0a8 100644
--- a/content/test/data/accessibility/event/remove-hidden-attribute-expected-win.txt
+++ b/content/test/data/accessibility/event/remove-hidden-attribute-expected-win.txt
@@ -1,3 +1,3 @@
-EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_LISTITEM name="Item 3"
IA2_EVENT_TEXT_INSERTED on role=ROLE_SYSTEM_LIST new_text={'<obj>' start=2 end=3}
+EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_LISTITEM name="Item 3"
EVENT_OBJECT_REORDER on role=ROLE_SYSTEM_LIST
diff --git a/content/test/data/accessibility/event/remove-hidden-attribute-subtree-expected-win.txt b/content/test/data/accessibility/event/remove-hidden-attribute-subtree-expected-win.txt
index d169afc..5a2f0a8 100644
--- a/content/test/data/accessibility/event/remove-hidden-attribute-subtree-expected-win.txt
+++ b/content/test/data/accessibility/event/remove-hidden-attribute-subtree-expected-win.txt
@@ -1,4 +1,3 @@
-EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_LISTITEM name="Item 3"
IA2_EVENT_TEXT_INSERTED on role=ROLE_SYSTEM_LIST new_text={'<obj>' start=2 end=3}
-IA2_EVENT_TEXT_INSERTED on role=ROLE_SYSTEM_LISTITEM name="Item 3" new_text={'<obj>Item 3' start=0 end=7}
+EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_LISTITEM name="Item 3"
EVENT_OBJECT_REORDER on role=ROLE_SYSTEM_LIST
diff --git a/content/test/data/accessibility/event/text-changed-expected-win.txt b/content/test/data/accessibility/event/text-changed-expected-win.txt
index 98953b9..92c253f 100644
--- a/content/test/data/accessibility/event/text-changed-expected-win.txt
+++ b/content/test/data/accessibility/event/text-changed-expected-win.txt
@@ -1,5 +1,5 @@
EVENT_OBJECT_HIDE on role=ROLE_SYSTEM_STATICTEXT name="Para"
-EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_STATICTEXT name="Modified Para"
IA2_EVENT_TEXT_INSERTED on role=P new_text={'Modified ' start=0 end=9}
+EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_STATICTEXT name="Modified Para"
EVENT_OBJECT_NAMECHANGE on role=ROLE_SYSTEM_STATICTEXT name="Modified Heading"
IA2_EVENT_TEXT_INSERTED on role=h2 name="Heading" new_text={'Modified ' start=0 end=9}