Web Inspector: add external resources size to the native memory diagram
[WebKit-https.git] / Source / WebCore / html / FormController.cpp
1 /*
2  * Copyright (C) 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
3  * Copyright (C) 2010, 2011, 2012 Google Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include "config.h"
22 #include "FormController.h"
23
24 #include "HTMLFormControlElementWithState.h"
25
26 namespace WebCore {
27
28 using namespace HTMLNames;
29
30 // ----------------------------------------------------------------------------
31
32 // Serilized form of FormControlState:
33 //  (',' means strings around it are separated in stateVector.)
34 //
35 // SerializedControlState ::= SkipState | RestoreState
36 // SkipState ::= '0'
37 // RestoreState ::= UnsignedNumber, ControlValue+
38 // UnsignedNumber ::= [0-9]+
39 // ControlValue ::= arbitrary string
40 //
41 // RestoreState has a sequence of ControlValues. The length of the
42 // sequence is represented by UnsignedNumber.
43
44 void FormControlState::serializeTo(Vector<String>& stateVector) const
45 {
46     ASSERT(!isFailure());
47     stateVector.append(String::number(m_values.size()));
48     for (size_t i = 0; i < m_values.size(); ++i)
49         stateVector.append(m_values[i].isNull() ? emptyString() : m_values[i]);
50 }
51
52 FormControlState FormControlState::deserialize(const Vector<String>& stateVector, size_t& index)
53 {
54     if (index >= stateVector.size())
55         return FormControlState(TypeFailure);
56     size_t valueSize = stateVector[index++].toUInt();
57     if (!valueSize)
58         return FormControlState();
59     if (index + valueSize > stateVector.size())
60         return FormControlState(TypeFailure);
61     FormControlState state;
62     state.m_values.reserveCapacity(valueSize);
63     for (size_t i = 0; i < valueSize; ++i)
64         state.append(stateVector[index++]);
65     return state;
66 }
67
68 // ----------------------------------------------------------------------------
69
70
71 FormController::FormController()
72 {
73 }
74
75 FormController::~FormController()
76 {
77 }
78
79 static String formStateSignature()
80 {
81     // In the legacy version of serialized state, the first item was a name
82     // attribute value of a form control. The following string literal should
83     // contain some characters which are rarely used for name attribute values.
84     DEFINE_STATIC_LOCAL(String, signature, ("\n\r?% WebKit serialized form state version 3 \n\r=&"));
85     return signature;
86 }
87
88 Vector<String> FormController::formElementsState() const
89 {
90     Vector<String> stateVector;
91     stateVector.reserveInitialCapacity(m_formElementsWithState.size() * 4 + 1);
92     stateVector.append(formStateSignature());
93     typedef FormElementListHashSet::const_iterator Iterator;
94     Iterator end = m_formElementsWithState.end();
95     for (Iterator it = m_formElementsWithState.begin(); it != end; ++it) {
96         HTMLFormControlElementWithState* elementWithState = *it;
97         if (!elementWithState->shouldSaveAndRestoreFormControlState())
98             continue;
99         stateVector.append(elementWithState->name().string());
100         stateVector.append(elementWithState->formControlType().string());
101         elementWithState->saveFormControlState().serializeTo(stateVector);
102     }
103     return stateVector;
104 }
105
106 static bool isNotFormControlTypeCharacter(UChar ch)
107 {
108     return ch != '-' && (ch > 'z' || ch < 'a');
109 }
110
111 void FormController::setStateForNewFormElements(const Vector<String>& stateVector)
112 {
113     typedef FormElementStateMap::iterator Iterator;
114     m_formElementsWithState.clear();
115
116     size_t i = 0;
117     if (stateVector.size() < 1 || stateVector[i++] != formStateSignature())
118         return;
119
120     while (i + 2 < stateVector.size()) {
121         AtomicString name = stateVector[i++];
122         AtomicString type = stateVector[i++];
123         FormControlState state = FormControlState::deserialize(stateVector, i);
124         if (type.isEmpty() || type.impl()->find(isNotFormControlTypeCharacter) != notFound || state.isFailure())
125             break;
126
127         FormElementKey key(name.impl(), type.impl());
128         Iterator it = m_stateForNewFormElements.find(key);
129         if (it != m_stateForNewFormElements.end())
130             it->second.append(state);
131         else {
132             Deque<FormControlState> stateList;
133             stateList.append(state);
134             m_stateForNewFormElements.set(key, stateList);
135         }
136     }
137     if (i != stateVector.size())
138         m_stateForNewFormElements.clear();
139 }
140
141 bool FormController::hasStateForNewFormElements() const
142 {
143     return !m_stateForNewFormElements.isEmpty();
144 }
145
146 FormControlState FormController::takeStateForFormElement(AtomicStringImpl* name, AtomicStringImpl* type)
147 {
148     typedef FormElementStateMap::iterator Iterator;
149     Iterator it = m_stateForNewFormElements.find(FormElementKey(name, type));
150     if (it == m_stateForNewFormElements.end())
151         return FormControlState();
152     ASSERT(it->second.size());
153     FormControlState state = it->second.takeFirst();
154     if (!it->second.size())
155         m_stateForNewFormElements.remove(it);
156     return state;
157 }
158
159 void FormController::registerFormElementWithFormAttribute(FormAssociatedElement* element)
160 {
161     ASSERT(toHTMLElement(element)->fastHasAttribute(formAttr));
162     m_formElementsWithFormAttribute.add(element);
163 }
164
165 void FormController::unregisterFormElementWithFormAttribute(FormAssociatedElement* element)
166 {
167     m_formElementsWithFormAttribute.remove(element);
168 }
169
170 void FormController::resetFormElementsOwner()
171 {
172     typedef FormAssociatedElementListHashSet::iterator Iterator;
173     Iterator end = m_formElementsWithFormAttribute.end();
174     for (Iterator it = m_formElementsWithFormAttribute.begin(); it != end; ++it)
175         (*it)->resetFormOwner();
176 }
177
178 FormElementKey::FormElementKey(AtomicStringImpl* name, AtomicStringImpl* type)
179     : m_name(name), m_type(type)
180 {
181     ref();
182 }
183
184 FormElementKey::~FormElementKey()
185 {
186     deref();
187 }
188
189 FormElementKey::FormElementKey(const FormElementKey& other)
190     : m_name(other.name()), m_type(other.type())
191 {
192     ref();
193 }
194
195 FormElementKey& FormElementKey::operator=(const FormElementKey& other)
196 {
197     other.ref();
198     deref();
199     m_name = other.name();
200     m_type = other.type();
201     return *this;
202 }
203
204 void FormElementKey::ref() const
205 {
206     if (name())
207         name()->ref();
208     if (type())
209         type()->ref();
210 }
211
212 void FormElementKey::deref() const
213 {
214     if (name())
215         name()->deref();
216     if (type())
217         type()->deref();
218 }
219
220 unsigned FormElementKeyHash::hash(const FormElementKey& key)
221 {
222     return StringHasher::hashMemory<sizeof(FormElementKey)>(&key);
223 }
224
225 } // namespace WebCore
226