Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Unified Diff: third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp

Issue 1628283002: posinset and setsize for input type, radio, exposed in AX tree (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: added AXRadioInput Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp
diff --git a/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp b/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp
index a09c6707046e34edadc476c3c5790a4a56f06f03..d92beb735012ca5aaa124f8d21b9822aa92b62ec 100644
--- a/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp
+++ b/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp
@@ -21,6 +21,7 @@
#include "core/html/forms/RadioButtonGroupScope.h"
#include "core/InputTypeNames.h"
+#include "core/dom/NodeTraversal.h"
#include "core/html/HTMLInputElement.h"
#include "wtf/HashMap.h"
@@ -38,6 +39,9 @@ public:
void requiredAttributeChanged(HTMLInputElement*);
void remove(HTMLInputElement*);
bool contains(HTMLInputElement*) const;
+ void setNeedToUpdate(bool);
+ void updateAXPosition();
+ unsigned sizeOfMembers() const;
DECLARE_TRACE();
@@ -46,6 +50,7 @@ private:
void setNeedsValidityCheckForAllButtons();
bool isValid() const;
void setCheckedButton(HTMLInputElement*);
+ bool isNextPosition(HTMLInputElement* list, HTMLInputElement* current) const;
// The map records the 'required' state of each (button) element.
using Members = WillBeHeapHashMap<RawPtrWillBeMember<HTMLInputElement>, bool>;
@@ -61,11 +66,13 @@ private:
Members m_members;
RawPtrWillBeMember<HTMLInputElement> m_checkedButton;
size_t m_requiredCount;
+ bool m_needToUpdateAXPosition;
};
RadioButtonGroup::RadioButtonGroup()
: m_checkedButton(nullptr)
, m_requiredCount(0)
+ , m_needToUpdateAXPosition(false)
{
}
@@ -89,6 +96,20 @@ void RadioButtonGroup::setCheckedButton(HTMLInputElement* button)
oldCheckedButton->setChecked(false);
}
+bool RadioButtonGroup::isNextPosition(HTMLInputElement* listItem, HTMLInputElement* current) const
+{
+ Node* commonAncestor = NodeTraversal::commonAncestor(*listItem, *current);
+ for (Node* node = commonAncestor; node; node = NodeTraversal::next(*node)) {
+ if (!node->isHTMLElement() || !isHTMLInputElement(node) || !toHTMLInputElement(node)->isRadioButton())
+ continue;
+ if (node == listItem)
+ return true;
+ if (node == current)
+ return false;
+ }
+ return true;
+}
+
void RadioButtonGroup::updateRequiredButton(MemberKeyValue& it, bool isRequired)
{
if (it.value == isRequired)
@@ -109,6 +130,8 @@ void RadioButtonGroup::add(HTMLInputElement* button)
auto addResult = m_members.add(button, false);
if (!addResult.isNewEntry)
return;
+
+ setNeedToUpdate(true);
bool groupWasValid = isValid();
updateRequiredButton(*addResult.storedValue, button->isRequired());
if (button->checked())
@@ -162,6 +185,8 @@ void RadioButtonGroup::remove(HTMLInputElement* button)
auto it = m_members.find(button);
if (it == m_members.end())
return;
+
+ setNeedToUpdate(true);
bool wasValid = isValid();
ASSERT(it->value == button->isRequired());
updateRequiredButton(*it, false);
@@ -196,6 +221,46 @@ bool RadioButtonGroup::contains(HTMLInputElement* button) const
return m_members.contains(button);
}
+void RadioButtonGroup::setNeedToUpdate(bool set)
+{
+ m_needToUpdateAXPosition = set;
+}
+
+void RadioButtonGroup::updateAXPosition()
+{
+ if (!m_needToUpdateAXPosition)
+ return;
+
+ WillBeHeapVector<RawPtrWillBeMember<HTMLInputElement>> orderdList;
+ for (auto& element : m_members) {
+ HTMLInputElement* const current = element.key;
+ if (orderdList.isEmpty()) {
+ orderdList.append(current);
+ } else {
+ unsigned position = 0;
+ for (auto& item : orderdList) {
+ if (!isNextPosition(item, current))
keishi 2016/02/23 09:43:00 This reordering is like O(N^3). Could we use Radio
je_julie(Not used) 2016/02/27 14:01:08 I moved handling position for AX to AXRadioInput a
+ break;
+ position++;
+ }
+ orderdList.insert(position, current);
+ }
+ }
+
+ unsigned index = 0;
+ for (auto& orderedNode : orderdList) {
+ index++;
+ if (AXObjectCache* cache = orderedNode->document().existingAXObjectCache())
+ cache->radiobuttonPositionChanged(orderedNode, index);
+ }
+ setNeedToUpdate(false);
+}
+
+unsigned RadioButtonGroup::sizeOfMembers() const
+{
+ return m_members.size();
+}
+
DEFINE_TRACE(RadioButtonGroup)
{
#if ENABLE(OILPAN)
@@ -277,6 +342,39 @@ bool RadioButtonGroupScope::isInRequiredGroup(HTMLInputElement* element) const
return group && group->isRequired() && group->contains(element);
}
+unsigned RadioButtonGroupScope::sizeOfGroup(const HTMLInputElement* element) const
+{
+ if (!m_nameToGroupMap)
+ return 0;
+
+ RadioButtonGroup* group = m_nameToGroupMap->get(element->name());
+ if (!group)
+ return 0;
+ return group->sizeOfMembers();
+}
+
+void RadioButtonGroupScope::updateAXPositionInGroup(const HTMLInputElement* element) const
+{
+ if (!m_nameToGroupMap)
+ return;
+
+ RadioButtonGroup* group = m_nameToGroupMap->get(element->name());
+ if (!group)
+ return;
+ group->updateAXPosition();
+}
+
+void RadioButtonGroupScope::setNeedToUpdateAXPositionInGroup(const HTMLInputElement* element, bool set) const
+{
+ if (!m_nameToGroupMap)
+ return;
+
+ RadioButtonGroup* group = m_nameToGroupMap->get(element->name());
+ if (!group)
+ return;
+ group->setNeedToUpdate(set);
keishi 2016/02/23 09:43:00 If we do something like RadioInputType::findNextFo
je_julie(Not used) 2016/02/27 14:01:08 I removed almost all handling to AXRadioInput as y
+}
+
void RadioButtonGroupScope::removeButton(HTMLInputElement* element)
{
ASSERT(element->type() == InputTypeNames::radio);

Powered by Google App Engine
This is Rietveld 408576698