OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. | |
3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> | |
4 * Copyright (C) 2012 Google Inc. All rights reserved. | |
5 * | |
6 * Redistribution and use in source and binary forms, with or without | |
7 * modification, are permitted provided that the following conditions | |
8 * are met: | |
9 * | |
10 * 1. Redistributions of source code must retain the above copyright | |
11 * notice, this list of conditions and the following disclaimer. | |
12 * 2. Redistributions in binary form must reproduce the above copyright | |
13 * notice, this list of conditions and the following disclaimer in the | |
14 * documentation and/or other materials provided with the distribution. | |
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of | |
16 * its contributors may be used to endorse or promote products derived | |
17 * from this software without specific prior written permission. | |
18 * | |
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | |
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | |
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 #include "core/inspector/InjectedScriptManager.h" | |
32 | |
33 #include "bindings/core/v8/V8Binding.h" | |
34 #include "core/inspector/InjectedScript.h" | |
35 #include "core/inspector/InjectedScriptHost.h" | |
36 #include "core/inspector/InjectedScriptNative.h" | |
37 #include "core/inspector/RemoteObjectId.h" | |
38 #include "core/inspector/v8/V8Debugger.h" | |
39 #include "core/inspector/v8/V8DebuggerClient.h" | |
40 #include "core/inspector/v8/V8InjectedScriptHost.h" | |
41 #include "public/platform/Platform.h" | |
42 #include "public/platform/WebData.h" | |
43 #include "wtf/PassOwnPtr.h" | |
44 | |
45 namespace blink { | |
46 | |
47 PassOwnPtr<InjectedScriptManager> InjectedScriptManager::create(V8DebuggerClient
* client) | |
48 { | |
49 return adoptPtr(new InjectedScriptManager(client)); | |
50 } | |
51 | |
52 InjectedScriptManager::InjectedScriptManager(V8DebuggerClient* client) | |
53 : m_injectedScriptHost(InjectedScriptHost::create()) | |
54 , m_customObjectFormatterEnabled(false) | |
55 , m_client(client) | |
56 { | |
57 } | |
58 | |
59 InjectedScriptManager::~InjectedScriptManager() | |
60 { | |
61 } | |
62 | |
63 void InjectedScriptManager::disconnect() | |
64 { | |
65 m_injectedScriptHost->disconnect(); | |
66 m_injectedScriptHost.clear(); | |
67 } | |
68 | |
69 InjectedScriptHost* InjectedScriptManager::injectedScriptHost() | |
70 { | |
71 return m_injectedScriptHost.get(); | |
72 } | |
73 | |
74 InjectedScript* InjectedScriptManager::findInjectedScript(int id) const | |
75 { | |
76 IdToInjectedScriptMap::const_iterator it = m_idToInjectedScript.find(id); | |
77 if (it != m_idToInjectedScript.end()) | |
78 return it->value.get(); | |
79 return nullptr; | |
80 } | |
81 | |
82 InjectedScript* InjectedScriptManager::findInjectedScript(RemoteObjectIdBase* ob
jectId) const | |
83 { | |
84 return objectId ? findInjectedScript(objectId->contextId()) : nullptr; | |
85 } | |
86 | |
87 void InjectedScriptManager::discardInjectedScripts() | |
88 { | |
89 m_idToInjectedScript.clear(); | |
90 } | |
91 | |
92 int InjectedScriptManager::discardInjectedScriptFor(v8::Local<v8::Context> conte
xt) | |
93 { | |
94 int contextId = V8Debugger::contextId(context); | |
95 discardInjectedScript(contextId); | |
96 return contextId; | |
97 } | |
98 | |
99 void InjectedScriptManager::discardInjectedScript(int contextId) | |
100 { | |
101 m_idToInjectedScript.remove(contextId); | |
102 } | |
103 | |
104 void InjectedScriptManager::releaseObjectGroup(const String& objectGroup) | |
105 { | |
106 Vector<int> keys; | |
107 keys.appendRange(m_idToInjectedScript.keys().begin(), m_idToInjectedScript.k
eys().end()); | |
108 for (auto& key : keys) { | |
109 IdToInjectedScriptMap::iterator s = m_idToInjectedScript.find(key); | |
110 if (s != m_idToInjectedScript.end()) | |
111 s->value->releaseObjectGroup(objectGroup); // m_idToInjectedScript m
ay change here. | |
112 } | |
113 } | |
114 | |
115 void InjectedScriptManager::setCustomObjectFormatterEnabled(bool enabled) | |
116 { | |
117 m_customObjectFormatterEnabled = enabled; | |
118 IdToInjectedScriptMap::iterator end = m_idToInjectedScript.end(); | |
119 for (IdToInjectedScriptMap::iterator it = m_idToInjectedScript.begin(); it !
= end; ++it) { | |
120 it->value->setCustomObjectFormatterEnabled(enabled); | |
121 } | |
122 } | |
123 | |
124 InjectedScript* InjectedScriptManager::injectedScriptFor(v8::Local<v8::Context>
context) | |
125 { | |
126 v8::Context::Scope scope(context); | |
127 int contextId = V8Debugger::contextId(context); | |
128 | |
129 IdToInjectedScriptMap::iterator it = m_idToInjectedScript.find(contextId); | |
130 if (it != m_idToInjectedScript.end()) | |
131 return it->value.get(); | |
132 | |
133 v8::Local<v8::Context> callingContext = context->GetIsolate()->GetCallingCon
text(); | |
134 if (!callingContext.IsEmpty() && !m_client->callingContextCanAccessContext(c
allingContext, context)) | |
135 return nullptr; | |
136 | |
137 RefPtr<InjectedScriptNative> injectedScriptNative = adoptRef(new InjectedScr
iptNative(context->GetIsolate())); | |
138 | |
139 const WebData& injectedScriptSourceResource = Platform::current()->loadResou
rce("InjectedScriptSource.js"); | |
140 String injectedScriptSource(injectedScriptSourceResource.data(), injectedScr
iptSourceResource.size()); | |
141 | |
142 v8::Local<v8::Object> object = createInjectedScript(injectedScriptSource, co
ntext, contextId, injectedScriptNative.get()); | |
143 OwnPtr<InjectedScript> result = adoptPtr(new InjectedScript(this, context, o
bject, m_client, injectedScriptNative.release(), contextId)); | |
144 InjectedScript* resultPtr = result.get(); | |
145 if (m_customObjectFormatterEnabled) | |
146 result->setCustomObjectFormatterEnabled(m_customObjectFormatterEnabled); | |
147 m_idToInjectedScript.set(contextId, result.release()); | |
148 return resultPtr; | |
149 } | |
150 | |
151 v8::Local<v8::Object> InjectedScriptManager::createInjectedScript(const String&
scriptSource, v8::Local<v8::Context> context, int id, InjectedScriptNative* inje
ctedScriptNative) | |
152 { | |
153 v8::Isolate* isolate = context->GetIsolate(); | |
154 v8::Context::Scope scope(context); | |
155 | |
156 v8::Local<v8::FunctionTemplate> wrapperTemplate = m_injectedScriptHost->wrap
perTemplate(isolate); | |
157 if (wrapperTemplate.IsEmpty()) { | |
158 wrapperTemplate = V8InjectedScriptHost::createWrapperTemplate(isolate); | |
159 m_injectedScriptHost->setWrapperTemplate(wrapperTemplate, isolate); | |
160 } | |
161 | |
162 v8::Local<v8::Object> scriptHostWrapper = V8InjectedScriptHost::wrap(wrapper
Template, context, m_injectedScriptHost); | |
163 if (scriptHostWrapper.IsEmpty()) | |
164 return v8::Local<v8::Object>(); | |
165 | |
166 injectedScriptNative->setOnInjectedScriptHost(scriptHostWrapper); | |
167 | |
168 // Inject javascript into the context. The compiled script is supposed to ev
aluate into | |
169 // a single anonymous function(it's anonymous to avoid cluttering the global
object with | |
170 // inspector's stuff) the function is called a few lines below with Injected
ScriptHost wrapper, | |
171 // injected script id and explicit reference to the inspected global object.
The function is expected | |
172 // to create and configure InjectedScript instance that is going to be used
by the inspector. | |
173 v8::Local<v8::Value> value; | |
174 if (!m_client->compileAndRunInternalScript(scriptSource).ToLocal(&value)) | |
175 return v8::Local<v8::Object>(); | |
176 ASSERT(value->IsFunction()); | |
177 | |
178 v8::Local<v8::Object> windowGlobal = context->Global(); | |
179 v8::Local<v8::Value> info[] = { scriptHostWrapper, windowGlobal, v8::Number:
:New(context->GetIsolate(), id) }; | |
180 v8::Local<v8::Value> injectedScriptValue; | |
181 if (!m_client->callInternalFunction(v8::Local<v8::Function>::Cast(value), wi
ndowGlobal, WTF_ARRAY_LENGTH(info), info).ToLocal(&injectedScriptValue)) | |
182 return v8::Local<v8::Object>(); | |
183 if (!injectedScriptValue->IsObject()) | |
184 return v8::Local<v8::Object>(); | |
185 return injectedScriptValue.As<v8::Object>(); | |
186 } | |
187 | |
188 } // namespace blink | |
OLD | NEW |