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 #include "InspectorDOMStorageAgent.h"
32
33 #if ENABLE(INSPECTOR) && ENABLE(DOM_STORAGE)
34
35 #include "Database.h"
36 #include "DOMWindow.h"
37 #include "ExceptionCode.h"
38 #include "Frame.h"
39 #include "InspectorDOMStorageResource.h"
40 #include "InspectorFrontend.h"
41 #include "InspectorValues.h"
42 #include "InstrumentingAgents.h"
43 #include "Storage.h"
44 #include "StorageArea.h"
45 #include "VoidCallback.h"
46
47 #include <wtf/Vector.h>
48
49 namespace WebCore {
50
51 typedef HashMap<int, RefPtr<InspectorDOMStorageResource> > DOMStorageResourcesMap;
52
InspectorDOMStorageAgent(InstrumentingAgents * instrumentingAgents)53 InspectorDOMStorageAgent::InspectorDOMStorageAgent(InstrumentingAgents* instrumentingAgents)
54 : m_instrumentingAgents(instrumentingAgents)
55 , m_frontend(0)
56 {
57 m_instrumentingAgents->setInspectorDOMStorageAgent(this);
58 }
59
~InspectorDOMStorageAgent()60 InspectorDOMStorageAgent::~InspectorDOMStorageAgent()
61 {
62 m_instrumentingAgents->setInspectorDOMStorageAgent(0);
63 m_instrumentingAgents = 0;
64 }
65
setFrontend(InspectorFrontend * frontend)66 void InspectorDOMStorageAgent::setFrontend(InspectorFrontend* frontend)
67 {
68 m_frontend = frontend;
69 DOMStorageResourcesMap::iterator resourcesEnd = m_resources.end();
70 for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it)
71 it->second->bind(m_frontend);
72 }
73
clearFrontend()74 void InspectorDOMStorageAgent::clearFrontend()
75 {
76 DOMStorageResourcesMap::iterator domStorageEnd = m_resources.end();
77 for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != domStorageEnd; ++it)
78 it->second->unbind();
79 m_frontend = 0;
80 }
81
getDOMStorageEntries(ErrorString *,int storageId,RefPtr<InspectorArray> * entries)82 void InspectorDOMStorageAgent::getDOMStorageEntries(ErrorString*, int storageId, RefPtr<InspectorArray>* entries)
83 {
84 InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId);
85 if (storageResource) {
86 storageResource->startReportingChangesToFrontend();
87 Storage* domStorage = storageResource->domStorage();
88 for (unsigned i = 0; i < domStorage->length(); ++i) {
89 String name(domStorage->key(i));
90 String value(domStorage->getItem(name));
91 RefPtr<InspectorArray> entry = InspectorArray::create();
92 entry->pushString(name);
93 entry->pushString(value);
94 (*entries)->pushArray(entry);
95 }
96 }
97 }
98
setDOMStorageItem(ErrorString *,int storageId,const String & key,const String & value,bool * success)99 void InspectorDOMStorageAgent::setDOMStorageItem(ErrorString*, int storageId, const String& key, const String& value, bool* success)
100 {
101 InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId);
102 if (storageResource) {
103 ExceptionCode exception = 0;
104 storageResource->domStorage()->setItem(key, value, exception);
105 *success = !exception;
106 }
107 }
108
removeDOMStorageItem(ErrorString *,int storageId,const String & key,bool * success)109 void InspectorDOMStorageAgent::removeDOMStorageItem(ErrorString*, int storageId, const String& key, bool* success)
110 {
111 InspectorDOMStorageResource* storageResource = getDOMStorageResourceForId(storageId);
112 if (storageResource) {
113 storageResource->domStorage()->removeItem(key);
114 *success = true;
115 }
116 }
117
storageId(Storage * storage)118 int InspectorDOMStorageAgent::storageId(Storage* storage)
119 {
120 ASSERT(storage);
121 Frame* frame = storage->frame();
122 ExceptionCode ec = 0;
123 bool isLocalStorage = (frame->domWindow()->localStorage(ec) == storage && !ec);
124 DOMStorageResourcesMap::iterator domStorageEnd = m_resources.end();
125 for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != domStorageEnd; ++it) {
126 if (it->second->isSameHostAndType(frame, isLocalStorage))
127 return it->first;
128 }
129 return 0;
130 }
131
getDOMStorageResourceForId(int storageId)132 InspectorDOMStorageResource* InspectorDOMStorageAgent::getDOMStorageResourceForId(int storageId)
133 {
134 DOMStorageResourcesMap::iterator it = m_resources.find(storageId);
135 if (it == m_resources.end())
136 return 0;
137 return it->second.get();
138 }
139
didUseDOMStorage(StorageArea * storageArea,bool isLocalStorage,Frame * frame)140 void InspectorDOMStorageAgent::didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame)
141 {
142 DOMStorageResourcesMap::iterator domStorageEnd = m_resources.end();
143 for (DOMStorageResourcesMap::iterator it = m_resources.begin(); it != domStorageEnd; ++it) {
144 if (it->second->isSameHostAndType(frame, isLocalStorage))
145 return;
146 }
147
148 RefPtr<Storage> domStorage = Storage::create(frame, storageArea);
149 RefPtr<InspectorDOMStorageResource> resource = InspectorDOMStorageResource::create(domStorage.get(), isLocalStorage, frame);
150
151 m_resources.set(resource->id(), resource);
152
153 // Resources are only bound while visible.
154 if (m_frontend)
155 resource->bind(m_frontend);
156 }
157
clearResources()158 void InspectorDOMStorageAgent::clearResources()
159 {
160 m_resources.clear();
161 }
162
163
164 } // namespace WebCore
165
166 #endif // ENABLE(INSPECTOR) && ENABLE(DOM_STORE)
167