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);
}
示例#2
0
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;
}
示例#3
0
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;
}