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 | 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights |
6 * reserved. | 6 * reserved. |
7 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 7 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 #include "wtf/AutoReset.h" | 60 #include "wtf/AutoReset.h" |
61 #include "wtf/text/AtomicString.h" | 61 #include "wtf/text/AtomicString.h" |
62 #include <limits> | 62 #include <limits> |
63 | 63 |
64 namespace blink { | 64 namespace blink { |
65 | 65 |
66 using namespace HTMLNames; | 66 using namespace HTMLNames; |
67 | 67 |
68 HTMLFormElement::HTMLFormElement(Document& document) | 68 HTMLFormElement::HTMLFormElement(Document& document) |
69 : HTMLElement(formTag, document), | 69 : HTMLElement(formTag, document), |
70 m_associatedElementsAreDirty(false), | 70 m_listedElementsAreDirty(false), |
71 m_imageElementsAreDirty(false), | 71 m_imageElementsAreDirty(false), |
72 m_hasElementsAssociatedByParser(false), | 72 m_hasElementsAssociatedByParser(false), |
73 m_hasElementsAssociatedByFormAttribute(false), | 73 m_hasElementsAssociatedByFormAttribute(false), |
74 m_didFinishParsingChildren(false), | 74 m_didFinishParsingChildren(false), |
75 m_isInResetFunction(false), | 75 m_isInResetFunction(false), |
76 m_wasDemoted(false) {} | 76 m_wasDemoted(false) {} |
77 | 77 |
78 HTMLFormElement* HTMLFormElement::create(Document& document) { | 78 HTMLFormElement* HTMLFormElement::create(Document& document) { |
79 UseCounter::count(document, UseCounter::FormElement); | 79 UseCounter::count(document, UseCounter::FormElement); |
80 return new HTMLFormElement(document); | 80 return new HTMLFormElement(document); |
81 } | 81 } |
82 | 82 |
83 HTMLFormElement::~HTMLFormElement() {} | 83 HTMLFormElement::~HTMLFormElement() {} |
84 | 84 |
85 DEFINE_TRACE(HTMLFormElement) { | 85 DEFINE_TRACE(HTMLFormElement) { |
86 visitor->trace(m_pastNamesMap); | 86 visitor->trace(m_pastNamesMap); |
87 visitor->trace(m_radioButtonGroupScope); | 87 visitor->trace(m_radioButtonGroupScope); |
88 visitor->trace(m_associatedElements); | 88 visitor->trace(m_listedElements); |
89 visitor->trace(m_imageElements); | 89 visitor->trace(m_imageElements); |
90 visitor->trace(m_plannedNavigation); | 90 visitor->trace(m_plannedNavigation); |
91 HTMLElement::trace(visitor); | 91 HTMLElement::trace(visitor); |
92 } | 92 } |
93 | 93 |
94 bool HTMLFormElement::matchesValidityPseudoClasses() const { | 94 bool HTMLFormElement::matchesValidityPseudoClasses() const { |
95 return true; | 95 return true; |
96 } | 96 } |
97 | 97 |
98 bool HTMLFormElement::isValidElement() { | 98 bool HTMLFormElement::isValidElement() { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 void notifyFormRemovedFromTree(const T& elements, Node& root) { | 147 void notifyFormRemovedFromTree(const T& elements, Node& root) { |
148 for (const auto& element : elements) | 148 for (const auto& element : elements) |
149 element->formRemovedFromTree(root); | 149 element->formRemovedFromTree(root); |
150 } | 150 } |
151 | 151 |
152 void HTMLFormElement::removedFrom(ContainerNode* insertionPoint) { | 152 void HTMLFormElement::removedFrom(ContainerNode* insertionPoint) { |
153 // We don't need to take care of form association by 'form' content | 153 // We don't need to take care of form association by 'form' content |
154 // attribute becuse IdTargetObserver handles it. | 154 // attribute becuse IdTargetObserver handles it. |
155 if (m_hasElementsAssociatedByParser) { | 155 if (m_hasElementsAssociatedByParser) { |
156 Node& root = NodeTraversal::highestAncestorOrSelf(*this); | 156 Node& root = NodeTraversal::highestAncestorOrSelf(*this); |
157 if (!m_associatedElementsAreDirty) { | 157 if (!m_listedElementsAreDirty) { |
158 FormAssociatedElement::List elements(associatedElements()); | 158 ListedElement::List elements(listedElements()); |
159 notifyFormRemovedFromTree(elements, root); | 159 notifyFormRemovedFromTree(elements, root); |
160 } else { | 160 } else { |
161 FormAssociatedElement::List elements; | 161 ListedElement::List elements; |
162 collectAssociatedElements( | 162 collectlistedElements( |
163 NodeTraversal::highestAncestorOrSelf(*insertionPoint), elements); | 163 NodeTraversal::highestAncestorOrSelf(*insertionPoint), elements); |
164 notifyFormRemovedFromTree(elements, root); | 164 notifyFormRemovedFromTree(elements, root); |
165 collectAssociatedElements(root, elements); | 165 collectlistedElements(root, elements); |
166 notifyFormRemovedFromTree(elements, root); | 166 notifyFormRemovedFromTree(elements, root); |
167 } | 167 } |
168 | 168 |
169 if (!m_imageElementsAreDirty) { | 169 if (!m_imageElementsAreDirty) { |
170 HeapVector<Member<HTMLImageElement>> images(imageElements()); | 170 HeapVector<Member<HTMLImageElement>> images(imageElements()); |
171 notifyFormRemovedFromTree(images, root); | 171 notifyFormRemovedFromTree(images, root); |
172 } else { | 172 } else { |
173 HeapVector<Member<HTMLImageElement>> images; | 173 HeapVector<Member<HTMLImageElement>> images; |
174 collectImageElements( | 174 collectImageElements( |
175 NodeTraversal::highestAncestorOrSelf(*insertionPoint), images); | 175 NodeTraversal::highestAncestorOrSelf(*insertionPoint), images); |
(...skipping 11 matching lines...) Expand all Loading... |
187 if (event.eventPhase() != Event::kCapturingPhase && targetNode && | 187 if (event.eventPhase() != Event::kCapturingPhase && targetNode && |
188 targetNode != this && (event.type() == EventTypeNames::submit || | 188 targetNode != this && (event.type() == EventTypeNames::submit || |
189 event.type() == EventTypeNames::reset)) { | 189 event.type() == EventTypeNames::reset)) { |
190 event.stopPropagation(); | 190 event.stopPropagation(); |
191 return; | 191 return; |
192 } | 192 } |
193 HTMLElement::handleLocalEvents(event); | 193 HTMLElement::handleLocalEvents(event); |
194 } | 194 } |
195 | 195 |
196 unsigned HTMLFormElement::length() const { | 196 unsigned HTMLFormElement::length() const { |
197 const FormAssociatedElement::List& elements = associatedElements(); | 197 const ListedElement::List& elements = listedElements(); |
198 unsigned len = 0; | 198 unsigned len = 0; |
199 for (unsigned i = 0; i < elements.size(); ++i) { | 199 for (unsigned i = 0; i < elements.size(); ++i) { |
200 if (elements[i]->isEnumeratable()) | 200 if (elements[i]->isEnumeratable()) |
201 ++len; | 201 ++len; |
202 } | 202 } |
203 return len; | 203 return len; |
204 } | 204 } |
205 | 205 |
206 HTMLElement* HTMLFormElement::item(unsigned index) { | 206 HTMLElement* HTMLFormElement::item(unsigned index) { |
207 return elements()->item(index); | 207 return elements()->item(index); |
208 } | 208 } |
209 | 209 |
210 void HTMLFormElement::submitImplicitly(Event* event, | 210 void HTMLFormElement::submitImplicitly(Event* event, |
211 bool fromImplicitSubmissionTrigger) { | 211 bool fromImplicitSubmissionTrigger) { |
212 int submissionTriggerCount = 0; | 212 int submissionTriggerCount = 0; |
213 bool seenDefaultButton = false; | 213 bool seenDefaultButton = false; |
214 const FormAssociatedElement::List& elements = associatedElements(); | 214 const ListedElement::List& elements = listedElements(); |
215 for (unsigned i = 0; i < elements.size(); ++i) { | 215 for (unsigned i = 0; i < elements.size(); ++i) { |
216 FormAssociatedElement* formAssociatedElement = elements[i]; | 216 ListedElement* ListedElement = elements[i]; |
217 if (!formAssociatedElement->isFormControlElement()) | 217 if (!ListedElement->isFormControlElement()) |
218 continue; | 218 continue; |
219 HTMLFormControlElement* control = | 219 HTMLFormControlElement* control = toHTMLFormControlElement(ListedElement); |
220 toHTMLFormControlElement(formAssociatedElement); | |
221 if (!seenDefaultButton && control->canBeSuccessfulSubmitButton()) { | 220 if (!seenDefaultButton && control->canBeSuccessfulSubmitButton()) { |
222 if (fromImplicitSubmissionTrigger) | 221 if (fromImplicitSubmissionTrigger) |
223 seenDefaultButton = true; | 222 seenDefaultButton = true; |
224 if (control->isSuccessfulSubmitButton()) { | 223 if (control->isSuccessfulSubmitButton()) { |
225 control->dispatchSimulatedClick(event); | 224 control->dispatchSimulatedClick(event); |
226 return; | 225 return; |
227 } | 226 } |
228 if (fromImplicitSubmissionTrigger) { | 227 if (fromImplicitSubmissionTrigger) { |
229 // Default (submit) button is not activated; no implicit submission. | 228 // Default (submit) button is not activated; no implicit submission. |
230 return; | 229 return; |
231 } | 230 } |
232 } else if (control->canTriggerImplicitSubmission()) { | 231 } else if (control->canTriggerImplicitSubmission()) { |
233 ++submissionTriggerCount; | 232 ++submissionTriggerCount; |
234 } | 233 } |
235 } | 234 } |
236 if (fromImplicitSubmissionTrigger && submissionTriggerCount == 1) | 235 if (fromImplicitSubmissionTrigger && submissionTriggerCount == 1) |
237 prepareForSubmission(event, nullptr); | 236 prepareForSubmission(event, nullptr); |
238 } | 237 } |
239 | 238 |
240 bool HTMLFormElement::validateInteractively() { | 239 bool HTMLFormElement::validateInteractively() { |
241 UseCounter::count(document(), UseCounter::FormValidationStarted); | 240 UseCounter::count(document(), UseCounter::FormValidationStarted); |
242 const FormAssociatedElement::List& elements = associatedElements(); | 241 const ListedElement::List& elements = listedElements(); |
243 for (unsigned i = 0; i < elements.size(); ++i) { | 242 for (unsigned i = 0; i < elements.size(); ++i) { |
244 if (elements[i]->isFormControlElement()) | 243 if (elements[i]->isFormControlElement()) |
245 toHTMLFormControlElement(elements[i])->hideVisibleValidationMessage(); | 244 toHTMLFormControlElement(elements[i])->hideVisibleValidationMessage(); |
246 } | 245 } |
247 | 246 |
248 HeapVector<Member<HTMLFormControlElement>> unhandledInvalidControls; | 247 HeapVector<Member<HTMLFormControlElement>> unhandledInvalidControls; |
249 if (!checkInvalidControlsAndCollectUnhandled( | 248 if (!checkInvalidControlsAndCollectUnhandled( |
250 &unhandledInvalidControls, CheckValidityDispatchInvalidEvent)) | 249 &unhandledInvalidControls, CheckValidityDispatchInvalidEvent)) |
251 return true; | 250 return true; |
252 UseCounter::count(document(), UseCounter::FormValidationAbortedSubmission); | 251 UseCounter::count(document(), UseCounter::FormValidationAbortedSubmission); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 | 362 |
364 // Delay dispatching 'close' to dialog until done submitting. | 363 // Delay dispatching 'close' to dialog until done submitting. |
365 EventQueueScope scopeForDialogClose; | 364 EventQueueScope scopeForDialogClose; |
366 AutoReset<bool> submitScope(&m_isSubmitting, true); | 365 AutoReset<bool> submitScope(&m_isSubmitting, true); |
367 | 366 |
368 if (event && !submitButton) { | 367 if (event && !submitButton) { |
369 // In a case of implicit submission without a submit button, 'submit' | 368 // In a case of implicit submission without a submit button, 'submit' |
370 // event handler might add a submit button. We search for a submit | 369 // event handler might add a submit button. We search for a submit |
371 // button again. | 370 // button again. |
372 // TODO(tkent): Do we really need to activate such submit button? | 371 // TODO(tkent): Do we really need to activate such submit button? |
373 for (const auto& associatedElement : associatedElements()) { | 372 for (const auto& listedElement : listedElements()) { |
374 if (!associatedElement->isFormControlElement()) | 373 if (!listedElement->isFormControlElement()) |
375 continue; | 374 continue; |
376 HTMLFormControlElement* control = | 375 HTMLFormControlElement* control = toHTMLFormControlElement(listedElement); |
377 toHTMLFormControlElement(associatedElement); | |
378 DCHECK(!control->isActivatedSubmit()); | 376 DCHECK(!control->isActivatedSubmit()); |
379 if (control->isSuccessfulSubmitButton()) { | 377 if (control->isSuccessfulSubmitButton()) { |
380 submitButton = control; | 378 submitButton = control; |
381 break; | 379 break; |
382 } | 380 } |
383 } | 381 } |
384 } | 382 } |
385 | 383 |
386 FormSubmission* formSubmission = | 384 FormSubmission* formSubmission = |
387 FormSubmission::create(this, m_attributes, event, submitButton); | 385 FormSubmission::create(this, m_attributes, event, submitButton); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 return; | 464 return; |
467 | 465 |
468 m_isInResetFunction = true; | 466 m_isInResetFunction = true; |
469 | 467 |
470 if (dispatchEvent(Event::createCancelableBubble(EventTypeNames::reset)) != | 468 if (dispatchEvent(Event::createCancelableBubble(EventTypeNames::reset)) != |
471 DispatchEventResult::NotCanceled) { | 469 DispatchEventResult::NotCanceled) { |
472 m_isInResetFunction = false; | 470 m_isInResetFunction = false; |
473 return; | 471 return; |
474 } | 472 } |
475 | 473 |
476 const FormAssociatedElement::List& elements = associatedElements(); | 474 const ListedElement::List& elements = listedElements(); |
477 for (unsigned i = 0; i < elements.size(); ++i) { | 475 for (unsigned i = 0; i < elements.size(); ++i) { |
478 if (elements[i]->isFormControlElement()) | 476 if (elements[i]->isFormControlElement()) |
479 toHTMLFormControlElement(elements[i])->reset(); | 477 toHTMLFormControlElement(elements[i])->reset(); |
480 } | 478 } |
481 | 479 |
482 m_isInResetFunction = false; | 480 m_isInResetFunction = false; |
483 } | 481 } |
484 | 482 |
485 void HTMLFormElement::parseAttribute(const QualifiedName& name, | 483 void HTMLFormElement::parseAttribute(const QualifiedName& name, |
486 const AtomicString& oldValue, | 484 const AtomicString& oldValue, |
(...skipping 20 matching lines...) Expand all Loading... |
507 m_attributes.updateMethodType(value); | 505 m_attributes.updateMethodType(value); |
508 } else if (name == enctypeAttr) { | 506 } else if (name == enctypeAttr) { |
509 m_attributes.updateEncodingType(value); | 507 m_attributes.updateEncodingType(value); |
510 } else if (name == accept_charsetAttr) { | 508 } else if (name == accept_charsetAttr) { |
511 m_attributes.setAcceptCharset(value); | 509 m_attributes.setAcceptCharset(value); |
512 } else { | 510 } else { |
513 HTMLElement::parseAttribute(name, oldValue, value); | 511 HTMLElement::parseAttribute(name, oldValue, value); |
514 } | 512 } |
515 } | 513 } |
516 | 514 |
517 void HTMLFormElement::associate(FormAssociatedElement& e) { | 515 void HTMLFormElement::associate(ListedElement& e) { |
518 m_associatedElementsAreDirty = true; | 516 m_listedElementsAreDirty = true; |
519 m_associatedElements.clear(); | 517 m_listedElements.clear(); |
520 if (toHTMLElement(e).fastHasAttribute(formAttr)) | 518 if (toHTMLElement(e).fastHasAttribute(formAttr)) |
521 m_hasElementsAssociatedByFormAttribute = true; | 519 m_hasElementsAssociatedByFormAttribute = true; |
522 } | 520 } |
523 | 521 |
524 void HTMLFormElement::disassociate(FormAssociatedElement& e) { | 522 void HTMLFormElement::disassociate(ListedElement& e) { |
525 m_associatedElementsAreDirty = true; | 523 m_listedElementsAreDirty = true; |
526 m_associatedElements.clear(); | 524 m_listedElements.clear(); |
527 removeFromPastNamesMap(toHTMLElement(e)); | 525 removeFromPastNamesMap(toHTMLElement(e)); |
528 } | 526 } |
529 | 527 |
530 bool HTMLFormElement::isURLAttribute(const Attribute& attribute) const { | 528 bool HTMLFormElement::isURLAttribute(const Attribute& attribute) const { |
531 return attribute.name() == actionAttr || | 529 return attribute.name() == actionAttr || |
532 HTMLElement::isURLAttribute(attribute); | 530 HTMLElement::isURLAttribute(attribute); |
533 } | 531 } |
534 | 532 |
535 bool HTMLFormElement::hasLegalLinkAttribute(const QualifiedName& name) const { | 533 bool HTMLFormElement::hasLegalLinkAttribute(const QualifiedName& name) const { |
536 return name == actionAttr || HTMLElement::hasLegalLinkAttribute(name); | 534 return name == actionAttr || HTMLElement::hasLegalLinkAttribute(name); |
(...skipping 14 matching lines...) Expand all Loading... |
551 if (!m_didFinishParsingChildren) | 549 if (!m_didFinishParsingChildren) |
552 return; | 550 return; |
553 m_hasElementsAssociatedByParser = true; | 551 m_hasElementsAssociatedByParser = true; |
554 UseCounter::count(document(), UseCounter::FormAssociationByParser); | 552 UseCounter::count(document(), UseCounter::FormAssociationByParser); |
555 } | 553 } |
556 | 554 |
557 HTMLFormControlsCollection* HTMLFormElement::elements() { | 555 HTMLFormControlsCollection* HTMLFormElement::elements() { |
558 return ensureCachedCollection<HTMLFormControlsCollection>(FormControls); | 556 return ensureCachedCollection<HTMLFormControlsCollection>(FormControls); |
559 } | 557 } |
560 | 558 |
561 void HTMLFormElement::collectAssociatedElements( | 559 void HTMLFormElement::collectlistedElements( |
562 Node& root, | 560 Node& root, |
563 FormAssociatedElement::List& elements) const { | 561 ListedElement::List& elements) const { |
564 elements.clear(); | 562 elements.clear(); |
565 for (HTMLElement& element : Traversal<HTMLElement>::startsAfter(root)) { | 563 for (HTMLElement& element : Traversal<HTMLElement>::startsAfter(root)) { |
566 FormAssociatedElement* associatedElement = 0; | 564 ListedElement* listedElement = 0; |
567 if (element.isFormControlElement()) | 565 if (element.isFormControlElement()) |
568 associatedElement = toHTMLFormControlElement(&element); | 566 listedElement = toHTMLFormControlElement(&element); |
569 else if (isHTMLObjectElement(element)) | 567 else if (isHTMLObjectElement(element)) |
570 associatedElement = toHTMLObjectElement(&element); | 568 listedElement = toHTMLObjectElement(&element); |
571 else | 569 else |
572 continue; | 570 continue; |
573 if (associatedElement->form() == this) | 571 if (listedElement->form() == this) |
574 elements.append(associatedElement); | 572 elements.append(listedElement); |
575 } | 573 } |
576 } | 574 } |
577 | 575 |
578 // This function should be const conceptually. However we update some fields | 576 // This function should be const conceptually. However we update some fields |
579 // because of lazy evaluation. | 577 // because of lazy evaluation. |
580 const FormAssociatedElement::List& HTMLFormElement::associatedElements() const { | 578 const ListedElement::List& HTMLFormElement::listedElements() const { |
581 if (!m_associatedElementsAreDirty) | 579 if (!m_listedElementsAreDirty) |
582 return m_associatedElements; | 580 return m_listedElements; |
583 HTMLFormElement* mutableThis = const_cast<HTMLFormElement*>(this); | 581 HTMLFormElement* mutableThis = const_cast<HTMLFormElement*>(this); |
584 Node* scope = mutableThis; | 582 Node* scope = mutableThis; |
585 if (m_hasElementsAssociatedByParser) | 583 if (m_hasElementsAssociatedByParser) |
586 scope = &NodeTraversal::highestAncestorOrSelf(*mutableThis); | 584 scope = &NodeTraversal::highestAncestorOrSelf(*mutableThis); |
587 if (isConnected() && m_hasElementsAssociatedByFormAttribute) | 585 if (isConnected() && m_hasElementsAssociatedByFormAttribute) |
588 scope = &treeScope().rootNode(); | 586 scope = &treeScope().rootNode(); |
589 DCHECK(scope); | 587 DCHECK(scope); |
590 collectAssociatedElements(*scope, mutableThis->m_associatedElements); | 588 collectlistedElements(*scope, mutableThis->m_listedElements); |
591 mutableThis->m_associatedElementsAreDirty = false; | 589 mutableThis->m_listedElementsAreDirty = false; |
592 return m_associatedElements; | 590 return m_listedElements; |
593 } | 591 } |
594 | 592 |
595 void HTMLFormElement::collectImageElements( | 593 void HTMLFormElement::collectImageElements( |
596 Node& root, | 594 Node& root, |
597 HeapVector<Member<HTMLImageElement>>& elements) { | 595 HeapVector<Member<HTMLImageElement>>& elements) { |
598 elements.clear(); | 596 elements.clear(); |
599 for (HTMLImageElement& image : | 597 for (HTMLImageElement& image : |
600 Traversal<HTMLImageElement>::startsAfter(root)) { | 598 Traversal<HTMLImageElement>::startsAfter(root)) { |
601 if (image.formOwner() == this) | 599 if (image.formOwner() == this) |
602 elements.append(&image); | 600 elements.append(&image); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 | 634 |
637 String HTMLFormElement::method() const { | 635 String HTMLFormElement::method() const { |
638 return FormSubmission::Attributes::methodString(m_attributes.method()); | 636 return FormSubmission::Attributes::methodString(m_attributes.method()); |
639 } | 637 } |
640 | 638 |
641 void HTMLFormElement::setMethod(const AtomicString& value) { | 639 void HTMLFormElement::setMethod(const AtomicString& value) { |
642 setAttribute(methodAttr, value); | 640 setAttribute(methodAttr, value); |
643 } | 641 } |
644 | 642 |
645 HTMLFormControlElement* HTMLFormElement::findDefaultButton() const { | 643 HTMLFormControlElement* HTMLFormElement::findDefaultButton() const { |
646 for (const auto& element : associatedElements()) { | 644 for (const auto& element : listedElements()) { |
647 if (!element->isFormControlElement()) | 645 if (!element->isFormControlElement()) |
648 continue; | 646 continue; |
649 HTMLFormControlElement* control = toHTMLFormControlElement(element); | 647 HTMLFormControlElement* control = toHTMLFormControlElement(element); |
650 if (control->canBeSuccessfulSubmitButton()) | 648 if (control->canBeSuccessfulSubmitButton()) |
651 return control; | 649 return control; |
652 } | 650 } |
653 return nullptr; | 651 return nullptr; |
654 } | 652 } |
655 | 653 |
656 bool HTMLFormElement::checkValidity() { | 654 bool HTMLFormElement::checkValidity() { |
657 return !checkInvalidControlsAndCollectUnhandled( | 655 return !checkInvalidControlsAndCollectUnhandled( |
658 0, CheckValidityDispatchInvalidEvent); | 656 0, CheckValidityDispatchInvalidEvent); |
659 } | 657 } |
660 | 658 |
661 bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled( | 659 bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled( |
662 HeapVector<Member<HTMLFormControlElement>>* unhandledInvalidControls, | 660 HeapVector<Member<HTMLFormControlElement>>* unhandledInvalidControls, |
663 CheckValidityEventBehavior eventBehavior) { | 661 CheckValidityEventBehavior eventBehavior) { |
664 // Copy associatedElements because event handlers called from | 662 // Copy listedElements because event handlers called from |
665 // HTMLFormControlElement::checkValidity() might change associatedElements. | 663 // HTMLFormControlElement::checkValidity() might change listedElements. |
666 const FormAssociatedElement::List& associatedElements = | 664 const ListedElement::List& listedElements = this->listedElements(); |
667 this->associatedElements(); | 665 HeapVector<Member<ListedElement>> elements; |
668 HeapVector<Member<FormAssociatedElement>> elements; | 666 elements.reserveCapacity(listedElements.size()); |
669 elements.reserveCapacity(associatedElements.size()); | 667 for (unsigned i = 0; i < listedElements.size(); ++i) |
670 for (unsigned i = 0; i < associatedElements.size(); ++i) | 668 elements.append(listedElements[i]); |
671 elements.append(associatedElements[i]); | |
672 int invalidControlsCount = 0; | 669 int invalidControlsCount = 0; |
673 for (unsigned i = 0; i < elements.size(); ++i) { | 670 for (unsigned i = 0; i < elements.size(); ++i) { |
674 if (elements[i]->form() == this && elements[i]->isFormControlElement()) { | 671 if (elements[i]->form() == this && elements[i]->isFormControlElement()) { |
675 HTMLFormControlElement* control = | 672 HTMLFormControlElement* control = |
676 toHTMLFormControlElement(elements[i].get()); | 673 toHTMLFormControlElement(elements[i].get()); |
677 if (control->isSubmittableElement() && | 674 if (control->isSubmittableElement() && |
678 !control->checkValidity(unhandledInvalidControls, eventBehavior) && | 675 !control->checkValidity(unhandledInvalidControls, eventBehavior) && |
679 control->formOwner() == this) { | 676 control->formOwner() == this) { |
680 ++invalidControlsCount; | 677 ++invalidControlsCount; |
681 if (!unhandledInvalidControls && | 678 if (!unhandledInvalidControls && |
(...skipping 14 matching lines...) Expand all Loading... |
696 if (pastName.isEmpty() || !m_pastNamesMap) | 693 if (pastName.isEmpty() || !m_pastNamesMap) |
697 return 0; | 694 return 0; |
698 Element* element = m_pastNamesMap->get(pastName); | 695 Element* element = m_pastNamesMap->get(pastName); |
699 #if DCHECK_IS_ON() | 696 #if DCHECK_IS_ON() |
700 if (!element) | 697 if (!element) |
701 return 0; | 698 return 0; |
702 SECURITY_DCHECK(toHTMLElement(element)->formOwner() == this); | 699 SECURITY_DCHECK(toHTMLElement(element)->formOwner() == this); |
703 if (isHTMLImageElement(*element)) { | 700 if (isHTMLImageElement(*element)) { |
704 SECURITY_DCHECK(imageElements().find(element) != kNotFound); | 701 SECURITY_DCHECK(imageElements().find(element) != kNotFound); |
705 } else if (isHTMLObjectElement(*element)) { | 702 } else if (isHTMLObjectElement(*element)) { |
706 SECURITY_DCHECK(associatedElements().find(toHTMLObjectElement(element)) != | 703 SECURITY_DCHECK(listedElements().find(toHTMLObjectElement(element)) != |
707 kNotFound); | 704 kNotFound); |
708 } else { | 705 } else { |
709 SECURITY_DCHECK(associatedElements().find( | 706 SECURITY_DCHECK(listedElements().find(toHTMLFormControlElement(element)) != |
710 toHTMLFormControlElement(element)) != kNotFound); | 707 kNotFound); |
711 } | 708 } |
712 #endif | 709 #endif |
713 return element; | 710 return element; |
714 } | 711 } |
715 | 712 |
716 void HTMLFormElement::addToPastNamesMap(Element* element, | 713 void HTMLFormElement::addToPastNamesMap(Element* element, |
717 const AtomicString& pastName) { | 714 const AtomicString& pastName) { |
718 if (pastName.isEmpty()) | 715 if (pastName.isEmpty()) |
719 return; | 716 return; |
720 if (!m_pastNamesMap) | 717 if (!m_pastNamesMap) |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
805 returnValue.setRadioNodeList(radioNodeList(name, onlyMatchImg)); | 802 returnValue.setRadioNodeList(radioNodeList(name, onlyMatchImg)); |
806 } | 803 } |
807 | 804 |
808 void HTMLFormElement::setDemoted(bool demoted) { | 805 void HTMLFormElement::setDemoted(bool demoted) { |
809 if (demoted) | 806 if (demoted) |
810 UseCounter::count(document(), UseCounter::DemotedFormElement); | 807 UseCounter::count(document(), UseCounter::DemotedFormElement); |
811 m_wasDemoted = demoted; | 808 m_wasDemoted = demoted; |
812 } | 809 } |
813 | 810 |
814 void HTMLFormElement::invalidateDefaultButtonStyle() const { | 811 void HTMLFormElement::invalidateDefaultButtonStyle() const { |
815 for (const auto& control : associatedElements()) { | 812 for (const auto& control : listedElements()) { |
816 if (!control->isFormControlElement()) | 813 if (!control->isFormControlElement()) |
817 continue; | 814 continue; |
818 if (toHTMLFormControlElement(control)->canBeSuccessfulSubmitButton()) | 815 if (toHTMLFormControlElement(control)->canBeSuccessfulSubmitButton()) |
819 toHTMLFormControlElement(control)->pseudoStateChanged( | 816 toHTMLFormControlElement(control)->pseudoStateChanged( |
820 CSSSelector::PseudoDefault); | 817 CSSSelector::PseudoDefault); |
821 } | 818 } |
822 } | 819 } |
823 | 820 |
824 } // namespace blink | 821 } // namespace blink |
OLD | NEW |