void HTMLFormElement::prepareForSubmission(Event* event) { RefPtrWillBeRawPtr<HTMLFormElement> protector(this); LocalFrame* frame = document().frame(); if (!frame || m_isSubmittingOrInUserJSSubmitEvent) return; bool skipValidation = !document().page() || noValidate(); ASSERT(event); HTMLFormControlElement* submitElement = submitElementFromEvent(event); if (submitElement && submitElement->formNoValidate()) skipValidation = true; // Interactive validation must be done before dispatching the submit event. if (!skipValidation && !validateInteractively()) return; m_isSubmittingOrInUserJSSubmitEvent = true; m_shouldSubmit = false; frame->loader().client()->dispatchWillSendSubmitEvent(this); if (dispatchEvent(Event::createCancelableBubble(EventTypeNames::submit))) m_shouldSubmit = true; m_isSubmittingOrInUserJSSubmitEvent = false; if (m_shouldSubmit) submit(event, true, true); }
bool HTMLFormElement::validateInteractively(Event* event) { ASSERT(event); if (!document()->page() || !document()->page()->settings()->interactiveFormValidationEnabled() || noValidate()) return true; HTMLFormControlElement* submitElement = submitElementFromEvent(event); if (submitElement && submitElement->formNoValidate()) return true; for (unsigned i = 0; i < m_associatedElements.size(); ++i) { if (m_associatedElements[i]->isFormControlElement()) static_cast<HTMLFormControlElement*>(m_associatedElements[i])->hideVisibleValidationMessage(); } Vector<RefPtr<FormAssociatedElement> > unhandledInvalidControls; collectUnhandledInvalidControls(unhandledInvalidControls); if (unhandledInvalidControls.isEmpty()) return true; // If the form has invalid controls, abort submission. RefPtr<HTMLFormElement> protector(this); // Focus on the first focusable control and show a validation message. for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) { FormAssociatedElement* unhandledAssociatedElement = unhandledInvalidControls[i].get(); HTMLElement* unhandled = toHTMLElement(unhandledAssociatedElement); if (unhandled->isFocusable() && unhandled->inDocument()) { RefPtr<Document> originalDocument(unhandled->document()); unhandled->scrollIntoViewIfNeeded(false); // scrollIntoViewIfNeeded() dispatches events, so the state // of 'unhandled' might be changed so it's no longer focusable or // moved to another document. if (unhandled->isFocusable() && unhandled->inDocument() && originalDocument == unhandled->document()) { unhandled->focus(); if (unhandled->isFormControlElement()) static_cast<HTMLFormControlElement*>(unhandled)->updateVisibleValidationMessage(); break; } } } // Warn about all of unfocusable controls. if (Frame* frame = document()->frame()) { for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) { FormAssociatedElement* unhandledAssociatedElement = unhandledInvalidControls[i].get(); HTMLElement* unhandled = toHTMLElement(unhandledAssociatedElement); if (unhandled->isFocusable() && unhandled->inDocument()) continue; String message("An invalid form control with name='%name' is not focusable."); message.replace("%name", unhandledAssociatedElement->name()); frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, ErrorMessageLevel, message, 0, document()->url().string()); } } return false; }
bool HTMLFormElement::validateInteractively(Event* event) { ASSERT(event); if (!document().page() || !document().page()->settings().interactiveFormValidationEnabled() || noValidate()) return true; HTMLFormControlElement* submitElement = submitElementFromEvent(event); if (submitElement && submitElement->formNoValidate()) return true; for (unsigned i = 0; i < m_associatedElements.size(); ++i) { if (m_associatedElements[i]->isFormControlElement()) static_cast<HTMLFormControlElement*>(m_associatedElements[i])->hideVisibleValidationMessage(); } Vector<RefPtr<FormAssociatedElement>> unhandledInvalidControls; if (!checkInvalidControlsAndCollectUnhandled(unhandledInvalidControls)) return true; // Because the form has invalid controls, we abort the form submission and // show a validation message on a focusable form control. // Needs to update layout now because we'd like to call isFocusable(), which // has !renderer()->needsLayout() assertion. document().updateLayoutIgnorePendingStylesheets(); Ref<HTMLFormElement> protect(*this); // Focus on the first focusable control and show a validation message. for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) { HTMLElement& element = unhandledInvalidControls[i]->asHTMLElement(); if (element.inDocument() && element.isFocusable()) { element.scrollIntoViewIfNeeded(false); element.focus(); if (element.isFormControlElement()) toHTMLFormControlElement(element).updateVisibleValidationMessage(); break; } } // Warn about all of unfocusable controls. if (document().frame()) { for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) { FormAssociatedElement& control = *unhandledInvalidControls[i]; HTMLElement& element = control.asHTMLElement(); if (element.inDocument() && element.isFocusable()) continue; String message("An invalid form control with name='%name' is not focusable."); message.replace("%name", control.name()); document().addConsoleMessage(RenderingMessageSource, ErrorMessageLevel, message); } } return false; }