Changeset 57346 in webkit
- Timestamp:
- Apr 9, 2010 11:03:06 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 13 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r57345 r57346 1 2010-04-09 Kent Tamura <tkent@chromium.org> 2 3 Reviewed by Darin Adler. 4 5 Implement interactive validation for forms. 6 https://bugs.webkit.org/show_bug.cgi?id=34930 7 8 Add tests for "invalid" event and interactive validation. 9 10 * fast/forms/checkValidity-cancel-expected.txt: Added. 11 * fast/forms/checkValidity-cancel.html: Added. 12 * fast/forms/interactive-validation-cancel-expected.txt: Added. 13 * fast/forms/interactive-validation-cancel.html: Added. 14 * fast/forms/interactive-validation-formnovalidate-expected.txt: Added. 15 * fast/forms/interactive-validation-formnovalidate.html: Added. 16 * fast/forms/interactive-validation-novalidate-expected.txt: Added. 17 * fast/forms/interactive-validation-novalidate.html: Added. 18 * fast/forms/interactive-validation-prevented-expected.txt: Added. 19 * fast/forms/interactive-validation-prevented.html: Added. 20 * fast/forms/interactive-validation-remove-node-in-handler-expected.txt: Added. 21 * fast/forms/interactive-validation-remove-node-in-handler.html: Added. 22 * fast/forms/script-tests/checkValidity-cancel.js: Added. 23 1 24 2010-04-09 Gustavo Noronha Silva <gns@gnome.org> 2 25 -
trunk/WebCore/ChangeLog
r57344 r57346 1 2010-04-09 Kent Tamura <tkent@chromium.org> 2 3 Reviewed by Darin Adler. 4 5 Implement interactive validation for forms. 6 https://bugs.webkit.org/show_bug.cgi?id=34930 7 8 - HTMLFormControlElement::checkValidity() supports unhandled invalid control list 9 - HTMLFormElement::validateInteractively() called from prepareSubmit() 10 prevents the submission if neither noValidate nor formNoValidate is 11 specified, and focuses on the first invalid control of which "invalid" 12 event is not canceled. 13 14 Tests: fast/forms/checkValidity-cancel.html 15 fast/forms/interactive-validation-cancel.html 16 fast/forms/interactive-validation-formnovalidate.html 17 fast/forms/interactive-validation-novalidate.html 18 fast/forms/interactive-validation-prevented.html 19 fast/forms/interactive-validation-remove-node-in-handler.html 20 21 * html/HTMLFormControlElement.cpp: 22 (WebCore::HTMLFormControlElement::checkValidity): 23 If the control is invalid and the "invalid" is not canceled, 24 push the control to the specified vector. 25 * html/HTMLFormControlElement.h: 26 * html/HTMLFormElement.cpp: 27 (WebCore::HTMLFormElement::validateInteractively): 28 The main part of the interactive validation. 29 (WebCore::HTMLFormElement::prepareSubmit): 30 Calls validateInteractively(). 31 (WebCore::HTMLFormElement::checkValidity): 32 Uses collectUnhandledInvalidControls(). 33 (WebCore::HTMLFormElement::collectUnhandledInvalidControls): 34 * html/HTMLFormElement.h: 35 1 36 2010-04-09 Sam Weinig <sam@webkit.org> 2 37 -
trunk/WebCore/html/HTMLFormControlElement.cpp
r57274 r57346 330 330 } 331 331 332 bool HTMLFormControlElement::checkValidity() 333 { 334 if (willValidate() && !isValidFormControlElement()) { 335 dispatchEvent(Event::create(eventNames().invalidEvent, false, true)); 336 return false; 337 } 338 339 return true; 332 bool HTMLFormControlElement::checkValidity(Vector<RefPtr<HTMLFormControlElement> >* unhandledInvalidControls) 333 { 334 if (!willValidate() || isValidFormControlElement()) 335 return true; 336 // An event handler can deref this object. 337 RefPtr<HTMLFormControlElement> protector(this); 338 RefPtr<Document> originalDocument(document()); 339 bool needsDefaultAction = dispatchEvent(Event::create(eventNames().invalidEvent, false, true)); 340 if (needsDefaultAction && unhandledInvalidControls && inDocument() && originalDocument == document()) 341 unhandledInvalidControls->append(this); 342 return false; 340 343 } 341 344 -
trunk/WebCore/html/HTMLFormControlElement.h
r57274 r57346 109 109 virtual bool willValidate() const; 110 110 String validationMessage(); 111 bool checkValidity( );111 bool checkValidity(Vector<RefPtr<HTMLFormControlElement> >* unhandledInvalidControls = 0); 112 112 // This must be called when a validation constraint or control value is changed. 113 113 void setNeedsValidityCheck(); -
trunk/WebCore/html/HTMLFormElement.cpp
r55821 r57346 28 28 #include "CSSHelper.h" 29 29 #include "DOMFormData.h" 30 #include "DOMWindow.h" 30 31 #include "Document.h" 31 32 #include "Event.h" … … 220 221 } 221 222 223 static inline HTMLFormControlElement* submitElementFromEvent(const Event* event) 224 { 225 Node* targetNode = event->target()->toNode(); 226 if (!targetNode || !targetNode->isElementNode()) 227 return 0; 228 Element* targetElement = static_cast<Element*>(targetNode); 229 if (!targetElement->isFormControlElement()) 230 return 0; 231 return static_cast<HTMLFormControlElement*>(targetElement); 232 } 233 234 bool HTMLFormElement::validateInteractively(Event* event) 235 { 236 ASSERT(event); 237 if (noValidate()) 238 return true; 239 240 HTMLFormControlElement* submitElement = submitElementFromEvent(event); 241 if (submitElement && submitElement->formNoValidate()) 242 return true; 243 244 Vector<RefPtr<HTMLFormControlElement> > unhandledInvalidControls; 245 collectUnhandledInvalidControls(unhandledInvalidControls); 246 if (unhandledInvalidControls.isEmpty()) 247 return true; 248 // If the form has invalid controls, abort submission. 249 250 RefPtr<HTMLFormElement> protector(this); 251 // Focus on the first focusable control. 252 for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) { 253 HTMLFormControlElement* unhandled = unhandledInvalidControls[i].get(); 254 if (unhandled->isFocusable() && unhandled->inDocument()) { 255 RefPtr<Document> originalDocument(unhandled->document()); 256 unhandled->scrollIntoViewIfNeeded(false); 257 // scrollIntoViewIfNeeded() dispatches events, so the state 258 // of 'unhandled' might be changed so it's no longer focusable or 259 // moved to another document. 260 if (unhandled->isFocusable() && unhandled->inDocument() && originalDocument == unhandled->document()) { 261 unhandled->focus(); 262 break; 263 } 264 } 265 } 266 // Warn about all of unfocusable controls. 267 if (Frame* frame = document()->frame()) { 268 for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) { 269 HTMLFormControlElement* unhandled = unhandledInvalidControls[i].get(); 270 if (unhandled->isFocusable() && unhandled->inDocument()) 271 continue; 272 String message("An invalid form control with name='%name' is not focusable."); 273 message.replace("%name", unhandled->name()); 274 frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, ErrorMessageLevel, message, 0, document()->url().string()); 275 } 276 } 277 m_insubmit = false; 278 return false; 279 } 280 222 281 bool HTMLFormElement::prepareSubmit(Event* event) 223 282 { … … 228 287 m_insubmit = true; 229 288 m_doingsubmit = false; 289 290 // Interactive validation must be done before dispatching the submit event. 291 if (!validateInteractively(event)) 292 return false; 230 293 231 294 if (dispatchEvent(Event::create(eventNames().submitEvent, true, true)) && !m_doingsubmit) … … 542 605 bool HTMLFormElement::checkValidity() 543 606 { 544 // TODO: Check for unhandled invalid controls, see #27452 for tips. 545 546 bool hasOnlyValidControls = true; 547 for (unsigned i = 0; i < formElements.size(); ++i) { 548 HTMLFormControlElement* control = formElements[i]; 549 if (!control->checkValidity()) 550 hasOnlyValidControls = false; 551 } 552 553 return hasOnlyValidControls; 607 Vector<RefPtr<HTMLFormControlElement> > controls; 608 collectUnhandledInvalidControls(controls); 609 return controls.isEmpty(); 610 } 611 612 void HTMLFormElement::collectUnhandledInvalidControls(Vector<RefPtr<HTMLFormControlElement> >& unhandledInvalidControls) 613 { 614 RefPtr<HTMLFormElement> protector(this); 615 // Copy formElements because event handlers called from 616 // HTMLFormControlElement::checkValidity() might change formElements. 617 Vector<RefPtr<HTMLFormControlElement> > elements; 618 elements.reserveCapacity(formElements.size()); 619 for (unsigned i = 0; i < formElements.size(); ++i) 620 elements.append(formElements[i]); 621 for (unsigned i = 0; i < elements.size(); ++i) { 622 if (elements[i]->form() == this) 623 elements[i]->checkValidity(&unhandledInvalidControls); 624 } 554 625 } 555 626 -
trunk/WebCore/html/HTMLFormElement.h
r55821 r57346 138 138 PassRefPtr<FormData> createFormData(); 139 139 unsigned formElementIndex(HTMLFormControlElement*); 140 // Returns true if the submission should be proceeded. 141 bool validateInteractively(Event*); 142 // Validates each of the controls, and stores controls of which 'invalid' 143 // event was not canceled to the specified vector. 144 void collectUnhandledInvalidControls(Vector<RefPtr<HTMLFormControlElement> >&); 140 145 141 146 friend class HTMLFormCollection;
Note: See TracChangeset
for help on using the changeset viewer.