Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / accessibility / AXNodeObject.cpp
index 34c1230..80dc7bb 100644 (file)
 #include "core/accessibility/AXNodeObject.h"
 
 #include "core/InputTypeNames.h"
-#include "core/accessibility/AXObjectCache.h"
+#include "core/accessibility/AXObjectCacheImpl.h"
 #include "core/dom/NodeTraversal.h"
 #include "core/dom/Text.h"
+#include "core/html/HTMLDListElement.h"
 #include "core/html/HTMLFieldSetElement.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/html/HTMLInputElement.h"
@@ -101,8 +102,8 @@ String AXNodeObject::accessibilityDescriptionForElements(WillBeHeapVector<RawPtr
         Element* idElement = elements[i];
 
         builder.append(accessibleNameForNode(idElement));
-        for (Node* n = idElement->firstChild(); n; n = NodeTraversal::next(*n, idElement))
-            builder.append(accessibleNameForNode(n));
+        for (Node& n : NodeTraversal::descendantsOf(*idElement))
+            builder.append(accessibleNameForNode(&n));
 
         if (i != size - 1)
             builder.append(' ');
@@ -151,7 +152,7 @@ void AXNodeObject::changeValueByStep(bool increase)
 
     setValue(String::number(value));
 
-    axObjectCache()->postNotification(node(), AXObjectCache::AXValueChanged, true);
+    axObjectCache()->postNotification(node(), AXObjectCacheImpl::AXValueChanged, true);
 }
 
 bool AXNodeObject::computeAccessibilityIsIgnored() const
@@ -202,16 +203,36 @@ AccessibilityRole AXNodeObject::determineAccessibilityRole()
     if (isHTMLInputElement(*node())) {
         HTMLInputElement& input = toHTMLInputElement(*node());
         const AtomicString& type = input.type();
-        if (type == InputTypeNames::checkbox)
+        if (type == InputTypeNames::button) {
+            if ((node()->parentNode() && isHTMLMenuElement(node()->parentNode())) || (parentObject() && parentObject()->roleValue() == MenuRole))
+                return MenuItemRole;
+            return buttonRoleType();
+        }
+        if (type == InputTypeNames::checkbox) {
+            if ((node()->parentNode() && isHTMLMenuElement(node()->parentNode())) || (parentObject() && parentObject()->roleValue() == MenuRole))
+                return MenuItemCheckBoxRole;
             return CheckBoxRole;
-        if (type == InputTypeNames::radio)
+        }
+        if (type == InputTypeNames::date)
+            return DateRole;
+        if (type == InputTypeNames::datetime
+            || type == InputTypeNames::datetime_local
+            || type == InputTypeNames::month
+            || type == InputTypeNames::week)
+            return DateTimeRole;
+        if (type == InputTypeNames::radio) {
+            if ((node()->parentNode() && isHTMLMenuElement(node()->parentNode())) || (parentObject() && parentObject()->roleValue() == MenuRole))
+                return MenuItemRadioRole;
             return RadioButtonRole;
+        }
         if (input.isTextButton())
             return buttonRoleType();
         if (type == InputTypeNames::range)
             return SliderRole;
         if (type == InputTypeNames::color)
             return ColorWellRole;
+        if (type == InputTypeNames::time)
+            return TimeRole;
         return TextFieldRole;
     }
     if (isHTMLSelectElement(*node())) {
@@ -224,10 +245,18 @@ AccessibilityRole AXNodeObject::determineAccessibilityRole()
         return HeadingRole;
     if (isHTMLDivElement(*node()))
         return DivRole;
+    if (isHTMLMeterElement(*node()))
+        return MeterRole;
+    if (isHTMLOutputElement(*node()))
+        return StatusRole;
     if (isHTMLParagraphElement(*node()))
         return ParagraphRole;
     if (isHTMLLabelElement(*node()))
         return LabelRole;
+    if (isHTMLDListElement(*node()))
+        return DescriptionListRole;
+    if (node()->isElementNode() && node()->hasTagName(blockquoteTag))
+        return BlockquoteRole;
     if (node()->isElementNode() && node()->hasTagName(figcaptionTag))
         return FigcaptionRole;
     if (node()->isElementNode() && node()->hasTagName(figureTag))
@@ -640,9 +669,11 @@ bool AXNodeObject::isChecked() const
     if (isHTMLInputElement(*node))
         return toHTMLInputElement(*node).shouldAppearChecked();
 
-    // Else, if this is an ARIA checkbox or radio, respect the aria-checked attribute
+    // Else, if this is an ARIA checkbox or radio OR ARIA role menuitemcheckbox
+    // or menuitemradio, respect the aria-checked attribute
     AccessibilityRole ariaRole = ariaRoleAttribute();
-    if (ariaRole == RadioButtonRole || ariaRole == CheckBoxRole) {
+    if (ariaRole == RadioButtonRole || ariaRole == CheckBoxRole
+        || ariaRole == MenuItemCheckBoxRole || ariaRole == MenuItemRadioRole) {
         if (equalIgnoringCase(getAttribute(aria_checkedAttr), "true"))
             return true;
         return false;
@@ -678,6 +709,17 @@ bool AXNodeObject::isEnabled() const
     return !toElement(node)->isDisabledFormControl();
 }
 
+AccessibilityExpanded AXNodeObject::isExpanded() const
+{
+    const AtomicString& expanded = getAttribute(aria_expandedAttr);
+    if (equalIgnoringCase(expanded, "true"))
+        return ExpandedExpanded;
+    if (equalIgnoringCase(expanded, "false"))
+        return ExpandedCollapsed;
+
+    return ExpandedUndefined;
+}
+
 bool AXNodeObject::isIndeterminate() const
 {
     Node* node = this->node();
@@ -1041,6 +1083,19 @@ String AXNodeObject::stringValue() const
     return String();
 }
 
+
+const AtomicString& AXNodeObject::textInputType() const
+{
+    Node* node = this->node();
+    if (!isHTMLInputElement(node))
+        return nullAtom;
+
+    HTMLInputElement& input = toHTMLInputElement(*node);
+    if (input.isTextField())
+        return input.type();
+    return nullAtom;
+}
+
 String AXNodeObject::ariaDescribedByAttribute() const
 {
     WillBeHeapVector<RawPtrWillBeMember<Element> > elements;
@@ -1049,7 +1104,6 @@ String AXNodeObject::ariaDescribedByAttribute() const
     return accessibilityDescriptionForElements(elements);
 }
 
-
 String AXNodeObject::ariaLabeledByAttribute() const
 {
     WillBeHeapVector<RawPtrWillBeMember<Element> > elements;
@@ -1065,7 +1119,7 @@ AccessibilityRole AXNodeObject::ariaRoleAttribute() const
 
 // When building the textUnderElement for an object, determine whether or not
 // we should include the inner text of this given descendant object or skip it.
-static bool shouldUseAccessiblityObjectInnerText(AXObject* obj)
+static bool shouldUseAccessibilityObjectInnerText(AXObject* obj)
 {
     // Consider this hypothetical example:
     // <div tabindex=0>
@@ -1107,7 +1161,7 @@ String AXNodeObject::textUnderElement() const
 
     StringBuilder builder;
     for (AXObject* child = firstChild(); child; child = child->nextSibling()) {
-        if (!shouldUseAccessiblityObjectInnerText(child))
+        if (!shouldUseAccessibilityObjectInnerText(child))
             continue;
 
         if (child->isAXNodeObject()) {
@@ -1187,6 +1241,8 @@ String AXNodeObject::title() const
     case ListBoxOptionRole:
     case MenuButtonRole:
     case MenuItemRole:
+    case MenuItemCheckBoxRole:
+    case MenuItemRadioRole:
     case RadioButtonRole:
     case TabRole:
         return textUnderElement();
@@ -1292,7 +1348,7 @@ LayoutRect AXNodeObject::elementRect() const
     return boundingBox;
 }
 
-AXObject* AXNodeObject::parentObject() const
+AXObject* AXNodeObject::computeParent() const
 {
     if (!node())
         return 0;
@@ -1304,9 +1360,16 @@ AXObject* AXNodeObject::parentObject() const
     return 0;
 }
 
-AXObject* AXNodeObject::parentObjectIfExists() const
+AXObject* AXNodeObject::computeParentIfExists() const
 {
-    return parentObject();
+    if (!node())
+        return 0;
+
+    Node* parentObj = node()->parentNode();
+    if (parentObj)
+        return axObjectCache()->get(parentObj);
+
+    return 0;
 }
 
 AXObject* AXNodeObject::firstChild() const
@@ -1351,6 +1414,9 @@ void AXNodeObject::addChildren()
 
     for (Node* child = m_node->firstChild(); child; child = child->nextSibling())
         addChild(axObjectCache()->getOrCreate(child));
+
+    for (unsigned i = 0; i < m_children.size(); ++i)
+        m_children[i].get()->setParent(this);
 }
 
 void AXNodeObject::addChild(AXObject* child)
@@ -1439,6 +1505,8 @@ Element* AXNodeObject::actionElement() const
     case ToggleButtonRole:
     case TabRole:
     case MenuItemRole:
+    case MenuItemCheckBoxRole:
+    case MenuItemRadioRole:
     case ListItemRole:
         return toElement(node);
     default:
@@ -1457,7 +1525,7 @@ Element* AXNodeObject::anchorElement() const
     if (!node)
         return 0;
 
-    AXObjectCache* cache = axObjectCache();
+    AXObjectCacheImpl* cache = axObjectCache();
 
     // search up the DOM tree for an anchor element
     // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement
@@ -1554,7 +1622,7 @@ void AXNodeObject::childrenChanged()
     if (!node() && !renderer())
         return;
 
-    axObjectCache()->postNotification(this, document(), AXObjectCache::AXChildrenChanged, true);
+    axObjectCache()->postNotification(this, document(), AXObjectCacheImpl::AXChildrenChanged, true);
 
     // Go up the accessibility parent chain, but only if the element already exists. This method is
     // called during render layouts, minimal work should be done.
@@ -1567,13 +1635,13 @@ void AXNodeObject::childrenChanged()
         // In other words, they need to be sent even when the screen reader has not accessed this live region since the last update.
 
         // If this element supports ARIA live regions, then notify the AT of changes.
-        if (parent->supportsARIALiveRegion())
-            axObjectCache()->postNotification(parent, parent->document(), AXObjectCache::AXLiveRegionChanged, true);
+        if (parent->isLiveRegion())
+            axObjectCache()->postNotification(parent, parent->document(), AXObjectCacheImpl::AXLiveRegionChanged, true);
 
         // If this element is an ARIA text box or content editable, post a "value changed" notification on it
         // so that it behaves just like a native input element or textarea.
         if (isNonNativeTextControl())
-            axObjectCache()->postNotification(parent, parent->document(), AXObjectCache::AXValueChanged, true);
+            axObjectCache()->postNotification(parent, parent->document(), AXObjectCacheImpl::AXValueChanged, true);
     }
 }
 
@@ -1583,7 +1651,7 @@ void AXNodeObject::selectionChanged()
     // focused (to handle form controls, ARIA text boxes and contentEditable),
     // or the web area if the selection is just in the document somewhere.
     if (isFocused() || isWebArea())
-        axObjectCache()->postNotification(this, document(), AXObjectCache::AXSelectedTextChanged, true);
+        axObjectCache()->postNotification(this, document(), AXObjectCacheImpl::AXSelectedTextChanged, true);
     else
         AXObject::selectionChanged(); // Calls selectionChanged on parent.
 }
@@ -1592,19 +1660,19 @@ void AXNodeObject::textChanged()
 {
     // If this element supports ARIA live regions, or is part of a region with an ARIA editable role,
     // then notify the AT of changes.
-    AXObjectCache* cache = axObjectCache();
+    AXObjectCacheImpl* cache = axObjectCache();
     for (Node* parentNode = node(); parentNode; parentNode = parentNode->parentNode()) {
         AXObject* parent = cache->get(parentNode);
         if (!parent)
             continue;
 
-        if (parent->supportsARIALiveRegion())
-            cache->postNotification(parentNode, AXObjectCache::AXLiveRegionChanged, true);
+        if (parent->isLiveRegion())
+            cache->postNotification(parentNode, AXObjectCacheImpl::AXLiveRegionChanged, true);
 
         // If this element is an ARIA text box or content editable, post a "value changed" notification on it
         // so that it behaves just like a native input element or textarea.
         if (parent->isNonNativeTextControl())
-            cache->postNotification(parentNode, AXObjectCache::AXValueChanged, true);
+            cache->postNotification(parentNode, AXObjectCacheImpl::AXValueChanged, true);
     }
 }
 
@@ -1707,7 +1775,7 @@ void AXNodeObject::changeValueByPercent(float percentChange)
     value += range * (percentChange / 100);
     setValue(String::number(value));
 
-    axObjectCache()->postNotification(node(), AXObjectCache::AXValueChanged, true);
+    axObjectCache()->postNotification(node(), AXObjectCacheImpl::AXValueChanged, true);
 }
 
 } // namespace blink