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

Side by Side Diff: Source/core/dom/CheckedRadioButtons.cpp

Issue 19509003: [oilpan] Completely move HTMLFormControlElement's hierarchy to the managed heap (Closed) Base URL: svn://svn.chromium.org/blink/branches/oilpan
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * 3 *
4 * This library is free software; you can redistribute it and/or 4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public 5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either 6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version. 7 * version 2 of the License, or (at your option) any later version.
8 * 8 *
9 * This library is distributed in the hope that it will be useful, 9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 14 matching lines...) Expand all
25 #include <wtf/HashSet.h> 25 #include <wtf/HashSet.h>
26 26
27 namespace WebCore { 27 namespace WebCore {
28 28
29 class RadioButtonGroup { 29 class RadioButtonGroup {
30 WTF_MAKE_FAST_ALLOCATED; 30 WTF_MAKE_FAST_ALLOCATED;
31 public: 31 public:
32 static PassOwnPtr<RadioButtonGroup> create(); 32 static PassOwnPtr<RadioButtonGroup> create();
33 bool isEmpty() const { return m_members.isEmpty(); } 33 bool isEmpty() const { return m_members.isEmpty(); }
34 bool isRequired() const { return m_requiredCount; } 34 bool isRequired() const { return m_requiredCount; }
35 HTMLInputElement* checkedButton() const { return m_checkedButton; } 35 Result<HTMLInputElement> checkedButton() const { return Handle<HTMLInputElem ent>(m_checkedButton); } // FIXME(oilpan): Remove Handle<>().
36 void add(HTMLInputElement*); 36 void add(Handle<HTMLInputElement>);
37 void updateCheckedState(HTMLInputElement*); 37 void updateCheckedState(Handle<HTMLInputElement>);
38 void requiredAttributeChanged(HTMLInputElement*); 38 void requiredAttributeChanged(Handle<HTMLInputElement>);
39 void remove(HTMLInputElement*); 39 void remove(Handle<HTMLInputElement>);
40 bool contains(HTMLInputElement*) const; 40 bool contains(Handle<HTMLInputElement>) const;
41 41
42 private: 42 private:
43 RadioButtonGroup(); 43 RadioButtonGroup();
44 void setNeedsValidityCheckForAllButtons(); 44 void setNeedsValidityCheckForAllButtons();
45 bool isValid() const; 45 bool isValid() const;
46 void setCheckedButton(HTMLInputElement*); 46 void setCheckedButton(Handle<HTMLInputElement>);
47 47
48 // FIXME(oilpan): Move RadioButtonGroup to the heap and use Members.
48 HashSet<HTMLInputElement*> m_members; 49 HashSet<HTMLInputElement*> m_members;
49 HTMLInputElement* m_checkedButton; 50 HTMLInputElement* m_checkedButton;
50 size_t m_requiredCount; 51 size_t m_requiredCount;
51 }; 52 };
52 53
53 RadioButtonGroup::RadioButtonGroup() 54 RadioButtonGroup::RadioButtonGroup()
54 : m_checkedButton(0) 55 : m_checkedButton(0)
55 , m_requiredCount(0) 56 , m_requiredCount(0)
56 { 57 {
57 } 58 }
58 59
59 PassOwnPtr<RadioButtonGroup> RadioButtonGroup::create() 60 PassOwnPtr<RadioButtonGroup> RadioButtonGroup::create()
60 { 61 {
61 return adoptPtr(new RadioButtonGroup); 62 return adoptPtr(new RadioButtonGroup);
62 } 63 }
63 64
64 inline bool RadioButtonGroup::isValid() const 65 inline bool RadioButtonGroup::isValid() const
65 { 66 {
66 return !isRequired() || m_checkedButton; 67 return !isRequired() || m_checkedButton;
67 } 68 }
68 69
69 void RadioButtonGroup::setCheckedButton(HTMLInputElement* button) 70 void RadioButtonGroup::setCheckedButton(Handle<HTMLInputElement> button)
70 { 71 {
71 HTMLInputElement* oldCheckedButton = m_checkedButton; 72 Handle<HTMLInputElement> oldCheckedButton = Handle<HTMLInputElement>(m_check edButton); // FIXME(oilpan): Remove Handle<>().
72 if (oldCheckedButton == button) 73 if (oldCheckedButton == button)
73 return; 74 return;
74 m_checkedButton = button; 75 m_checkedButton = button.raw();
75 if (oldCheckedButton) 76 if (oldCheckedButton)
76 oldCheckedButton->setChecked(false); 77 oldCheckedButton->setChecked(false);
77 } 78 }
78 79
79 void RadioButtonGroup::add(HTMLInputElement* button) 80 void RadioButtonGroup::add(Handle<HTMLInputElement> button)
80 { 81 {
81 ASSERT(button->isRadioButton()); 82 ASSERT(button->isRadioButton());
82 if (!m_members.add(button).isNewEntry) 83 if (!m_members.add(button.raw()).isNewEntry)
83 return; 84 return;
84 bool groupWasValid = isValid(); 85 bool groupWasValid = isValid();
85 if (button->isRequired()) 86 if (button->isRequired())
86 ++m_requiredCount; 87 ++m_requiredCount;
87 if (button->checked()) 88 if (button->checked())
88 setCheckedButton(button); 89 setCheckedButton(button);
89 90
90 bool groupIsValid = isValid(); 91 bool groupIsValid = isValid();
91 if (groupWasValid != groupIsValid) 92 if (groupWasValid != groupIsValid)
92 setNeedsValidityCheckForAllButtons(); 93 setNeedsValidityCheckForAllButtons();
93 else if (!groupIsValid) { 94 else if (!groupIsValid) {
94 // A radio button not in a group is always valid. We need to make it 95 // A radio button not in a group is always valid. We need to make it
95 // invalid only if the group is invalid. 96 // invalid only if the group is invalid.
96 button->setNeedsValidityCheck(); 97 button->setNeedsValidityCheck();
97 } 98 }
98 } 99 }
99 100
100 void RadioButtonGroup::updateCheckedState(HTMLInputElement* button) 101 void RadioButtonGroup::updateCheckedState(Handle<HTMLInputElement> button)
101 { 102 {
102 ASSERT(button->isRadioButton()); 103 ASSERT(button->isRadioButton());
103 ASSERT(m_members.contains(button)); 104 ASSERT(m_members.contains(button.raw()));
104 bool wasValid = isValid(); 105 bool wasValid = isValid();
105 if (button->checked()) 106 if (button->checked())
106 setCheckedButton(button); 107 setCheckedButton(button);
107 else { 108 else {
108 if (m_checkedButton == button) 109 if (m_checkedButton == button.raw())
109 m_checkedButton = 0; 110 m_checkedButton = 0;
110 } 111 }
111 if (wasValid != isValid()) 112 if (wasValid != isValid())
112 setNeedsValidityCheckForAllButtons(); 113 setNeedsValidityCheckForAllButtons();
113 } 114 }
114 115
115 void RadioButtonGroup::requiredAttributeChanged(HTMLInputElement* button) 116 void RadioButtonGroup::requiredAttributeChanged(Handle<HTMLInputElement> button)
116 { 117 {
117 ASSERT(button->isRadioButton()); 118 ASSERT(button->isRadioButton());
118 ASSERT(m_members.contains(button)); 119 ASSERT(m_members.contains(button.raw()));
119 bool wasValid = isValid(); 120 bool wasValid = isValid();
120 if (button->isRequired()) 121 if (button->isRequired())
121 ++m_requiredCount; 122 ++m_requiredCount;
122 else { 123 else {
123 ASSERT(m_requiredCount); 124 ASSERT(m_requiredCount);
124 --m_requiredCount; 125 --m_requiredCount;
125 } 126 }
126 if (wasValid != isValid()) 127 if (wasValid != isValid())
127 setNeedsValidityCheckForAllButtons(); 128 setNeedsValidityCheckForAllButtons();
128 } 129 }
129 130
130 void RadioButtonGroup::remove(HTMLInputElement* button) 131 void RadioButtonGroup::remove(Handle<HTMLInputElement> button)
131 { 132 {
132 ASSERT(button->isRadioButton()); 133 ASSERT(button->isRadioButton());
133 HashSet<HTMLInputElement*>::iterator it = m_members.find(button); 134 HashSet<HTMLInputElement*>::iterator it = m_members.find(button.raw());
134 if (it == m_members.end()) 135 if (it == m_members.end())
135 return; 136 return;
136 bool wasValid = isValid(); 137 bool wasValid = isValid();
137 m_members.remove(it); 138 m_members.remove(it);
138 if (button->isRequired()) { 139 if (button->isRequired()) {
139 ASSERT(m_requiredCount); 140 ASSERT(m_requiredCount);
140 --m_requiredCount; 141 --m_requiredCount;
141 } 142 }
142 if (m_checkedButton == button) 143 if (m_checkedButton == button.raw())
143 m_checkedButton = 0; 144 m_checkedButton = 0;
144 145
145 if (m_members.isEmpty()) { 146 if (m_members.isEmpty()) {
146 ASSERT(!m_requiredCount); 147 ASSERT(!m_requiredCount);
147 ASSERT(!m_checkedButton); 148 ASSERT(!m_checkedButton);
148 } else if (wasValid != isValid()) 149 } else if (wasValid != isValid())
149 setNeedsValidityCheckForAllButtons(); 150 setNeedsValidityCheckForAllButtons();
150 if (!wasValid) { 151 if (!wasValid) {
151 // A radio button not in a group is always valid. We need to make it 152 // A radio button not in a group is always valid. We need to make it
152 // valid only if the group was invalid. 153 // valid only if the group was invalid.
153 button->setNeedsValidityCheck(); 154 button->setNeedsValidityCheck();
154 } 155 }
155 } 156 }
156 157
157 void RadioButtonGroup::setNeedsValidityCheckForAllButtons() 158 void RadioButtonGroup::setNeedsValidityCheckForAllButtons()
158 { 159 {
159 typedef HashSet<HTMLInputElement*>::const_iterator Iterator; 160 typedef HashSet<HTMLInputElement*>::const_iterator Iterator;
160 Iterator end = m_members.end(); 161 Iterator end = m_members.end();
161 for (Iterator it = m_members.begin(); it != end; ++it) { 162 for (Iterator it = m_members.begin(); it != end; ++it) {
162 HTMLInputElement* button = *it; 163 Handle<HTMLInputElement> button = Handle<HTMLInputElement>(*it); // FIXM E(oilpan): Remove Handle<>().
163 ASSERT(button->isRadioButton()); 164 ASSERT(button->isRadioButton());
164 button->setNeedsValidityCheck(); 165 button->setNeedsValidityCheck();
165 } 166 }
166 } 167 }
167 168
168 bool RadioButtonGroup::contains(HTMLInputElement* button) const 169 bool RadioButtonGroup::contains(Handle<HTMLInputElement> button) const
169 { 170 {
170 return m_members.contains(button); 171 return m_members.contains(button.raw());
171 } 172 }
172 173
173 // ---------------------------------------------------------------- 174 // ----------------------------------------------------------------
174 175
175 // Explicity define empty constructor and destructor in order to prevent the 176 // Explicity define empty constructor and destructor in order to prevent the
176 // compiler from generating them as inlines. So we don't need to to define 177 // compiler from generating them as inlines. So we don't need to to define
177 // RadioButtonGroup in the header. 178 // RadioButtonGroup in the header.
178 CheckedRadioButtons::CheckedRadioButtons() 179 CheckedRadioButtons::CheckedRadioButtons()
179 { 180 {
180 } 181 }
181 182
182 CheckedRadioButtons::~CheckedRadioButtons() 183 CheckedRadioButtons::~CheckedRadioButtons()
183 { 184 {
184 } 185 }
185 186
186 void CheckedRadioButtons::addButton(HTMLInputElement* element) 187 void CheckedRadioButtons::addButton(Handle<HTMLInputElement> element)
187 { 188 {
188 ASSERT(element->isRadioButton()); 189 ASSERT(element->isRadioButton());
189 if (element->name().isEmpty()) 190 if (element->name().isEmpty())
190 return; 191 return;
191 192
192 if (!m_nameToGroupMap) 193 if (!m_nameToGroupMap)
193 m_nameToGroupMap = adoptPtr(new NameToGroupMap); 194 m_nameToGroupMap = adoptPtr(new NameToGroupMap);
194 195
195 OwnPtr<RadioButtonGroup>& group = m_nameToGroupMap->add(element->name().impl (), PassOwnPtr<RadioButtonGroup>()).iterator->value; 196 OwnPtr<RadioButtonGroup>& group = m_nameToGroupMap->add(element->name().impl (), PassOwnPtr<RadioButtonGroup>()).iterator->value;
196 if (!group) 197 if (!group)
197 group = RadioButtonGroup::create(); 198 group = RadioButtonGroup::create();
198 group->add(element); 199 group->add(element);
199 } 200 }
200 201
201 void CheckedRadioButtons::updateCheckedState(HTMLInputElement* element) 202 void CheckedRadioButtons::updateCheckedState(Handle<HTMLInputElement> element)
202 { 203 {
203 ASSERT(element->isRadioButton()); 204 ASSERT(element->isRadioButton());
204 if (element->name().isEmpty()) 205 if (element->name().isEmpty())
205 return; 206 return;
206 ASSERT(m_nameToGroupMap); 207 ASSERT(m_nameToGroupMap);
207 if (!m_nameToGroupMap) 208 if (!m_nameToGroupMap)
208 return; 209 return;
209 RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl()); 210 RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl());
210 ASSERT(group); 211 ASSERT(group);
211 group->updateCheckedState(element); 212 group->updateCheckedState(element);
212 } 213 }
213 214
214 void CheckedRadioButtons::requiredAttributeChanged(HTMLInputElement* element) 215 void CheckedRadioButtons::requiredAttributeChanged(Handle<HTMLInputElement> elem ent)
215 { 216 {
216 ASSERT(element->isRadioButton()); 217 ASSERT(element->isRadioButton());
217 if (element->name().isEmpty()) 218 if (element->name().isEmpty())
218 return; 219 return;
219 ASSERT(m_nameToGroupMap); 220 ASSERT(m_nameToGroupMap);
220 if (!m_nameToGroupMap) 221 if (!m_nameToGroupMap)
221 return; 222 return;
222 RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl()); 223 RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl());
223 ASSERT(group); 224 ASSERT(group);
224 group->requiredAttributeChanged(element); 225 group->requiredAttributeChanged(element);
225 } 226 }
226 227
227 HTMLInputElement* CheckedRadioButtons::checkedButtonForGroup(const AtomicString& name) const 228 Result<HTMLInputElement> CheckedRadioButtons::checkedButtonForGroup(const Atomic String& name) const
228 { 229 {
229 if (!m_nameToGroupMap) 230 if (!m_nameToGroupMap)
230 return 0; 231 return nullptr;
231 m_nameToGroupMap->checkConsistency(); 232 m_nameToGroupMap->checkConsistency();
232 RadioButtonGroup* group = m_nameToGroupMap->get(name.impl()); 233 RadioButtonGroup* group = m_nameToGroupMap->get(name.impl());
233 return group ? group->checkedButton() : 0; 234 return group ? group->checkedButton() : nullptr;
234 } 235 }
235 236
236 bool CheckedRadioButtons::isInRequiredGroup(HTMLInputElement* element) const 237 bool CheckedRadioButtons::isInRequiredGroup(Handle<HTMLInputElement> element) co nst
237 { 238 {
238 ASSERT(element->isRadioButton()); 239 ASSERT(element->isRadioButton());
239 if (element->name().isEmpty()) 240 if (element->name().isEmpty())
240 return false; 241 return false;
241 if (!m_nameToGroupMap) 242 if (!m_nameToGroupMap)
242 return false; 243 return false;
243 RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl()); 244 RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl());
244 return group && group->isRequired() && group->contains(element); 245 return group && group->isRequired() && group->contains(element);
245 } 246 }
246 247
247 void CheckedRadioButtons::removeButton(HTMLInputElement* element) 248 void CheckedRadioButtons::removeButton(Handle<HTMLInputElement> element)
248 { 249 {
249 ASSERT(element->isRadioButton()); 250 ASSERT(element->isRadioButton());
250 if (element->name().isEmpty()) 251 if (element->name().isEmpty())
251 return; 252 return;
252 if (!m_nameToGroupMap) 253 if (!m_nameToGroupMap)
253 return; 254 return;
254 255
255 m_nameToGroupMap->checkConsistency(); 256 m_nameToGroupMap->checkConsistency();
256 NameToGroupMap::iterator it = m_nameToGroupMap->find(element->name().impl()) ; 257 NameToGroupMap::iterator it = m_nameToGroupMap->find(element->name().impl()) ;
257 if (it == m_nameToGroupMap->end()) 258 if (it == m_nameToGroupMap->end())
258 return; 259 return;
259 it->value->remove(element); 260 it->value->remove(element);
260 if (it->value->isEmpty()) { 261 if (it->value->isEmpty()) {
261 // FIXME: We may skip deallocating the empty RadioButtonGroup for 262 // FIXME: We may skip deallocating the empty RadioButtonGroup for
262 // performance improvement. If we do so, we need to change the key type 263 // performance improvement. If we do so, we need to change the key type
263 // of m_nameToGroupMap from AtomicStringImpl* to RefPtr<AtomicStringImpl >. 264 // of m_nameToGroupMap from AtomicStringImpl* to RefPtr<AtomicStringImpl >.
264 m_nameToGroupMap->remove(it); 265 m_nameToGroupMap->remove(it);
265 if (m_nameToGroupMap->isEmpty()) 266 if (m_nameToGroupMap->isEmpty())
266 m_nameToGroupMap.clear(); 267 m_nameToGroupMap.clear();
267 } 268 }
268 } 269 }
269 270
270 } // namespace 271 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698