Commit bb69e1eb authored by beidson@apple.com's avatar beidson@apple.com

2008-04-16 Brady Eidson <beidson@apple.com>

        Reviewed by Darin Adler

        Merge the StorageAreaClient into the StorageArea class itself as pure virtual methods.
        Add "LocalStorageArea" add "SessionStorageArea" implementations, and have SessionStorage
        and LocalStorage instantiate the appropriate type of StorageArea object.

        This purpose of this change is because while adding the persistent store to LocalStorage,
        it became obvious that the client approach wasn't scaling well.  Additionally, a StorageArea
        backing a local storage area required vastly different data members compared to one backing
        a session storage area.

        This will be much cleaner going forward.

        * GNUmakefile.am:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * WebCoreSources.bkl:

        * storage/LocalStorage.cpp:
        (WebCore::LocalStorage::storageArea):
        * storage/LocalStorage.h:

        * storage/LocalStorageArea.cpp: Added.
        (WebCore::LocalStorageArea::LocalStorageArea):
        (WebCore::LocalStorageArea::itemChanged):
        (WebCore::LocalStorageArea::itemRemoved):
        (WebCore::LocalStorageArea::dispatchStorageEvent):
        * storage/LocalStorageArea.h: Added.
        (WebCore::LocalStorageArea::create):

        * storage/SessionStorage.cpp:
        (WebCore::SessionStorage::copy):
        (WebCore::SessionStorage::storageArea):
        * storage/SessionStorage.h:

        * storage/SessionStorageArea.cpp: Added.
        (WebCore::SessionStorageArea::copy):
        (WebCore::SessionStorageArea::SessionStorageArea):
        (WebCore::SessionStorageArea::itemChanged):
        (WebCore::SessionStorageArea::itemRemoved):
        (WebCore::SessionStorageArea::dispatchStorageEvent):
        * storage/SessionStorageArea.h: Added.
        (WebCore::SessionStorageArea::create):
        (WebCore::SessionStorageArea::page):

        * storage/StorageArea.cpp:
        (WebCore::StorageArea::StorageArea):
        (WebCore::StorageArea::setItem):
        (WebCore::StorageArea::removeItem):
        (WebCore::StorageArea::storageMap):
        * storage/StorageArea.h:

        * storage/StorageAreaClient.h: Removed.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@31983 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 7f192d4a
2008-04-16 Brady Eidson <beidson@apple.com>
Reviewed by Darin Adler
Merge the StorageAreaClient into the StorageArea class itself as pure virtual methods.
Add "LocalStorageArea" add "SessionStorageArea" implementations, and have SessionStorage
and LocalStorage instantiate the appropriate type of StorageArea object.
This purpose of this change is because while adding the persistent store to LocalStorage,
it became obvious that the client approach wasn't scaling well. Additionally, a StorageArea
backing a local storage area required vastly different data members compared to one backing
a session storage area.
This will be much cleaner going forward.
* GNUmakefile.am:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* WebCoreSources.bkl:
* storage/LocalStorage.cpp:
(WebCore::LocalStorage::storageArea):
* storage/LocalStorage.h:
* storage/LocalStorageArea.cpp: Added.
(WebCore::LocalStorageArea::LocalStorageArea):
(WebCore::LocalStorageArea::itemChanged):
(WebCore::LocalStorageArea::itemRemoved):
(WebCore::LocalStorageArea::dispatchStorageEvent):
* storage/LocalStorageArea.h: Added.
(WebCore::LocalStorageArea::create):
* storage/SessionStorage.cpp:
(WebCore::SessionStorage::copy):
(WebCore::SessionStorage::storageArea):
* storage/SessionStorage.h:
* storage/SessionStorageArea.cpp: Added.
(WebCore::SessionStorageArea::copy):
(WebCore::SessionStorageArea::SessionStorageArea):
(WebCore::SessionStorageArea::itemChanged):
(WebCore::SessionStorageArea::itemRemoved):
(WebCore::SessionStorageArea::dispatchStorageEvent):
* storage/SessionStorageArea.h: Added.
(WebCore::SessionStorageArea::create):
(WebCore::SessionStorageArea::page):
* storage/StorageArea.cpp:
(WebCore::StorageArea::StorageArea):
(WebCore::StorageArea::setItem):
(WebCore::StorageArea::removeItem):
(WebCore::StorageArea::storageMap):
* storage/StorageArea.h:
* storage/StorageAreaClient.h: Removed.
2008-04-16 David Hyatt <hyatt@apple.com>
Add support for the ability to draw directly into CSS images using CanvasRenderingContext2D.
......@@ -1200,11 +1200,13 @@ webcore_cppflags += \
webcore_sources += \
WebCore/storage/LocalStorage.cpp \
WebCore/storage/LocalStorageArea.cpp \
WebCore/storage/Storage.cpp \
WebCore/storage/StorageArea.cpp \
WebCore/storage/StorageEvent.cpp \
WebCore/storage/StorageMap.cpp \
WebCore/storage/SessionStorage.cpp \
WebCore/storage/SessionStorageArea.cpp \
WebCore/bindings/js/JSStorageCustom.cpp
endif # END ENABLE_DOM_STORAGE
......
......@@ -1218,11 +1218,13 @@ contains(DEFINES, ENABLE_DOM_STORAGE=1) {
SOURCES += \
storage/LocalStorage.cpp \
storage/LocalStorageArea.cpp \
storage/Storage.cpp \
storage/StorageArea.cpp \
storage/StorageEvent.cpp \
storage/StorageMap.cpp \
storage/SessionStorage.cpp \
storage/SessionStorageArea.cpp \
bindings/js/JSStorage.cpp \
bindings/js/JSStorageCustom.cpp \
bindings/js/JSStorageEvent.cpp \
......
......@@ -15895,6 +15895,14 @@
RelativePath="..\storage\LocalStorage.h"
>
</File>
<File
RelativePath="..\storage\LocalStorageArea.cpp"
>
</File>
<File
RelativePath="..\storage\LocalStorageArea.h"
>
</File>
<File
RelativePath="..\storage\OriginQuotaManager.cpp"
>
......@@ -15919,6 +15927,14 @@
RelativePath="..\storage\SessionStorage.h"
>
</File>
<File
RelativePath="..\storage\SessionStorageArea.cpp"
>
</File>
<File
RelativePath="..\storage\SessionStorageArea.h"
>
</File>
<File
RelativePath="..\storage\SQLCallback.h"
>
......@@ -15991,10 +16007,6 @@
RelativePath="..\storage\StorageArea.h"
>
</File>
<File
RelativePath="..\storage\StorageAreaClient.h"
>
</File>
<File
RelativePath="..\storage\StorageEvent.cpp"
>
......
......@@ -450,6 +450,10 @@
514185EF0CD65F0400763C99 /* ChangeVersionWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 514185ED0CD65F0400763C99 /* ChangeVersionWrapper.cpp */; };
514B3F730C722047000530DF /* FileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 514B3F720C722047000530DF /* FileSystem.h */; };
514B3F760C722055000530DF /* FileSystemMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 514B3F750C722055000530DF /* FileSystemMac.mm */; };
514B49DB0DB6D6AD001C3770 /* LocalStorageArea.h in Headers */ = {isa = PBXBuildFile; fileRef = 514B49D90DB6D6AD001C3770 /* LocalStorageArea.h */; };
514B49DC0DB6D6AD001C3770 /* LocalStorageArea.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 514B49DA0DB6D6AD001C3770 /* LocalStorageArea.cpp */; };
514B49DF0DB6D6B6001C3770 /* SessionStorageArea.h in Headers */ = {isa = PBXBuildFile; fileRef = 514B49DD0DB6D6B6001C3770 /* SessionStorageArea.h */; };
514B49E00DB6D6B6001C3770 /* SessionStorageArea.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 514B49DE0DB6D6B6001C3770 /* SessionStorageArea.cpp */; };
514C76370CE9225E007EF3CD /* JSSQLError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 514C76350CE9225E007EF3CD /* JSSQLError.cpp */; };
514C76380CE9225E007EF3CD /* JSSQLTransaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 514C76360CE9225E007EF3CD /* JSSQLTransaction.cpp */; };
514C764C0CE9234E007EF3CD /* AuthenticationMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 514C76420CE9234E007EF3CD /* AuthenticationMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -512,7 +516,6 @@
51BE37E00DAEE00E001085FC /* StorageArea.h in Headers */ = {isa = PBXBuildFile; fileRef = 51BE37DE0DAEE00E001085FC /* StorageArea.h */; };
51BE38280DAEF7DA001085FC /* LocalStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51BE38260DAEF7DA001085FC /* LocalStorage.cpp */; };
51BE38290DAEF7DA001085FC /* LocalStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 51BE38270DAEF7DA001085FC /* LocalStorage.h */; };
51BE382C0DAEF7F3001085FC /* StorageAreaClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 51BE382B0DAEF7F3001085FC /* StorageAreaClient.h */; };
51C81B890C4422F70019ECE3 /* FTPDirectoryParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51C81B870C4422F70019ECE3 /* FTPDirectoryParser.cpp */; };
51C81B8A0C4422F70019ECE3 /* FTPDirectoryParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 51C81B880C4422F70019ECE3 /* FTPDirectoryParser.h */; };
51CBFC990D10E483002DBF51 /* CachedPagePlatformData.h in Headers */ = {isa = PBXBuildFile; fileRef = 51CBFC980D10E483002DBF51 /* CachedPagePlatformData.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -4894,6 +4897,10 @@
514185ED0CD65F0400763C99 /* ChangeVersionWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChangeVersionWrapper.cpp; sourceTree = "<group>"; };
514B3F720C722047000530DF /* FileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSystem.h; sourceTree = "<group>"; };
514B3F750C722055000530DF /* FileSystemMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FileSystemMac.mm; sourceTree = "<group>"; };
514B49D90DB6D6AD001C3770 /* LocalStorageArea.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalStorageArea.h; sourceTree = "<group>"; };
514B49DA0DB6D6AD001C3770 /* LocalStorageArea.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LocalStorageArea.cpp; sourceTree = "<group>"; };
514B49DD0DB6D6B6001C3770 /* SessionStorageArea.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SessionStorageArea.h; sourceTree = "<group>"; };
514B49DE0DB6D6B6001C3770 /* SessionStorageArea.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SessionStorageArea.cpp; sourceTree = "<group>"; };
514C76350CE9225E007EF3CD /* JSSQLError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSQLError.cpp; sourceTree = "<group>"; };
514C76360CE9225E007EF3CD /* JSSQLTransaction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSQLTransaction.cpp; sourceTree = "<group>"; };
514C76420CE9234E007EF3CD /* AuthenticationMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuthenticationMac.h; sourceTree = "<group>"; };
......@@ -4960,7 +4967,6 @@
51BE37DE0DAEE00E001085FC /* StorageArea.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageArea.h; sourceTree = "<group>"; };
51BE38260DAEF7DA001085FC /* LocalStorage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LocalStorage.cpp; sourceTree = "<group>"; };
51BE38270DAEF7DA001085FC /* LocalStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalStorage.h; sourceTree = "<group>"; };
51BE382B0DAEF7F3001085FC /* StorageAreaClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageAreaClient.h; sourceTree = "<group>"; };
51C81B870C4422F70019ECE3 /* FTPDirectoryParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FTPDirectoryParser.cpp; sourceTree = "<group>"; };
51C81B880C4422F70019ECE3 /* FTPDirectoryParser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FTPDirectoryParser.h; sourceTree = "<group>"; };
51CBFC980D10E483002DBF51 /* CachedPagePlatformData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedPagePlatformData.h; sourceTree = "<group>"; };
......@@ -8584,10 +8590,16 @@
51FAFE330CECBF2D00BB3F24 /* DatabaseTrackerClient.h */,
51BE38260DAEF7DA001085FC /* LocalStorage.cpp */,
51BE38270DAEF7DA001085FC /* LocalStorage.h */,
514B49DA0DB6D6AD001C3770 /* LocalStorageArea.cpp */,
514B49D90DB6D6AD001C3770 /* LocalStorageArea.h */,
51A926780D53F0570063ECC2 /* OriginQuotaManager.cpp */,
51A926790D53F0570063ECC2 /* OriginQuotaManager.h */,
51A9267A0D53F0570063ECC2 /* OriginUsageRecord.cpp */,
51A9267B0D53F0570063ECC2 /* OriginUsageRecord.h */,
51E0BB220DA572A600A9E417 /* SessionStorage.cpp */,
51E0BB210DA572A600A9E417 /* SessionStorage.h */,
514B49DE0DB6D6B6001C3770 /* SessionStorageArea.cpp */,
514B49DD0DB6D6B6001C3770 /* SessionStorageArea.h */,
51EC92570CE90DB400F90308 /* SQLError.h */,
51EC92580CE90DB400F90308 /* SQLError.idl */,
519611670CAC56570010A80C /* SQLResultSet.cpp */,
......@@ -8614,14 +8626,11 @@
51E3F9D10DA05D7100250911 /* Storage.idl */,
51BE37DD0DAEE00E001085FC /* StorageArea.cpp */,
51BE37DE0DAEE00E001085FC /* StorageArea.h */,
51BE382B0DAEF7F3001085FC /* StorageAreaClient.h */,
51E0BABA0DA5547100A9E417 /* StorageEvent.cpp */,
51E0BAB90DA5547100A9E417 /* StorageEvent.h */,
51E0BABD0DA5548400A9E417 /* StorageEvent.idl */,
51E0BB370DA5ACB600A9E417 /* StorageMap.cpp */,
51E0BB360DA5ACB600A9E417 /* StorageMap.h */,
51E0BB220DA572A600A9E417 /* SessionStorage.cpp */,
51E0BB210DA572A600A9E417 /* SessionStorage.h */,
);
indentWidth = 4;
path = storage;
......@@ -14898,7 +14907,6 @@
BC53C6920DA591140021EB5D /* CSSGradientValue.h in Headers */,
51BE37E00DAEE00E001085FC /* StorageArea.h in Headers */,
51BE38290DAEF7DA001085FC /* LocalStorage.h in Headers */,
51BE382C0DAEF7F3001085FC /* StorageAreaClient.h in Headers */,
BC23EE920DAED2BC009FDC91 /* CSSImageGeneratorValue.h in Headers */,
BC23F0DB0DAFF4A4009FDC91 /* GeneratedImage.h in Headers */,
BCE04C8A0DAFF7A0007A0F41 /* Generator.h in Headers */,
......@@ -14919,6 +14927,8 @@
1A8F6BC30DB55CDC001DB794 /* DOMApplicationCache.h in Headers */,
1A8F6BC60DB55CDC001DB794 /* ManifestParser.h in Headers */,
1AC2260D0DB69F190089B669 /* JSDOMApplicationCache.h in Headers */,
514B49DB0DB6D6AD001C3770 /* LocalStorageArea.h in Headers */,
514B49DF0DB6D6B6001C3770 /* SessionStorageArea.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -16621,6 +16631,8 @@
C0DFC8700DB6841A003EAE7C /* JSConsoleCustom.cpp in Sources */,
1AC2260C0DB69F190089B669 /* JSDOMApplicationCache.cpp in Sources */,
1AC226170DB69F740089B669 /* JSDOMApplicationCacheCustom.cpp in Sources */,
514B49DC0DB6D6AD001C3770 /* LocalStorageArea.cpp in Sources */,
514B49E00DB6D6B6001C3770 /* SessionStorageArea.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -801,6 +801,7 @@ This file contains the list of files needed to build WebCore.
storage/DatabaseThread.cpp
storage/DatabaseTracker.cpp
storage/LocalStorage.cpp
storage/LocalStorageArea.cpp
storage/OriginQuotaManager.cpp
storage/OriginUsageRecord.cpp
storage/SQLResultSet.cpp
......@@ -812,6 +813,7 @@ This file contains the list of files needed to build WebCore.
storage/StorageEvent.cpp
storage/StorageMap.cpp
storage/SessionStorage.cpp
storage/SessionStorageArea.cpp
</set>
<set append="1" var="WEBCORE_SOURCES_XML">
......
......@@ -29,6 +29,7 @@
#include "EventNames.h"
#include "Frame.h"
#include "FrameTree.h"
#include "LocalStorageArea.h"
#include "Page.h"
#include "PageGroup.h"
#include "StorageArea.h"
......@@ -55,49 +56,9 @@ PassRefPtr<StorageArea> LocalStorage::storageArea(SecurityOrigin* origin)
if (storageArea = m_storageAreaMap.get(origin))
return storageArea.release();
storageArea = StorageArea::create(origin, 0, this);
storageArea = LocalStorageArea::create(origin);
m_storageAreaMap.set(origin, storageArea);
return storageArea.release();
}
void LocalStorage::itemChanged(StorageArea* area, const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
{
// FIXME: Flag this change to be written out to the persistent store
dispatchStorageEvent(area, key, oldValue, newValue, sourceFrame);
}
void LocalStorage::itemRemoved(StorageArea* area, const String& key, const String& oldValue, Frame* sourceFrame)
{
// FIXME: Flag this removal to be written out to the persistent store
dispatchStorageEvent(area, key, oldValue, String(), sourceFrame);
}
void LocalStorage::dispatchStorageEvent(StorageArea* area, const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
{
Page* page = sourceFrame->page();
if (!page)
return;
// Need to copy all relevant frames from every page to a vector, since sending the event to one frame might mutate the frame tree
// of any given page in the group, or mutate the page group itself
Vector<RefPtr<Frame> > frames;
const HashSet<Page*>& pages = page->group().pages();
HashSet<Page*>::const_iterator end = pages.end();
for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
if (Document* document = frame->document())
if (document->securityOrigin()->equal(area->securityOrigin()))
frames.append(frame);
}
}
for (unsigned i = 0; i < frames.size(); ++i) {
if (HTMLElement* body = frames[i]->document()->body())
body->dispatchStorageEvent(EventNames::storageEvent, key, oldValue, newValue, sourceFrame);
}
}
} // namespace WebCore
......@@ -27,27 +27,24 @@
#define LocalStorage_h
#include "SecurityOriginHash.h"
#include "StorageAreaClient.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
namespace WebCore {
class LocalStorage : public StorageAreaClient {
class StorageArea;
class LocalStorage : Noncopyable{
public:
static LocalStorage& sharedLocalStorage();
PassRefPtr<StorageArea> storageArea(SecurityOrigin*);
virtual void itemChanged(StorageArea*, const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame);
virtual void itemRemoved(StorageArea*, const String& key, const String& oldValue, Frame* sourceFrame);
private:
LocalStorage();
void dispatchStorageEvent(StorageArea*, const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame);
typedef HashMap<RefPtr<SecurityOrigin>, RefPtr<StorageArea>, SecurityOriginHash, SecurityOriginTraits> StorageAreaMap;
StorageAreaMap m_storageAreaMap;
};
......
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "LocalStorageArea.h"
#include "EventNames.h"
#include "Frame.h"
#include "FrameTree.h"
#include "Page.h"
#include "PageGroup.h"
#include "PlatformString.h"
#include "SecurityOrigin.h"
namespace WebCore {
LocalStorageArea::LocalStorageArea(SecurityOrigin* origin)
: StorageArea(origin)
{
}
void LocalStorageArea::itemChanged(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
{
// FIXME: Flag this change to be written out to the persistent store
dispatchStorageEvent(key, oldValue, newValue, sourceFrame);
}
void LocalStorageArea::itemRemoved(const String& key, const String& oldValue, Frame* sourceFrame)
{
// FIXME: Flag this removal to be written out to the persistent store
dispatchStorageEvent(key, oldValue, String(), sourceFrame);
}
void LocalStorageArea::dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
{
Page* page = sourceFrame->page();
if (!page)
return;
// Need to copy all relevant frames from every page to a vector, since sending the event to one frame might mutate the frame tree
// of any given page in the group, or mutate the page group itself
Vector<RefPtr<Frame> > frames;
const HashSet<Page*>& pages = page->group().pages();
HashSet<Page*>::const_iterator end = pages.end();
for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
if (Document* document = frame->document())
if (document->securityOrigin()->equal(securityOrigin()))
frames.append(frame);
}
}
for (unsigned i = 0; i < frames.size(); ++i) {
if (HTMLElement* body = frames[i]->document()->body())
body->dispatchStorageEvent(EventNames::storageEvent, key, oldValue, newValue, sourceFrame);
}
}
} // namespace WebCore
......@@ -23,27 +23,28 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef StorageAreaClient_h
#define StorageAreaClient_h
#ifndef LocalStorageArea_h
#define LocalStorageArea_h
#include <wtf/RefCounted.h>
#include "StorageArea.h"
namespace WebCore {
#include <wtf/PassRefPtr.h>
class StorageArea;
class String;
namespace WebCore {
class LocalStorageArea : public StorageArea {
public:
static PassRefPtr<LocalStorageArea> create(SecurityOrigin* origin) { return adoptRef(new LocalStorageArea(origin)); }
class StorageAreaClient : public RefCounted<StorageAreaClient> {
public:
virtual ~StorageAreaClient() { }
private:
LocalStorageArea(SecurityOrigin*);
virtual void itemChanged(StorageArea*, const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame) = 0;
virtual void itemRemoved(StorageArea*, const String& key, const String& oldValue, Frame* sourceFrame) = 0;
virtual void itemChanged(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame);
virtual void itemRemoved(const String& key, const String& oldValue, Frame* sourceFrame);
protected:
StorageAreaClient() { }
};
void dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame);
};
} // namespace WebCore
#endif // StorageAreaClient_h
#endif // LocalStorageArea_h
......@@ -52,10 +52,9 @@ PassRefPtr<SessionStorage> SessionStorage::copy(Page* newPage)
ASSERT(newPage);
RefPtr<SessionStorage> newSession = SessionStorage::create(newPage);
StorageAreaMap::iterator end = m_storageAreaMap.end();
for (StorageAreaMap::iterator i = m_storageAreaMap.begin(); i != end; ++i) {
RefPtr<StorageArea> areaCopy = i->second->copy(i->first.get(), newPage);
areaCopy->setClient(newSession.get());
SessionStorageAreaMap::iterator end = m_storageAreaMap.end();
for (SessionStorageAreaMap::iterator i = m_storageAreaMap.begin(); i != end; ++i) {
RefPtr<SessionStorageArea> areaCopy = i->second->copy(i->first.get(), newPage);
newSession->m_storageAreaMap.set(i->first, areaCopy.release());
}
......@@ -64,42 +63,13 @@ PassRefPtr<SessionStorage> SessionStorage::copy(Page* newPage)
PassRefPtr<StorageArea> SessionStorage::storageArea(SecurityOrigin* origin)
{
RefPtr<StorageArea> storageArea;
RefPtr<SessionStorageArea> storageArea;
if (storageArea = m_storageAreaMap.get(origin))
return storageArea.release();
storageArea = StorageArea::create(origin, m_page, this);
storageArea = SessionStorageArea::create(origin, m_page);
m_storageAreaMap.set(origin, storageArea);
return storageArea.release();
}
void SessionStorage::itemChanged(StorageArea* area, const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
{
dispatchStorageEvent(area, key, oldValue, newValue, sourceFrame);
}
void SessionStorage::itemRemoved(StorageArea* area, const String& key, const String& oldValue, Frame* sourceFrame)
{
dispatchStorageEvent(area, key, oldValue, String(), sourceFrame);
}
void SessionStorage::dispatchStorageEvent(StorageArea* area, const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
{
ASSERT(area->page() == m_page);
ASSERT(m_page);
// For SessionStorage events, each frame in the page's frametree with the same origin as this Storage needs to be notified of the change
Vector<RefPtr<Frame> > frames;
for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
if (Document* document = frame->document())
if (document->securityOrigin()->equal(area->securityOrigin()))
frames.append(frame);
}
for (unsigned i = 0; i < frames.size(); ++i) {
if (HTMLElement* body = frames[i]->document()->body())
body->dispatchStorageEvent(EventNames::storageEvent, key, oldValue, newValue, sourceFrame);
}
}
}
......@@ -27,27 +27,23 @@
#define SessionStorage_h
#include "SecurityOriginHash.h"
#include "SessionStorageArea.h"
#include "StorageAreaClient.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/RefCounted.h>
namespace WebCore {
class StorageArea;
class Page;
class SessionStorage : public StorageAreaClient {
class SessionStorage : public RefCounted<SessionStorage> {
public:
static PassRefPtr<SessionStorage> create(Page*);
PassRefPtr<SessionStorage> copy(Page*);
PassRefPtr<StorageArea> storageArea(SecurityOrigin*);
virtual void itemChanged(StorageArea*, const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame);
virtual void itemRemoved(StorageArea*, const String& key, const String& oldValue, Frame* sourceFrame);
#ifndef NDEBUG
Page* page() { return m_page; }
#endif
......@@ -59,8 +55,8 @@ namespace WebCore {
Page* m_page;
typedef HashMap<RefPtr<SecurityOrigin>, RefPtr<StorageArea>, SecurityOriginHash, SecurityOriginTraits> StorageAreaMap;
StorageAreaMap m_storageAreaMap;
typedef HashMap<RefPtr<SecurityOrigin>, RefPtr<SessionStorageArea>, SecurityOriginHash, SecurityOriginTraits> SessionStorageAreaMap;
SessionStorageAreaMap m_storageAreaMap;
};
} // namespace WebCore
......
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "SessionStorageArea.h"
#include "EventNames.h"
#include "Frame.h"
#include "FrameTree.h"
#include "Page.h"
#include "PlatformString.h"
#include "SecurityOrigin.h"
#include "StorageMap.h"
namespace WebCore {
PassRefPtr<SessionStorageArea> SessionStorageArea::copy(SecurityOrigin* origin, Page* page)
{
return adoptRef(new SessionStorageArea(origin, page, storageMap()));
}
SessionStorageArea::SessionStorageArea(SecurityOrigin* origin, Page* page)
: StorageArea(origin)
, m_page(page)
{
ASSERT(page);
}
SessionStorageArea::SessionStorageArea(SecurityOrigin* origin, Page* page, PassRefPtr<StorageMap> map)
: StorageArea(origin, map)
, m_page(page)
{
ASSERT(page);
}
void SessionStorageArea::itemChanged(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
{
dispatchStorageEvent(key, oldValue, newValue, sourceFrame);
}
void SessionStorageArea::itemRemoved(const String& key, const String& oldValue, Frame* sourceFrame)
{
dispatchStorageEvent(key, oldValue, String(), sourceFrame);
}
void SessionStorageArea::dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
{
// For SessionStorage events, each frame in the page's frametree with the same origin as this StorageArea needs to be notified of the change
Vector&