• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008, 2009 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 "DOMApplicationCache.h"
28 
29 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
30 
31 #include "ApplicationCacheHost.h"
32 #include "DocumentLoader.h"
33 #include "Event.h"
34 #include "EventException.h"
35 #include "EventListener.h"
36 #include "EventNames.h"
37 #include "Frame.h"
38 #include "FrameLoader.h"
39 
40 namespace WebCore {
41 
DOMApplicationCache(Frame * frame)42 DOMApplicationCache::DOMApplicationCache(Frame* frame)
43     : m_frame(frame)
44 {
45     ASSERT(applicationCacheHost());
46     applicationCacheHost()->setDOMApplicationCache(this);
47 }
48 
disconnectFrame()49 void DOMApplicationCache::disconnectFrame()
50 {
51     ApplicationCacheHost* cacheHost = applicationCacheHost();
52     if (cacheHost)
53         cacheHost->setDOMApplicationCache(0);
54     m_frame = 0;
55 }
56 
applicationCacheHost() const57 ApplicationCacheHost* DOMApplicationCache::applicationCacheHost() const
58 {
59     if (!m_frame || !m_frame->loader()->documentLoader())
60         return 0;
61     return m_frame->loader()->documentLoader()->applicationCacheHost();
62 }
63 
status() const64 unsigned short DOMApplicationCache::status() const
65 {
66     ApplicationCacheHost* cacheHost = applicationCacheHost();
67     if (!cacheHost)
68         return ApplicationCacheHost::UNCACHED;
69     return cacheHost->status();
70 }
71 
update(ExceptionCode & ec)72 void DOMApplicationCache::update(ExceptionCode& ec)
73 {
74     ApplicationCacheHost* cacheHost = applicationCacheHost();
75     if (!cacheHost || !cacheHost->update())
76         ec = INVALID_STATE_ERR;
77 }
78 
swapCache()79 bool DOMApplicationCache::swapCache()
80 {
81     ApplicationCacheHost* cacheHost = applicationCacheHost();
82     if (!cacheHost)
83         return false;
84     return cacheHost->swapCache();
85 }
86 
swapCache(ExceptionCode & ec)87 void DOMApplicationCache::swapCache(ExceptionCode& ec)
88 {
89     if (!swapCache())
90         ec = INVALID_STATE_ERR;
91 }
92 
scriptExecutionContext() const93 ScriptExecutionContext* DOMApplicationCache::scriptExecutionContext() const
94 {
95     return m_frame->document();
96 }
97 
addEventListener(const AtomicString & eventType,PassRefPtr<EventListener> eventListener,bool)98 void DOMApplicationCache::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
99 {
100     EventListenersMap::iterator iter = m_eventListeners.find(eventType);
101     if (iter == m_eventListeners.end()) {
102         ListenerVector listeners;
103         listeners.append(eventListener);
104         m_eventListeners.add(eventType, listeners);
105     } else {
106         ListenerVector& listeners = iter->second;
107         for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
108             if (*listenerIter == eventListener)
109                 return;
110         }
111 
112         listeners.append(eventListener);
113         m_eventListeners.add(eventType, listeners);
114     }
115 }
116 
removeEventListener(const AtomicString & eventType,EventListener * eventListener,bool)117 void DOMApplicationCache::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
118 {
119     EventListenersMap::iterator iter = m_eventListeners.find(eventType);
120     if (iter == m_eventListeners.end())
121         return;
122 
123     ListenerVector& listeners = iter->second;
124     for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
125         if (*listenerIter == eventListener) {
126             listeners.remove(listenerIter - listeners.begin());
127             return;
128         }
129     }
130 }
131 
dispatchEvent(PassRefPtr<Event> event,ExceptionCode & ec)132 bool DOMApplicationCache::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
133 {
134     if (!event || event->type().isEmpty()) {
135         ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
136         return true;
137     }
138 
139     ListenerVector listenersCopy = m_eventListeners.get(event->type());
140     for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
141         event->setTarget(this);
142         event->setCurrentTarget(this);
143         listenerIter->get()->handleEvent(event.get(), false);
144     }
145 
146     return !event->defaultPrevented();
147 }
148 
callListener(const AtomicString & eventType,EventListener * listener)149 void DOMApplicationCache::callListener(const AtomicString& eventType, EventListener* listener)
150 {
151     ASSERT(m_frame);
152 
153     RefPtr<Event> event = Event::create(eventType, false, false);
154     if (listener) {
155         event->setTarget(this);
156         event->setCurrentTarget(this);
157         listener->handleEvent(event.get(), false);
158     }
159 
160     ExceptionCode ec = 0;
161     dispatchEvent(event.release(), ec);
162     ASSERT(!ec);
163 }
164 
toEventType(ApplicationCacheHost::EventID id)165 const AtomicString& DOMApplicationCache::toEventType(ApplicationCacheHost::EventID id)
166 {
167     switch (id) {
168     case ApplicationCacheHost::CHECKING_EVENT:
169         return eventNames().checkingEvent;
170     case ApplicationCacheHost::ERROR_EVENT:
171         return eventNames().errorEvent;
172     case ApplicationCacheHost::NOUPDATE_EVENT:
173         return eventNames().noupdateEvent;
174     case ApplicationCacheHost::DOWNLOADING_EVENT:
175         return eventNames().downloadingEvent;
176     case ApplicationCacheHost::PROGRESS_EVENT:
177         return eventNames().progressEvent;
178     case ApplicationCacheHost::UPDATEREADY_EVENT:
179         return eventNames().updatereadyEvent;
180     case ApplicationCacheHost::CACHED_EVENT:
181         return eventNames().cachedEvent;
182     case ApplicationCacheHost::OBSOLETE_EVENT:
183         return eventNames().obsoleteEvent;
184     }
185     ASSERT_NOT_REACHED();
186     return eventNames().errorEvent;
187 }
188 
toEventID(const AtomicString & eventType)189 ApplicationCacheHost::EventID DOMApplicationCache::toEventID(const AtomicString& eventType)
190 {
191     if (eventType == eventNames().checkingEvent)
192         return ApplicationCacheHost::CHECKING_EVENT;
193     if (eventType == eventNames().errorEvent)
194         return ApplicationCacheHost::ERROR_EVENT;
195     if (eventType == eventNames().noupdateEvent)
196         return ApplicationCacheHost::NOUPDATE_EVENT;
197     if (eventType == eventNames().downloadingEvent)
198         return ApplicationCacheHost::DOWNLOADING_EVENT;
199     if (eventType == eventNames().progressEvent)
200         return ApplicationCacheHost::PROGRESS_EVENT;
201     if (eventType == eventNames().updatereadyEvent)
202         return ApplicationCacheHost::UPDATEREADY_EVENT;
203     if (eventType == eventNames().cachedEvent)
204         return ApplicationCacheHost::CACHED_EVENT;
205     if (eventType == eventNames().obsoleteEvent)
206         return ApplicationCacheHost::OBSOLETE_EVENT;
207 
208     ASSERT_NOT_REACHED();
209     return ApplicationCacheHost::ERROR_EVENT;
210 }
211 
212 } // namespace WebCore
213 
214 #endif // ENABLE(OFFLINE_WEB_APPLICATIONS)
215