Unreviewed, rolling out r126914.
[WebKit-https.git] / Source / WebCore / inspector / InspectorDOMStorageAgent.cpp
1 /*
2  * Copyright (C) 2010 Google 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30
31 #if ENABLE(INSPECTOR)
32
33 #include "InspectorDOMStorageAgent.h"
34
35 #include "Database.h"
36 #include "DOMWindow.h"
37 #include "Document.h"
38 #include "ExceptionCode.h"
39 #include "Frame.h"
40 #include "InspectorDOMStorageResource.h"
41 #include "InspectorFrontend.h"
42 #include "InspectorState.h"
43 #include "InspectorValues.h"
44 #include "InstrumentingAgents.h"
45 #include "Storage.h"
46 #include "StorageArea.h"
47 #include "VoidCallback.h"
48
49 #include <wtf/Vector.h>
50
51 namespace WebCore {
52
53 namespace DOMStorageAgentState {
54 static const char domStorageAgentEnabled[] = "domStorageAgentEnabled";
55 };
56
57 InspectorDOMStorageAgent::InspectorDOMStorageAgent(InstrumentingAgents* instrumentingAgents, InspectorState* state)
58     : InspectorBaseAgent<InspectorDOMStorageAgent>("DOMStorage", instrumentingAgents, state)
59     , m_frontend(0)
60     , m_enabled(false)
61 {
62     m_instrumentingAgents->setInspectorDOMStorageAgent(this);
63 }
64
65 InspectorDOMStorageAgent::~InspectorDOMStorageAgent()
66 {
67     m_instrumentingAgents->setInspectorDOMStorageAgent(0);
68     m_instrumentingAgents = 0;
69 }
70
71 void InspectorDOMStorageAgent::setFrontend(InspectorFrontend* frontend)
72 {
73     m_frontend = frontend;
74 }
75
76 void InspectorDOMStorageAgent::clearFrontend()
77 {
78     DOMStorageResourcesMap::iterator domStorageEnd = m_resources.end();
79     for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != domStorageEnd; ++it)
80         it->second->unbind();
81     m_frontend = 0;
82     disable(0);
83 }
84
85 void InspectorDOMStorageAgent::restore()
86 {
87     m_enabled =  m_state->getBoolean(DOMStorageAgentState::domStorageAgentEnabled);
88 }
89
90 void InspectorDOMStorageAgent::enable(ErrorString*)
91 {
92     if (m_enabled)
93         return;
94     m_enabled = true;
95     m_state->setBoolean(DOMStorageAgentState::domStorageAgentEnabled, m_enabled);
96
97     DOMStorageResourcesMap::iterator resourcesEnd = m_resources.end();
98     for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it)
99         it->second->bind(m_frontend);
100 }
101
102 void InspectorDOMStorageAgent::disable(ErrorString*)
103 {
104     if (!m_enabled)
105         return;
106     m_enabled = false;
107     m_state->setBoolean(DOMStorageAgentState::domStorageAgentEnabled, m_enabled);
108 }
109
110 void InspectorDOMStorageAgent::getDOMStorageEntries(ErrorString*, const String& storageId, RefPtr<TypeBuilder::Array<TypeBuilder::Array<String> > >& entries)
111 {
112     // FIXME: consider initializing this array after 2 checks below. The checks should return error messages in this case.
113     entries = TypeBuilder::Array<TypeBuilder::Array<String> >::create();
114
115     InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId);
116     if (!storageResource)
117         return;
118     Frame* frame = storageResource->frame();
119     if (!frame)
120         return;
121         
122     StorageArea* storageArea = storageResource->storageArea();
123     for (unsigned i = 0; i < storageArea->length(frame); ++i) {
124         String name(storageArea->key(i, frame));
125         String value(storageArea->getItem(name, frame));
126         RefPtr<TypeBuilder::Array<String> > entry = TypeBuilder::Array<String>::create();
127         entry->addItem(name);
128         entry->addItem(value);
129         entries->addItem(entry);
130     }
131 }
132
133 void InspectorDOMStorageAgent::setDOMStorageItem(ErrorString*, const String& storageId, const String& key, const String& value, bool* success)
134 {
135     InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId);
136     if (storageResource) {
137         ExceptionCode exception = 0;
138         storageResource->storageArea()->setItem(key, value, exception, storageResource->frame());
139         *success = !exception;
140     } else
141         *success = false;
142 }
143
144 void InspectorDOMStorageAgent::removeDOMStorageItem(ErrorString*, const String& storageId, const String& key, bool* success)
145 {
146     InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId);
147     if (storageResource) {
148         storageResource->storageArea()->removeItem(key, storageResource->frame());
149         *success = true;
150     } else
151         *success = false;
152 }
153
154 String InspectorDOMStorageAgent::storageId(Storage* storage)
155 {
156     ASSERT(storage);
157     Frame* frame = storage->frame();
158     ExceptionCode ec = 0;
159     bool isLocalStorage = (frame->document()->domWindow()->localStorage(ec) == storage && !ec);
160     return storageId(frame->document()->securityOrigin(), isLocalStorage);
161 }
162
163 String InspectorDOMStorageAgent::storageId(SecurityOrigin* securityOrigin, bool isLocalStorage)
164 {
165     ASSERT(securityOrigin);
166     DOMStorageResourcesMap::iterator domStorageEnd = m_resources.end();
167     for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != domStorageEnd; ++it) {
168         if (it->second->isSameOriginAndType(securityOrigin, isLocalStorage))
169             return it->first;
170     }
171     return String();
172 }
173
174 InspectorDOMStorageResource* InspectorDOMStorageAgent::getDOMStorageResourceForId(const String& storageId)
175 {
176     DOMStorageResourcesMap::iterator it = m_resources.find(storageId);
177     if (it == m_resources.end())
178         return 0;
179     return it->second.get();
180 }
181
182 void InspectorDOMStorageAgent::didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame)
183 {
184     DOMStorageResourcesMap::iterator domStorageEnd = m_resources.end();
185     for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != domStorageEnd; ++it) {
186         if (it->second->isSameOriginAndType(frame->document()->securityOrigin(), isLocalStorage))
187             return;
188     }
189
190     RefPtr<InspectorDOMStorageResource> resource = InspectorDOMStorageResource::create(storageArea, isLocalStorage, frame);
191
192     m_resources.set(resource->id(), resource);
193
194     // Resources are only bound while visible.
195     if (m_enabled)
196         resource->bind(m_frontend);
197 }
198
199 void InspectorDOMStorageAgent::didDispatchDOMStorageEvent(const String&, const String&, const String&, StorageType storageType, SecurityOrigin* securityOrigin, Page*)
200 {
201     if (!m_frontend || !m_enabled)
202         return;
203
204     String id = storageId(securityOrigin, storageType == LocalStorage);
205
206     if (id.isEmpty())
207         return;
208
209     m_frontend->domstorage()->domStorageUpdated(id);
210 }
211
212 void InspectorDOMStorageAgent::clearResources()
213 {
214     m_resources.clear();
215 }
216
217 size_t InspectorDOMStorageAgent::memoryBytesUsedByStorageCache() const
218 {
219     size_t size = 0;
220     for (DOMStorageResourcesMap::const_iterator it = m_resources.begin(); it != m_resources.end(); ++it)
221         size += it->second->storageArea()->memoryBytesUsedByCache();
222     return size;
223 }
224
225
226 } // namespace WebCore
227
228 #endif // ENABLE(INSPECTOR)