Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / accessibility / AXNodeObject.cpp
index 6410e9c..9327110 100644 (file)
@@ -37,6 +37,7 @@
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLLabelElement.h"
 #include "core/html/HTMLLegendElement.h"
+#include "core/html/HTMLPlugInElement.h"
 #include "core/html/HTMLSelectElement.h"
 #include "core/html/HTMLTextAreaElement.h"
 #include "core/rendering/RenderObject.h"
@@ -44,7 +45,7 @@
 #include "wtf/text/StringBuilder.h"
 
 
-namespace WebCore {
+namespace blink {
 
 using namespace HTMLNames;
 
@@ -52,7 +53,7 @@ AXNodeObject::AXNodeObject(Node* node)
     : AXObject()
     , m_ariaRole(UnknownRole)
     , m_childrenDirty(false)
-#ifndef NDEBUG
+#if ENABLE(ASSERT)
     , m_initialized(false)
 #endif
     , m_node(node)
@@ -91,7 +92,7 @@ static String accessibleNameForNode(Node* node)
     return String();
 }
 
-String AXNodeObject::accessibilityDescriptionForElements(Vector<Element*> &elements) const
+String AXNodeObject::accessibilityDescriptionForElements(WillBeHeapVector<RawPtrWillBeMember<Element> > &elements) const
 {
     StringBuilder builder;
     unsigned size = elements.size();
@@ -133,7 +134,7 @@ String AXNodeObject::ariaAccessibilityDescription() const
 }
 
 
-void AXNodeObject::ariaLabeledByElements(Vector<Element*>& elements) const
+void AXNodeObject::ariaLabeledByElements(WillBeHeapVector<RawPtrWillBeMember<Element> >& elements) const
 {
     elementsFromAttribute(elements, aria_labeledbyAttr);
     if (!elements.size())
@@ -154,7 +155,7 @@ void AXNodeObject::changeValueByStep(bool increase)
 
 bool AXNodeObject::computeAccessibilityIsIgnored() const
 {
-#ifndef NDEBUG
+#if ENABLE(ASSERT)
     // Double-check that an AXObject is never accessed before
     // it's been initialized.
     ASSERT(m_initialized);
@@ -224,7 +225,7 @@ AccessibilityRole AXNodeObject::determineAccessibilityRole()
         return GroupRole;
     if (isHTMLAnchorElement(*node()) && isClickable())
         return LinkRole;
-    if (node()->hasTagName(iframeTag))
+    if (isHTMLIFrameElement(*node()))
         return IframeRole;
     if (isEmbeddedObject())
         return EmbeddedObjectRole;
@@ -258,7 +259,7 @@ AccessibilityRole AXNodeObject::determineAriaRoleAttribute() const
     return UnknownRole;
 }
 
-void AXNodeObject::elementsFromAttribute(Vector<Element*>& elements, const QualifiedName& attribute) const
+void AXNodeObject::elementsFromAttribute(WillBeHeapVector<RawPtrWillBeMember<Element> >& elements, const QualifiedName& attribute) const
 {
     Node* node = this->node();
     if (!node || !node->isElementNode())
@@ -283,7 +284,7 @@ void AXNodeObject::elementsFromAttribute(Vector<Element*>& elements, const Quali
     }
 }
 
-// If you call node->rendererIsEditable() since that will return true if an ancestor is editable.
+// If you call node->hasEditableStyle() since that will return true if an ancestor is editable.
 // This only returns true if this is the element that actually has the contentEditable attribute set.
 bool AXNodeObject::hasContentEditableAttributeSet() const
 {
@@ -446,7 +447,7 @@ AccessibilityRole AXNodeObject::remapAriaRoleDueToParent(AccessibilityRole role)
 
 void AXNodeObject::init()
 {
-#ifndef NDEBUG
+#if ENABLE(ASSERT)
     ASSERT(!m_initialized);
     m_initialized = true;
 #endif
@@ -477,9 +478,7 @@ bool AXNodeObject::isControl() const
 
 bool AXNodeObject::isEmbeddedObject() const
 {
-    return node()
-        && (node()->hasTagName(objectTag) || node()->hasTagName(embedTag)
-        || node()->hasTagName(appletTag));
+    return isHTMLPlugInElement(node());
 }
 
 bool AXNodeObject::isFieldset() const
@@ -565,7 +564,7 @@ bool AXNodeObject::isNativeImage() const
     if (isHTMLImageElement(*node))
         return true;
 
-    if (isHTMLAppletElement(*node) || isHTMLEmbedElement(*node) || isHTMLObjectElement(*node))
+    if (isHTMLPlugInElement(*node))
         return true;
 
     if (isHTMLInputElement(*node))
@@ -718,7 +717,7 @@ bool AXNodeObject::isReadOnly() const
             return input.isReadOnly();
     }
 
-    return !node->rendererIsEditable();
+    return !node->hasEditableStyle();
 }
 
 bool AXNodeObject::isRequired() const
@@ -814,27 +813,31 @@ int AXNodeObject::headingLevel() const
     // headings can be in block flow and non-block flow
     Node* node = this->node();
     if (!node)
-        return false;
+        return 0;
 
     if (ariaRoleAttribute() == HeadingRole)
         return getAttribute(aria_levelAttr).toInt();
 
-    if (node->hasTagName(h1Tag))
+    if (!node->isHTMLElement())
+        return 0;
+
+    HTMLElement& element = toHTMLElement(*node);
+    if (element.hasTagName(h1Tag))
         return 1;
 
-    if (node->hasTagName(h2Tag))
+    if (element.hasTagName(h2Tag))
         return 2;
 
-    if (node->hasTagName(h3Tag))
+    if (element.hasTagName(h3Tag))
         return 3;
 
-    if (node->hasTagName(h4Tag))
+    if (element.hasTagName(h4Tag))
         return 4;
 
-    if (node->hasTagName(h5Tag))
+    if (element.hasTagName(h5Tag))
         return 5;
 
-    if (node->hasTagName(h6Tag))
+    if (element.hasTagName(h6Tag))
         return 6;
 
     return 0;
@@ -1036,7 +1039,7 @@ String AXNodeObject::stringValue() const
 
 String AXNodeObject::ariaDescribedByAttribute() const
 {
-    Vector<Element*> elements;
+    WillBeHeapVector<RawPtrWillBeMember<Element> > elements;
     elementsFromAttribute(elements, aria_describedbyAttr);
 
     return accessibilityDescriptionForElements(elements);
@@ -1045,7 +1048,7 @@ String AXNodeObject::ariaDescribedByAttribute() const
 
 String AXNodeObject::ariaLabeledByAttribute() const
 {
-    Vector<Element*> elements;
+    WillBeHeapVector<RawPtrWillBeMember<Element> > elements;
     ariaLabeledByElements(elements);
 
     return accessibilityDescriptionForElements(elements);
@@ -1247,8 +1250,28 @@ LayoutRect AXNodeObject::elementRect() const
     if (!m_explicitElementRect.isEmpty())
         return m_explicitElementRect;
 
-    // AXNodeObjects have no mechanism yet to return a size or position.
-    // For now, let's return the position of the ancestor that does have a position,
+    // FIXME: If there are a lot of elements in the canvas, it will be inefficient.
+    // We can avoid the inefficient calculations by using AXComputedObjectAttributeCache.
+    if (node()->parentElement()->isInCanvasSubtree()) {
+        LayoutRect rect;
+
+        for (Node* child = node()->firstChild(); child; child = child->nextSibling()) {
+            if (child->isHTMLElement()) {
+                if (AXObject* obj = axObjectCache()->get(child)) {
+                    if (rect.isEmpty())
+                        rect = obj->elementRect();
+                    else
+                        rect.unite(obj->elementRect());
+                }
+            }
+        }
+
+        if (!rect.isEmpty())
+            return rect;
+    }
+
+    // If this object doesn't have an explicit element rect or computable from its children,
+    // for now, let's return the position of the ancestor that does have a position,
     // and make it the width of that parent, and about the height of a line of text, so that it's clear the object is a child of the parent.
 
     LayoutRect boundingBox;
@@ -1665,7 +1688,7 @@ void AXNodeObject::ariaLabeledByText(Vector<AccessibilityText>& textOrder) const
 {
     String ariaLabeledBy = ariaLabeledByAttribute();
     if (!ariaLabeledBy.isEmpty()) {
-        Vector<Element*> elements;
+        WillBeHeapVector<RawPtrWillBeMember<Element> > elements;
         ariaLabeledByElements(elements);
 
         unsigned length = elements.size();
@@ -1687,4 +1710,4 @@ void AXNodeObject::changeValueByPercent(float percentChange)
     axObjectCache()->postNotification(node(), AXObjectCache::AXValueChanged, true);
 }
 
-} // namespace WebCore
+} // namespace blink