Chromium Code Reviews| Index: content/renderer/accessibility/blink_ax_tree_source.cc |
| diff --git a/content/renderer/accessibility/accessibility_node_serializer.cc b/content/renderer/accessibility/blink_ax_tree_source.cc |
| similarity index 81% |
| copy from content/renderer/accessibility/accessibility_node_serializer.cc |
| copy to content/renderer/accessibility/blink_ax_tree_source.cc |
| index 9912332d63f9613b373cf7d4d5c1f6afd999c386..bfd3bbc8bab4272e42bf5e3a5057fafa5d73063f 100644 |
| --- a/content/renderer/accessibility/accessibility_node_serializer.cc |
| +++ b/content/renderer/accessibility/blink_ax_tree_source.cc |
| @@ -1,8 +1,8 @@ |
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Copyright (c) 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/renderer/accessibility/accessibility_node_serializer.h" |
| +#include "content/renderer/accessibility/blink_ax_tree_source.h" |
| #include <set> |
| @@ -10,6 +10,7 @@ |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "content/renderer/accessibility/blink_ax_enum_conversion.h" |
| +#include "content/renderer/render_view_impl.h" |
| #include "third_party/WebKit/public/platform/WebRect.h" |
| #include "third_party/WebKit/public/platform/WebSize.h" |
| #include "third_party/WebKit/public/platform/WebString.h" |
| @@ -23,31 +24,36 @@ |
| #include "third_party/WebKit/public/web/WebFrame.h" |
| #include "third_party/WebKit/public/web/WebInputElement.h" |
| #include "third_party/WebKit/public/web/WebNode.h" |
| +#include "third_party/WebKit/public/web/WebView.h" |
| +using base::ASCIIToUTF16; |
| using base::UTF16ToUTF8; |
| using blink::WebAXObject; |
| using blink::WebDocument; |
| using blink::WebDocumentType; |
| using blink::WebElement; |
| +using blink::WebFrame; |
| using blink::WebNode; |
| using blink::WebVector; |
| +using blink::WebView; |
| namespace content { |
| + |
| namespace { |
| // Returns true if |ancestor| is the first unignored parent of |child|, |
| // which means that when walking up the parent chain from |child|, |
| // |ancestor| is the *first* ancestor that isn't marked as |
| // accessibilityIsIgnored(). |
| -bool IsParentUnignoredOf(const WebAXObject& ancestor, |
| - const WebAXObject& child) { |
| +bool IsParentUnignoredOf(WebAXObject ancestor, |
|
aboxhall
2014/02/25 17:45:35
Why are these pass by value now? I guess it doesn'
dmazzoni
2014/02/27 20:51:44
I had to switch to just use WebAXObject consistent
|
| + WebAXObject child) { |
| WebAXObject parent = child.parentObject(); |
| while (!parent.isDetached() && parent.accessibilityIsIgnored()) |
| parent = parent.parentObject(); |
| return parent.equals(ancestor); |
| } |
| - bool IsTrue(std::string html_value) { |
| +bool IsTrue(std::string html_value) { |
| return LowerCaseEqualsASCII(html_value, "true"); |
| } |
| @@ -77,14 +83,79 @@ std::string GetEquivalentAriaRoleString(const ui::AXRole role) { |
| } // Anonymous namespace |
| -void SerializeAccessibilityNode( |
| - const WebAXObject& src, |
| - ui::AXNodeData* dst) { |
| +BlinkAXTreeSource::BlinkAXTreeSource(RenderViewImpl* render_view) |
| + : render_view_(render_view) { |
| +} |
| + |
| +BlinkAXTreeSource::~BlinkAXTreeSource() { |
| +} |
| + |
| +blink::WebAXObject BlinkAXTreeSource::GetRoot() const { |
| + return GetMainDocument().accessibilityObject(); |
| +} |
| + |
| +blink::WebAXObject BlinkAXTreeSource::GetFromId(int32 id) const { |
| + return GetMainDocument().accessibilityObjectFromID(id); |
| +} |
| + |
| +int32 BlinkAXTreeSource::GetId(blink::WebAXObject node) const { |
| + return node.axID(); |
| +} |
| + |
| +void BlinkAXTreeSource::GetChildren( |
| + blink::WebAXObject parent, |
| + std::vector<blink::WebAXObject>* out_children) const { |
| + bool is_iframe = false; |
| + WebNode node = parent.node(); |
| + if (!node.isNull() && node.isElementNode()) { |
| + WebElement element = node.to<WebElement>(); |
| + is_iframe = (element.tagName() == ASCIIToUTF16("IFRAME")); |
| + } |
| + |
| + for (unsigned i = 0; i < parent.childCount(); i++) { |
| + blink::WebAXObject child = parent.childAt(i); |
| + |
| + // The child may be invalid due to issues in webkit accessibility code. |
| + // Don't add children that are invalid thus preventing a crash. |
| + // https://bugs.webkit.org/show_bug.cgi?id=44149 |
| + // TODO(ctguil): We may want to remove this check as webkit stabilizes. |
|
aboxhall
2014/02/25 17:45:35
Might be time to remove this TODO?
dmazzoni
2014/02/27 20:51:44
Agreed! :)
|
| + if (child.isDetached()) |
| + continue; |
| + |
| + // Skip children whose parent isn't |parent|. |
| + // As an exception, include children of an iframe element. |
| + if (!is_iframe && !IsParentUnignoredOf(parent, child)) |
| + continue; |
| + |
| + out_children->push_back(child); |
| + } |
| +} |
| + |
| +blink::WebAXObject BlinkAXTreeSource::GetParent( |
| + blink::WebAXObject node) const { |
| + return node.parentObject(); |
| +} |
| + |
| +bool BlinkAXTreeSource::IsValid(blink::WebAXObject node) const { |
| + return !node.isDetached(); // This also checks if it's null. |
| +} |
| + |
| +bool BlinkAXTreeSource::IsEqual(blink::WebAXObject node1, |
| + blink::WebAXObject node2) const { |
| + return node1.equals(node2); |
| +} |
| + |
| +blink::WebAXObject BlinkAXTreeSource::GetNull() const { |
| + return blink::WebAXObject(); |
| +} |
| + |
| +void BlinkAXTreeSource::SerializeNode(blink::WebAXObject src, |
| + ui::AXNodeData* dst) const { |
| dst->role = AXRoleFromBlink(src.role()); |
| dst->state = AXStateFromBlink(src); |
| dst->location = src.boundingBoxRect(); |
| dst->id = src.axID(); |
| - std::string name = base::UTF16ToUTF8(src.title()); |
| + std::string name = UTF16ToUTF8(src.title()); |
| std::string value; |
| if (src.valueDescription().length()) { |
| @@ -129,9 +200,10 @@ void SerializeAccessibilityNode( |
| dst->AddIntListAttribute(ui::AX_ATTR_WORD_ENDS, word_ends); |
| } |
| - if (src.accessKey().length()) |
| + if (src.accessKey().length()) { |
| dst->AddStringAttribute(ui::AX_ATTR_ACCESS_KEY, |
| - UTF16ToUTF8(src.accessKey())); |
| + UTF16ToUTF8(src.accessKey())); |
| + } |
| if (src.actionVerb().length()) |
| dst->AddStringAttribute(ui::AX_ATTR_ACTION, UTF16ToUTF8(src.actionVerb())); |
| if (src.isAriaReadOnly()) |
| @@ -167,7 +239,7 @@ void SerializeAccessibilityNode( |
| dst->role == ui::AX_ROLE_ROW) && |
| src.hierarchicalLevel() > 0) { |
| dst->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL, |
| - src.hierarchicalLevel()); |
| + src.hierarchicalLevel()); |
| } |
| // Treat the active list box item as focused. |
| @@ -188,7 +260,7 @@ void SerializeAccessibilityNode( |
| if (!node.isNull() && node.isElementNode()) { |
| WebElement element = node.to<WebElement>(); |
| - is_iframe = (element.tagName() == base::ASCIIToUTF16("IFRAME")); |
| + is_iframe = (element.tagName() == ASCIIToUTF16("IFRAME")); |
| if (LowerCaseEqualsASCII(element.getAttribute("aria-expanded"), "true")) |
| dst->state |= (1 << ui::AX_STATE_EXPANDED); |
| @@ -200,9 +272,9 @@ void SerializeAccessibilityNode( |
| ui::AX_ATTR_HTML_TAG, |
| StringToLowerASCII(UTF16ToUTF8(element.tagName()))); |
| for (unsigned i = 0; i < element.attributeCount(); ++i) { |
| - std::string name = StringToLowerASCII(base::UTF16ToUTF8( |
| + std::string name = StringToLowerASCII(UTF16ToUTF8( |
| element.attributeLocalName(i))); |
| - std::string value = base::UTF16ToUTF8(element.attributeValue(i)); |
| + std::string value = UTF16ToUTF8(element.attributeValue(i)); |
| dst->html_attributes.push_back(std::make_pair(name, value)); |
| } |
| @@ -234,10 +306,10 @@ void SerializeAccessibilityNode( |
| } |
| // Live region attributes |
| - live_atomic = base::UTF16ToUTF8(element.getAttribute("aria-atomic")); |
| - live_busy = base::UTF16ToUTF8(element.getAttribute("aria-busy")); |
| - live_status = base::UTF16ToUTF8(element.getAttribute("aria-live")); |
| - live_relevant = base::UTF16ToUTF8(element.getAttribute("aria-relevant")); |
| + live_atomic = UTF16ToUTF8(element.getAttribute("aria-atomic")); |
| + live_busy = UTF16ToUTF8(element.getAttribute("aria-busy")); |
| + live_status = UTF16ToUTF8(element.getAttribute("aria-live")); |
| + live_relevant = UTF16ToUTF8(element.getAttribute("aria-relevant")); |
| } |
| // Walk up the parent chain to set live region attributes of containers |
| @@ -253,22 +325,22 @@ void SerializeAccessibilityNode( |
| if (container_elem.hasAttribute("aria-atomic") && |
| container_live_atomic.empty()) { |
| container_live_atomic = |
| - base::UTF16ToUTF8(container_elem.getAttribute("aria-atomic")); |
| + UTF16ToUTF8(container_elem.getAttribute("aria-atomic")); |
| } |
| if (container_elem.hasAttribute("aria-busy") && |
| container_live_busy.empty()) { |
| container_live_busy = |
| - base::UTF16ToUTF8(container_elem.getAttribute("aria-busy")); |
| + UTF16ToUTF8(container_elem.getAttribute("aria-busy")); |
| } |
| if (container_elem.hasAttribute("aria-live") && |
| container_live_status.empty()) { |
| container_live_status = |
| - base::UTF16ToUTF8(container_elem.getAttribute("aria-live")); |
| + UTF16ToUTF8(container_elem.getAttribute("aria-live")); |
| } |
| if (container_elem.hasAttribute("aria-relevant") && |
| container_live_relevant.empty()) { |
| container_live_relevant = |
| - base::UTF16ToUTF8(container_elem.getAttribute("aria-relevant")); |
| + UTF16ToUTF8(container_elem.getAttribute("aria-relevant")); |
| } |
| } |
| container_accessible = container_accessible.parentObject(); |
| @@ -318,7 +390,7 @@ void SerializeAccessibilityNode( |
| if (name.empty()) |
| name = UTF16ToUTF8(document.title()); |
| dst->AddStringAttribute(ui::AX_ATTR_DOC_TITLE, |
| - UTF16ToUTF8(document.title())); |
| + UTF16ToUTF8(document.title())); |
| dst->AddStringAttribute(ui::AX_ATTR_DOC_URL, document.url().spec()); |
| dst->AddStringAttribute( |
| ui::AX_ATTR_DOC_MIMETYPE, |
| @@ -421,26 +493,14 @@ void SerializeAccessibilityNode( |
| } |
| } |
| -bool ShouldIncludeChildNode( |
| - const WebAXObject& parent, |
| - const WebAXObject& child) { |
| - // The child may be invalid due to issues in webkit accessibility code. |
| - // Don't add children that are invalid thus preventing a crash. |
| - // https://bugs.webkit.org/show_bug.cgi?id=44149 |
| - // TODO(ctguil): We may want to remove this check as webkit stabilizes. |
| - if (child.isDetached()) |
| - return false; |
| - |
| - // Skip children whose parent isn't this - see indirect_child_ids, above. |
| - // As an exception, include children of an iframe element. |
| - bool is_iframe = false; |
| - WebNode node = parent.node(); |
| - if (!node.isNull() && node.isElementNode()) { |
| - WebElement element = node.to<WebElement>(); |
| - is_iframe = (element.tagName() == base::ASCIIToUTF16("IFRAME")); |
| - } |
| +blink::WebDocument BlinkAXTreeSource::GetMainDocument() const { |
| + WebView* view = render_view_->GetWebView(); |
| + WebFrame* main_frame = view ? view->mainFrame() : NULL; |
| + |
| + if (main_frame) |
| + return main_frame->document(); |
| - return (is_iframe || IsParentUnignoredOf(parent, child)); |
| + return WebDocument(); |
| } |
| } // namespace content |