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

Side by Side Diff: third_party/WebKit/Source/modules/accessibility/AXRadioInput.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: removed isRadiobutton() Created 4 years, 9 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5
6 #include "modules/accessibility/AXRadioInput.h"
7
8 #include "core/InputTypeNames.h"
9 #include "core/dom/ElementTraversal.h"
10 #include "core/html/HTMLFormElement.h"
11 #include "core/html/HTMLInputElement.h"
12 #include "modules/accessibility/AXObjectCacheImpl.h"
13
14 namespace blink {
15
16 namespace {
17
18 HTMLElement* nextElement(const HTMLElement& element, HTMLFormElement* stayWithin , bool forward)
19 {
20 return forward ? Traversal<HTMLElement>::next(element, static_cast<Node*>(st ayWithin)) : Traversal<HTMLElement>::previous(element, static_cast<Node*>(stayWi thin));
21 }
22
23 } // namespace
24
25 using namespace HTMLNames;
26
27 AXRadioInput::AXRadioInput(LayoutObject* layoutObject, AXObjectCacheImpl& axObje ctCache)
28 : AXLayoutObject(layoutObject, axObjectCache)
29 {
30 // Updates posInSet and setSize for the current object and the next objects.
31 if (!calculatePosInSet())
32 return;
33 // When a new object is inserted, it needs to update setSize for the previou s objects.
34 requestUpdateToNextNode(false);
35 }
36
37 AXRadioInput* AXRadioInput::create(LayoutObject* layoutObject, AXObjectCacheImpl & axObjectCache)
38 {
39 return new AXRadioInput(layoutObject, axObjectCache);
40 }
41
42 void AXRadioInput::updatePosAndSetSize(int position)
43 {
44 if (position)
45 m_posInSet = position;
46 m_setSize = sizeOfRadioGroup();
47 }
48
49 void AXRadioInput::requestUpdateToNextNode(bool forward)
50 {
51 HTMLInputElement* nextElement = findNextRadioButtonInGroup(element(), forwar d);
52 AXObject* nextAXobject = axObjectCache().get(nextElement);
53 if (!nextAXobject || !nextAXobject->isAXRadioInput())
54 return;
55
56 int position = 0;
57 if (forward)
58 position = posInSet() + 1;
59 // If it is backward, it keeps position as positions are already assigned fo r previous objects.
60 // updatePosAndSetSize() is called with '0' and it doesn't modify m_posInSet and updates m_setSize as size is increased.
61
62 toAXRadioInput(nextAXobject)->updatePosAndSetSize(position);
63 axObjectCache().postNotification(nextAXobject, AXObjectCacheImpl::AXAriaAttr ibuteChanged);
64 toAXRadioInput(nextAXobject)->requestUpdateToNextNode(forward);
65 }
66
67 HTMLInputElement* AXRadioInput::findFirstRadioButtonInGroup(HTMLInputElement* cu rrent) const
68 {
69 while (HTMLInputElement* prevElement = findNextRadioButtonInGroup(current, f alse))
70 current = prevElement;
71 return current;
72 }
73
74 int AXRadioInput::posInSet() const
75 {
76 if (hasAttribute(aria_posinsetAttr))
77 return getAttribute(aria_posinsetAttr).toInt();
78 return m_posInSet;
79 }
80
81 int AXRadioInput::setSize() const
82 {
83 if (hasAttribute(aria_setsizeAttr))
84 return getAttribute(aria_setsizeAttr).toInt();
85 return m_setSize;
86 }
87
88 bool AXRadioInput::calculatePosInSet()
89 {
90 // Calculate 'posInSet' attribute when AXRadioInputs need to be updated
91 // as a new AXRadioInput Object is added or one of objects from RadioGroup i s removed.
92 bool needToUpdatePrev = false;
93 int position = 1;
94 HTMLInputElement* prevElement = findNextRadioButtonInGroup(element(), false) ;
95 if (prevElement) {
96 AXObject* object = axObjectCache().get(prevElement);
97 // If the previous element doesn't have AXObject yet, caculate position from the first element.
98 // Otherwise, get position from the previous AXObject.
99 if (!object || !object->isAXRadioInput()) {
100 position = countFromFirstElement();
101 } else {
102 position = object->posInSet() + 1;
103 // It returns true if previous objects need to be updated.
104 // When AX tree exists already and a new node is inserted,
105 // as updating is started from the inserted node,
106 // we need to update setSize for previous nodes.
107 if (setSize() != object->setSize())
108 needToUpdatePrev = true;
109 }
110 }
111 updatePosAndSetSize(position);
112
113 // If it is not the last element, request update to the next node.
114 if (position != setSize())
115 requestUpdateToNextNode(true);
116 return needToUpdatePrev;
117 }
118
119 HTMLInputElement* AXRadioInput::findNextRadioButtonInGroup(HTMLInputElement* cur rent, bool forward) const
120 {
121 for (HTMLElement* htmlElement = nextElement(*current, current->form(), forwa rd); htmlElement; htmlElement = nextElement(*htmlElement, current->form(), forwa rd)) {
122 if (!isHTMLInputElement(*htmlElement))
123 continue;
124 HTMLInputElement* inputElement = toHTMLInputElement(htmlElement);
125 if (current->form() == inputElement->form() && inputElement->type() == I nputTypeNames::radio && inputElement->name() == current->name())
126 return inputElement;
127 }
128 return nullptr;
129 }
130
131 int AXRadioInput::countFromFirstElement() const
132 {
133 int count = 1;
134 HTMLInputElement* current = element();
135 while (HTMLInputElement* prevElement = findNextRadioButtonInGroup(current, f alse)) {
136 current = prevElement;
137 count++;
138 }
139 return count;
140 }
141
142 HTMLInputElement* AXRadioInput::element() const
143 {
144 return toHTMLInputElement(m_layoutObject->node());
145 }
146
147 int AXRadioInput::sizeOfRadioGroup() const
148 {
149 int size = element()->sizeOfRadioGroup();
150 // If it has no size in Group, it means that there is only itself.
151 if (!size)
152 return 1;
153 return size;
154 }
155
156 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/accessibility/AXRadioInput.h ('k') | third_party/WebKit/Source/modules/modules.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698