| Index: content/browser/frame_host/frame_accessibility.cc
|
| diff --git a/content/browser/frame_host/frame_accessibility.cc b/content/browser/frame_host/frame_accessibility.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..aa2c32667bfd4d184965dbf6233220380aa26792
|
| --- /dev/null
|
| +++ b/content/browser/frame_host/frame_accessibility.cc
|
| @@ -0,0 +1,179 @@
|
| +// 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 "content/browser/frame_host/frame_accessibility.h"
|
| +
|
| +#include "content/browser/frame_host/frame_tree.h"
|
| +#include "content/browser/frame_host/frame_tree_node.h"
|
| +#include "content/browser/frame_host/render_frame_host_delegate.h"
|
| +#include "content/browser/frame_host/render_frame_host_impl.h"
|
| +#include "content/public/browser/browser_context.h"
|
| +
|
| +namespace content {
|
| +
|
| +// static
|
| +FrameAccessibility* FrameAccessibility::GetInstance() {
|
| + return Singleton<FrameAccessibility>::get();
|
| +}
|
| +
|
| +FrameAccessibility::ChildFrameMapping::ChildFrameMapping()
|
| + : parent_frame_host(NULL),
|
| + accessibility_node_id(0),
|
| + child_frame_tree_node_id(0),
|
| + browser_plugin_instance_id(0) {}
|
| +
|
| +FrameAccessibility::FrameAccessibility() {}
|
| +
|
| +FrameAccessibility::~FrameAccessibility() {}
|
| +
|
| +void FrameAccessibility::AddChildFrame(
|
| + RenderFrameHostImpl* parent_frame_host,
|
| + int accessibility_node_id,
|
| + int64 child_frame_tree_node_id) {
|
| + for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin();
|
| + iter != mappings_.end();
|
| + ++iter) {
|
| + // TODO(dmazzoni): the renderer should keep track of these mappings
|
| + // and clear an existing mapping before setting a new one, that would
|
| + // be safer than just updating existing mappings. http://crbug.com/413464
|
| + if (iter->parent_frame_host == parent_frame_host &&
|
| + (iter->accessibility_node_id == accessibility_node_id ||
|
| + iter->child_frame_tree_node_id == child_frame_tree_node_id)) {
|
| + iter->accessibility_node_id = accessibility_node_id;
|
| + iter->child_frame_tree_node_id = child_frame_tree_node_id;
|
| + return;
|
| + }
|
| + }
|
| +
|
| + ChildFrameMapping new_mapping;
|
| + new_mapping.parent_frame_host = parent_frame_host;
|
| + new_mapping.accessibility_node_id = accessibility_node_id;
|
| + new_mapping.child_frame_tree_node_id = child_frame_tree_node_id;
|
| + mappings_.push_back(new_mapping);
|
| +}
|
| +
|
| +void FrameAccessibility::AddGuestWebContents(
|
| + RenderFrameHostImpl* parent_frame_host,
|
| + int accessibility_node_id,
|
| + int browser_plugin_instance_id) {
|
| + for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin();
|
| + iter != mappings_.end();
|
| + ++iter) {
|
| + // TODO(dmazzoni): the renderer should keep track of these mappings
|
| + // and clear an existing mapping before setting a new one, that would
|
| + // be safer than just updating existing mappings. http://crbug.com/413464
|
| + if (iter->parent_frame_host == parent_frame_host &&
|
| + (iter->accessibility_node_id == accessibility_node_id ||
|
| + iter->browser_plugin_instance_id == browser_plugin_instance_id)) {
|
| + iter->accessibility_node_id = accessibility_node_id;
|
| + iter->browser_plugin_instance_id = browser_plugin_instance_id;
|
| + return;
|
| + }
|
| + }
|
| +
|
| + ChildFrameMapping new_mapping;
|
| + new_mapping.parent_frame_host = parent_frame_host;
|
| + new_mapping.accessibility_node_id = accessibility_node_id;
|
| + new_mapping.browser_plugin_instance_id = browser_plugin_instance_id;
|
| + mappings_.push_back(new_mapping);
|
| +}
|
| +
|
| +void FrameAccessibility::OnRenderFrameHostDestroyed(
|
| + RenderFrameHostImpl* render_frame_host) {
|
| + // Since the order doesn't matter, the fastest way to remove all items
|
| + // with this render_frame_host is to iterate over the vector backwards,
|
| + // swapping each one with the back element if we need to delete it.
|
| + int initial_len = static_cast<int>(mappings_.size());
|
| + for (int i = initial_len - 1; i >= 0; i--) {
|
| + if (mappings_[i].parent_frame_host == render_frame_host) {
|
| + mappings_[i] = mappings_.back();
|
| + mappings_.pop_back();
|
| + }
|
| + }
|
| +}
|
| +
|
| +RenderFrameHostImpl* FrameAccessibility::GetChild(
|
| + RenderFrameHostImpl* parent_frame_host,
|
| + int accessibility_node_id) {
|
| + for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin();
|
| + iter != mappings_.end();
|
| + ++iter) {
|
| + if (iter->parent_frame_host != parent_frame_host ||
|
| + iter->accessibility_node_id != accessibility_node_id) {
|
| + continue;
|
| + }
|
| +
|
| + if (iter->child_frame_tree_node_id) {
|
| + FrameTreeNode* child_node =
|
| + FrameTree::GloballyFindByID(iter->child_frame_tree_node_id);
|
| + if (!child_node)
|
| + return NULL;
|
| +
|
| + // We should have gotten a node in the same frame tree.
|
| + if (child_node->frame_tree() !=
|
| + parent_frame_host->frame_tree_node()->frame_tree()) {
|
| + NOTREACHED();
|
| + return NULL;
|
| + }
|
| +
|
| + return child_node->current_frame_host();
|
| + }
|
| +
|
| + if (iter->browser_plugin_instance_id) {
|
| + RenderFrameHost* guest =
|
| + parent_frame_host->delegate()->GetGuestByInstanceID(
|
| + iter->browser_plugin_instance_id);
|
| + if (guest)
|
| + return static_cast<RenderFrameHostImpl*>(guest);
|
| + }
|
| + }
|
| +
|
| + return NULL;
|
| +}
|
| +
|
| +bool FrameAccessibility::GetParent(
|
| + RenderFrameHostImpl* child_frame_host,
|
| + RenderFrameHostImpl** out_parent_frame_host,
|
| + int* out_accessibility_node_id) {
|
| + for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin();
|
| + iter != mappings_.end();
|
| + ++iter) {
|
| + if (iter->child_frame_tree_node_id) {
|
| + FrameTreeNode* child_node =
|
| + FrameTree::GloballyFindByID(iter->child_frame_tree_node_id);
|
| + if (child_node &&
|
| + child_node->current_frame_host() == child_frame_host) {
|
| + // We should have gotten a node in the same frame tree.
|
| + if (child_node->frame_tree() !=
|
| + iter->parent_frame_host->frame_tree_node()->frame_tree()) {
|
| + NOTREACHED();
|
| + return false;
|
| + }
|
| +
|
| + if (out_parent_frame_host)
|
| + *out_parent_frame_host = iter->parent_frame_host;
|
| + if (out_accessibility_node_id)
|
| + *out_accessibility_node_id = iter->accessibility_node_id;
|
| + return true;
|
| + }
|
| + }
|
| +
|
| + if (iter->browser_plugin_instance_id) {
|
| + RenderFrameHost* guest =
|
| + iter->parent_frame_host->delegate()->GetGuestByInstanceID(
|
| + iter->browser_plugin_instance_id);
|
| + if (guest == child_frame_host) {
|
| + if (out_parent_frame_host)
|
| + *out_parent_frame_host = iter->parent_frame_host;
|
| + if (out_accessibility_node_id)
|
| + *out_accessibility_node_id = iter->accessibility_node_id;
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| +} // namespace content
|
|
|