Move form-related functions of Document to FormController
https://bugs.webkit.org/show_bug.cgi?id=88497
Reviewed by Hajime Morita.
A lot of files depend on Document.h. We had to build many files when we
touched form-related features in Document.h or
CheckedRadioButtons.h. This patch reduces such pain.
No new tests. Just a refactoring.
* CMakeLists.txt: Add FormController.cpp and/or FormController.h.
* GNUmakefile.list.am: ditto.
* Target.pri: ditto.
* WebCore.gypi: ditto.
* WebCore.vcproj/WebCore.vcproj: ditto.
* WebCore.xcodeproj/project.pbxproj: ditto.
* dom/Document.cpp: Removed form-releated features except the followings.
(WebCore::Document::formController): Accessor for a FormController.
(WebCore::Document::formElementsState):
Just returns FormController::formElementsState().
We don't create new FormController.
(WebCore::Document::setStateForNewFormElements):
Just returns FormController::setStateForNewFormElements().
We don't create new FormController if the specified vector is empty.
* dom/Document.h:
Moved form-related functions to FormController.
* html/FormController.cpp: Added. Moved from Document.cpp.
* html/FormController.h: Added. Moved from Document.h
* html/FormAssociatedElement.cpp: Use Document::formController().
(WebCore::FormAssociatedElement::didMoveToNewDocument):
(WebCore::FormAssociatedElement::insertedInto):
(WebCore::FormAssociatedElement::removedFrom):
(WebCore::FormAssociatedElement::formAttributeChanged):
* html/HTMLFormControlElementWithState.cpp: Use Document::formController().
(WebCore::HTMLFormControlElementWithState::HTMLFormControlElementWithState):
(WebCore::HTMLFormControlElementWithState::~HTMLFormControlElementWithState):
(WebCore::HTMLFormControlElementWithState::didMoveToNewDocument):
(WebCore::HTMLFormControlElementWithState::finishParsingChildren):
* html/HTMLFormElement.cpp: Use Document::formController().
(WebCore::HTMLFormElement::didNotifyDescendantInsertions):
(WebCore::HTMLFormElement::removedFrom):
* html/HTMLInputElement.cpp: Use Document::formController().
(WebCore::HTMLInputElement::~HTMLInputElement):
(WebCore::HTMLInputElement::didMoveToNewDocument):
(WebCore::HTMLInputElement::checkedRadioButtons):
* html/HTMLInputElement.h:
Declare CheckedRadioButtons. It was provided by Document.h.
* html/parser/HTMLConstructionSite.h:
Declare HTMLFormElement. It was provided by Document.h
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@119816 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/html/FormController.cpp b/Source/WebCore/html/FormController.cpp
new file mode 100644
index 0000000..69b931f
--- /dev/null
+++ b/Source/WebCore/html/FormController.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2011, 2012 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FormController.h"
+
+#include "HTMLFormControlElementWithState.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+FormController::FormController()
+{
+}
+
+FormController::~FormController()
+{
+}
+
+Vector<String> FormController::formElementsState() const
+{
+ Vector<String> stateVector;
+ stateVector.reserveInitialCapacity(m_formElementsWithState.size() * 3);
+ typedef FormElementListHashSet::const_iterator Iterator;
+ Iterator end = m_formElementsWithState.end();
+ for (Iterator it = m_formElementsWithState.begin(); it != end; ++it) {
+ HTMLFormControlElementWithState* elementWithState = *it;
+ if (!elementWithState->shouldSaveAndRestoreFormControlState())
+ continue;
+ String value;
+ if (!elementWithState->saveFormControlState(value))
+ continue;
+ stateVector.append(elementWithState->formControlName().string());
+ stateVector.append(elementWithState->formControlType().string());
+ stateVector.append(value);
+ }
+ return stateVector;
+}
+
+void FormController::setStateForNewFormElements(const Vector<String>& stateVector)
+{
+ // Walk the state vector backwards so that the value to use for each
+ // name/type pair first is the one at the end of each individual vector
+ // in the FormElementStateMap. We're using them like stacks.
+ typedef FormElementStateMap::iterator Iterator;
+ m_formElementsWithState.clear();
+ for (size_t i = stateVector.size() / 3 * 3; i; i -= 3) {
+ AtomicString a = stateVector[i - 3];
+ AtomicString b = stateVector[i - 2];
+ const String& c = stateVector[i - 1];
+ FormElementKey key(a.impl(), b.impl());
+ Iterator it = m_stateForNewFormElements.find(key);
+ if (it != m_stateForNewFormElements.end())
+ it->second.append(c);
+ else {
+ Vector<String> v(1);
+ v[0] = c;
+ m_stateForNewFormElements.set(key, v);
+ }
+ }
+}
+
+bool FormController::hasStateForNewFormElements() const
+{
+ return !m_stateForNewFormElements.isEmpty();
+}
+
+bool FormController::takeStateForFormElement(AtomicStringImpl* name, AtomicStringImpl* type, String& state)
+{
+ typedef FormElementStateMap::iterator Iterator;
+ Iterator it = m_stateForNewFormElements.find(FormElementKey(name, type));
+ if (it == m_stateForNewFormElements.end())
+ return false;
+ ASSERT(it->second.size());
+ state = it->second.last();
+ if (it->second.size() > 1)
+ it->second.removeLast();
+ else
+ m_stateForNewFormElements.remove(it);
+ return true;
+}
+
+void FormController::registerFormElementWithFormAttribute(FormAssociatedElement* element)
+{
+ ASSERT(toHTMLElement(element)->fastHasAttribute(formAttr));
+ m_formElementsWithFormAttribute.add(element);
+}
+
+void FormController::unregisterFormElementWithFormAttribute(FormAssociatedElement* element)
+{
+ m_formElementsWithFormAttribute.remove(element);
+}
+
+void FormController::resetFormElementsOwner()
+{
+ typedef FormAssociatedElementListHashSet::iterator Iterator;
+ Iterator end = m_formElementsWithFormAttribute.end();
+ for (Iterator it = m_formElementsWithFormAttribute.begin(); it != end; ++it)
+ (*it)->resetFormOwner();
+}
+
+FormElementKey::FormElementKey(AtomicStringImpl* name, AtomicStringImpl* type)
+ : m_name(name), m_type(type)
+{
+ ref();
+}
+
+FormElementKey::~FormElementKey()
+{
+ deref();
+}
+
+FormElementKey::FormElementKey(const FormElementKey& other)
+ : m_name(other.name()), m_type(other.type())
+{
+ ref();
+}
+
+FormElementKey& FormElementKey::operator=(const FormElementKey& other)
+{
+ other.ref();
+ deref();
+ m_name = other.name();
+ m_type = other.type();
+ return *this;
+}
+
+void FormElementKey::ref() const
+{
+ if (name())
+ name()->ref();
+ if (type())
+ type()->ref();
+}
+
+void FormElementKey::deref() const
+{
+ if (name())
+ name()->deref();
+ if (type())
+ type()->deref();
+}
+
+unsigned FormElementKeyHash::hash(const FormElementKey& key)
+{
+ return StringHasher::hashMemory<sizeof(FormElementKey)>(&key);
+}
+
+} // namespace WebCore
+