15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 1999 Antti Koivisto (koivisto@kde.org)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 2001 Dirk Mueller (mueller@kde.org)
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/FormAssociatedElement.h"
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/IdTargetObserver.h"
30c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/dom/NodeTraversal.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLFormControlElement.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLFormElement.h"
337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/html/HTMLLabelElement.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLObjectElement.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/ValidityState.h"
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames;
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
41f523d2789ac2f83c4eca0ee4d5161bfdb5f2d052Torne (Richard Coles)class FormAttributeTargetObserver : public IdTargetObserver {
42323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
44323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    static PassOwnPtrWillBeRawPtr<FormAttributeTargetObserver> create(const AtomicString& id, FormAssociatedElement*);
45f523d2789ac2f83c4eca0ee4d5161bfdb5f2d052Torne (Richard Coles)    virtual void trace(Visitor*) OVERRIDE;
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void idTargetChanged() OVERRIDE;
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FormAttributeTargetObserver(const AtomicString& id, FormAssociatedElement*);
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
51323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    RawPtrWillBeMember<FormAssociatedElement> m_element;
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FormAssociatedElement::FormAssociatedElement()
5509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    : m_formWasSetByParser(false)
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FormAssociatedElement::~FormAssociatedElement()
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
618abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // We can't call setForm here because it contains virtual calls.
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
64323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void FormAssociatedElement::trace(Visitor* visitor)
65323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){
66323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    visitor->trace(m_formAttributeTargetObserver);
67323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    visitor->trace(m_form);
68323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    visitor->trace(m_validityState);
69323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)}
70323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ValidityState* FormAssociatedElement::validity()
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_validityState)
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_validityState = ValidityState::create(this);
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_validityState.get();
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)void FormAssociatedElement::didMoveToNewDocument(Document& oldDocument)
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElement* element = toHTMLElement(this);
821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (element->fastHasAttribute(formAttr))
83323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        setFormAttributeTargetObserver(nullptr);
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FormAssociatedElement::insertedInto(ContainerNode* insertionPoint)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
889e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (!m_formWasSetByParser || !m_form || NodeTraversal::highestAncestorOrSelf(*insertionPoint) != NodeTraversal::highestAncestorOrSelf(*m_form.get()))
8909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        resetFormOwner();
90e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!insertionPoint->inDocument())
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElement* element = toHTMLElement(this);
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (element->fastHasAttribute(formAttr))
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        resetFormAttributeTargetObserver();
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FormAssociatedElement::removedFrom(ContainerNode* insertionPoint)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElement* element = toHTMLElement(this);
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (insertionPoint->inDocument() && element->fastHasAttribute(formAttr))
103323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        setFormAttributeTargetObserver(nullptr);
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the form and element are both in the same tree, preserve the connection to the form.
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Otherwise, null out our form and remove ourselves from the form's list of elements.
106c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (m_form && NodeTraversal::highestAncestorOrSelf(*element) != NodeTraversal::highestAncestorOrSelf(*m_form.get()))
10709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        resetFormOwner();
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)HTMLFormElement* FormAssociatedElement::findAssociatedForm(const HTMLElement* element)
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const AtomicString& formId(element->fastGetAttribute(formAttr));
11309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // 3. If the element is reassociateable, has a form content attribute, and
11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // is itself in a Document, then run these substeps:
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!formId.isNull() && element->inDocument()) {
11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // 3.1. If the first element in the Document to have an ID that is
11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // case-sensitively equal to the element's form content attribute's
11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // value is a form element, then associate the form-associated element
11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // with that form element.
12009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // 3.2. Abort the "reset the form owner" steps.
1218abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        Element* newFormCandidate = element->treeScope().getElementById(formId);
122d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return isHTMLFormElement(newFormCandidate) ? toHTMLFormElement(newFormCandidate) : 0;
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // 4. Otherwise, if the form-associated element in question has an ancestor
12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // form element, then associate the form-associated element with the nearest
12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // such ancestor form element.
12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return element->findFormAncestor();
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
130d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void FormAssociatedElement::formRemovedFromTree(const Node& formRoot)
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_form);
133c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (NodeTraversal::highestAncestorOrSelf(toHTMLElement(*this)) == formRoot)
13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
13509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    resetFormOwner();
13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
13709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
13809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void FormAssociatedElement::associateByParser(HTMLFormElement* form)
13909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
14009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (form && form->inDocument()) {
14109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_formWasSetByParser = true;
14209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        setForm(form);
14309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        form->didAssociateByParser();
14409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FormAssociatedElement::setForm(HTMLFormElement* newForm)
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (m_form.get() == newForm)
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    willChangeForm();
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_form)
15309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_form->disassociate(*this);
15409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (newForm) {
155323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#if ENABLE(OILPAN)
156323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        m_form = newForm;
157323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#else
15809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_form = newForm->createWeakPtr();
159323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#endif
16009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_form->associate(*this);
16109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    } else {
162323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#if ENABLE(OILPAN)
163323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        m_form = nullptr;
164323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#else
16509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_form = WeakPtr<HTMLFormElement>();
166323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#endif
16709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    didChangeForm();
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FormAssociatedElement::willChangeForm()
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FormAssociatedElement::didChangeForm()
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FormAssociatedElement::resetFormOwner()
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_formWasSetByParser = false;
18202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    HTMLElement* element = toHTMLElement(this);
18309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const AtomicString& formId(element->fastGetAttribute(formAttr));
18409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    HTMLFormElement* nearestForm = element->findFormAncestor();
18509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // 1. If the element's form owner is not null, and either the element is not
18609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // reassociateable or its form content attribute is not present, and the
18709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // element's form owner is its nearest form element ancestor after the
18809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // change to the ancestor chain, then do nothing, and abort these steps.
18909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (m_form && formId.isNull() && m_form.get() == nearestForm)
19009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
19109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    HTMLFormElement* originalForm = m_form.get();
19309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    setForm(findAssociatedForm(element));
19409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // FIXME: Move didAssociateFormControl call to didChangeForm or
19509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // HTMLFormElement::associate.
19609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (m_form && m_form.get() != originalForm && m_form->inDocument())
1978abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        element->document().didAssociateFormControl(element);
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FormAssociatedElement::formAttributeChanged()
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
20209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    resetFormOwner();
20309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    resetFormAttributeTargetObserver();
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FormAssociatedElement::customError() const
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const HTMLElement* element = toHTMLElement(this);
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return element->willValidate() && !m_customValidationMessage.isEmpty();
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
212926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool FormAssociatedElement::hasBadInput() const
213926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return false;
215926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
216926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FormAssociatedElement::patternMismatch() const
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FormAssociatedElement::rangeOverflow() const
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FormAssociatedElement::rangeUnderflow() const
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FormAssociatedElement::stepMismatch() const
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FormAssociatedElement::tooLong() const
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FormAssociatedElement::typeMismatch() const
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FormAssociatedElement::valid() const
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool someError = typeMismatch() || stepMismatch() || rangeUnderflow() || rangeOverflow()
250926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        || tooLong() || patternMismatch() || valueMissing() || hasBadInput() || customError();
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return !someError;
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FormAssociatedElement::valueMissing() const
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String FormAssociatedElement::customValidationMessage() const
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_customValidationMessage;
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String FormAssociatedElement::validationMessage() const
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return customError() ? m_customValidationMessage : String();
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FormAssociatedElement::setCustomValidity(const String& error)
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_customValidationMessage = error;
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
274323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void FormAssociatedElement::setFormAttributeTargetObserver(PassOwnPtrWillBeRawPtr<FormAttributeTargetObserver> newObserver)
275323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){
276323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (m_formAttributeTargetObserver)
277323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        m_formAttributeTargetObserver->unregister();
278323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    m_formAttributeTargetObserver = newObserver;
279323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)}
280323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FormAssociatedElement::resetFormAttributeTargetObserver()
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
28309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    HTMLElement* element = toHTMLElement(this);
28409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const AtomicString& formId(element->fastGetAttribute(formAttr));
28509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!formId.isNull() && element->inDocument())
286323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        setFormAttributeTargetObserver(FormAttributeTargetObserver::create(formId, this));
28709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    else
288323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        setFormAttributeTargetObserver(nullptr);
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FormAssociatedElement::formAttributeTargetChanged()
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    resetFormOwner();
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const AtomicString& FormAssociatedElement::name() const
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const AtomicString& name = toHTMLElement(this)->getNameAttribute();
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return name.isNull() ? emptyAtom : name;
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FormAssociatedElement::isFormControlElementWithState() const
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)const HTMLElement& toHTMLElement(const FormAssociatedElement& associatedElement)
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
30951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (associatedElement.isFormControlElement())
3108abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        return toHTMLFormControlElement(associatedElement);
3117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    else if (associatedElement.isLabelElement())
3127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return toHTMLLabelElement(associatedElement);
3137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    else
3147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return toHTMLObjectElement(associatedElement);
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
31751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)const HTMLElement* toHTMLElement(const FormAssociatedElement* associatedElement)
31851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
31951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(associatedElement);
32051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return &toHTMLElement(*associatedElement);
32151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
32251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HTMLElement* toHTMLElement(FormAssociatedElement* associatedElement)
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return const_cast<HTMLElement*>(toHTMLElement(static_cast<const FormAssociatedElement*>(associatedElement)));
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
32851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)HTMLElement& toHTMLElement(FormAssociatedElement& associatedElement)
32951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
33051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return const_cast<HTMLElement&>(toHTMLElement(static_cast<const FormAssociatedElement&>(associatedElement)));
33151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
33251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
333323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)PassOwnPtrWillBeRawPtr<FormAttributeTargetObserver> FormAttributeTargetObserver::create(const AtomicString& id, FormAssociatedElement* element)
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
335323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return adoptPtrWillBeNoop(new FormAttributeTargetObserver(id, element));
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FormAttributeTargetObserver::FormAttributeTargetObserver(const AtomicString& id, FormAssociatedElement* element)
3398abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    : IdTargetObserver(toHTMLElement(element)->treeScope().idTargetObserverRegistry(), id)
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_element(element)
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
344f523d2789ac2f83c4eca0ee4d5161bfdb5f2d052Torne (Richard Coles)void FormAttributeTargetObserver::trace(Visitor* visitor)
345f523d2789ac2f83c4eca0ee4d5161bfdb5f2d052Torne (Richard Coles){
346f523d2789ac2f83c4eca0ee4d5161bfdb5f2d052Torne (Richard Coles)    visitor->trace(m_element);
347f523d2789ac2f83c4eca0ee4d5161bfdb5f2d052Torne (Richard Coles)    IdTargetObserver::trace(visitor);
348f523d2789ac2f83c4eca0ee4d5161bfdb5f2d052Torne (Richard Coles)}
349f523d2789ac2f83c4eca0ee4d5161bfdb5f2d052Torne (Richard Coles)
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FormAttributeTargetObserver::idTargetChanged()
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_element->formAttributeTargetChanged();
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} // namespace blink
356