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 10 matching lines...) Expand all Loading... |
21 * Boston, MA 02110-1301, USA. | 21 * Boston, MA 02110-1301, USA. |
22 * | 22 * |
23 */ | 23 */ |
24 | 24 |
25 #include "config.h" | 25 #include "config.h" |
26 #include "core/html/HTMLFormElement.h" | 26 #include "core/html/HTMLFormElement.h" |
27 | 27 |
28 #include <limits> | 28 #include <limits> |
29 #include "HTMLNames.h" | 29 #include "HTMLNames.h" |
30 #include "bindings/v8/Dictionary.h" | 30 #include "bindings/v8/Dictionary.h" |
| 31 #include "bindings/v8/NewScriptState.h" |
31 #include "bindings/v8/ScriptController.h" | 32 #include "bindings/v8/ScriptController.h" |
32 #include "bindings/v8/ScriptEventListener.h" | 33 #include "bindings/v8/ScriptEventListener.h" |
| 34 #include "bindings/v8/ScriptPromiseResolverWithContext.h" |
33 #include "core/dom/Attribute.h" | 35 #include "core/dom/Attribute.h" |
| 36 #include "core/dom/AutocompleteError.h" |
34 #include "core/dom/Document.h" | 37 #include "core/dom/Document.h" |
35 #include "core/dom/ElementTraversal.h" | 38 #include "core/dom/ElementTraversal.h" |
36 #include "core/dom/IdTargetObserverRegistry.h" | 39 #include "core/dom/IdTargetObserverRegistry.h" |
37 #include "core/events/AutocompleteErrorEvent.h" | 40 #include "core/events/AutocompleteErrorEvent.h" |
38 #include "core/events/Event.h" | 41 #include "core/events/Event.h" |
39 #include "core/events/ScopedEventQueue.h" | 42 #include "core/events/ScopedEventQueue.h" |
40 #include "core/html/HTMLCollection.h" | 43 #include "core/html/HTMLCollection.h" |
41 #include "core/html/HTMLDialogElement.h" | 44 #include "core/html/HTMLDialogElement.h" |
42 #include "core/html/HTMLImageElement.h" | 45 #include "core/html/HTMLImageElement.h" |
43 #include "core/html/HTMLInputElement.h" | 46 #include "core/html/HTMLInputElement.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 { | 81 { |
79 UseCounter::count(document, UseCounter::FormElement); | 82 UseCounter::count(document, UseCounter::FormElement); |
80 return adoptRef(new HTMLFormElement(document)); | 83 return adoptRef(new HTMLFormElement(document)); |
81 } | 84 } |
82 | 85 |
83 HTMLFormElement::~HTMLFormElement() | 86 HTMLFormElement::~HTMLFormElement() |
84 { | 87 { |
85 document().formController().willDeleteForm(this); | 88 document().formController().willDeleteForm(this); |
86 } | 89 } |
87 | 90 |
| 91 class AutocompleteRequest { |
| 92 public: |
| 93 static PassOwnPtr<AutocompleteRequest> create(HTMLFormElement* form) |
| 94 { |
| 95 return adoptPtr(new AutocompleteRequest(form)); |
| 96 } |
| 97 |
| 98 ScriptPromise promise() |
| 99 { |
| 100 return m_resolver->promise(); |
| 101 } |
| 102 |
| 103 void setResult(HTMLFormElement::AutocompleteResult result) |
| 104 { |
| 105 ASSERT(!m_isResultSet); |
| 106 m_result = result; |
| 107 m_isResultSet = true; |
| 108 } |
| 109 |
| 110 void dispatchAndFulfill() |
| 111 { |
| 112 ASSERT(m_isResultSet); |
| 113 |
| 114 String reason; |
| 115 if (m_result == HTMLFormElement::AutocompleteResultErrorDisabled) |
| 116 reason = "disabled"; |
| 117 else if (m_result == HTMLFormElement::AutocompleteResultErrorCancel) |
| 118 reason = "cancel"; |
| 119 else if (m_result == HTMLFormElement::AutocompleteResultErrorInvalid) |
| 120 reason = "invalid"; |
| 121 |
| 122 RefPtrWillBeRawPtr<Event> event = reason.isEmpty() ? Event::createBubble
(EventTypeNames::autocomplete) : AutocompleteErrorEvent::create(reason); |
| 123 event->setTarget(m_form); |
| 124 m_form->dispatchEvent(event.release()); |
| 125 |
| 126 if (reason.isEmpty()) |
| 127 m_resolver->resolve(V8UndefinedType()); |
| 128 else |
| 129 m_resolver->reject(AutocompleteError::create(reason)); |
| 130 } |
| 131 |
| 132 private: |
| 133 AutocompleteRequest(HTMLFormElement* form) |
| 134 : m_form(form) |
| 135 , m_resolver(ScriptPromiseResolverWithContext::create(NewScriptState::cu
rrent(toIsolate(form->executionContext())))) |
| 136 , m_isResultSet(false) |
| 137 { } |
| 138 |
| 139 HTMLFormElement* m_form; |
| 140 RefPtr<ScriptPromiseResolverWithContext> m_resolver; |
| 141 HTMLFormElement::AutocompleteResult m_result; |
| 142 bool m_isResultSet; |
| 143 }; |
| 144 |
88 bool HTMLFormElement::rendererIsNeeded(const RenderStyle& style) | 145 bool HTMLFormElement::rendererIsNeeded(const RenderStyle& style) |
89 { | 146 { |
90 if (!m_wasDemoted) | 147 if (!m_wasDemoted) |
91 return HTMLElement::rendererIsNeeded(style); | 148 return HTMLElement::rendererIsNeeded(style); |
92 | 149 |
93 ContainerNode* node = parentNode(); | 150 ContainerNode* node = parentNode(); |
94 if (!node || !node->renderer()) | 151 if (!node || !node->renderer()) |
95 return HTMLElement::rendererIsNeeded(style); | 152 return HTMLElement::rendererIsNeeded(style); |
96 RenderObject* parentRenderer = node->renderer(); | 153 RenderObject* parentRenderer = node->renderer(); |
97 // FIXME: Shouldn't we also check for table caption (see |formIsTablePart| b
elow). | 154 // FIXME: Shouldn't we also check for table caption (see |formIsTablePart| b
elow). |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 | 466 |
410 const Vector<FormAssociatedElement*>& elements = associatedElements(); | 467 const Vector<FormAssociatedElement*>& elements = associatedElements(); |
411 for (unsigned i = 0; i < elements.size(); ++i) { | 468 for (unsigned i = 0; i < elements.size(); ++i) { |
412 if (elements[i]->isFormControlElement()) | 469 if (elements[i]->isFormControlElement()) |
413 toHTMLFormControlElement(elements[i])->reset(); | 470 toHTMLFormControlElement(elements[i])->reset(); |
414 } | 471 } |
415 | 472 |
416 m_isInResetFunction = false; | 473 m_isInResetFunction = false; |
417 } | 474 } |
418 | 475 |
419 void HTMLFormElement::requestAutocomplete(const Dictionary& details) | 476 ScriptPromise HTMLFormElement::requestAutocomplete(const Dictionary& details) |
420 { | 477 { |
| 478 OwnPtr<AutocompleteRequest> request = AutocompleteRequest::create(this); |
| 479 ScriptPromise promise = request->promise(); |
| 480 |
421 String errorMessage; | 481 String errorMessage; |
422 | |
423 if (!document().frame()) | 482 if (!document().frame()) |
424 errorMessage = "requestAutocomplete: form is not owned by a displayed do
cument."; | 483 errorMessage = "requestAutocomplete: form is not owned by a displayed do
cument."; |
425 else if (!shouldAutocomplete()) | 484 else if (!shouldAutocomplete()) |
426 errorMessage = "requestAutocomplete: form autocomplete attribute is set
to off."; | 485 errorMessage = "requestAutocomplete: form autocomplete attribute is set
to off."; |
427 else if (!UserGestureIndicator::processingUserGesture()) | 486 else if (!UserGestureIndicator::processingUserGesture()) |
428 errorMessage = "requestAutocomplete: must be called in response to a use
r gesture."; | 487 errorMessage = "requestAutocomplete: must be called in response to a use
r gesture."; |
| 488 else if (!!m_pendingAutocompleteRequest) |
| 489 errorMessage = "requestAutocomplete: already in progess."; |
429 | 490 |
430 if (!errorMessage.isEmpty()) { | 491 if (!errorMessage.isEmpty()) { |
431 document().addConsoleMessage(RenderingMessageSource, LogMessageLevel, er
rorMessage); | 492 document().addConsoleMessage(RenderingMessageSource, LogMessageLevel, er
rorMessage); |
432 finishRequestAutocomplete(AutocompleteResultErrorDisabled); | 493 doFinishRequestAutocomplete(AutocompleteResultErrorDisabled, request.rel
ease()); |
433 } else { | 494 } else { |
| 495 m_pendingAutocompleteRequest = request.release(); |
434 document().frame()->loader().client()->didRequestAutocomplete(this, deta
ils); | 496 document().frame()->loader().client()->didRequestAutocomplete(this, deta
ils); |
435 } | 497 } |
| 498 |
| 499 return promise; |
436 } | 500 } |
437 | 501 |
438 void HTMLFormElement::finishRequestAutocomplete(AutocompleteResult result) | 502 void HTMLFormElement::finishRequestAutocomplete(AutocompleteResult result) |
439 { | 503 { |
440 RefPtrWillBeRawPtr<Event> event = nullptr; | 504 doFinishRequestAutocomplete(result, m_pendingAutocompleteRequest.release()); |
441 if (result == AutocompleteResultSuccess) | 505 } |
442 event = Event::createBubble(EventTypeNames::autocomplete); | |
443 else if (result == AutocompleteResultErrorDisabled) | |
444 event = AutocompleteErrorEvent::create("disabled"); | |
445 else if (result == AutocompleteResultErrorCancel) | |
446 event = AutocompleteErrorEvent::create("cancel"); | |
447 else if (result == AutocompleteResultErrorInvalid) | |
448 event = AutocompleteErrorEvent::create("invalid"); | |
449 else | |
450 ASSERT_NOT_REACHED(); | |
451 | 506 |
452 event->setTarget(this); | 507 void HTMLFormElement::doFinishRequestAutocomplete(AutocompleteResult result, Pas
sOwnPtr<AutocompleteRequest> request) |
453 m_pendingAutocompleteEvents.append(event.release()); | 508 { |
| 509 request->setResult(result); |
| 510 m_finishedAutocompleteRequests.append(request); |
454 | 511 |
455 // Dispatch events later as this API is meant to work asynchronously in all
situations and implementations. | 512 // Finish the request later as this API is meant to work asynchronously in a
ll situations and implementations. |
456 if (!m_requestAutocompleteTimer.isActive()) | 513 if (!m_requestAutocompleteTimer.isActive()) |
457 m_requestAutocompleteTimer.startOneShot(0, FROM_HERE); | 514 m_requestAutocompleteTimer.startOneShot(0, FROM_HERE); |
458 } | 515 } |
459 | 516 |
460 void HTMLFormElement::requestAutocompleteTimerFired(Timer<HTMLFormElement>*) | 517 void HTMLFormElement::requestAutocompleteTimerFired(Timer<HTMLFormElement>*) |
461 { | 518 { |
462 WillBeHeapVector<RefPtrWillBeMember<Event> > pendingEvents; | 519 Vector<OwnPtr<AutocompleteRequest> > finishedRequests; |
463 m_pendingAutocompleteEvents.swap(pendingEvents); | 520 m_finishedAutocompleteRequests.swap(finishedRequests); |
464 for (size_t i = 0; i < pendingEvents.size(); ++i) | 521 |
465 dispatchEvent(pendingEvents[i].release()); | 522 RefPtr<HTMLFormElement> protector(this); |
| 523 for (size_t i = 0; i < finishedRequests.size(); ++i) |
| 524 finishedRequests[i]->dispatchAndFulfill(); |
466 } | 525 } |
467 | 526 |
468 void HTMLFormElement::parseAttribute(const QualifiedName& name, const AtomicStri
ng& value) | 527 void HTMLFormElement::parseAttribute(const QualifiedName& name, const AtomicStri
ng& value) |
469 { | 528 { |
470 if (name == actionAttr) | 529 if (name == actionAttr) |
471 m_attributes.parseAction(value); | 530 m_attributes.parseAction(value); |
472 else if (name == targetAttr) | 531 else if (name == targetAttr) |
473 m_attributes.setTarget(value); | 532 m_attributes.setTarget(value); |
474 else if (name == methodAttr) | 533 else if (name == methodAttr) |
475 m_attributes.updateMethodType(value); | 534 m_attributes.updateMethodType(value); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 } | 832 } |
774 | 833 |
775 void HTMLFormElement::setDemoted(bool demoted) | 834 void HTMLFormElement::setDemoted(bool demoted) |
776 { | 835 { |
777 if (demoted) | 836 if (demoted) |
778 UseCounter::count(document(), UseCounter::DemotedFormElement); | 837 UseCounter::count(document(), UseCounter::DemotedFormElement); |
779 m_wasDemoted = demoted; | 838 m_wasDemoted = demoted; |
780 } | 839 } |
781 | 840 |
782 } // namespace | 841 } // namespace |
OLD | NEW |