Changeset 48937 in webkit


Ignore:
Timestamp:
Sep 30, 2009 11:17:12 AM (15 years ago)
Author:
jorlow@chromium.org
Message:

2009-09-28 Jeremy Orlow <jorlow@chromium.org>

Reviewed by Darin Fisher.

Chromium needs to be able to override the way storage events are delivered
https://bugs.webkit.org/show_bug.cgi?id=29655

Chromium needs to be able to override the way storage events are delivered.
This replaced https://bugs.webkit.org/show_bug.cgi?id=29257 because it'll be
faster (no vtables and extra allocation) and somewhat cleaner (no dependency
injection). This is necessary because Chromium needs to transport events across
a process barrier and then dispatch them without use of a Frame*.

Behavior should not change with this, so no updates to tests.

  • GNUmakefile.am:
  • WebCore.gypi:
  • WebCore.vcproj/WebCore.vcproj:
  • WebCore.xcodeproj/project.pbxproj:
  • WebCoreSources.bkl:
  • storage/StorageAreaImpl.cpp: (WebCore::StorageAreaImpl::setItem): (WebCore::StorageAreaImpl::removeItem): (WebCore::StorageAreaImpl::clear):
  • storage/StorageAreaImpl.h:
  • storage/StorageEventDispatcher.cpp: Copied from WebCore/storage/StorageAreaImpl.cpp. (WebCore::StorageEventDispatcher::dispatch):
  • storage/StorageEventDispatcher.h: Added. (Well, technically in the other half of this patch.)
Location:
trunk/WebCore
Files:
9 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r48934 r48937  
     12009-09-28  Jeremy Orlow  <jorlow@chromium.org>
     2
     3        Reviewed by Darin Fisher.
     4
     5        Chromium needs to be able to override the way storage events are delivered
     6        https://bugs.webkit.org/show_bug.cgi?id=29655
     7
     8        Chromium needs to be able to override the way storage events are delivered.
     9        This replaced https://bugs.webkit.org/show_bug.cgi?id=29257 because it'll be
     10        faster (no vtables and extra allocation) and somewhat cleaner (no dependency
     11        injection).  This is necessary because Chromium needs to transport events across
     12        a process barrier and then dispatch them without use of a Frame*.
     13
     14        Behavior should not change with this, so no updates to tests.
     15
     16        * GNUmakefile.am:
     17        * WebCore.gypi:
     18        * WebCore.vcproj/WebCore.vcproj:
     19        * WebCore.xcodeproj/project.pbxproj:
     20        * WebCoreSources.bkl:
     21        * storage/StorageAreaImpl.cpp:
     22        (WebCore::StorageAreaImpl::setItem):
     23        (WebCore::StorageAreaImpl::removeItem):
     24        (WebCore::StorageAreaImpl::clear):
     25        * storage/StorageAreaImpl.h:
     26        * storage/StorageEventDispatcher.cpp: Copied from WebCore/storage/StorageAreaImpl.cpp.
     27        (WebCore::StorageEventDispatcher::dispatch):
     28        * storage/StorageEventDispatcher.h: Added.  (Well, technically in the other half of this patch.)
     29
    1302009-09-30  Jian Li  <jianli@chromium.org>
    231
  • trunk/WebCore/GNUmakefile.am

    r48912 r48937  
    22302230        WebCore/storage/StorageAreaSync.h \
    22312231        WebCore/storage/StorageEvent.cpp \
     2232        WebCore/storage/StorageEventDispatcher.cpp \
    22322233        WebCore/storage/StorageEvent.h \
    22332234        WebCore/storage/StorageMap.cpp \
  • trunk/WebCore/WebCore.gyp/WebCore.gyp

    r48827 r48937  
    498498        '../storage/StorageNamespace.cpp',
    499499
     500        # Don't build StorageEventDispatcher.  We have our own implementation.
     501        '../storage/StorageEventDispatcher.cpp',
     502
    500503        # Use history/BackForwardListChromium.cpp instead.
    501504        '../history/BackForwardList.cpp',
  • trunk/WebCore/WebCore.gypi

    r48912 r48937  
    31063106            'storage/StorageEvent.cpp',
    31073107            'storage/StorageEvent.h',
     3108            'storage/StorageEventDispatcher.cpp',
    31083109            'storage/StorageEventDispatcher.h',
    31093110            'storage/StorageMap.cpp',
  • trunk/WebCore/WebCore.vcproj/WebCore.vcproj

    r48912 r48937  
    3112131121                        </File>
    3112231122                        <File
     31123                                RelativePath="..\storage\StorageEventDispatcher.cpp"
     31124                                >
     31125                        </File>
     31126                        <File
     31127                                RelativePath="..\storage\StorageEventDispatcher.h"
     31128                                >
     31129                        </File>
     31130                        <File
    3112331131                                RelativePath="..\storage\StorageMap.cpp"
    3112431132                                >
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r48912 r48937  
    45114511                C55E38BF10040D5D00A56BDB /* StorageNamespaceImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = C55E38BB10040D5D00A56BDB /* StorageNamespaceImpl.h */; };
    45124512                C55E38C010040D5D00A56BDB /* StorageNamespaceImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C55E38BC10040D5D00A56BDB /* StorageNamespaceImpl.cpp */; };
     4513                C5E9B67710697E1300C7BB1A /* StorageEventDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C5E9B67610697E1300C7BB1A /* StorageEventDispatcher.cpp */; };
     4514                C5EBDD84105EDDEC0056816F /* StorageEventDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EBDD81105EDDEC0056816F /* StorageEventDispatcher.h */; };
    45134515                C6D74AD509AA282E000B0A52 /* ModifySelectionListLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = C6D74AD309AA282E000B0A52 /* ModifySelectionListLevel.h */; };
    45144516                C6D74AE409AA290A000B0A52 /* ModifySelectionListLevel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */; };
     
    96159617                C55E38BB10040D5D00A56BDB /* StorageNamespaceImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageNamespaceImpl.h; sourceTree = "<group>"; };
    96169618                C55E38BC10040D5D00A56BDB /* StorageNamespaceImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StorageNamespaceImpl.cpp; sourceTree = "<group>"; };
     9619                C5E9B67610697E1300C7BB1A /* StorageEventDispatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StorageEventDispatcher.cpp; sourceTree = "<group>"; };
     9620                C5EBDD81105EDDEC0056816F /* StorageEventDispatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageEventDispatcher.h; sourceTree = "<group>"; };
    96179621                C6D74AD309AA282E000B0A52 /* ModifySelectionListLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModifySelectionListLevel.h; sourceTree = "<group>"; };
    96189622                C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModifySelectionListLevel.cpp; sourceTree = "<group>"; };
     
    1023810242                                51E0BAB90DA5547100A9E417 /* StorageEvent.h */,
    1023910243                                51E0BABD0DA5548400A9E417 /* StorageEvent.idl */,
     10244                                C5E9B67610697E1300C7BB1A /* StorageEventDispatcher.cpp */,
     10245                                C5EBDD81105EDDEC0056816F /* StorageEventDispatcher.h */,
    1024010246                                51E0BB370DA5ACB600A9E417 /* StorageMap.cpp */,
    1024110247                                51E0BB360DA5ACB600A9E417 /* StorageMap.h */,
     
    1790417910                                510D4A50103177A20049EA54 /* WebSocketChannelClient.h in Headers */,
    1790517911                                51ABAE451043AB4A008C5260 /* WebSocketHandshake.h in Headers */,
     17912                                C5EBDD84105EDDEC0056816F /* StorageEventDispatcher.h in Headers */,
    1790617913                                FABE72F51059C1EB00D999DD /* MathMLElement.h in Headers */,
    1790717914                                FABE72F71059C1EB00D999DD /* MathMLInlineContainerElement.h in Headers */,
     
    2002420031                                BCCE58AC1061E8CF008FB35A /* JSDatabaseCustom.cpp in Sources */,
    2002520032                                BCCE58AF1061E90C008FB35A /* JSDocumentFragmentCustom.cpp in Sources */,
     20033                                C5E9B67710697E1300C7BB1A /* StorageEventDispatcher.cpp in Sources */,
    2002620034                                14CD8D82106B529000A46D23 /* JSSharedWorkerCustom.cpp in Sources */,
    2002720035                                7693BAD3106C2DCA007B0823 /* PluginHalter.cpp in Sources */,
  • trunk/WebCore/WebCoreSources.bkl

    r48826 r48937  
    10571057        storage/StorageAreaSync.cpp
    10581058        storage/StorageEvent.cpp
     1059        storage/StorageEventDispatcher.cpp
    10591060        storage/StorageNamespace.cpp
    10601061        storage/StorageNamespaceImpl.cpp
  • trunk/WebCore/storage/StorageAreaImpl.cpp

    r48734 r48937  
    2929#if ENABLE(DOM_STORAGE)
    3030
    31 #include "DOMWindow.h"
    32 #include "EventNames.h"
    3331#include "ExceptionCode.h"
    3432#include "Frame.h"
    35 #include "Page.h"
    36 #include "PageGroup.h"
    37 #include "SecurityOrigin.h"
    3833#include "Settings.h"
    39 #include "StorageEvent.h"
    4034#include "StorageAreaSync.h"
     35#include "StorageEventDispatcher.h"
    4136#include "StorageMap.h"
    4237#include "StorageSyncManager.h"
     
    155150        if (m_storageAreaSync)
    156151            m_storageAreaSync->scheduleItemForSync(key, value);
    157         dispatchStorageEvent(key, oldValue, value, frame);
     152        StorageEventDispatcher::dispatch(key, oldValue, value, m_storageType, m_securityOrigin.get(), frame);
    158153    }
    159154}
     
    176171        if (m_storageAreaSync)
    177172            m_storageAreaSync->scheduleItemForSync(key, String());
    178         dispatchStorageEvent(key, oldValue, String(), frame);
     173        StorageEventDispatcher::dispatch(key, oldValue, String(), m_storageType, m_securityOrigin.get(), frame);
    179174    }
    180175}
     
    192187    if (m_storageAreaSync)
    193188        m_storageAreaSync->scheduleClear();
    194     dispatchStorageEvent(String(), String(), String(), frame);
     189    StorageEventDispatcher::dispatch(String(), String(), String(), m_storageType, m_securityOrigin.get(), frame);
    195190}
    196191
     
    230225}
    231226
    232 void StorageAreaImpl::dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
    233 {
    234 #if PLATFORM(CHROMIUM)
    235     // FIXME: Events are currently broken in Chromium.
    236     return;
    237 #endif
    238 
    239     Page* page = sourceFrame->page();
    240     if (!page)
    241         return;
    242 
    243     // We need to copy all relevant frames from every page to a vector since sending the event to one frame might mutate the frame tree
    244     // of any given page in the group or mutate the page group itself.
    245     Vector<RefPtr<Frame> > frames;
    246     if (m_storageType == SessionStorage) {
    247         // Send events only to our page.
    248         for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
    249             if (frame->document()->securityOrigin()->equal(securityOrigin()))
    250                 frames.append(frame);
    251         }
    252 
    253         for (unsigned i = 0; i < frames.size(); ++i)
    254             frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->documentURI(), sourceFrame->domWindow(), frames[i]->domWindow()->sessionStorage()));
    255     } else {
    256         // Send events to every page.
    257         const HashSet<Page*>& pages = page->group().pages();
    258         HashSet<Page*>::const_iterator end = pages.end();
    259         for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
    260             for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
    261                 if (frame->document()->securityOrigin()->equal(securityOrigin()))
    262                     frames.append(frame);
    263             }
    264         }
    265 
    266         for (unsigned i = 0; i < frames.size(); ++i)
    267             frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->documentURI(), sourceFrame->domWindow(), frames[i]->domWindow()->localStorage()));
    268     }
    269 }
    270 
    271227}
    272228
  • trunk/WebCore/storage/StorageAreaImpl.h

    r48734 r48937  
    6767        void blockUntilImportComplete() const;
    6868
    69         void dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame);
    70 
    7169        StorageType m_storageType;
    7270        RefPtr<SecurityOrigin> m_securityOrigin;
  • trunk/WebCore/storage/StorageEventDispatcher.cpp

    r48651 r48937  
    2525
    2626#include "config.h"
    27 #include "StorageAreaImpl.h"
     27#include "StorageEventDispatcher.h"
    2828
    2929#if ENABLE(DOM_STORAGE)
     
    3131#include "DOMWindow.h"
    3232#include "EventNames.h"
    33 #include "ExceptionCode.h"
    3433#include "Frame.h"
    3534#include "Page.h"
    3635#include "PageGroup.h"
    3736#include "SecurityOrigin.h"
    38 #include "Settings.h"
    3937#include "StorageEvent.h"
    40 #include "StorageAreaSync.h"
    41 #include "StorageMap.h"
    42 #include "StorageSyncManager.h"
    4338
    4439namespace WebCore {
    4540
    46 StorageAreaImpl::~StorageAreaImpl()
     41void StorageEventDispatcher::dispatch(const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin, Frame* sourceFrame)
    4742{
    48 }
    49 
    50 StorageAreaImpl::StorageAreaImpl(StorageType storageType, PassRefPtr<SecurityOrigin> origin, PassRefPtr<StorageSyncManager> syncManager)
    51     : m_storageType(storageType)
    52     , m_securityOrigin(origin)
    53     , m_storageMap(StorageMap::create())
    54     , m_storageSyncManager(syncManager)
    55 #ifndef NDEBUG
    56     , m_isShutdown(false)
    57 #endif
    58 {
    59     ASSERT(m_securityOrigin);
    60     ASSERT(m_storageMap);
    61 
    62     // FIXME: If there's no backing storage for LocalStorage, the default WebKit behavior should be that of private browsing,
    63     // not silently ignoring it.  https://bugs.webkit.org/show_bug.cgi?id=25894
    64     if (m_storageSyncManager) {
    65         m_storageAreaSync = StorageAreaSync::create(m_storageSyncManager, this);
    66         ASSERT(m_storageAreaSync);
    67     }
    68 }
    69 
    70 PassRefPtr<StorageAreaImpl> StorageAreaImpl::copy()
    71 {
    72     ASSERT(!m_isShutdown);
    73     return adoptRef(new StorageAreaImpl(this));
    74 }
    75 
    76 StorageAreaImpl::StorageAreaImpl(StorageAreaImpl* area)
    77     : m_storageType(area->m_storageType)
    78     , m_securityOrigin(area->m_securityOrigin)
    79     , m_storageMap(area->m_storageMap)
    80     , m_storageSyncManager(area->m_storageSyncManager)
    81 #ifndef NDEBUG
    82     , m_isShutdown(area->m_isShutdown)
    83 #endif
    84 {
    85     ASSERT(m_securityOrigin);
    86     ASSERT(m_storageMap);
    87     ASSERT(!m_isShutdown);
    88 }
    89 
    90 static bool privateBrowsingEnabled(Frame* frame)
    91 {
    92 #if PLATFORM(CHROMIUM)
    93     // The frame pointer can be NULL in Chromium since this call is made in a different
    94     // process from where the Frame object exists.  Luckily, private browseing is
    95     // implemented differently in Chromium, so it'd never return true anyway.
    96     ASSERT(!frame);
    97     return false;
    98 #else
    99     return frame->page()->settings()->privateBrowsingEnabled();
    100 #endif
    101 }
    102 
    103 unsigned StorageAreaImpl::length() const
    104 {
    105     ASSERT(!m_isShutdown);
    106     return m_storageMap->length();
    107 }
    108 
    109 String StorageAreaImpl::key(unsigned index) const
    110 {
    111     ASSERT(!m_isShutdown);
    112     blockUntilImportComplete();
    113     return m_storageMap->key(index);
    114 }
    115 
    116 String StorageAreaImpl::getItem(const String& key) const
    117 {
    118     ASSERT(!m_isShutdown);
    119     blockUntilImportComplete();
    120 
    121     return m_storageMap->getItem(key);
    122 }
    123 
    124 void StorageAreaImpl::setItem(const String& key, const String& value, ExceptionCode& ec, Frame* frame)
    125 {
    126     ASSERT(!m_isShutdown);
    127     ASSERT(!value.isNull());
    128     blockUntilImportComplete();
    129 
    130     if (privateBrowsingEnabled(frame)) {
    131         ec = QUOTA_EXCEEDED_ERR;
    132         return;
    133     }
    134 
    135     // FIXME: For LocalStorage where a disk quota will be enforced, here is where we need to do quota checking.
    136     //        If we decide to enforce a memory quota for SessionStorage, this is where we'd do that, also.
    137     // if (<over quota>) {
    138     //     ec = QUOTA_EXCEEDED_ERR;
    139     //     return;
    140     // }
    141 
    142     String oldValue;
    143     RefPtr<StorageMap> newMap = m_storageMap->setItem(key, value, oldValue);
    144 
    145     if (newMap)
    146         m_storageMap = newMap.release();
    147 
    148     // Only notify the client if an item was actually changed
    149     if (oldValue != value) {
    150         if (m_storageAreaSync)
    151             m_storageAreaSync->scheduleItemForSync(key, value);
    152         dispatchStorageEvent(key, oldValue, value, frame);
    153     }
    154 }
    155 
    156 void StorageAreaImpl::removeItem(const String& key, Frame* frame)
    157 {
    158     ASSERT(!m_isShutdown);
    159     blockUntilImportComplete();
    160 
    161     if (privateBrowsingEnabled(frame))
    162         return;
    163 
    164     String oldValue;
    165     RefPtr<StorageMap> newMap = m_storageMap->removeItem(key, oldValue);
    166     if (newMap)
    167         m_storageMap = newMap.release();
    168 
    169     // Only notify the client if an item was actually removed
    170     if (!oldValue.isNull()) {
    171         if (m_storageAreaSync)
    172             m_storageAreaSync->scheduleItemForSync(key, String());
    173         dispatchStorageEvent(key, oldValue, String(), frame);
    174     }
    175 }
    176 
    177 void StorageAreaImpl::clear(Frame* frame)
    178 {
    179     ASSERT(!m_isShutdown);
    180     blockUntilImportComplete();
    181 
    182     if (privateBrowsingEnabled(frame))
    183         return;
    184 
    185     m_storageMap = StorageMap::create();
    186 
    187     if (m_storageAreaSync)
    188         m_storageAreaSync->scheduleClear();
    189     dispatchStorageEvent(String(), String(), String(), frame);
    190 }
    191 
    192 bool StorageAreaImpl::contains(const String& key) const
    193 {
    194     ASSERT(!m_isShutdown);
    195     blockUntilImportComplete();
    196 
    197     return m_storageMap->contains(key);
    198 }
    199 
    200 void StorageAreaImpl::importItem(const String& key, const String& value)
    201 {
    202     ASSERT(!m_isShutdown);
    203     m_storageMap->importItem(key, value);
    204 }
    205 
    206 SecurityOrigin* StorageAreaImpl::securityOrigin()
    207 {
    208     return m_securityOrigin.get();
    209 }
    210 
    211 void StorageAreaImpl::close()
    212 {
    213     if (m_storageAreaSync)
    214         m_storageAreaSync->scheduleFinalSync();
    215 
    216 #ifndef NDEBUG
    217     m_isShutdown = true;
    218 #endif
    219 }
    220 
    221 void StorageAreaImpl::blockUntilImportComplete() const
    222 {
    223     if (m_storageAreaSync)
    224         m_storageAreaSync->blockUntilImportComplete();
    225 }
    226 
    227 void StorageAreaImpl::dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
    228 {
    229 #if PLATFORM(CHROMIUM)
    230     // FIXME: Events are currently broken in Chromium.
    231     return;
    232 #endif
    233 
    23443    Page* page = sourceFrame->page();
    23544    if (!page)
     
    23948    // of any given page in the group or mutate the page group itself.
    24049    Vector<RefPtr<Frame> > frames;
    241     if (m_storageType == SessionStorage) {
     50    if (storageType == SessionStorage) {
    24251        // Send events only to our page.
    24352        for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
    244             if (frame->document()->securityOrigin()->equal(securityOrigin()))
     53            if (frame->document()->securityOrigin()->equal(securityOrigin))
    24554                frames.append(frame);
    24655        }
     
    25463        for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
    25564            for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
    256                 if (frame->document()->securityOrigin()->equal(securityOrigin()))
     65                if (frame->document()->securityOrigin()->equal(securityOrigin))
    25766                    frames.append(frame);
    25867            }
Note: See TracChangeset for help on using the changeset viewer.