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

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: fixed typo 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/dom/ElementTraversal.h"
9 #include "core/html/HTMLInputElement.h"
10 #include "modules/accessibility/AXObjectCacheImpl.h"
11
12 namespace blink {
13
14 namespace {
15
16 HTMLElement* nextElement(const HTMLElement& element, HTMLFormElement* stayWithin , bool forward)
17 {
18 return forward ? Traversal<HTMLElement>::next(element, (Node* )stayWithin) : Traversal<HTMLElement>::previous(element, (Node* )stayWithin);
dmazzoni 2016/02/29 17:16:19 Is it necessary to cast |stayWithin| to Node*? If
je_julie(Not used) 2016/03/01 13:46:07 I'll update it at next patch.
19 }
20
21 } // namespace
22
23 using namespace HTMLNames;
24
25 AXRadioInput::AXRadioInput(LayoutObject* layoutObject, AXObjectCacheImpl& axObje ctCache)
26 : AXLayoutObject(layoutObject, axObjectCache)
27 {
28 // Updates posInSet and setSize for the current object and the next objects.
29 if (!calculatePosInSet())
30 return;
31 // When a new object is inserted, it needs to update setSize for the previou s objects.
32 requestUpdateToNextNode(false);
33 }
34
35 AXRadioInput* AXRadioInput::create(LayoutObject* layoutObject, AXObjectCacheImpl & axObjectCache)
36 {
37 return new AXRadioInput(layoutObject, axObjectCache);
38 }
39
40 void AXRadioInput::updatePosAndSetSize(int position)
41 {
42 if (position)
43 m_posInSet = position;
44 m_setSize = sizeOfRadioGroup();
45 }
46
47 void AXRadioInput::requestUpdateToNextNode(bool forward)
48 {
49 HTMLInputElement* nextElement = findNextFocusableRadioButtonInGroup(element( ), forward);
50 AXObject* nextAXobject = axObjectCache().get(nextElement);
51 if (!nextAXobject || !nextAXobject->isAXRadioInput())
52 return;
53 int position = 0;
54 if (forward)
dmazzoni 2016/02/29 17:16:19 What if |forward| is false, should position be pos
je_julie(Not used) 2016/03/01 13:46:07 'requestUpdateToNextNode(false)' is only called in
55 position = posInSet() + 1;
56 // It moves to backward only when a new node inserted to AX tree which alrea dy exists.
57 // it just needs update for setSize and its position is not changed.
58 toAXRadioInput(nextAXobject)->updatePosAndSetSize(position);
59 axObjectCache().postNotification(nextAXobject, AXObjectCacheImpl::AXAriaAttr ibuteChanged);
60 toAXRadioInput(nextAXobject)->requestUpdateToNextNode(forward);
61 }
62
63 HTMLInputElement* AXRadioInput::findFirstFocusableRadioButtonInGroup(HTMLInputEl ement* current) const
64 {
65 while (HTMLInputElement* prevElement = findNextFocusableRadioButtonInGroup(c urrent, false))
66 current = prevElement;
67 return current;
68 }
69
70 int AXRadioInput::posInSet() const
71 {
72 if (hasAttribute(aria_posinsetAttr))
73 return getAttribute(aria_posinsetAttr).toInt();
74 return m_posInSet;
75 }
76
77 int AXRadioInput::setSize() const
78 {
79 if (hasAttribute(aria_setsizeAttr))
80 return getAttribute(aria_setsizeAttr).toInt();
81 return m_setSize;
82 }
83
84 bool AXRadioInput::calculatePosInSet()
85 {
86 // Calculate 'posInSet' attribute when AXRadioInputs need to be updated
87 // as a new AXRadioInput Object is added or one of objects from RadioGroup i s removed.
88 bool needToUpdatePrev = false;
89 int position = 1;
90 HTMLInputElement* prevElement = findNextFocusableRadioButtonInGroup(element( ), false);
91 if (prevElement) {
92 AXObject* object = axObjectCache().get(prevElement);
93 // If the previous element doesn't have AXObject yet, caculate position from the first element.
94 // Otherwise, get position from the previous AXObject.
95 if (!object || !object->isAXRadioInput()) {
96 position = countFromFirstElement();
97 } else {
98 position = object->posInSet() + 1;
99 // It returns true if previous objects need to be updated.
100 // When AX tree exists already and a new node is inserted,
101 // as updating is started from the inserted node,
102 // we need to update setSize for previous nodes.
103 if (setSize() != object->setSize())
104 needToUpdatePrev = true;
105 }
106 }
107 updatePosAndSetSize(position);
108
109 // If it is not the last element, request update to the next node.
110 if (position != setSize())
111 requestUpdateToNextNode(true);
112 return needToUpdatePrev;
113 }
114
115 HTMLInputElement* AXRadioInput::findNextFocusableRadioButtonInGroup(HTMLInputEle ment* current, bool forward) const
116 {
117 for (HTMLElement* htmlElement = nextElement(*current, current->form(), forwa rd); htmlElement; htmlElement = nextElement(*htmlElement, current->form(), forwa rd)) {
118 if (!isHTMLInputElement(*htmlElement))
119 continue;
120 HTMLInputElement* inputElement = toHTMLInputElement(htmlElement);
121 if (current->form() == inputElement->form() && inputElement->isRadioButt on() && inputElement->name() == current->name())
122 return inputElement;
123 }
124 return nullptr;
125 }
126
127 int AXRadioInput::countFromFirstElement() const
128 {
129 int count = 1;
130 HTMLInputElement* current = element();
131 while (HTMLInputElement* prevElement = findNextFocusableRadioButtonInGroup(c urrent, false)) {
132 current = prevElement;
133 count++;
134 }
135 return count;
136 }
137
138 HTMLInputElement* AXRadioInput::element() const
139 {
140 return toHTMLInputElement(m_layoutObject->node());
141 }
142
143 int AXRadioInput::sizeOfRadioGroup() const
144 {
145 int size = element()->sizeOfRadioGroup();
146 // If it has no size in Group, it means that there is only itself.
147 if (!size)
tkent 2016/03/01 01:43:00 Does this actually happen?
je_julie(Not used) 2016/03/01 13:46:07 It could happen when radio input element doesn't h
148 return 1;
149 return size;
150 }
151
152 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698