1 /*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27 #include "XMLHttpRequestUpload.h"
28
29 #include "AtomicString.h"
30 #include "Event.h"
31 #include "EventException.h"
32 #include "EventNames.h"
33 #include "XMLHttpRequest.h"
34 #include "XMLHttpRequestProgressEvent.h"
35 #include <wtf/Assertions.h>
36
37 namespace WebCore {
38
XMLHttpRequestUpload(XMLHttpRequest * xmlHttpRequest)39 XMLHttpRequestUpload::XMLHttpRequestUpload(XMLHttpRequest* xmlHttpRequest)
40 : m_xmlHttpRequest(xmlHttpRequest)
41 {
42 }
43
hasListeners() const44 bool XMLHttpRequestUpload::hasListeners() const
45 {
46 return m_onAbortListener || m_onErrorListener || m_onLoadListener || m_onLoadStartListener || m_onProgressListener || !m_eventListeners.isEmpty();
47 }
48
scriptExecutionContext() const49 ScriptExecutionContext* XMLHttpRequestUpload::scriptExecutionContext() const
50 {
51 XMLHttpRequest* xmlHttpRequest = associatedXMLHttpRequest();
52 if (!xmlHttpRequest)
53 return 0;
54 return xmlHttpRequest->scriptExecutionContext();
55 }
56
addEventListener(const AtomicString & eventType,PassRefPtr<EventListener> eventListener,bool)57 void XMLHttpRequestUpload::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
58 {
59 EventListenersMap::iterator iter = m_eventListeners.find(eventType);
60 if (iter == m_eventListeners.end()) {
61 ListenerVector listeners;
62 listeners.append(eventListener);
63 m_eventListeners.add(eventType, listeners);
64 } else {
65 ListenerVector& listeners = iter->second;
66 for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
67 if (*listenerIter == eventListener)
68 return;
69 }
70
71 listeners.append(eventListener);
72 m_eventListeners.add(eventType, listeners);
73 }
74 }
75
removeEventListener(const AtomicString & eventType,EventListener * eventListener,bool)76 void XMLHttpRequestUpload::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
77 {
78 EventListenersMap::iterator iter = m_eventListeners.find(eventType);
79 if (iter == m_eventListeners.end())
80 return;
81
82 ListenerVector& listeners = iter->second;
83 for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
84 if (*listenerIter == eventListener) {
85 listeners.remove(listenerIter - listeners.begin());
86 return;
87 }
88 }
89 }
90
dispatchEvent(PassRefPtr<Event> evt,ExceptionCode & ec)91 bool XMLHttpRequestUpload::dispatchEvent(PassRefPtr<Event> evt, ExceptionCode& ec)
92 {
93 // FIXME: check for other error conditions enumerated in the spec.
94 if (!evt || evt->type().isEmpty()) {
95 ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
96 return true;
97 }
98
99 ListenerVector listenersCopy = m_eventListeners.get(evt->type());
100 for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
101 evt->setTarget(this);
102 evt->setCurrentTarget(this);
103 listenerIter->get()->handleEvent(evt.get(), false);
104 }
105
106 return !evt->defaultPrevented();
107 }
108
dispatchXMLHttpRequestProgressEvent(EventListener * listener,const AtomicString & type,bool lengthComputable,unsigned loaded,unsigned total)109 void XMLHttpRequestUpload::dispatchXMLHttpRequestProgressEvent(EventListener* listener, const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total)
110 {
111 RefPtr<XMLHttpRequestProgressEvent> evt = XMLHttpRequestProgressEvent::create(type, lengthComputable, loaded, total);
112 if (listener) {
113 evt->setTarget(this);
114 evt->setCurrentTarget(this);
115 listener->handleEvent(evt.get(), false);
116 }
117
118 ExceptionCode ec = 0;
119 dispatchEvent(evt.release(), ec);
120 ASSERT(!ec);
121 }
122
dispatchAbortEvent()123 void XMLHttpRequestUpload::dispatchAbortEvent()
124 {
125 dispatchXMLHttpRequestProgressEvent(m_onAbortListener.get(), eventNames().abortEvent, false, 0, 0);
126 }
127
dispatchErrorEvent()128 void XMLHttpRequestUpload::dispatchErrorEvent()
129 {
130 dispatchXMLHttpRequestProgressEvent(m_onErrorListener.get(), eventNames().errorEvent, false, 0, 0);
131 }
132
dispatchLoadEvent()133 void XMLHttpRequestUpload::dispatchLoadEvent()
134 {
135 dispatchXMLHttpRequestProgressEvent(m_onLoadListener.get(), eventNames().loadEvent, false, 0, 0);
136 }
137
dispatchLoadStartEvent()138 void XMLHttpRequestUpload::dispatchLoadStartEvent()
139 {
140 dispatchXMLHttpRequestProgressEvent(m_onLoadStartListener.get(), eventNames().loadstartEvent, false, 0, 0);
141 }
142
dispatchProgressEvent(long long bytesSent,long long totalBytesToBeSent)143 void XMLHttpRequestUpload::dispatchProgressEvent(long long bytesSent, long long totalBytesToBeSent)
144 {
145 dispatchXMLHttpRequestProgressEvent(m_onProgressListener.get(), eventNames().progressEvent, true, static_cast<unsigned>(bytesSent), static_cast<unsigned>(totalBytesToBeSent));
146 }
147
148 } // namespace WebCore
149