OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "platform/v8_inspector/V8Console.h" | |
6 | |
7 #include "platform/inspector_protocol/String16.h" | |
8 #include "platform/v8_inspector/InspectedContext.h" | |
9 #include "platform/v8_inspector/V8DebuggerImpl.h" | |
10 #include "platform/v8_inspector/V8InspectorSessionImpl.h" | |
11 #include "platform/v8_inspector/V8ProfilerAgentImpl.h" | |
12 #include "platform/v8_inspector/V8StackTraceImpl.h" | |
13 #include "platform/v8_inspector/V8StringUtil.h" | |
14 #include "platform/v8_inspector/public/ConsoleAPITypes.h" | |
15 #include "platform/v8_inspector/public/ConsoleTypes.h" | |
16 #include "platform/v8_inspector/public/V8DebuggerClient.h" | |
17 | |
18 namespace blink { | |
19 | |
20 namespace { | |
21 | |
22 v8::Local<v8::Private> inspectedContextPrivateKey(v8::Isolate* isolate) | |
23 { | |
24 return v8::Private::ForApi(isolate, toV8StringInternalized(isolate, "V8Conso le#InspectedContext")); | |
25 } | |
26 | |
27 class ConsoleScope { | |
dgozman
2016/04/12 23:21:57
ConsoleHelper
kozy
2016/04/12 23:34:25
Done.
| |
28 PROTOCOL_DISALLOW_COPY(ConsoleScope); | |
29 public: | |
30 ConsoleScope(const v8::FunctionCallbackInfo<v8::Value>& info) | |
31 : m_info(info) | |
32 , m_isolate(info.GetIsolate()) | |
33 , m_context(info.GetIsolate()->GetCurrentContext()) | |
34 , m_inspectedContext(nullptr) | |
35 , m_debuggerClient(nullptr) | |
36 { | |
37 } | |
38 | |
39 v8::Local<v8::Object> ensureConsole() | |
40 { | |
41 if (m_console.IsEmpty()) { | |
42 ASSERT(!m_info.Data().IsEmpty()); | |
43 ASSERT(!m_info.Data()->IsUndefined()); | |
44 m_console = m_info.Data().As<v8::Object>(); | |
45 } | |
46 return m_console; | |
47 } | |
48 | |
49 InspectedContext* ensureInspectedContext() | |
50 { | |
51 if (m_inspectedContext) | |
52 return m_inspectedContext; | |
53 v8::Local<v8::Object> console = ensureConsole(); | |
54 | |
55 v8::Local<v8::Private> key = inspectedContextPrivateKey(m_isolate); | |
56 v8::Local<v8::Value> inspectedContextValue; | |
57 if (!console->GetPrivate(m_context, key).ToLocal(&inspectedContextValue) ) | |
58 return nullptr; | |
59 ASSERT(inspectedContextValue->IsExternal()); | |
60 m_inspectedContext = static_cast<InspectedContext*>(inspectedContextValu e.As<v8::External>()->Value()); | |
61 return m_inspectedContext; | |
62 } | |
63 | |
64 V8DebuggerClient* ensureDebuggerClient() | |
65 { | |
66 if (m_debuggerClient) | |
67 return m_debuggerClient; | |
68 InspectedContext* inspectedContext = ensureInspectedContext(); | |
69 if (!inspectedContext) | |
70 return nullptr; | |
71 m_debuggerClient = inspectedContext->debugger()->client(); | |
72 return m_debuggerClient; | |
73 } | |
74 | |
75 void addMessage(MessageType type, MessageLevel level, bool allowEmptyArgumen ts, int skipArgumentCount) | |
76 { | |
77 if (!allowEmptyArguments && !m_info.Length()) | |
78 return; | |
79 if (V8DebuggerClient* debuggerClient = ensureDebuggerClient()) | |
80 debuggerClient->reportMessageToConsole(m_info.GetIsolate()->GetCurre ntContext(), type, level, String16(), &m_info, skipArgumentCount, -1); | |
dgozman
2016/04/12 23:21:57
m_context
kozy
2016/04/12 23:34:25
Done.
| |
81 } | |
82 | |
83 void addMessage(MessageType type, MessageLevel level, const String16& messag e) | |
84 { | |
85 if (V8DebuggerClient* debuggerClient = ensureDebuggerClient()) | |
86 debuggerClient->reportMessageToConsole(m_info.GetIsolate()->GetCurre ntContext(), type, level, message, nullptr, 0, 1); | |
dgozman
2016/04/12 23:21:57
0 /* skipArgumentsCount */, 1 /* maxStackSize */
dgozman
2016/04/12 23:21:58
ditto
kozy
2016/04/12 23:34:25
Done.
kozy
2016/04/12 23:34:26
Done.
| |
87 } | |
88 | |
89 void addDeprecationMessage(const char* id, const String16& message) | |
90 { | |
91 if (checkAndSetPrivateFlagOnConsole(id, false)) | |
92 return; | |
93 if (V8DebuggerClient* debuggerClient = ensureDebuggerClient()) | |
94 debuggerClient->reportMessageToConsole(m_info.GetIsolate()->GetCurre ntContext(), LogMessageType, WarningMessageLevel, message, nullptr, false, 0); | |
dgozman
2016/04/12 23:21:57
0 /* skipArgumentsCount */, 0 /* maxStackSize */
kozy
2016/04/12 23:34:25
Done.
| |
95 } | |
96 | |
97 bool firstArgAsBoolean(bool defaultValue) | |
dgozman
2016/04/12 23:21:57
firstArgToBoolean
kozy
2016/04/12 23:34:25
Done.
| |
98 { | |
99 if (m_info.Length() < 1) | |
100 return defaultValue; | |
101 if (m_info[0]->IsBoolean()) | |
102 return m_info[0].As<v8::Boolean>()->Value(); | |
103 return m_info[0]->BooleanValue(m_info.GetIsolate()->GetCurrentContext()) .FromMaybe(defaultValue); | |
104 } | |
105 | |
106 String16 firstArgAsString(const String16& defaultValue) | |
107 { | |
108 return m_info.Length() > 0 ? toProtocolStringWithTypeCheck(m_info[0]) : defaultValue; | |
109 } | |
110 | |
111 String16 firstArgToString(const String16& defaultValue) | |
112 { | |
113 if (m_info.Length() > 0 && (!m_info[0]->IsNull() || !m_info[0]->IsUndefi ned())) { | |
dgozman
2016/04/12 23:21:57
Let's treat null and undefined as everything else.
kozy
2016/04/12 23:34:25
Done.
| |
114 v8::Local<v8::String> titleValue; | |
115 if (m_info[0]->IsObject()) { | |
116 if (!m_info[0].As<v8::Object>()->ObjectProtoToString(m_context). ToLocal(&titleValue)) | |
117 return defaultValue; | |
118 } else { | |
119 if (!m_info[0]->ToString(m_context).ToLocal(&titleValue)) | |
120 return defaultValue; | |
121 } | |
122 return toProtocolString(titleValue); | |
123 } | |
124 return defaultValue; | |
dgozman
2016/04/12 23:21:57
nit: let's do early bailout
kozy
2016/04/12 23:34:25
Done.
| |
125 } | |
126 | |
127 v8::MaybeLocal<v8::Map> privateMapFromConsole(const char* name) | |
dgozman
2016/04/12 23:21:57
nit: privateMap
kozy
2016/04/12 23:34:26
Done.
| |
128 { | |
129 v8::Local<v8::Object> console = ensureConsole(); | |
130 v8::Local<v8::Private> privateKey = v8::Private::ForApi(m_isolate, toV8S tringInternalized(m_isolate, name)); | |
131 v8::Local<v8::Value> mapValue; | |
132 if (!console->GetPrivate(m_context, privateKey).ToLocal(&mapValue)) | |
133 return v8::MaybeLocal<v8::Map>(); | |
134 if (mapValue->IsUndefined()) { | |
135 v8::Local<v8::Map> map = v8::Map::New(m_isolate); | |
136 if (!console->SetPrivate(m_context, privateKey, map).FromMaybe(false )) | |
137 return v8::MaybeLocal<v8::Map>(); | |
138 return map; | |
139 } | |
140 return mapValue->IsMap() ? mapValue.As<v8::Map>() : v8::MaybeLocal<v8::M ap>(); | |
141 } | |
142 | |
143 int64_t getIntFromMap(v8::Local<v8::Map> map, const String16& key, int64_t d efaultValue) | |
144 { | |
145 v8::Local<v8::String> v8Key = toV8String(m_isolate, key); | |
146 if (!map->Has(m_context, v8Key).FromMaybe(false)) | |
147 return defaultValue; | |
148 v8::Local<v8::Value> intValue; | |
149 if (!map->Get(m_context, v8Key).ToLocal(&intValue)) | |
150 return defaultValue; | |
151 return intValue.As<v8::Integer>()->Value(); | |
152 } | |
153 | |
154 void setIntOnMap(v8::Local<v8::Map> map, const String16& key, int64_t value) | |
155 { | |
156 v8::Local<v8::String> v8Key = toV8String(m_isolate, key); | |
157 if (!map->Set(m_context, v8Key, v8::Integer::New(m_isolate, value)).ToLo cal(&map)) | |
158 return; | |
159 } | |
160 | |
161 double getDoubleFromMap(v8::Local<v8::Map> map, const String16& key, double defaultValue) | |
162 { | |
163 v8::Local<v8::String> v8Key = toV8String(m_isolate, key); | |
164 if (!map->Has(m_context, v8Key).FromMaybe(false)) | |
165 return defaultValue; | |
166 v8::Local<v8::Value> intValue; | |
167 if (!map->Get(m_context, v8Key).ToLocal(&intValue)) | |
168 return defaultValue; | |
169 return intValue.As<v8::Number>()->Value(); | |
170 } | |
171 | |
172 void setDoubleOnMap(v8::Local<v8::Map> map, const String16& key, double valu e) | |
173 { | |
174 v8::Local<v8::String> v8Key = toV8String(m_isolate, key); | |
175 if (!map->Set(m_context, v8Key, v8::Number::New(m_isolate, value)).ToLoc al(&map)) | |
176 return; | |
177 } | |
178 | |
179 V8ProfilerAgentImpl* profileAgent() | |
180 { | |
181 InspectedContext* inspectedContext = ensureInspectedContext(); | |
182 if (!inspectedContext) | |
183 return nullptr; | |
184 V8InspectorSessionImpl* session = inspectedContext->debugger()->sessionF orContextGroup(inspectedContext->contextGroupId()); | |
185 if (session && session->profileAgentImpl()->enabled()) | |
186 return session->profileAgentImpl(); | |
187 return nullptr; | |
188 } | |
189 private: | |
190 const v8::FunctionCallbackInfo<v8::Value>& m_info; | |
191 v8::Isolate* m_isolate; | |
192 v8::Local<v8::Context> m_context; | |
193 v8::Local<v8::Object> m_console; | |
194 InspectedContext* m_inspectedContext; | |
195 V8DebuggerClient* m_debuggerClient; | |
196 | |
197 bool checkAndSetPrivateFlagOnConsole(const char* name, bool defaultValue) | |
198 { | |
199 v8::Local<v8::Object> console = ensureConsole(); | |
200 v8::Local<v8::Private> key = v8::Private::ForApi(m_isolate, toV8StringIn ternalized(m_isolate, name)); | |
201 v8::Local<v8::Value> flagValue; | |
202 if (!console->GetPrivate(m_context, key).ToLocal(&flagValue)) | |
203 return defaultValue; | |
204 ASSERT(flagValue->IsUndefined() || flagValue->IsBoolean()); | |
205 if (flagValue->IsBoolean()) { | |
206 ASSERT(flagValue.As<v8::Boolean>()->Value()); | |
207 return true; | |
208 } | |
209 if (!console->SetPrivate(m_context, key, v8::True(m_isolate)).FromMaybe( false)) | |
210 return defaultValue; | |
211 return false; | |
212 } | |
213 }; | |
214 | |
215 v8::MaybeLocal<v8::Object> createObjectWithClassName(V8DebuggerImpl* debugger, v 8::Local<v8::Context> context, const char* className) | |
216 { | |
217 v8::Isolate* isolate = debugger->isolate(); | |
218 v8::Local<v8::FunctionTemplate> functionTemplate; | |
219 String16 functionTemplateName = String16("V8Console#") + className; | |
220 if (!debugger->functionTemplate(functionTemplateName).ToLocal(&functionTempl ate)) { | |
221 functionTemplate = v8::FunctionTemplate::New(isolate); | |
222 functionTemplate->SetClassName(toV8StringInternalized(isolate, className )); | |
223 debugger->setFunctionTemplate(functionTemplateName, functionTemplate); | |
224 } | |
225 v8::Local<v8::Function> constructor; | |
226 if (!functionTemplate->GetFunction(context).ToLocal(&constructor)) | |
227 return v8::MaybeLocal<v8::Object>(); | |
228 return constructor->NewInstance(context, 0, nullptr); | |
229 } | |
230 | |
231 void createBoundFunctionProperty(v8::Local<v8::Context> context, v8::Local<v8::O bject> obj, v8::Local<v8::Object> prototype, const char* name, v8::FunctionCallb ack callback) | |
232 { | |
233 v8::Local<v8::String> funcName = toV8StringInternalized(context->GetIsolate( ), name); | |
234 v8::Local<v8::Function> func; | |
235 if (!v8::Function::New(context, callback, obj).ToLocal(&func)) | |
236 return; | |
237 func->SetName(funcName); | |
238 if (!prototype->Set(context, funcName, func).FromMaybe(false)) | |
239 return; | |
240 } | |
241 | |
242 } // namespace | |
243 | |
244 void V8Console::debugCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
245 { | |
246 ConsoleScope(info).addMessage(LogMessageType, DebugMessageLevel, false, 0); | |
247 } | |
248 | |
249 void V8Console::errorCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
250 { | |
251 ConsoleScope(info).addMessage(LogMessageType, ErrorMessageLevel, false, 0); | |
252 } | |
253 | |
254 void V8Console::infoCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
255 { | |
256 ConsoleScope(info).addMessage(LogMessageType, InfoMessageLevel, false, 0); | |
257 } | |
258 | |
259 void V8Console::logCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
260 { | |
261 ConsoleScope(info).addMessage(LogMessageType, LogMessageLevel, false, 0); | |
262 } | |
263 | |
264 void V8Console::warnCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
265 { | |
266 ConsoleScope(info).addMessage(LogMessageType, WarningMessageLevel, false, 0) ; | |
267 } | |
268 | |
269 void V8Console::dirCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
270 { | |
271 ConsoleScope(info).addMessage(DirMessageType, LogMessageLevel, false, 0); | |
272 } | |
273 | |
274 void V8Console::dirxmlCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
275 { | |
276 ConsoleScope(info).addMessage(DirXMLMessageType, LogMessageLevel, false, 0); | |
277 } | |
278 | |
279 void V8Console::tableCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
280 { | |
281 ConsoleScope(info).addMessage(TableMessageType, LogMessageLevel, false, 0); | |
282 } | |
283 | |
284 void V8Console::traceCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
285 { | |
286 ConsoleScope(info).addMessage(TraceMessageType, LogMessageLevel, true, 0); | |
287 } | |
288 | |
289 void V8Console::groupCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
290 { | |
291 ConsoleScope(info).addMessage(StartGroupMessageType, LogMessageLevel, true, 0); | |
292 } | |
293 | |
294 void V8Console::groupCollapsedCallback(const v8::FunctionCallbackInfo<v8::Value> & info) | |
295 { | |
296 ConsoleScope(info).addMessage(StartGroupCollapsedMessageType, LogMessageLeve l, true, 0); | |
297 } | |
298 | |
299 void V8Console::groupEndCallback(const v8::FunctionCallbackInfo<v8::Value>& info ) | |
300 { | |
301 ConsoleScope(info).addMessage(EndGroupMessageType, LogMessageLevel, true, 0) ; | |
302 } | |
303 | |
304 void V8Console::clearCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
305 { | |
306 ConsoleScope(info).addMessage(ClearMessageType, LogMessageLevel, true, 0); | |
307 } | |
308 | |
309 void V8Console::countCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
310 { | |
311 ConsoleScope scope(info); | |
312 | |
313 // Follow Firebug's behavior of counting with null and undefined title in | |
dgozman
2016/04/12 23:21:57
This is not true in stable. Let's abandon.
kozy
2016/04/12 23:34:25
Done.
| |
314 // the same bucket as no argument | |
315 String16 title = scope.firstArgToString(String16()); | |
316 String16 identifier; | |
317 if (title.isEmpty()) { | |
318 OwnPtr<V8StackTraceImpl> stackTrace = V8StackTraceImpl::capture(nullptr, 1); | |
319 if (stackTrace) | |
320 identifier = stackTrace->topSourceURL() + ":" + String16::number(sta ckTrace->topLineNumber()); | |
321 } else { | |
322 identifier = title + "@"; | |
323 } | |
324 | |
325 v8::Local<v8::Map> countMap; | |
326 if (!scope.privateMapFromConsole("V8Console#countMap").ToLocal(&countMap)) | |
327 return; | |
328 int64_t count = scope.getIntFromMap(countMap, identifier, 0) + 1; | |
329 scope.setIntOnMap(countMap, identifier, count); | |
330 scope.addMessage(CountMessageType, DebugMessageLevel, title + ": " + String1 6::number(count)); | |
331 } | |
332 | |
333 void V8Console::assertCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
334 { | |
335 ConsoleScope scope(info); | |
336 if (scope.firstArgAsBoolean(false)) | |
337 return; | |
338 scope.addMessage(AssertMessageType, ErrorMessageLevel, true, 1); | |
339 } | |
340 | |
341 void V8Console::markTimelineCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
342 { | |
343 ConsoleScope(info).addDeprecationMessage("V8Console#markTimelineDeprecated", "'console.markTimeline' is deprecated. Please use 'console.timeStamp' instead." ); | |
344 timeStampCallback(info); | |
345 } | |
346 | |
347 void V8Console::profileCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
348 { | |
349 ConsoleScope scope(info); | |
350 if (V8ProfilerAgentImpl* profileAgent = scope.profileAgent()) | |
351 profileAgent->consoleProfile(scope.firstArgAsString(String16())); | |
352 } | |
353 | |
354 void V8Console::profileEndCallback(const v8::FunctionCallbackInfo<v8::Value>& in fo) | |
355 { | |
356 ConsoleScope scope(info); | |
357 if (V8ProfilerAgentImpl* profileAgent = scope.profileAgent()) | |
dgozman
2016/04/12 23:21:57
nit: profilerAgent
kozy
2016/04/12 23:34:25
Done.
| |
358 profileAgent->consoleProfileEnd(scope.firstArgAsString(String16())); | |
359 } | |
360 | |
361 static void timeFunction(const v8::FunctionCallbackInfo<v8::Value>& info, bool t imelinePrefix) | |
362 { | |
363 ConsoleScope scope(info); | |
364 if (V8DebuggerClient* client = scope.ensureDebuggerClient()) { | |
365 String16 protocolTitle = scope.firstArgAsString(String16()); | |
366 if (timelinePrefix) | |
367 protocolTitle = "Timeline '" + protocolTitle + "'"; | |
368 client->consoleTime(protocolTitle); | |
369 | |
370 if (info.Length() < 1) | |
371 return; | |
372 v8::Local<v8::Map> timeMap; | |
373 if (!scope.privateMapFromConsole("V8Console#timeMap").ToLocal(&timeMap)) | |
374 return; | |
375 scope.setDoubleOnMap(timeMap, protocolTitle, client->currentTimeMS()); | |
376 } | |
377 } | |
378 | |
379 static void timeEndFunction(const v8::FunctionCallbackInfo<v8::Value>& info, boo l timelinePrefix) | |
380 { | |
381 ConsoleScope scope(info); | |
382 if (V8DebuggerClient* client = scope.ensureDebuggerClient()) { | |
383 String16 protocolTitle = scope.firstArgAsString(String16()); | |
384 if (timelinePrefix) | |
385 protocolTitle = "Timeline '" + protocolTitle + "'"; | |
386 client->consoleTimeEnd(protocolTitle); | |
387 | |
388 if (info.Length() < 1) | |
389 return; | |
390 v8::Local<v8::Map> timeMap; | |
391 if (!scope.privateMapFromConsole("V8Console#timeMap").ToLocal(&timeMap)) | |
392 return; | |
393 double elapsed = client->currentTimeMS() - scope.getDoubleFromMap(timeMa p, protocolTitle, 0.0); | |
394 String16 message = protocolTitle + ": " + String16::fromDoubleFixedPreci sion(elapsed, 3) + "ms"; | |
395 scope.addMessage(TimeEndMessageType, DebugMessageLevel, message); | |
396 } | |
397 } | |
398 | |
399 void V8Console::timelineCallback(const v8::FunctionCallbackInfo<v8::Value>& info ) | |
400 { | |
401 ConsoleScope(info).addDeprecationMessage("V8Console#timeline", "'console.tim eline' is deprecated. Please use 'console.time' instead."); | |
402 timeFunction(info, true); | |
403 } | |
404 | |
405 void V8Console::timelineEndCallback(const v8::FunctionCallbackInfo<v8::Value>& i nfo) | |
406 { | |
407 ConsoleScope(info).addDeprecationMessage("V8Console#timelineEnd", "'console. timelineEnd' is deprecated. Please use 'console.timeEnd' instead."); | |
408 timeEndFunction(info, true); | |
409 } | |
410 | |
411 void V8Console::timeCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
412 { | |
413 timeFunction(info, false); | |
414 } | |
415 | |
416 void V8Console::timeEndCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
417 { | |
418 timeEndFunction(info, false); | |
419 } | |
420 | |
421 void V8Console::timeStampCallback(const v8::FunctionCallbackInfo<v8::Value>& inf o) | |
422 { | |
423 ConsoleScope scope(info); | |
424 if (V8DebuggerClient* client = scope.ensureDebuggerClient()) | |
425 client->consoleTimeStamp(scope.firstArgAsString(String16())); | |
426 } | |
427 | |
428 void V8Console::memoryGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
429 { | |
430 if (V8DebuggerClient* client = ConsoleScope(info).ensureDebuggerClient()) { | |
431 v8::Local<v8::Value> memoryValue; | |
432 if (!client->memoryInfo(info.GetIsolate(), info.GetIsolate()->GetCurrent Context(), info.Holder()).ToLocal(&memoryValue)) | |
433 return; | |
434 info.GetReturnValue().Set(memoryValue); | |
435 } | |
436 } | |
437 | |
438 void V8Console::memorySetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
439 { | |
440 // We can't make the attribute readonly as it breaks existing code that reli es on being able to assign to console.memory in strict mode. Instead, the setter just ignores the passed value. http://crbug.com/468611 | |
441 } | |
442 | |
443 v8::MaybeLocal<v8::Object> V8Console::create(v8::Local<v8::Context> context, Ins pectedContext* inspectedContext, bool hasMemoryAttribute) | |
444 { | |
445 v8::Isolate* isolate = context->GetIsolate(); | |
446 v8::MicrotasksScope microtasksScope(isolate, v8::MicrotasksScope::kDoNotRunM icrotasks); | |
447 | |
448 v8::Local<v8::Object> console; | |
449 if (!createObjectWithClassName(inspectedContext->debugger(), context, "Conso le").ToLocal(&console)) | |
450 return v8::MaybeLocal<v8::Object>(); | |
451 | |
452 v8::Local<v8::Object> prototype; | |
453 if (!createObjectWithClassName(inspectedContext->debugger(), context, "Conso lePrototype").ToLocal(&prototype)) | |
454 return v8::MaybeLocal<v8::Object>(); | |
455 | |
456 createBoundFunctionProperty(context, console, prototype, "debug", V8Console: :debugCallback); | |
457 createBoundFunctionProperty(context, console, prototype, "error", V8Console: :errorCallback); | |
458 createBoundFunctionProperty(context, console, prototype, "info", V8Console:: infoCallback); | |
459 createBoundFunctionProperty(context, console, prototype, "log", V8Console::l ogCallback); | |
460 createBoundFunctionProperty(context, console, prototype, "warn", V8Console:: warnCallback); | |
461 createBoundFunctionProperty(context, console, prototype, "dir", V8Console::d irCallback); | |
462 createBoundFunctionProperty(context, console, prototype, "dirxml", V8Console ::dirxmlCallback); | |
463 createBoundFunctionProperty(context, console, prototype, "table", V8Console: :tableCallback); | |
464 createBoundFunctionProperty(context, console, prototype, "trace", V8Console: :traceCallback); | |
465 createBoundFunctionProperty(context, console, prototype, "group", V8Console: :groupCallback); | |
466 createBoundFunctionProperty(context, console, prototype, "groupCollapsed", V 8Console::groupCollapsedCallback); | |
467 createBoundFunctionProperty(context, console, prototype, "groupEnd", V8Conso le::groupEndCallback); | |
468 createBoundFunctionProperty(context, console, prototype, "clear", V8Console: :clearCallback); | |
469 createBoundFunctionProperty(context, console, prototype, "count", V8Console: :countCallback); | |
470 createBoundFunctionProperty(context, console, prototype, "assert", V8Console ::assertCallback); | |
471 createBoundFunctionProperty(context, console, prototype, "markTimeline", V8C onsole::markTimelineCallback); | |
472 createBoundFunctionProperty(context, console, prototype, "profile", V8Consol e::profileCallback); | |
473 createBoundFunctionProperty(context, console, prototype, "profileEnd", V8Con sole::profileEndCallback); | |
474 createBoundFunctionProperty(context, console, prototype, "timeline", V8Conso le::timelineCallback); | |
475 createBoundFunctionProperty(context, console, prototype, "timelineEnd", V8Co nsole::timelineEndCallback); | |
476 createBoundFunctionProperty(context, console, prototype, "time", V8Console:: timeCallback); | |
477 createBoundFunctionProperty(context, console, prototype, "timeEnd", V8Consol e::timeEndCallback); | |
478 createBoundFunctionProperty(context, console, prototype, "timeStamp", V8Cons ole::timeStampCallback); | |
479 | |
480 if (!console->SetPrototype(context, prototype).FromMaybe(false)) | |
481 return v8::MaybeLocal<v8::Object>(); | |
482 | |
483 if (hasMemoryAttribute) | |
484 console->SetAccessorProperty(toV8StringInternalized(isolate, "memory"), v8::Function::New(isolate, V8Console::memoryGetterCallback, console), v8::Functi on::New(isolate, V8Console::memorySetterCallback), static_cast<v8::PropertyAttri bute>(v8::None), v8::DEFAULT); | |
485 | |
486 console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::Extern al::New(isolate, inspectedContext)); | |
487 return console; | |
488 } | |
489 | |
490 } // namespace blink | |
OLD | NEW |