| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
| 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
| 6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 } | 163 } |
| 164 HTMLElement::insertedInto(insertionPoint); | 164 HTMLElement::insertedInto(insertionPoint); |
| 165 if (insertionPoint->inDocument()) | 165 if (insertionPoint->inDocument()) |
| 166 this->document().didAssociateFormControl(this); | 166 this->document().didAssociateFormControl(this); |
| 167 return InsertionDone; | 167 return InsertionDone; |
| 168 } | 168 } |
| 169 | 169 |
| 170 template<class T> | 170 template<class T> |
| 171 void notifyFormRemovedFromTree(const T& elements, Node& root) | 171 void notifyFormRemovedFromTree(const T& elements, Node& root) |
| 172 { | 172 { |
| 173 size_t size = elements.size(); | 173 for (const auto& element : elements) |
| 174 for (size_t i = 0; i < size; ++i) | 174 element->formRemovedFromTree(root); |
| 175 elements[i]->formRemovedFromTree(root); | |
| 176 ASSERT(elements.size() == size); | |
| 177 } | 175 } |
| 178 | 176 |
| 179 void HTMLFormElement::removedFrom(ContainerNode* insertionPoint) | 177 void HTMLFormElement::removedFrom(ContainerNode* insertionPoint) |
| 180 { | 178 { |
| 181 // We don't need to take care of form association by 'form' content | 179 // We don't need to take care of form association by 'form' content |
| 182 // attribute becuse IdTargetObserver handles it. | 180 // attribute becuse IdTargetObserver handles it. |
| 183 if (m_hasElementsAssociatedByParser) { | 181 if (m_hasElementsAssociatedByParser) { |
| 184 Node& root = NodeTraversal::highestAncestorOrSelf(*this); | 182 Node& root = NodeTraversal::highestAncestorOrSelf(*this); |
| 185 if (!m_associatedElementsAreDirty) { | 183 if (!m_associatedElementsAreDirty) { |
| 186 FormAssociatedElement::List elements(associatedElements()); | 184 FormAssociatedElement::List elements(associatedElements()); |
| 187 notifyFormRemovedFromTree(elements, root); | 185 notifyFormRemovedFromTree(elements, root); |
| 188 } else { | 186 } else { |
| 189 FormAssociatedElement::List elements; | 187 FormAssociatedElement::List elements; |
| 190 collectAssociatedElements(NodeTraversal::highestAncestorOrSelf(*inse
rtionPoint), elements); | 188 collectAssociatedElements(NodeTraversal::highestAncestorOrSelf(*inse
rtionPoint), elements); |
| 191 notifyFormRemovedFromTree(elements, root); | 189 notifyFormRemovedFromTree(elements, root); |
| 192 collectAssociatedElements(root, elements); | 190 collectAssociatedElements(root, elements); |
| 193 notifyFormRemovedFromTree(elements, root); | 191 notifyFormRemovedFromTree(elements, root); |
| 194 } | 192 } |
| 195 | 193 |
| 196 if (!m_imageElementsAreDirty) { | 194 if (!m_imageElementsAreDirty) { |
| 197 WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> > images(image
Elements()); | 195 WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement>> images(imageE
lements()); |
| 198 notifyFormRemovedFromTree(images, root); | 196 notifyFormRemovedFromTree(images, root); |
| 199 } else { | 197 } else { |
| 200 WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> > images; | 198 WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement>> images; |
| 201 collectImageElements(NodeTraversal::highestAncestorOrSelf(*insertion
Point), images); | 199 collectImageElements(NodeTraversal::highestAncestorOrSelf(*insertion
Point), images); |
| 202 notifyFormRemovedFromTree(images, root); | 200 notifyFormRemovedFromTree(images, root); |
| 203 collectImageElements(root, images); | 201 collectImageElements(root, images); |
| 204 notifyFormRemovedFromTree(images, root); | 202 notifyFormRemovedFromTree(images, root); |
| 205 } | 203 } |
| 206 } | 204 } |
| 207 #if ENABLE(OILPAN) | 205 #if ENABLE(OILPAN) |
| 208 document().formController().willDeleteForm(this); | 206 document().formController().willDeleteForm(this); |
| 209 #endif | 207 #endif |
| 210 HTMLElement::removedFrom(insertionPoint); | 208 HTMLElement::removedFrom(insertionPoint); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 } | 273 } |
| 276 | 274 |
| 277 bool HTMLFormElement::validateInteractively() | 275 bool HTMLFormElement::validateInteractively() |
| 278 { | 276 { |
| 279 const FormAssociatedElement::List& elements = associatedElements(); | 277 const FormAssociatedElement::List& elements = associatedElements(); |
| 280 for (unsigned i = 0; i < elements.size(); ++i) { | 278 for (unsigned i = 0; i < elements.size(); ++i) { |
| 281 if (elements[i]->isFormControlElement()) | 279 if (elements[i]->isFormControlElement()) |
| 282 toHTMLFormControlElement(elements[i])->hideVisibleValidationMessage(
); | 280 toHTMLFormControlElement(elements[i])->hideVisibleValidationMessage(
); |
| 283 } | 281 } |
| 284 | 282 |
| 285 WillBeHeapVector<RefPtrWillBeMember<HTMLFormControlElement> > unhandledInval
idControls; | 283 WillBeHeapVector<RefPtrWillBeMember<HTMLFormControlElement>> unhandledInvali
dControls; |
| 286 if (!checkInvalidControlsAndCollectUnhandled(&unhandledInvalidControls, Chec
kValidityDispatchInvalidEvent)) | 284 if (!checkInvalidControlsAndCollectUnhandled(&unhandledInvalidControls, Chec
kValidityDispatchInvalidEvent)) |
| 287 return true; | 285 return true; |
| 288 // Because the form has invalid controls, we abort the form submission and | 286 // Because the form has invalid controls, we abort the form submission and |
| 289 // show a validation message on a focusable form control. | 287 // show a validation message on a focusable form control. |
| 290 | 288 |
| 291 // Needs to update layout now because we'd like to call isFocusable(), which | 289 // Needs to update layout now because we'd like to call isFocusable(), which |
| 292 // has !renderer()->needsLayout() assertion. | 290 // has !renderer()->needsLayout() assertion. |
| 293 document().updateLayoutIgnorePendingStylesheets(); | 291 document().updateLayoutIgnorePendingStylesheets(); |
| 294 | 292 |
| 295 RefPtrWillBeRawPtr<HTMLFormElement> protector(this); | 293 RefPtrWillBeRawPtr<HTMLFormElement> protector(this); |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 if (m_hasElementsAssociatedByParser) | 638 if (m_hasElementsAssociatedByParser) |
| 641 scope = &NodeTraversal::highestAncestorOrSelf(*mutableThis); | 639 scope = &NodeTraversal::highestAncestorOrSelf(*mutableThis); |
| 642 if (inDocument() && treeScope().idTargetObserverRegistry().hasObservers(fast
GetAttribute(idAttr))) | 640 if (inDocument() && treeScope().idTargetObserverRegistry().hasObservers(fast
GetAttribute(idAttr))) |
| 643 scope = &treeScope().rootNode(); | 641 scope = &treeScope().rootNode(); |
| 644 ASSERT(scope); | 642 ASSERT(scope); |
| 645 collectAssociatedElements(*scope, mutableThis->m_associatedElements); | 643 collectAssociatedElements(*scope, mutableThis->m_associatedElements); |
| 646 mutableThis->m_associatedElementsAreDirty = false; | 644 mutableThis->m_associatedElementsAreDirty = false; |
| 647 return m_associatedElements; | 645 return m_associatedElements; |
| 648 } | 646 } |
| 649 | 647 |
| 650 void HTMLFormElement::collectImageElements(Node& root, WillBeHeapVector<RawPtrWi
llBeMember<HTMLImageElement> >& elements) | 648 void HTMLFormElement::collectImageElements(Node& root, WillBeHeapVector<RawPtrWi
llBeMember<HTMLImageElement>>& elements) |
| 651 { | 649 { |
| 652 elements.clear(); | 650 elements.clear(); |
| 653 for (HTMLImageElement& image : Traversal<HTMLImageElement>::startsAfter(root
)) { | 651 for (HTMLImageElement& image : Traversal<HTMLImageElement>::startsAfter(root
)) { |
| 654 if (image.formOwner() == this) | 652 if (image.formOwner() == this) |
| 655 elements.append(&image); | 653 elements.append(&image); |
| 656 } | 654 } |
| 657 } | 655 } |
| 658 | 656 |
| 659 const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& HTMLFormElement::
imageElements() | 657 const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement>>& HTMLFormElement::i
mageElements() |
| 660 { | 658 { |
| 661 if (!m_imageElementsAreDirty) | 659 if (!m_imageElementsAreDirty) |
| 662 return m_imageElements; | 660 return m_imageElements; |
| 663 collectImageElements(m_hasElementsAssociatedByParser ? NodeTraversal::highes
tAncestorOrSelf(*this) : *this, m_imageElements); | 661 collectImageElements(m_hasElementsAssociatedByParser ? NodeTraversal::highes
tAncestorOrSelf(*this) : *this, m_imageElements); |
| 664 m_imageElementsAreDirty = false; | 662 m_imageElementsAreDirty = false; |
| 665 return m_imageElements; | 663 return m_imageElements; |
| 666 } | 664 } |
| 667 | 665 |
| 668 String HTMLFormElement::name() const | 666 String HTMLFormElement::name() const |
| 669 { | 667 { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 724 // recalculate style only if it changed. | 722 // recalculate style only if it changed. |
| 725 pseudoStateChanged(CSSSelector::PseudoValid); | 723 pseudoStateChanged(CSSSelector::PseudoValid); |
| 726 pseudoStateChanged(CSSSelector::PseudoInvalid); | 724 pseudoStateChanged(CSSSelector::PseudoInvalid); |
| 727 } | 725 } |
| 728 | 726 |
| 729 bool HTMLFormElement::checkValidity() | 727 bool HTMLFormElement::checkValidity() |
| 730 { | 728 { |
| 731 return !checkInvalidControlsAndCollectUnhandled(0, CheckValidityDispatchInva
lidEvent); | 729 return !checkInvalidControlsAndCollectUnhandled(0, CheckValidityDispatchInva
lidEvent); |
| 732 } | 730 } |
| 733 | 731 |
| 734 bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<R
efPtrWillBeMember<HTMLFormControlElement> >* unhandledInvalidControls, CheckVali
dityEventBehavior eventBehavior) | 732 bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<R
efPtrWillBeMember<HTMLFormControlElement>>* unhandledInvalidControls, CheckValid
ityEventBehavior eventBehavior) |
| 735 { | 733 { |
| 736 RefPtrWillBeRawPtr<HTMLFormElement> protector(this); | 734 RefPtrWillBeRawPtr<HTMLFormElement> protector(this); |
| 737 // Copy associatedElements because event handlers called from | 735 // Copy associatedElements because event handlers called from |
| 738 // HTMLFormControlElement::checkValidity() might change associatedElements. | 736 // HTMLFormControlElement::checkValidity() might change associatedElements. |
| 739 const FormAssociatedElement::List& associatedElements = this->associatedElem
ents(); | 737 const FormAssociatedElement::List& associatedElements = this->associatedElem
ents(); |
| 740 WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> > elements; | 738 WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement>> elements; |
| 741 elements.reserveCapacity(associatedElements.size()); | 739 elements.reserveCapacity(associatedElements.size()); |
| 742 for (unsigned i = 0; i < associatedElements.size(); ++i) | 740 for (unsigned i = 0; i < associatedElements.size(); ++i) |
| 743 elements.append(associatedElements[i]); | 741 elements.append(associatedElements[i]); |
| 744 bool hasInvalidControls = false; | 742 bool hasInvalidControls = false; |
| 745 for (unsigned i = 0; i < elements.size(); ++i) { | 743 for (unsigned i = 0; i < elements.size(); ++i) { |
| 746 if (elements[i]->form() == this && elements[i]->isFormControlElement())
{ | 744 if (elements[i]->form() == this && elements[i]->isFormControlElement())
{ |
| 747 HTMLFormControlElement* control = toHTMLFormControlElement(elements[
i].get()); | 745 HTMLFormControlElement* control = toHTMLFormControlElement(elements[
i].get()); |
| 748 if (!control->checkValidity(unhandledInvalidControls, eventBehavior)
&& control->formOwner() == this) | 746 if (!control->checkValidity(unhandledInvalidControls, eventBehavior)
&& control->formOwner() == this) |
| 749 hasInvalidControls = true; | 747 hasInvalidControls = true; |
| 750 } | 748 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 return; | 781 return; |
| 784 if (!m_pastNamesMap) | 782 if (!m_pastNamesMap) |
| 785 m_pastNamesMap = adoptPtrWillBeNoop(new PastNamesMap); | 783 m_pastNamesMap = adoptPtrWillBeNoop(new PastNamesMap); |
| 786 m_pastNamesMap->set(pastName, element); | 784 m_pastNamesMap->set(pastName, element); |
| 787 } | 785 } |
| 788 | 786 |
| 789 void HTMLFormElement::removeFromPastNamesMap(HTMLElement& element) | 787 void HTMLFormElement::removeFromPastNamesMap(HTMLElement& element) |
| 790 { | 788 { |
| 791 if (!m_pastNamesMap) | 789 if (!m_pastNamesMap) |
| 792 return; | 790 return; |
| 793 PastNamesMap::iterator end = m_pastNamesMap->end(); | 791 for (auto& it : *m_pastNamesMap) { |
| 794 for (PastNamesMap::iterator it = m_pastNamesMap->begin(); it != end; ++it) { | 792 if (it.value == &element) { |
| 795 if (it->value == &element) { | 793 it.value = nullptr; |
| 796 it->value = nullptr; | |
| 797 // Keep looping. Single element can have multiple names. | 794 // Keep looping. Single element can have multiple names. |
| 798 } | 795 } |
| 799 } | 796 } |
| 800 } | 797 } |
| 801 | 798 |
| 802 void HTMLFormElement::getNamedElements(const AtomicString& name, WillBeHeapVecto
r<RefPtrWillBeMember<Element> >& namedItems) | 799 void HTMLFormElement::getNamedElements(const AtomicString& name, WillBeHeapVecto
r<RefPtrWillBeMember<Element>>& namedItems) |
| 803 { | 800 { |
| 804 // http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#do
m-form-nameditem | 801 // http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#do
m-form-nameditem |
| 805 elements()->namedItems(name, namedItems); | 802 elements()->namedItems(name, namedItems); |
| 806 | 803 |
| 807 Element* elementFromPast = elementFromPastNamesMap(name); | 804 Element* elementFromPast = elementFromPastNamesMap(name); |
| 808 if (namedItems.size() && namedItems.first() != elementFromPast) { | 805 if (namedItems.size() && namedItems.first() != elementFromPast) { |
| 809 addToPastNamesMap(namedItems.first().get(), name); | 806 addToPastNamesMap(namedItems.first().get(), name); |
| 810 } else if (elementFromPast && namedItems.isEmpty()) { | 807 } else if (elementFromPast && namedItems.isEmpty()) { |
| 811 namedItems.append(elementFromPast); | 808 namedItems.append(elementFromPast); |
| 812 UseCounter::count(document(), UseCounter::FormNameAccessForPastNamesMap)
; | 809 UseCounter::count(document(), UseCounter::FormNameAccessForPastNamesMap)
; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 830 m_wasDemoted = static_cast<const HTMLFormElement&>(source).m_wasDemoted; | 827 m_wasDemoted = static_cast<const HTMLFormElement&>(source).m_wasDemoted; |
| 831 HTMLElement::copyNonAttributePropertiesFromElement(source); | 828 HTMLElement::copyNonAttributePropertiesFromElement(source); |
| 832 } | 829 } |
| 833 | 830 |
| 834 void HTMLFormElement::anonymousNamedGetter(const AtomicString& name, RadioNodeLi
stOrElement& returnValue) | 831 void HTMLFormElement::anonymousNamedGetter(const AtomicString& name, RadioNodeLi
stOrElement& returnValue) |
| 835 { | 832 { |
| 836 // Call getNamedElements twice, first time check if it has a value | 833 // Call getNamedElements twice, first time check if it has a value |
| 837 // and let HTMLFormElement update its cache. | 834 // and let HTMLFormElement update its cache. |
| 838 // See issue: 867404 | 835 // See issue: 867404 |
| 839 { | 836 { |
| 840 WillBeHeapVector<RefPtrWillBeMember<Element> > elements; | 837 WillBeHeapVector<RefPtrWillBeMember<Element>> elements; |
| 841 getNamedElements(name, elements); | 838 getNamedElements(name, elements); |
| 842 if (elements.isEmpty()) | 839 if (elements.isEmpty()) |
| 843 return; | 840 return; |
| 844 } | 841 } |
| 845 | 842 |
| 846 // Second call may return different results from the first call, | 843 // Second call may return different results from the first call, |
| 847 // but if the first the size cannot be zero. | 844 // but if the first the size cannot be zero. |
| 848 WillBeHeapVector<RefPtrWillBeMember<Element> > elements; | 845 WillBeHeapVector<RefPtrWillBeMember<Element>> elements; |
| 849 getNamedElements(name, elements); | 846 getNamedElements(name, elements); |
| 850 ASSERT(!elements.isEmpty()); | 847 ASSERT(!elements.isEmpty()); |
| 851 | 848 |
| 852 if (elements.size() == 1) { | 849 if (elements.size() == 1) { |
| 853 returnValue.setElement(elements.at(0)); | 850 returnValue.setElement(elements.at(0)); |
| 854 return; | 851 return; |
| 855 } | 852 } |
| 856 | 853 |
| 857 bool onlyMatchImg = !elements.isEmpty() && isHTMLImageElement(*elements.firs
t()); | 854 bool onlyMatchImg = !elements.isEmpty() && isHTMLImageElement(*elements.firs
t()); |
| 858 returnValue.setRadioNodeList(radioNodeList(name, onlyMatchImg)); | 855 returnValue.setRadioNodeList(radioNodeList(name, onlyMatchImg)); |
| 859 } | 856 } |
| 860 | 857 |
| 861 void HTMLFormElement::setDemoted(bool demoted) | 858 void HTMLFormElement::setDemoted(bool demoted) |
| 862 { | 859 { |
| 863 if (demoted) | 860 if (demoted) |
| 864 UseCounter::count(document(), UseCounter::DemotedFormElement); | 861 UseCounter::count(document(), UseCounter::DemotedFormElement); |
| 865 m_wasDemoted = demoted; | 862 m_wasDemoted = demoted; |
| 866 } | 863 } |
| 867 | 864 |
| 868 } // namespace | 865 } // namespace |
| OLD | NEW |