Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: Source/core/html/HTMLFormElement.cpp

Issue 660783002: Implement reportValidity() (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Apply couple more tkent's comments + pull Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/html/HTMLFormElement.h ('k') | Source/core/html/HTMLFormElement.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 // FIXME: Consolidate this and similar code in FormSubmission.cpp. 266 // FIXME: Consolidate this and similar code in FormSubmission.cpp.
267 static inline HTMLFormControlElement* submitElementFromEvent(const Event* event) 267 static inline HTMLFormControlElement* submitElementFromEvent(const Event* event)
268 { 268 {
269 for (Node* node = event->target()->toNode(); node; node = node->parentOrShad owHostNode()) { 269 for (Node* node = event->target()->toNode(); node; node = node->parentOrShad owHostNode()) {
270 if (node->isElementNode() && toElement(node)->isFormControlElement()) 270 if (node->isElementNode() && toElement(node)->isFormControlElement())
271 return toHTMLFormControlElement(node); 271 return toHTMLFormControlElement(node);
272 } 272 }
273 return 0; 273 return 0;
274 } 274 }
275 275
276 bool HTMLFormElement::validateInteractively(Event* event) 276 bool HTMLFormElement::validateInteractively()
277 { 277 {
278 ASSERT(event);
279 if (!document().page() || noValidate())
280 return true;
281
282 HTMLFormControlElement* submitElement = submitElementFromEvent(event);
283 if (submitElement && submitElement->formNoValidate())
284 return true;
285
286 const FormAssociatedElement::List& elements = associatedElements(); 278 const FormAssociatedElement::List& elements = associatedElements();
287 for (unsigned i = 0; i < elements.size(); ++i) { 279 for (unsigned i = 0; i < elements.size(); ++i) {
288 if (elements[i]->isFormControlElement()) 280 if (elements[i]->isFormControlElement())
289 toHTMLFormControlElement(elements[i])->hideVisibleValidationMessage( ); 281 toHTMLFormControlElement(elements[i])->hideVisibleValidationMessage( );
290 } 282 }
291 283
292 WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> > unhandledInvali dControls; 284 WillBeHeapVector<RefPtrWillBeMember<HTMLFormControlElement> > unhandledInval idControls;
293 if (!checkInvalidControlsAndCollectUnhandled(&unhandledInvalidControls, Chec kValidityDispatchInvalidEvent)) 285 if (!checkInvalidControlsAndCollectUnhandled(&unhandledInvalidControls, Chec kValidityDispatchInvalidEvent))
294 return true; 286 return true;
295 // Because the form has invalid controls, we abort the form submission and 287 // Because the form has invalid controls, we abort the form submission and
296 // show a validation message on a focusable form control. 288 // show a validation message on a focusable form control.
297 289
298 // Needs to update layout now because we'd like to call isFocusable(), which 290 // Needs to update layout now because we'd like to call isFocusable(), which
299 // has !renderer()->needsLayout() assertion. 291 // has !renderer()->needsLayout() assertion.
300 document().updateLayoutIgnorePendingStylesheets(); 292 document().updateLayoutIgnorePendingStylesheets();
301 293
302 RefPtrWillBeRawPtr<HTMLFormElement> protector(this); 294 RefPtrWillBeRawPtr<HTMLFormElement> protector(this);
303 // Focus on the first focusable control and show a validation message. 295 // Focus on the first focusable control and show a validation message.
304 for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) { 296 for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) {
305 FormAssociatedElement* unhandledAssociatedElement = unhandledInvalidCont rols[i].get(); 297 HTMLFormControlElement* unhandled = unhandledInvalidControls[i].get();
306 HTMLElement* unhandled = toHTMLElement(unhandledAssociatedElement); 298 if (unhandled->isFocusable()) {
307 if (unhandled->isFocusable() && unhandled->inDocument()) { 299 unhandled->showValidationMessage();
308 unhandled->scrollIntoViewIfNeeded(false);
309 unhandled->focus();
310 if (unhandled->isFormControlElement())
311 toHTMLFormControlElement(unhandled)->updateVisibleValidationMess age();
312 break; 300 break;
313 } 301 }
314 } 302 }
315 // Warn about all of unfocusable controls. 303 // Warn about all of unfocusable controls.
316 if (document().frame()) { 304 if (document().frame()) {
317 for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) { 305 for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) {
318 FormAssociatedElement* unhandledAssociatedElement = unhandledInvalid Controls[i].get(); 306 HTMLFormControlElement* unhandled = unhandledInvalidControls[i].get( );
319 HTMLElement* unhandled = toHTMLElement(unhandledAssociatedElement); 307 if (unhandled->isFocusable())
320 if (unhandled->isFocusable() && unhandled->inDocument())
321 continue; 308 continue;
322 String message("An invalid form control with name='%name' is not foc usable."); 309 String message("An invalid form control with name='%name' is not foc usable.");
323 message.replace("%name", unhandledAssociatedElement->name()); 310 message.replace("%name", unhandled->name());
324 document().addConsoleMessage(ConsoleMessage::create(RenderingMessage Source, ErrorMessageLevel, message)); 311 document().addConsoleMessage(ConsoleMessage::create(RenderingMessage Source, ErrorMessageLevel, message));
325 } 312 }
326 } 313 }
327 return false; 314 return false;
328 } 315 }
329 316
330 void HTMLFormElement::prepareForSubmission(Event* event) 317 void HTMLFormElement::prepareForSubmission(Event* event)
331 { 318 {
332 RefPtrWillBeRawPtr<HTMLFormElement> protector(this); 319 RefPtrWillBeRawPtr<HTMLFormElement> protector(this);
333 LocalFrame* frame = document().frame(); 320 LocalFrame* frame = document().frame();
334 if (!frame || m_isSubmittingOrInUserJSSubmitEvent) 321 if (!frame || m_isSubmittingOrInUserJSSubmitEvent)
335 return; 322 return;
336 323
324 bool skipValidation = !document().page() || noValidate();
325 ASSERT(event);
326 HTMLFormControlElement* submitElement = submitElementFromEvent(event);
327 if (submitElement && submitElement->formNoValidate())
328 skipValidation = true;
329
337 // Interactive validation must be done before dispatching the submit event. 330 // Interactive validation must be done before dispatching the submit event.
338 if (!validateInteractively(event)) 331 if (!skipValidation && !validateInteractively())
339 return; 332 return;
340 333
341 m_isSubmittingOrInUserJSSubmitEvent = true; 334 m_isSubmittingOrInUserJSSubmitEvent = true;
342 m_shouldSubmit = false; 335 m_shouldSubmit = false;
343 336
344 frame->loader().client()->dispatchWillSendSubmitEvent(this); 337 frame->loader().client()->dispatchWillSendSubmitEvent(this);
345 338
346 if (dispatchEvent(Event::createCancelableBubble(EventTypeNames::submit))) 339 if (dispatchEvent(Event::createCancelableBubble(EventTypeNames::submit)))
347 m_shouldSubmit = true; 340 m_shouldSubmit = true;
348 341
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 // validity recalculation. In the near future, implement validity cache and 722 // validity recalculation. In the near future, implement validity cache and
730 // recalculate style only if it changed. 723 // recalculate style only if it changed.
731 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::createW ithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Invalid)); 724 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::createW ithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Invalid));
732 } 725 }
733 726
734 bool HTMLFormElement::checkValidity() 727 bool HTMLFormElement::checkValidity()
735 { 728 {
736 return !checkInvalidControlsAndCollectUnhandled(0, CheckValidityDispatchInva lidEvent); 729 return !checkInvalidControlsAndCollectUnhandled(0, CheckValidityDispatchInva lidEvent);
737 } 730 }
738 731
739 bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<R efPtrWillBeMember<FormAssociatedElement> >* unhandledInvalidControls, CheckValid ityEventBehavior eventBehavior) 732 bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<R efPtrWillBeMember<HTMLFormControlElement> >* unhandledInvalidControls, CheckVali dityEventBehavior eventBehavior)
740 { 733 {
741 RefPtrWillBeRawPtr<HTMLFormElement> protector(this); 734 RefPtrWillBeRawPtr<HTMLFormElement> protector(this);
742 // Copy associatedElements because event handlers called from 735 // Copy associatedElements because event handlers called from
743 // HTMLFormControlElement::checkValidity() might change associatedElements. 736 // HTMLFormControlElement::checkValidity() might change associatedElements.
744 const FormAssociatedElement::List& associatedElements = this->associatedElem ents(); 737 const FormAssociatedElement::List& associatedElements = this->associatedElem ents();
745 WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> > elements; 738 WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> > elements;
746 elements.reserveCapacity(associatedElements.size()); 739 elements.reserveCapacity(associatedElements.size());
747 for (unsigned i = 0; i < associatedElements.size(); ++i) 740 for (unsigned i = 0; i < associatedElements.size(); ++i)
748 elements.append(associatedElements[i]); 741 elements.append(associatedElements[i]);
749 bool hasInvalidControls = false; 742 bool hasInvalidControls = false;
750 for (unsigned i = 0; i < elements.size(); ++i) { 743 for (unsigned i = 0; i < elements.size(); ++i) {
751 if (elements[i]->form() == this && elements[i]->isFormControlElement()) { 744 if (elements[i]->form() == this && elements[i]->isFormControlElement()) {
752 HTMLFormControlElement* control = toHTMLFormControlElement(elements[ i].get()); 745 HTMLFormControlElement* control = toHTMLFormControlElement(elements[ i].get());
753 if (!control->checkValidity(unhandledInvalidControls, eventBehavior) && control->formOwner() == this) 746 if (!control->checkValidity(unhandledInvalidControls, eventBehavior) && control->formOwner() == this)
754 hasInvalidControls = true; 747 hasInvalidControls = true;
755 } 748 }
756 } 749 }
757 return hasInvalidControls; 750 return hasInvalidControls;
758 } 751 }
759 752
753 bool HTMLFormElement::reportValidity()
754 {
755 return validateInteractively();
756 }
757
760 Element* HTMLFormElement::elementFromPastNamesMap(const AtomicString& pastName) 758 Element* HTMLFormElement::elementFromPastNamesMap(const AtomicString& pastName)
761 { 759 {
762 if (pastName.isEmpty() || !m_pastNamesMap) 760 if (pastName.isEmpty() || !m_pastNamesMap)
763 return 0; 761 return 0;
764 Element* element = m_pastNamesMap->get(pastName); 762 Element* element = m_pastNamesMap->get(pastName);
765 #if ENABLE(ASSERT) 763 #if ENABLE(ASSERT)
766 if (!element) 764 if (!element)
767 return 0; 765 return 0;
768 ASSERT_WITH_SECURITY_IMPLICATION(toHTMLElement(element)->formOwner() == this ); 766 ASSERT_WITH_SECURITY_IMPLICATION(toHTMLElement(element)->formOwner() == this );
769 if (isHTMLImageElement(*element)) { 767 if (isHTMLImageElement(*element)) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 } 857 }
860 858
861 void HTMLFormElement::setDemoted(bool demoted) 859 void HTMLFormElement::setDemoted(bool demoted)
862 { 860 {
863 if (demoted) 861 if (demoted)
864 UseCounter::count(document(), UseCounter::DemotedFormElement); 862 UseCounter::count(document(), UseCounter::DemotedFormElement);
865 m_wasDemoted = demoted; 863 m_wasDemoted = demoted;
866 } 864 }
867 865
868 } // namespace 866 } // namespace
OLDNEW
« no previous file with comments | « Source/core/html/HTMLFormElement.h ('k') | Source/core/html/HTMLFormElement.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698