Commit 0d86d9d8 authored by andersca@apple.com's avatar andersca@apple.com
Browse files

2008-04-17 Anders Carlsson <andersca@apple.com>

        Reviewed by Sam.

        Add DOMApplicationCache implementation.
        
        * dom/EventNames.h:
        Add new event names.
        
        * dom/EventTarget.cpp:
        (WebCore::EventTarget::toDOMApplicationCache):
        * dom/EventTarget.h:
        Add EventTarget conversion method.
        
        * loader/appcache/ApplicationCacheGroup.h:
        (WebCore::ApplicationCacheGroup::):
        (WebCore::ApplicationCacheGroup::status):
        (WebCore::ApplicationCacheGroup::update):
        (WebCore::ApplicationCacheGroup::newestCache):
        Add more stubs.
        
        * loader/appcache/DOMApplicationCache.cpp:
        * loader/appcache/DOMApplicationCache.h:

        * page/DOMWindow.cpp:
        (WebCore::DOMWindow::clear):
        (WebCore::DOMWindow::applicationCache):
        * page/DOMWindow.h:
        (WebCore::DOMWindow::optionalApplicationCache):
        Add ApplicationCache member.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@32006 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 263cce1a
2008-04-17 Anders Carlsson <andersca@apple.com>
Reviewed by Sam.
Add DOMApplicationCache implementation.
* dom/EventNames.h:
Add new event names.
* dom/EventTarget.cpp:
(WebCore::EventTarget::toDOMApplicationCache):
* dom/EventTarget.h:
Add EventTarget conversion method.
* loader/appcache/ApplicationCacheGroup.h:
(WebCore::ApplicationCacheGroup::):
(WebCore::ApplicationCacheGroup::status):
(WebCore::ApplicationCacheGroup::update):
(WebCore::ApplicationCacheGroup::newestCache):
Add more stubs.
* loader/appcache/DOMApplicationCache.cpp:
* loader/appcache/DOMApplicationCache.h:
* page/DOMWindow.cpp:
(WebCore::DOMWindow::clear):
(WebCore::DOMWindow::applicationCache):
* page/DOMWindow.h:
(WebCore::DOMWindow::optionalApplicationCache):
Add ApplicationCache member.
2008-04-17 Anders Carlsson <andersca@apple.com>
 
Build fix.
......@@ -34,12 +34,15 @@ namespace WebCore { namespace EventNames {
macro(beforepaste) \
macro(beforeunload) \
macro(blur) \
macro(cached) \
macro(change) \
macro(checking) \
macro(click) \
macro(contextmenu) \
macro(copy) \
macro(cut) \
macro(dblclick) \
macro(downloading) \
macro(drag) \
macro(dragend) \
macro(dragenter) \
......@@ -61,6 +64,7 @@ namespace WebCore { namespace EventNames {
macro(mouseover) \
macro(mouseup) \
macro(mousewheel) \
macro(noupdate) \
macro(overflowchanged) \
macro(paste) \
macro(readystatechange) \
......@@ -74,6 +78,7 @@ namespace WebCore { namespace EventNames {
macro(submit) \
macro(textInput) \
macro(unload) \
macro(updateready) \
macro(zoom) \
\
macro(DOMActivate) \
......
......@@ -67,6 +67,13 @@ XMLHttpRequest* EventTarget::toXMLHttpRequest()
return 0;
}
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
DOMApplicationCache* EventTarget::toDOMApplicationCache()
{
return 0;
}
#endif
#if ENABLE(SVG)
SVGElementInstance* EventTarget::toSVGElementInstance()
{
......
......@@ -39,6 +39,7 @@
namespace WebCore {
class AtomicString;
class DOMApplicationCache;
class Event;
class EventListener;
class EventTargetNode;
......@@ -55,7 +56,9 @@ namespace WebCore {
public:
virtual EventTargetNode* toNode();
virtual XMLHttpRequest* toXMLHttpRequest();
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
virtual DOMApplicationCache* toDOMApplicationCache();
#endif
#if ENABLE(SVG)
virtual SVGElementInstance* toSVGElementInstance();
#endif
......
......@@ -34,13 +34,20 @@ namespace WebCore {
class ApplicationCache;
class DocumentLoader;
class Frame;
class ApplicationCacheGroup {
public:
enum Status { Idle, Checking, Downloading };
const KURL& manifestURL() const { return m_manifestURL; }
Status status() const { return Idle; }
void update(Frame*) { }
void cacheDestroyed(ApplicationCache*) { }
ApplicationCache* newestCache() const { return 0; }
void documentLoaderDestroyed(DocumentLoader*) { }
private:
KURL m_manifestURL;
......
......@@ -28,5 +28,261 @@
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
#include "ApplicationCache.h"
#include "ApplicationCacheGroup.h"
#include "DocumentLoader.h"
#include "Event.h"
#include "EventException.h"
#include "EventListener.h"
#include "EventNames.h"
#include "Frame.h"
#include "FrameLoader.h"
namespace WebCore {
using namespace EventNames;
DOMApplicationCache::DOMApplicationCache(Frame* frame)
: m_frame(frame)
{
}
void DOMApplicationCache::disconnectFrame()
{
m_frame = 0;
}
ApplicationCache* DOMApplicationCache::associatedCache() const
{
if (!m_frame)
return 0;
return m_frame->loader()->documentLoader()->toplevelApplicationCache();
}
unsigned short DOMApplicationCache::status() const
{
ApplicationCache* cache = associatedCache();
if (!cache)
return UNCACHED;
switch (cache->group()->status()) {
case ApplicationCacheGroup::Checking:
return CHECKING;
case ApplicationCacheGroup::Downloading:
return DOWNLOADING;
case ApplicationCacheGroup::Idle: {
if (cache != cache->group()->newestCache())
return UPDATEREADY;
return IDLE;
}
default:
ASSERT_NOT_REACHED();
}
return 0;
}
void DOMApplicationCache::update(ExceptionCode& ec)
{
ApplicationCache* cache = associatedCache();
if (!cache) {
ec = INVALID_STATE_ERR;
return;
}
cache->group()->update(m_frame);
}
bool DOMApplicationCache::swapCache()
{
if (!m_frame)
return false;
ApplicationCache* cache = m_frame->loader()->documentLoader()->applicationCache();
if (!cache)
return false;
// Check if we already have the newest cache
ApplicationCache* newestCache = cache->group()->newestCache();
if (cache == newestCache)
return false;
ASSERT(cache->group() == newestCache->group());
m_frame->loader()->documentLoader()->setApplicationCache(newestCache);
return true;
}
void DOMApplicationCache::swapCache(ExceptionCode& ec)
{
if (!swapCache())
ec = INVALID_STATE_ERR;
}
unsigned DOMApplicationCache::length() const
{
ApplicationCache* cache = associatedCache();
if (!cache)
return 0;
return cache->numDynamicEntries();
}
String DOMApplicationCache::item(unsigned item, ExceptionCode& ec)
{
ApplicationCache* cache = associatedCache();
if (!cache) {
ec = INVALID_STATE_ERR;
return String();
}
if (item >= length()) {
ec = INDEX_SIZE_ERR;
return String();
}
return cache->dynamicEntry(item);
}
void DOMApplicationCache::add(const KURL& url, ExceptionCode& ec)
{
ApplicationCache* cache = associatedCache();
if (!cache) {
ec = INVALID_STATE_ERR;
return;
}
if (!url.isValid()) {
ec = SYNTAX_ERR;
return;
}
if (!cache->addDynamicEntry(url)) {
// This should use the (currently not specified) security exceptions in HTML5 4.3.4
ec = SECURITY_ERR;
}
}
void DOMApplicationCache::remove(const KURL& url, ExceptionCode& ec)
{
ApplicationCache* cache = associatedCache();
if (!cache) {
ec = INVALID_STATE_ERR;
return;
}
if (!url.isValid()) {
ec = SYNTAX_ERR;
return;
}
cache->removeDynamicEntry(url);
}
void DOMApplicationCache::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
{
EventListenersMap::iterator iter = m_eventListeners.find(eventType.impl());
if (iter == m_eventListeners.end()) {
ListenerVector listeners;
listeners.append(eventListener);
m_eventListeners.add(eventType.impl(), listeners);
} else {
ListenerVector& listeners = iter->second;
for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
if (*listenerIter == eventListener)
return;
}
listeners.append(eventListener);
m_eventListeners.add(eventType.impl(), listeners);
}
}
void DOMApplicationCache::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool useCapture)
{
EventListenersMap::iterator iter = m_eventListeners.find(eventType.impl());
if (iter == m_eventListeners.end())
return;
ListenerVector& listeners = iter->second;
for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
if (*listenerIter == eventListener) {
listeners.remove(listenerIter - listeners.begin());
return;
}
}
}
bool DOMApplicationCache::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec, bool tempEvent)
{
if (event->type().isEmpty()) {
ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
return true;
}
ListenerVector listenersCopy = m_eventListeners.get(event->type().impl());
for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
event->setTarget(this);
event->setCurrentTarget(this);
listenerIter->get()->handleEvent(event.get(), false);
}
return !event->defaultPrevented();
}
void DOMApplicationCache::callListener(const AtomicString& eventType, EventListener* listener)
{
ASSERT(m_frame);
RefPtr<Event> event = new Event(eventType, false, false);
if (listener) {
event->setTarget(this);
event->setCurrentTarget(this);
listener->handleEvent(event.get(), false);
}
ExceptionCode ec = 0;
dispatchEvent(event.release(), ec, false);
ASSERT(!ec);
}
void DOMApplicationCache::callCheckingListener()
{
callListener(checkingEvent, m_onCheckingListener.get());
}
void DOMApplicationCache::callErrorListener()
{
callListener(errorEvent, m_onErrorListener.get());
}
void DOMApplicationCache::callNoUpdateListener()
{
callListener(noupdateEvent, m_onNoUpdateListener.get());
}
void DOMApplicationCache::callDownloadingListener()
{
callListener(downloadingEvent, m_onDownloadingListener.get());
}
void DOMApplicationCache::callProgressListener()
{
callListener(progressEvent, m_onProgressListener.get());
}
void DOMApplicationCache::callUpdateReadyListener()
{
callListener(updatereadyEvent, m_onUpdateReadyListener.get());
}
void DOMApplicationCache::callCachedListener()
{
callListener(cachedEvent, m_onCachedListener.get());
}
} // namespace WebCore
#endif // ENABLE(OFFLINE_WEB_APPLICATIONS)
......@@ -28,16 +28,112 @@
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
#include <wtf/RefCounted.h>
#include "EventTarget.h"
#include "EventListener.h"
#include <wtf/HashMap.h>
#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
class DOMApplicationCache : public RefCounted<DOMApplicationCache> {
};
class ApplicationCache;
class AtomicStringImpl;
class Frame;
class KURL;
class String;
class DOMApplicationCache : public RefCounted<DOMApplicationCache>, public EventTarget {
public:
static PassRefPtr<DOMApplicationCache> create(Frame* frame) { return adoptRef(new DOMApplicationCache(frame)); }
void disconnectFrame();
enum Status {
UNCACHED = 0,
IDLE = 1,
CHECKING = 2,
DOWNLOADING = 3,
UPDATEREADY = 4,
};
unsigned short status() const;
void update(ExceptionCode&);
void swapCache(ExceptionCode&);
}
unsigned length() const;
String item(unsigned item, ExceptionCode&);
void add(const KURL&, ExceptionCode&);
void remove(const KURL&, ExceptionCode&);
virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&, bool tempEvent = false);
typedef Vector<RefPtr<EventListener> > ListenerVector;
typedef HashMap<AtomicStringImpl*, ListenerVector> EventListenersMap;
EventListenersMap& eventListeners() { return m_eventListeners; }
using RefCounted<DOMApplicationCache>::ref;
using RefCounted<DOMApplicationCache>::deref;
void setOnCheckingListener(EventListener* eventListener) { m_onCheckingListener = eventListener; }
EventListener* onCheckingListener() const { return m_onCheckingListener.get(); }
void setOnErrorListener(EventListener* eventListener) { m_onErrorListener = eventListener; }
EventListener* onErrorListener() const { return m_onErrorListener.get(); }
void setOnNoUpdateListener(EventListener* eventListener) { m_onNoUpdateListener = eventListener; }
EventListener* onNoUpdateListener() const { return m_onNoUpdateListener.get(); }
void setOnDownloadingListener(EventListener* eventListener) { m_onDownloadingListener = eventListener; }
EventListener* onDownloadingListener() const { return m_onDownloadingListener.get(); }
void setOnProgressListener(EventListener* eventListener) { m_onProgressListener = eventListener; }
EventListener* onProgressListener() const { return m_onProgressListener.get(); }
void setOnUpdateReadyListener(EventListener* eventListener) { m_onUpdateReadyListener = eventListener; }
EventListener* onUpdateReadyListener() const { return m_onUpdateReadyListener.get(); }
void setOnCachedListener(EventListener* eventListener) { m_onCachedListener = eventListener; }
EventListener* onCachedListener() const { return m_onCachedListener.get(); }
Frame* frame() const { return m_frame; }
DOMApplicationCache* toDOMApplicationCache() { return this; }
void callCheckingListener();
void callErrorListener();
void callNoUpdateListener();
void callDownloadingListener();
void callProgressListener();
void callUpdateReadyListener();
void callCachedListener();
private:
DOMApplicationCache(Frame* frame);
void callListener(const AtomicString& eventType, EventListener* listener);
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
ApplicationCache* associatedCache() const;
bool swapCache();
RefPtr<EventListener> m_onCheckingListener;
RefPtr<EventListener> m_onErrorListener;
RefPtr<EventListener> m_onNoUpdateListener;
RefPtr<EventListener> m_onDownloadingListener;
RefPtr<EventListener> m_onProgressListener;
RefPtr<EventListener> m_onUpdateReadyListener;
RefPtr<EventListener> m_onCachedListener;
EventListenersMap m_eventListeners;
Frame* m_frame;
};
} // namespace WebCore
#endif // ENABLE(OFFLINE_WEB_APPLICATIONS)
......
......@@ -32,6 +32,9 @@
#include "CSSStyleSelector.h"
#include "Chrome.h"
#include "Console.h"
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
#include "DOMApplicationCache.h"
#endif
#include "DOMSelection.h"
#include "Document.h"
#include "Element.h"
......@@ -185,6 +188,12 @@ void DOMWindow::clear()
m_localStorage->disconnectFrame();
m_localStorage = 0;
#endif
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
if (m_applicationCache)
m_applicationCache->disconnectFrame();
m_applicationCache = 0;
#endif
}
Screen* DOMWindow::screen() const
......@@ -250,6 +259,15 @@ Console* DOMWindow::console() const
return m_console.get();
}
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
DOMApplicationCache* DOMWindow::applicationCache() const
{
if (!m_applicationCache)
m_applicationCache = DOMApplicationCache::create(m_frame);
return m_applicationCache.get();
}
#endif
Navigator* DOMWindow::navigator() const
{
if (!m_navigator)
......
......@@ -37,6 +37,9 @@ namespace WebCore {
class CSSRuleList;
class CSSStyleDeclaration;
class Console;
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
class DOMApplicationCache;
#endif
class DOMSelection;
class Database;
class Document;
......@@ -157,7 +160,10 @@ namespace WebCore {
#endif
Console* console() const;
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
DOMApplicationCache* applicationCache() const;
#endif
#if ENABLE(CROSS_DOCUMENT_MESSAGING)
void postMessage(const String& message, const String& domain, const String& uri, DOMWindow* source) const;
#endif
......@@ -172,6 +178,8 @@ namespace WebCore {
void resizeBy(float x, float y) const;
void resizeTo(float width, float height) const;
// These methods are used for GC marking. See JSDOMWindow::mark() in
// JSDOMWindowCustom.cpp.
Screen* optionalScreen() const { return m_screen.get(); }
DOMSelection* optionalSelection() const { return m_selection.get(); }
History* optionalHistory() const { return m_history.get(); }
......@@ -188,7 +196,10 @@ namespace WebCore {
Storage* optionalSessionStorage() const { return m_sessionStorage.get(); }
Storage* optionalLocalStorage() const { return m_sessionStorage.get(); }
#endif
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
DOMApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); }
#endif
private:
DOMWindow(Frame*);
......@@ -208,6 +219,9 @@ namespace WebCore {
#if ENABLE(DOM_STORAGE)
mutable RefPtr<Storage> m_sessionStorage;
mutable RefPtr<Storage> m_localStorage;
#endif
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
mutable RefPtr<DOMApplicationCache> m_applicationCache;
#endif
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment