| Index: content/browser/accessibility/browser_accessibility_com_win.cc
|
| diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc
|
| index 13b61e85215b7215b9e8791ce2e1fa7b088c25aa..bf705ee55fd79c85f950c08fadab221ff2f5f5a3 100644
|
| --- a/content/browser/accessibility/browser_accessibility_com_win.cc
|
| +++ b/content/browser/accessibility/browser_accessibility_com_win.cc
|
| @@ -39,10 +39,6 @@ const uint32_t kScreenReaderAndHTMLAccessibilityModes =
|
| content::AccessibilityMode::kScreenReader |
|
| content::AccessibilityMode::kHTML;
|
|
|
| -const WCHAR* const IA2_RELATION_DETAILS = L"details";
|
| -const WCHAR* const IA2_RELATION_DETAILS_FOR = L"detailsFor";
|
| -const WCHAR* const IA2_RELATION_ERROR_MESSAGE = L"errorMessage";
|
| -
|
| namespace content {
|
|
|
| using AXPlatformPositionInstance = AXPlatformPosition::AXPositionInstance;
|
| @@ -69,153 +65,6 @@ void AddAccessibilityModeFlags(AccessibilityMode mode_flags) {
|
| }
|
|
|
| //
|
| -// BrowserAccessibilityRelation
|
| -//
|
| -// A simple implementation of IAccessibleRelation, used to represent
|
| -// a relationship between two accessible nodes in the tree.
|
| -//
|
| -
|
| -class BrowserAccessibilityRelation
|
| - : public CComObjectRootEx<CComMultiThreadModel>,
|
| - public IAccessibleRelation {
|
| - BEGIN_COM_MAP(BrowserAccessibilityRelation)
|
| - COM_INTERFACE_ENTRY(IAccessibleRelation)
|
| - END_COM_MAP()
|
| -
|
| - CONTENT_EXPORT BrowserAccessibilityRelation() {}
|
| - CONTENT_EXPORT virtual ~BrowserAccessibilityRelation() {}
|
| -
|
| - CONTENT_EXPORT void Initialize(BrowserAccessibilityComWin* owner,
|
| - const base::string16& type);
|
| - CONTENT_EXPORT void AddTarget(int target_id);
|
| - CONTENT_EXPORT void RemoveTarget(int target_id);
|
| -
|
| - // Accessors.
|
| - const base::string16& get_type() const { return type_; }
|
| - const std::vector<int>& get_target_ids() const { return target_ids_; }
|
| -
|
| - // IAccessibleRelation methods.
|
| - CONTENT_EXPORT STDMETHODIMP get_relationType(BSTR* relation_type) override;
|
| - CONTENT_EXPORT STDMETHODIMP get_nTargets(long* n_targets) override;
|
| - CONTENT_EXPORT STDMETHODIMP get_target(long target_index,
|
| - IUnknown** target) override;
|
| - CONTENT_EXPORT STDMETHODIMP get_targets(long max_targets,
|
| - IUnknown** targets,
|
| - long* n_targets) override;
|
| -
|
| - // IAccessibleRelation methods not implemented.
|
| - CONTENT_EXPORT STDMETHODIMP
|
| - get_localizedRelationType(BSTR* relation_type) override {
|
| - return E_NOTIMPL;
|
| - }
|
| -
|
| - private:
|
| - base::string16 type_;
|
| - base::win::ScopedComPtr<BrowserAccessibilityComWin> owner_;
|
| - std::vector<int> target_ids_;
|
| -};
|
| -
|
| -void BrowserAccessibilityRelation::Initialize(BrowserAccessibilityComWin* owner,
|
| - const base::string16& type) {
|
| - owner_ = owner;
|
| - type_ = type;
|
| -}
|
| -
|
| -void BrowserAccessibilityRelation::AddTarget(int target_id) {
|
| - target_ids_.push_back(target_id);
|
| -}
|
| -
|
| -void BrowserAccessibilityRelation::RemoveTarget(int target_id) {
|
| - target_ids_.erase(
|
| - std::remove(target_ids_.begin(), target_ids_.end(), target_id),
|
| - target_ids_.end());
|
| -}
|
| -
|
| -STDMETHODIMP BrowserAccessibilityRelation::get_relationType(
|
| - BSTR* relation_type) {
|
| - if (!relation_type)
|
| - return E_INVALIDARG;
|
| -
|
| - if (!owner_->owner())
|
| - return E_FAIL;
|
| -
|
| - *relation_type = SysAllocString(type_.c_str());
|
| - DCHECK(*relation_type);
|
| - return S_OK;
|
| -}
|
| -
|
| -STDMETHODIMP BrowserAccessibilityRelation::get_nTargets(long* n_targets) {
|
| - if (!n_targets)
|
| - return E_INVALIDARG;
|
| -
|
| - if (!owner_->owner())
|
| - return E_FAIL;
|
| -
|
| - *n_targets = static_cast<long>(target_ids_.size());
|
| -
|
| - for (long i = *n_targets - 1; i >= 0; --i) {
|
| - BrowserAccessibilityComWin* result = owner_->GetFromID(target_ids_[i]);
|
| - if (!result || !result->owner()) {
|
| - *n_targets = 0;
|
| - break;
|
| - }
|
| - }
|
| - return S_OK;
|
| -}
|
| -
|
| -STDMETHODIMP BrowserAccessibilityRelation::get_target(long target_index,
|
| - IUnknown** target) {
|
| - if (!target)
|
| - return E_INVALIDARG;
|
| -
|
| - if (!owner_->owner())
|
| - return E_FAIL;
|
| -
|
| - auto* manager = owner_->Manager();
|
| - if (!manager)
|
| - return E_FAIL;
|
| -
|
| - if (target_index < 0 ||
|
| - target_index >= static_cast<long>(target_ids_.size())) {
|
| - return E_INVALIDARG;
|
| - }
|
| -
|
| - BrowserAccessibility* result = manager->GetFromID(target_ids_[target_index]);
|
| - if (!result || !result->instance_active())
|
| - return E_FAIL;
|
| -
|
| - *target = static_cast<IAccessible*>(
|
| - ToBrowserAccessibilityComWin(result)->NewReference());
|
| - return S_OK;
|
| -}
|
| -
|
| -STDMETHODIMP BrowserAccessibilityRelation::get_targets(long max_targets,
|
| - IUnknown** targets,
|
| - long* n_targets) {
|
| - if (!targets || !n_targets)
|
| - return E_INVALIDARG;
|
| -
|
| - if (!owner_->owner())
|
| - return E_FAIL;
|
| -
|
| - long count = static_cast<long>(target_ids_.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;
|
| -}
|
| -
|
| -//
|
| // BrowserAccessibilityComWin::WinAttributes
|
| //
|
|
|
| @@ -234,8 +83,6 @@ BrowserAccessibilityComWin::BrowserAccessibilityComWin()
|
| previous_scroll_y_(0) {}
|
|
|
| BrowserAccessibilityComWin::~BrowserAccessibilityComWin() {
|
| - for (BrowserAccessibilityRelation* relation : relations_)
|
| - relation->Release();
|
| }
|
|
|
| //
|
| @@ -326,14 +173,7 @@ STDMETHODIMP BrowserAccessibilityComWin::get_indexInParent(
|
| STDMETHODIMP BrowserAccessibilityComWin::get_nRelations(LONG* n_relations) {
|
| WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_RELATIONS);
|
| AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes);
|
| - if (!owner())
|
| - return E_FAIL;
|
| -
|
| - if (!n_relations)
|
| - return E_INVALIDARG;
|
| -
|
| - *n_relations = relations_.size();
|
| - return S_OK;
|
| + return AXPlatformNodeWin::get_nRelations(n_relations);
|
| }
|
|
|
| STDMETHODIMP BrowserAccessibilityComWin::get_relation(
|
| @@ -341,20 +181,7 @@ STDMETHODIMP BrowserAccessibilityComWin::get_relation(
|
| IAccessibleRelation** relation) {
|
| WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_RELATION);
|
| AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes);
|
| - if (!owner())
|
| - return E_FAIL;
|
| -
|
| - if (relation_index < 0 ||
|
| - relation_index >= static_cast<long>(relations_.size())) {
|
| - return E_INVALIDARG;
|
| - }
|
| -
|
| - if (!relation)
|
| - return E_INVALIDARG;
|
| -
|
| - relations_[relation_index]->AddRef();
|
| - *relation = relations_[relation_index];
|
| - return S_OK;
|
| + return AXPlatformNodeWin::get_relation(relation_index, relation);
|
| }
|
|
|
| STDMETHODIMP BrowserAccessibilityComWin::get_relations(
|
| @@ -363,23 +190,8 @@ STDMETHODIMP BrowserAccessibilityComWin::get_relations(
|
| LONG* n_relations) {
|
| WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_RELATIONS);
|
| AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes);
|
| - if (!owner())
|
| - return E_FAIL;
|
| -
|
| - if (!relations || !n_relations)
|
| - return E_INVALIDARG;
|
| -
|
| - long count = static_cast<long>(relations_.size());
|
| - *n_relations = count;
|
| - if (count == 0)
|
| - return S_FALSE;
|
| -
|
| - for (long i = 0; i < count; ++i) {
|
| - relations_[i]->AddRef();
|
| - relations[i] = relations_[i];
|
| - }
|
| -
|
| - return S_OK;
|
| + return AXPlatformNodeWin::get_relations(max_relations, relations,
|
| + n_relations);
|
| }
|
|
|
| STDMETHODIMP BrowserAccessibilityComWin::scrollTo(IA2ScrollType scroll_type) {
|
| @@ -2640,33 +2452,7 @@ void BrowserAccessibilityComWin::UpdateStep1ComputeWinAttributes() {
|
|
|
| win_attributes_->value = value;
|
|
|
| - ClearOwnRelations();
|
| - AddBidirectionalRelations(IA2_RELATION_CONTROLLER_FOR,
|
| - IA2_RELATION_CONTROLLED_BY,
|
| - ui::AX_ATTR_CONTROLS_IDS);
|
| - AddBidirectionalRelations(IA2_RELATION_DESCRIBED_BY,
|
| - IA2_RELATION_DESCRIPTION_FOR,
|
| - ui::AX_ATTR_DESCRIBEDBY_IDS);
|
| - AddBidirectionalRelations(IA2_RELATION_FLOWS_TO, IA2_RELATION_FLOWS_FROM,
|
| - ui::AX_ATTR_FLOWTO_IDS);
|
| - AddBidirectionalRelations(IA2_RELATION_LABELLED_BY, IA2_RELATION_LABEL_FOR,
|
| - ui::AX_ATTR_LABELLEDBY_IDS);
|
| -
|
| - int32_t details_id;
|
| - if (GetIntAttribute(ui::AX_ATTR_DETAILS_ID, &details_id)) {
|
| - std::vector<int32_t> details_ids;
|
| - details_ids.push_back(details_id);
|
| - AddBidirectionalRelations(IA2_RELATION_DETAILS, IA2_RELATION_DETAILS_FOR,
|
| - details_ids);
|
| - }
|
| -
|
| - int member_of_id;
|
| - if (owner()->GetIntAttribute(ui::AX_ATTR_MEMBER_OF_ID, &member_of_id))
|
| - AddRelation(IA2_RELATION_MEMBER_OF, member_of_id);
|
| -
|
| - int error_message_id;
|
| - if (owner()->GetIntAttribute(ui::AX_ATTR_ERRORMESSAGE_ID, &error_message_id))
|
| - AddRelation(IA2_RELATION_ERROR_MESSAGE, error_message_id);
|
| + CalculateRelationships();
|
| }
|
|
|
| void BrowserAccessibilityComWin::UpdateStep2ComputeHypertext() {
|
| @@ -3598,135 +3384,6 @@ bool BrowserAccessibilityComWin::IsListBoxOptionOrMenuListOption() {
|
| return false;
|
| }
|
|
|
| -void BrowserAccessibilityComWin::AddRelation(
|
| - const base::string16& relation_type,
|
| - int target_id) {
|
| - // Reflexive relations don't need to be exposed through IA2.
|
| - if (target_id == owner()->GetId())
|
| - return;
|
| -
|
| - CComObject<BrowserAccessibilityRelation>* relation;
|
| - HRESULT hr =
|
| - CComObject<BrowserAccessibilityRelation>::CreateInstance(&relation);
|
| - DCHECK(SUCCEEDED(hr));
|
| - relation->AddRef();
|
| - relation->Initialize(this, relation_type);
|
| - relation->AddTarget(target_id);
|
| - relations_.push_back(relation);
|
| -}
|
| -
|
| -void BrowserAccessibilityComWin::AddBidirectionalRelations(
|
| - const base::string16& relation_type,
|
| - const base::string16& reverse_relation_type,
|
| - ui::AXIntListAttribute attribute) {
|
| - if (!owner()->HasIntListAttribute(attribute))
|
| - return;
|
| -
|
| - const std::vector<int32_t>& target_ids =
|
| - owner()->GetIntListAttribute(attribute);
|
| - AddBidirectionalRelations(relation_type, reverse_relation_type, target_ids);
|
| -}
|
| -
|
| -void BrowserAccessibilityComWin::AddBidirectionalRelations(
|
| - const base::string16& relation_type,
|
| - const base::string16& reverse_relation_type,
|
| - const std::vector<int32_t>& target_ids) {
|
| - // Reflexive relations don't need to be exposed through IA2.
|
| - std::vector<int32_t> filtered_target_ids;
|
| - int32_t current_id = owner()->GetId();
|
| - std::copy_if(target_ids.begin(), target_ids.end(),
|
| - std::back_inserter(filtered_target_ids),
|
| - [current_id](int32_t id) { return id != current_id; });
|
| - if (filtered_target_ids.empty())
|
| - return;
|
| -
|
| - CComObject<BrowserAccessibilityRelation>* relation;
|
| - HRESULT hr =
|
| - CComObject<BrowserAccessibilityRelation>::CreateInstance(&relation);
|
| - DCHECK(SUCCEEDED(hr));
|
| - relation->AddRef();
|
| - relation->Initialize(this, relation_type);
|
| -
|
| - for (int target_id : filtered_target_ids) {
|
| - BrowserAccessibilityComWin* target =
|
| - GetFromID(static_cast<int32_t>(target_id));
|
| - if (!target || !target->owner())
|
| - continue;
|
| - relation->AddTarget(target_id);
|
| - target->AddRelation(reverse_relation_type, owner()->GetId());
|
| - }
|
| -
|
| - relations_.push_back(relation);
|
| -}
|
| -
|
| -// Clears all the forward relations from this object to any other object and the
|
| -// associated reverse relations on the other objects, but leaves any reverse
|
| -// relations on this object alone.
|
| -void BrowserAccessibilityComWin::ClearOwnRelations() {
|
| - RemoveBidirectionalRelationsOfType(IA2_RELATION_CONTROLLER_FOR,
|
| - IA2_RELATION_CONTROLLED_BY);
|
| - RemoveBidirectionalRelationsOfType(IA2_RELATION_DESCRIBED_BY,
|
| - IA2_RELATION_DESCRIPTION_FOR);
|
| - RemoveBidirectionalRelationsOfType(IA2_RELATION_FLOWS_TO,
|
| - IA2_RELATION_FLOWS_FROM);
|
| - RemoveBidirectionalRelationsOfType(IA2_RELATION_LABELLED_BY,
|
| - IA2_RELATION_LABEL_FOR);
|
| -
|
| - relations_.erase(
|
| - std::remove_if(relations_.begin(), relations_.end(),
|
| - [](BrowserAccessibilityRelation* relation) {
|
| - if (relation->get_type() == IA2_RELATION_MEMBER_OF) {
|
| - relation->Release();
|
| - return true;
|
| - }
|
| - return false;
|
| - }),
|
| - relations_.end());
|
| -}
|
| -
|
| -void BrowserAccessibilityComWin::RemoveBidirectionalRelationsOfType(
|
| - const base::string16& relation_type,
|
| - const base::string16& reverse_relation_type) {
|
| - for (auto iter = relations_.begin(); iter != relations_.end();) {
|
| - BrowserAccessibilityRelation* relation = *iter;
|
| - DCHECK(relation);
|
| - if (relation->get_type() == relation_type) {
|
| - for (int target_id : relation->get_target_ids()) {
|
| - BrowserAccessibilityComWin* target =
|
| - GetFromID(static_cast<int32_t>(target_id));
|
| - if (!target || !target->owner())
|
| - continue;
|
| - DCHECK_NE(target, this);
|
| - target->RemoveTargetFromRelation(reverse_relation_type,
|
| - owner()->GetId());
|
| - }
|
| - iter = relations_.erase(iter);
|
| - relation->Release();
|
| - } else {
|
| - ++iter;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void BrowserAccessibilityComWin::RemoveTargetFromRelation(
|
| - const base::string16& relation_type,
|
| - int target_id) {
|
| - for (auto iter = relations_.begin(); iter != relations_.end();) {
|
| - BrowserAccessibilityRelation* relation = *iter;
|
| - DCHECK(relation);
|
| - if (relation->get_type() == relation_type) {
|
| - // If |target_id| is not present, |RemoveTarget| will do nothing.
|
| - relation->RemoveTarget(target_id);
|
| - }
|
| - if (relation->get_target_ids().empty()) {
|
| - iter = relations_.erase(iter);
|
| - relation->Release();
|
| - } else {
|
| - ++iter;
|
| - }
|
| - }
|
| -}
|
| -
|
| void BrowserAccessibilityComWin::FireNativeEvent(LONG win_event_type) const {
|
| (new BrowserAccessibilityEventWin(BrowserAccessibilityEvent::FromTreeChange,
|
| ui::AX_EVENT_NONE, win_event_type, owner()))
|
|
|