Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / core / v8 / DOMWrapperWorld.cpp
1 /*
2  * Copyright (C) 2009 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 are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "bindings/core/v8/DOMWrapperWorld.h"
33
34 #include "bindings/core/v8/DOMDataStore.h"
35 #include "bindings/core/v8/ScriptController.h"
36 #include "bindings/core/v8/V8Binding.h"
37 #include "bindings/core/v8/V8DOMActivityLogger.h"
38 #include "bindings/core/v8/V8DOMWrapper.h"
39 #include "bindings/core/v8/V8Window.h"
40 #include "bindings/core/v8/WindowProxy.h"
41 #include "bindings/core/v8/WrapperTypeInfo.h"
42 #include "core/dom/ExecutionContext.h"
43 #include "wtf/HashTraits.h"
44 #include "wtf/StdLibExtras.h"
45
46 namespace blink {
47
48 unsigned DOMWrapperWorld::isolatedWorldCount = 0;
49 DOMWrapperWorld* DOMWrapperWorld::worldOfInitializingWindow = 0;
50
51 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::create(int worldId, int extensionGroup)
52 {
53     return adoptRef(new DOMWrapperWorld(worldId, extensionGroup));
54 }
55
56 DOMWrapperWorld::DOMWrapperWorld(int worldId, int extensionGroup)
57     : m_worldId(worldId)
58     , m_extensionGroup(extensionGroup)
59     , m_domDataStore(adoptPtr(new DOMDataStore(isMainWorld())))
60 {
61 }
62
63 DOMWrapperWorld& DOMWrapperWorld::mainWorld()
64 {
65     ASSERT(isMainThread());
66     DEFINE_STATIC_REF(DOMWrapperWorld, cachedMainWorld, (DOMWrapperWorld::create(MainWorldId, mainWorldExtensionGroup)));
67     return *cachedMainWorld;
68 }
69
70 DOMWrapperWorld& DOMWrapperWorld::privateScriptIsolatedWorld()
71 {
72     ASSERT(isMainThread());
73     DEFINE_STATIC_LOCAL(RefPtr<DOMWrapperWorld>, cachedPrivateScriptIsolatedWorld, ());
74     if (!cachedPrivateScriptIsolatedWorld) {
75         cachedPrivateScriptIsolatedWorld = DOMWrapperWorld::create(PrivateScriptIsolatedWorldId, privateScriptIsolatedWorldExtensionGroup);
76         isolatedWorldCount++;
77     }
78     return *cachedPrivateScriptIsolatedWorld;
79 }
80
81 typedef HashMap<int, DOMWrapperWorld*> WorldMap;
82 static WorldMap& isolatedWorldMap()
83 {
84     ASSERT(isMainThread());
85     DEFINE_STATIC_LOCAL(WorldMap, map, ());
86     return map;
87 }
88
89 void DOMWrapperWorld::allWorldsInMainThread(Vector<RefPtr<DOMWrapperWorld> >& worlds)
90 {
91     ASSERT(isMainThread());
92     worlds.append(&mainWorld());
93     WorldMap& isolatedWorlds = isolatedWorldMap();
94     for (WorldMap::iterator it = isolatedWorlds.begin(); it != isolatedWorlds.end(); ++it)
95         worlds.append(it->value);
96 }
97
98 DOMWrapperWorld::~DOMWrapperWorld()
99 {
100     ASSERT(!isMainWorld());
101
102     dispose();
103
104     if (!isIsolatedWorld())
105         return;
106
107     WorldMap& map = isolatedWorldMap();
108     WorldMap::iterator it = map.find(m_worldId);
109     if (it == map.end()) {
110         ASSERT_NOT_REACHED();
111         return;
112     }
113     ASSERT(it->value == this);
114
115     map.remove(it);
116     isolatedWorldCount--;
117 }
118
119 void DOMWrapperWorld::dispose()
120 {
121     m_domObjectHolders.clear();
122     m_domDataStore.clear();
123 }
124
125 #if ENABLE(ASSERT)
126 static bool isIsolatedWorldId(int worldId)
127 {
128     return MainWorldId < worldId  && worldId < IsolatedWorldIdLimit;
129 }
130 #endif
131
132 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::ensureIsolatedWorld(int worldId, int extensionGroup)
133 {
134     ASSERT(isIsolatedWorldId(worldId));
135
136     WorldMap& map = isolatedWorldMap();
137     WorldMap::AddResult result = map.add(worldId, 0);
138     RefPtr<DOMWrapperWorld> world = result.storedValue->value;
139     if (world) {
140         ASSERT(world->worldId() == worldId);
141         ASSERT(world->extensionGroup() == extensionGroup);
142         return world.release();
143     }
144
145     world = DOMWrapperWorld::create(worldId, extensionGroup);
146     result.storedValue->value = world.get();
147     isolatedWorldCount++;
148     return world.release();
149 }
150
151 typedef HashMap<int, RefPtr<SecurityOrigin> > IsolatedWorldSecurityOriginMap;
152 static IsolatedWorldSecurityOriginMap& isolatedWorldSecurityOrigins()
153 {
154     ASSERT(isMainThread());
155     DEFINE_STATIC_LOCAL(IsolatedWorldSecurityOriginMap, map, ());
156     return map;
157 }
158
159 SecurityOrigin* DOMWrapperWorld::isolatedWorldSecurityOrigin()
160 {
161     ASSERT(this->isIsolatedWorld());
162     IsolatedWorldSecurityOriginMap& origins = isolatedWorldSecurityOrigins();
163     IsolatedWorldSecurityOriginMap::iterator it = origins.find(worldId());
164     return it == origins.end() ? 0 : it->value.get();
165 }
166
167 void DOMWrapperWorld::setIsolatedWorldSecurityOrigin(int worldId, PassRefPtr<SecurityOrigin> securityOrigin)
168 {
169     ASSERT(isIsolatedWorldId(worldId));
170     if (securityOrigin)
171         isolatedWorldSecurityOrigins().set(worldId, securityOrigin);
172     else
173         isolatedWorldSecurityOrigins().remove(worldId);
174 }
175
176 typedef HashMap<int, String > IsolatedWorldHumanReadableNameMap;
177 static IsolatedWorldHumanReadableNameMap& isolatedWorldHumanReadableNames()
178 {
179     ASSERT(isMainThread());
180     DEFINE_STATIC_LOCAL(IsolatedWorldHumanReadableNameMap, map, ());
181     return map;
182 }
183
184 String DOMWrapperWorld::isolatedWorldHumanReadableName()
185 {
186     ASSERT(this->isIsolatedWorld());
187     return isolatedWorldHumanReadableNames().get(worldId());
188 }
189
190 void DOMWrapperWorld::setIsolatedWorldHumanReadableName(int worldId, const String& humanReadableName)
191 {
192     ASSERT(isIsolatedWorldId(worldId));
193     isolatedWorldHumanReadableNames().set(worldId, humanReadableName);
194 }
195
196 typedef HashMap<int, bool> IsolatedWorldContentSecurityPolicyMap;
197 static IsolatedWorldContentSecurityPolicyMap& isolatedWorldContentSecurityPolicies()
198 {
199     ASSERT(isMainThread());
200     DEFINE_STATIC_LOCAL(IsolatedWorldContentSecurityPolicyMap, map, ());
201     return map;
202 }
203
204 bool DOMWrapperWorld::isolatedWorldHasContentSecurityPolicy()
205 {
206     ASSERT(this->isIsolatedWorld());
207     IsolatedWorldContentSecurityPolicyMap& policies = isolatedWorldContentSecurityPolicies();
208     IsolatedWorldContentSecurityPolicyMap::iterator it = policies.find(worldId());
209     return it == policies.end() ? false : it->value;
210 }
211
212 void DOMWrapperWorld::setIsolatedWorldContentSecurityPolicy(int worldId, const String& policy)
213 {
214     ASSERT(isIsolatedWorldId(worldId));
215     if (!policy.isEmpty())
216         isolatedWorldContentSecurityPolicies().set(worldId, true);
217     else
218         isolatedWorldContentSecurityPolicies().remove(worldId);
219 }
220
221 void DOMWrapperWorld::registerDOMObjectHolderInternal(PassOwnPtr<DOMObjectHolderBase> holderBase)
222 {
223     ASSERT(!m_domObjectHolders.contains(holderBase.get()));
224     holderBase->setWorld(this);
225     holderBase->setWeak(&DOMWrapperWorld::weakCallbackForDOMObjectHolder);
226     m_domObjectHolders.add(holderBase);
227 }
228
229 void DOMWrapperWorld::unregisterDOMObjectHolder(DOMObjectHolderBase* holderBase)
230 {
231     ASSERT(m_domObjectHolders.contains(holderBase));
232     m_domObjectHolders.remove(holderBase);
233 }
234
235 void DOMWrapperWorld::weakCallbackForDOMObjectHolder(const v8::WeakCallbackData<v8::Value, DOMObjectHolderBase>& data)
236 {
237     DOMObjectHolderBase* holderBase = data.GetParameter();
238     holderBase->world()->unregisterDOMObjectHolder(holderBase);
239 }
240
241 } // namespace blink