| 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 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 #include "core/html/RadioNodeList.h" | 48 #include "core/html/RadioNodeList.h" |
| 49 #include "core/html/forms/FormController.h" | 49 #include "core/html/forms/FormController.h" |
| 50 #include "core/inspector/ConsoleMessage.h" | 50 #include "core/inspector/ConsoleMessage.h" |
| 51 #include "core/loader/FormSubmission.h" | 51 #include "core/loader/FormSubmission.h" |
| 52 #include "core/loader/FrameLoader.h" | 52 #include "core/loader/FrameLoader.h" |
| 53 #include "core/loader/FrameLoaderClient.h" | 53 #include "core/loader/FrameLoaderClient.h" |
| 54 #include "core/loader/MixedContentChecker.h" | 54 #include "core/loader/MixedContentChecker.h" |
| 55 #include "core/loader/NavigationScheduler.h" | 55 #include "core/loader/NavigationScheduler.h" |
| 56 #include "platform/UserGestureIndicator.h" | 56 #include "platform/UserGestureIndicator.h" |
| 57 #include "public/platform/WebInsecureRequestPolicy.h" | 57 #include "public/platform/WebInsecureRequestPolicy.h" |
| 58 #include "wtf/AutoReset.h" |
| 58 #include "wtf/text/AtomicString.h" | 59 #include "wtf/text/AtomicString.h" |
| 59 #include <limits> | 60 #include <limits> |
| 60 | 61 |
| 61 namespace blink { | 62 namespace blink { |
| 62 | 63 |
| 63 using namespace HTMLNames; | 64 using namespace HTMLNames; |
| 64 | 65 |
| 65 HTMLFormElement::HTMLFormElement(Document& document) | 66 HTMLFormElement::HTMLFormElement(Document& document) |
| 66 : HTMLElement(formTag, document) | 67 : HTMLElement(formTag, document) |
| 67 , m_associatedElementsAreDirty(false) | 68 , m_associatedElementsAreDirty(false) |
| 68 , m_imageElementsAreDirty(false) | 69 , m_imageElementsAreDirty(false) |
| 69 , m_hasElementsAssociatedByParser(false) | 70 , m_hasElementsAssociatedByParser(false) |
| 70 , m_hasElementsAssociatedByFormAttribute(false) | 71 , m_hasElementsAssociatedByFormAttribute(false) |
| 71 , m_didFinishParsingChildren(false) | 72 , m_didFinishParsingChildren(false) |
| 72 , m_isSubmittingOrInUserJSSubmitEvent(false) | |
| 73 , m_shouldSubmit(false) | 73 , m_shouldSubmit(false) |
| 74 , m_isInResetFunction(false) | 74 , m_isInResetFunction(false) |
| 75 , m_wasDemoted(false) | 75 , m_wasDemoted(false) |
| 76 { | 76 { |
| 77 } | 77 } |
| 78 | 78 |
| 79 HTMLFormElement* HTMLFormElement::create(Document& document) | 79 HTMLFormElement* HTMLFormElement::create(Document& document) |
| 80 { | 80 { |
| 81 UseCounter::count(document, UseCounter::FormElement); | 81 UseCounter::count(document, UseCounter::FormElement); |
| 82 return new HTMLFormElement(document); | 82 return new HTMLFormElement(document); |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 message.replace("%name", unhandled->name()); | 286 message.replace("%name", unhandled->name()); |
| 287 document().addConsoleMessage(ConsoleMessage::create(RenderingMessage
Source, ErrorMessageLevel, message)); | 287 document().addConsoleMessage(ConsoleMessage::create(RenderingMessage
Source, ErrorMessageLevel, message)); |
| 288 } | 288 } |
| 289 } | 289 } |
| 290 return false; | 290 return false; |
| 291 } | 291 } |
| 292 | 292 |
| 293 void HTMLFormElement::prepareForSubmission(Event* event) | 293 void HTMLFormElement::prepareForSubmission(Event* event) |
| 294 { | 294 { |
| 295 LocalFrame* frame = document().frame(); | 295 LocalFrame* frame = document().frame(); |
| 296 if (!frame || m_isSubmittingOrInUserJSSubmitEvent) | 296 if (!frame || m_isSubmitting || m_inUserJSSubmitEvent) |
| 297 return; | 297 return; |
| 298 | 298 |
| 299 if (document().isSandboxed(SandboxForms)) { | 299 if (document().isSandboxed(SandboxForms)) { |
| 300 document().addConsoleMessage(ConsoleMessage::create(SecurityMessageSourc
e, ErrorMessageLevel, "Blocked form submission to '" + m_attributes.action() + "
' because the form's frame is sandboxed and the 'allow-forms' permission is not
set.")); | 300 document().addConsoleMessage(ConsoleMessage::create(SecurityMessageSourc
e, ErrorMessageLevel, "Blocked form submission to '" + m_attributes.action() + "
' because the form's frame is sandboxed and the 'allow-forms' permission is not
set.")); |
| 301 return; | 301 return; |
| 302 } | 302 } |
| 303 | 303 |
| 304 bool skipValidation = !document().page() || noValidate(); | 304 bool skipValidation = !document().page() || noValidate(); |
| 305 ASSERT(event); | 305 ASSERT(event); |
| 306 HTMLFormControlElement* submitElement = submitElementFromEvent(event); | 306 HTMLFormControlElement* submitElement = submitElementFromEvent(event); |
| 307 if (submitElement && submitElement->formNoValidate()) | 307 if (submitElement && submitElement->formNoValidate()) |
| 308 skipValidation = true; | 308 skipValidation = true; |
| 309 | 309 |
| 310 UseCounter::count(document(), UseCounter::FormSubmissionStarted); | 310 UseCounter::count(document(), UseCounter::FormSubmissionStarted); |
| 311 // Interactive validation must be done before dispatching the submit event. | 311 // Interactive validation must be done before dispatching the submit event. |
| 312 if (!skipValidation && !validateInteractively()) | 312 if (!skipValidation && !validateInteractively()) |
| 313 return; | 313 return; |
| 314 | 314 |
| 315 m_isSubmittingOrInUserJSSubmitEvent = true; | 315 { |
| 316 m_shouldSubmit = false; | 316 AutoReset<bool> submitEventHandlerScope(&m_inUserJSSubmitEvent, true); |
| 317 | 317 m_shouldSubmit = false; |
| 318 frame->loader().client()->dispatchWillSendSubmitEvent(this); | 318 frame->loader().client()->dispatchWillSendSubmitEvent(this); |
| 319 | 319 if (dispatchEvent(Event::createCancelableBubble(EventTypeNames::submit))
== DispatchEventResult::NotCanceled) |
| 320 if (dispatchEvent(Event::createCancelableBubble(EventTypeNames::submit)) ==
DispatchEventResult::NotCanceled) | 320 m_shouldSubmit = true; |
| 321 m_shouldSubmit = true; | 321 } |
| 322 | |
| 323 m_isSubmittingOrInUserJSSubmitEvent = false; | |
| 324 | 322 |
| 325 if (m_shouldSubmit) | 323 if (m_shouldSubmit) |
| 326 submit(event, true); | 324 submit(event, true); |
| 327 } | 325 } |
| 328 | 326 |
| 329 void HTMLFormElement::submitFromJavaScript() | 327 void HTMLFormElement::submitFromJavaScript() |
| 330 { | 328 { |
| 331 submit(0, false); | 329 submit(0, false); |
| 332 } | 330 } |
| 333 | 331 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 344 void HTMLFormElement::submit(Event* event, bool activateSubmitButton) | 342 void HTMLFormElement::submit(Event* event, bool activateSubmitButton) |
| 345 { | 343 { |
| 346 FrameView* view = document().view(); | 344 FrameView* view = document().view(); |
| 347 LocalFrame* frame = document().frame(); | 345 LocalFrame* frame = document().frame(); |
| 348 if (!view || !frame || !frame->page()) | 346 if (!view || !frame || !frame->page()) |
| 349 return; | 347 return; |
| 350 // See crbug.com/586749. | 348 // See crbug.com/586749. |
| 351 if (!isConnected()) | 349 if (!isConnected()) |
| 352 UseCounter::count(document(), UseCounter::FormSubmissionNotInDocumentTre
e); | 350 UseCounter::count(document(), UseCounter::FormSubmissionNotInDocumentTre
e); |
| 353 | 351 |
| 354 if (m_isSubmittingOrInUserJSSubmitEvent) { | 352 if (m_isSubmitting || m_inUserJSSubmitEvent) { |
| 355 m_shouldSubmit = true; | 353 m_shouldSubmit = true; |
| 356 return; | 354 return; |
| 357 } | 355 } |
| 358 | 356 |
| 359 m_isSubmittingOrInUserJSSubmitEvent = true; | 357 // Delay dispatching 'close' to dialog until done submitting. |
| 358 EventQueueScope scopeForDialogClose; |
| 359 AutoReset<bool> submitScope(&m_isSubmitting, true); |
| 360 | 360 |
| 361 HTMLFormControlElement* firstSuccessfulSubmitButton = nullptr; | 361 HTMLFormControlElement* firstSuccessfulSubmitButton = nullptr; |
| 362 bool needButtonActivation = activateSubmitButton; // do we need to activate
a submit button? | 362 bool needButtonActivation = activateSubmitButton; // do we need to activate
a submit button? |
| 363 | 363 |
| 364 const FormAssociatedElement::List& elements = associatedElements(); | 364 const FormAssociatedElement::List& elements = associatedElements(); |
| 365 for (unsigned i = 0; i < elements.size(); ++i) { | 365 for (unsigned i = 0; i < elements.size(); ++i) { |
| 366 FormAssociatedElement* associatedElement = elements[i]; | 366 FormAssociatedElement* associatedElement = elements[i]; |
| 367 if (!associatedElement->isFormControlElement()) | 367 if (!associatedElement->isFormControlElement()) |
| 368 continue; | 368 continue; |
| 369 if (needButtonActivation) { | 369 if (needButtonActivation) { |
| 370 HTMLFormControlElement* control = toHTMLFormControlElement(associate
dElement); | 370 HTMLFormControlElement* control = toHTMLFormControlElement(associate
dElement); |
| 371 if (control->isActivatedSubmit()) | 371 if (control->isActivatedSubmit()) |
| 372 needButtonActivation = false; | 372 needButtonActivation = false; |
| 373 else if (firstSuccessfulSubmitButton == 0 && control->isSuccessfulSu
bmitButton()) | 373 else if (firstSuccessfulSubmitButton == 0 && control->isSuccessfulSu
bmitButton()) |
| 374 firstSuccessfulSubmitButton = control; | 374 firstSuccessfulSubmitButton = control; |
| 375 } | 375 } |
| 376 } | 376 } |
| 377 | 377 |
| 378 if (needButtonActivation && firstSuccessfulSubmitButton) | 378 if (needButtonActivation && firstSuccessfulSubmitButton) |
| 379 firstSuccessfulSubmitButton->setActivatedSubmit(true); | 379 firstSuccessfulSubmitButton->setActivatedSubmit(true); |
| 380 | 380 |
| 381 FormSubmission* formSubmission = FormSubmission::create(this, m_attributes,
event); | 381 FormSubmission* formSubmission = FormSubmission::create(this, m_attributes,
event); |
| 382 EventQueueScope scopeForDialogClose; // Delay dispatching 'close' to dialog
until done submitting. | 382 if (formSubmission->method() == FormSubmission::DialogMethod) { |
| 383 if (formSubmission->method() == FormSubmission::DialogMethod) | |
| 384 submitDialog(formSubmission); | 383 submitDialog(formSubmission); |
| 385 else | 384 } else { |
| 385 // This runs JavaScript code if action attribute value is javascript: |
| 386 // protocol. |
| 386 scheduleFormSubmission(formSubmission); | 387 scheduleFormSubmission(formSubmission); |
| 388 } |
| 387 | 389 |
| 388 if (needButtonActivation && firstSuccessfulSubmitButton) | 390 if (needButtonActivation && firstSuccessfulSubmitButton) |
| 389 firstSuccessfulSubmitButton->setActivatedSubmit(false); | 391 firstSuccessfulSubmitButton->setActivatedSubmit(false); |
| 390 | 392 |
| 391 m_shouldSubmit = false; | 393 m_shouldSubmit = false; |
| 392 m_isSubmittingOrInUserJSSubmitEvent = false; | |
| 393 } | 394 } |
| 394 | 395 |
| 395 void HTMLFormElement::scheduleFormSubmission(FormSubmission* submission) | 396 void HTMLFormElement::scheduleFormSubmission(FormSubmission* submission) |
| 396 { | 397 { |
| 397 ASSERT(submission->method() == FormSubmission::PostMethod || submission->met
hod() == FormSubmission::GetMethod); | 398 ASSERT(submission->method() == FormSubmission::PostMethod || submission->met
hod() == FormSubmission::GetMethod); |
| 398 ASSERT(submission->data()); | 399 ASSERT(submission->data()); |
| 399 ASSERT(submission->form()); | 400 ASSERT(submission->form()); |
| 400 if (submission->action().isEmpty()) | 401 if (submission->action().isEmpty()) |
| 401 return; | 402 return; |
| 402 if (document().isSandboxed(SandboxForms)) { | 403 if (document().isSandboxed(SandboxForms)) { |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 { | 790 { |
| 790 for (const auto& control : associatedElements()) { | 791 for (const auto& control : associatedElements()) { |
| 791 if (!control->isFormControlElement()) | 792 if (!control->isFormControlElement()) |
| 792 continue; | 793 continue; |
| 793 if (toHTMLFormControlElement(control)->canBeSuccessfulSubmitButton()) | 794 if (toHTMLFormControlElement(control)->canBeSuccessfulSubmitButton()) |
| 794 toHTMLFormControlElement(control)->pseudoStateChanged(CSSSelector::P
seudoDefault); | 795 toHTMLFormControlElement(control)->pseudoStateChanged(CSSSelector::P
seudoDefault); |
| 795 } | 796 } |
| 796 } | 797 } |
| 797 | 798 |
| 798 } // namespace blink | 799 } // namespace blink |
| OLD | NEW |