7#include "../../third_party/inspector_protocol/crdtp/json.h"
24using protocol::Runtime::CustomPreview;
30 V8InspectorImpl* inspector =
33 int groupId = inspector->contextGroupId(contextId);
35 if (!tryCatch.
Message().IsEmpty()) message = tryCatch.
Message()->Get();
37 toV8String(isolate,
"Custom Formatter Failed: ");
40 arguments.push_back(message);
41 V8ConsoleMessageStorage* storage =
42 inspector->ensureConsoleMessageStorage(groupId);
45 context, contextId, groupId, inspector,
47 {arguments.begin(), arguments.end()}, String16(),
nullptr));
51 const String16& message) {
54 reportError(context, tryCatch);
60 V8InspectorImpl* inspector =
62 InspectedContext* inspectedContext =
64 if (!inspectedContext)
return nullptr;
65 return inspectedContext->getInjectedScript(sessionId);
68bool substituteObjectTags(
int sessionId,
const String16& groupName,
71 if (!jsonML->Length())
return true;
76 reportError(context, tryCatch,
77 "Too deep hierarchy of inlined custom previews");
82 if (!jsonML->Get(context, 0).ToLocal(&firstValue)) {
83 reportError(context, tryCatch);
87 if (jsonML->Length() == 2 && firstValue->IsString() &&
90 if (!jsonML->Get(context, 1).ToLocal(&attributesValue)) {
91 reportError(context, tryCatch);
94 if (!attributesValue->IsObject()) {
95 reportError(context, tryCatch,
"attributes should be an Object");
100 if (!attributes->Get(context, objectLiteral).ToLocal(&originValue)) {
101 reportError(context, tryCatch);
104 if (originValue->IsUndefined()) {
105 reportError(context, tryCatch,
106 "obligatory attribute \"object\" isn't specified");
111 if (!attributes->Get(context,
toV8String(isolate,
"config"))
113 reportError(context, tryCatch);
117 InjectedScript* injectedScript = getInjectedScript(context, sessionId);
118 if (!injectedScript) {
119 reportError(context, tryCatch,
"cannot find context with specified id");
122 std::unique_ptr<protocol::Runtime::RemoteObject> wrapper;
123 protocol::Response response = injectedScript->wrapObject(
125 maxDepth - 1, &wrapper);
126 if (!response.IsSuccess() || !wrapper) {
127 reportError(context, tryCatch,
"cannot wrap value");
130 std::vector<uint8_t> json;
131 v8_crdtp::json::ConvertCBORToJSON(v8_crdtp::SpanFrom(wrapper->Serialize()),
137 reportError(context, tryCatch,
"cannot wrap value");
140 if (jsonML->Set(context, 1, jsonWrapper).IsNothing()) {
141 reportError(context, tryCatch);
145 for (uint32_t
i = 0;
i < jsonML->Length(); ++
i) {
147 if (!jsonML->Get(context,
i).ToLocal(&value)) {
148 reportError(context, tryCatch);
152 !substituteObjectTags(sessionId, groupName, context,
168 if (!bodyConfig->Get(context,
toV8String(isolate,
"object"))
170 reportError(context, tryCatch);
173 if (!objectValue->IsObject()) {
174 reportError(context, tryCatch,
"object should be an Object");
180 if (!bodyConfig->Get(context,
toV8String(isolate,
"formatter"))
182 reportError(context, tryCatch);
185 if (!formatterValue->IsObject()) {
186 reportError(context, tryCatch,
"formatter should be an Object");
192 if (!formatter->Get(context,
toV8String(isolate,
"body"))
194 reportError(context, tryCatch);
197 if (!bodyValue->IsFunction()) {
198 reportError(context, tryCatch,
"body should be a Function");
204 if (!bodyConfig->Get(context,
toV8String(isolate,
"config"))
206 reportError(context, tryCatch);
211 if (!bodyConfig->Get(context,
toV8String(isolate,
"sessionId"))
213 reportError(context, tryCatch);
216 if (!sessionIdValue->IsInt32()) {
217 reportError(context, tryCatch,
"sessionId should be an Int32");
222 if (!bodyConfig->Get(context,
toV8String(isolate,
"groupName"))
224 reportError(context, tryCatch);
227 if (!groupNameValue->IsString()) {
228 reportError(context, tryCatch,
"groupName should be a string");
234 if (!bodyFunction->Call(context, formatter, 2,
args)
235 .ToLocal(&formattedValue)) {
236 reportError(context, tryCatch);
239 if (formattedValue->IsNull()) {
240 info.GetReturnValue().Set(formattedValue);
243 if (!formattedValue->IsArray()) {
244 reportError(context, tryCatch,
"body should return an Array");
248 if (jsonML->Length() &&
249 !substituteObjectTags(
255 info.GetReturnValue().
Set(jsonML);
263 std::unique_ptr<CustomPreview>* preview) {
265 if (!object->GetCreationContext(isolate).ToLocal(&context)) {
278 if (!global->Get(context,
toV8String(isolate,
"devtoolsFormatters"))
279 .ToLocal(&formattersValue)) {
280 reportError(context, tryCatch);
283 if (!formattersValue->IsArray())
return;
287 for (uint32_t
i = 0;
i < formatters->Length(); ++
i) {
289 if (!formatters->Get(context,
i).ToLocal(&formatterValue)) {
290 reportError(context, tryCatch);
293 if (!formatterValue->IsObject()) {
294 reportError(context, tryCatch,
"formatter should be an Object");
300 if (!formatter->Get(context, headerLiteral).ToLocal(&headerValue)) {
301 reportError(context, tryCatch);
304 if (!headerValue->IsFunction()) {
305 reportError(context, tryCatch,
"header should be a Function");
312 if (!headerFunction->Call(context, formatter, 2,
args)
313 .ToLocal(&formattedValue)) {
314 reportError(context, tryCatch);
317 if (!formattedValue->IsArray())
continue;
321 if (!formatter->Get(context, hasBodyLiteral)
322 .ToLocal(&hasBodyFunctionValue)) {
323 reportError(context, tryCatch);
326 if (!hasBodyFunctionValue->IsFunction())
continue;
330 if (!hasBodyFunction->Call(context, formatter, 2,
args)
331 .ToLocal(&hasBodyValue)) {
332 reportError(context, tryCatch);
335 bool hasBody = hasBodyValue->ToBoolean(isolate)->Value();
337 if (jsonML->Length() && !substituteObjectTags(sessionId, groupName, context,
344 reportError(context, tryCatch);
352 ->CreateDataProperty(context,
toV8String(isolate,
"sessionId"),
355 reportError(context, tryCatch);
359 ->CreateDataProperty(context,
toV8String(isolate,
"formatter"),
362 reportError(context, tryCatch);
366 ->CreateDataProperty(context,
toV8String(isolate,
"groupName"),
369 reportError(context, tryCatch);
373 ->CreateDataProperty(context,
toV8String(isolate,
"config"),
376 reportError(context, tryCatch);
380 ->CreateDataProperty(context,
toV8String(isolate,
"object"),
383 reportError(context, tryCatch);
387 .ToLocal(&bodyFunction)) {
388 reportError(context, tryCatch);
392 *preview = CustomPreview::create()
396 InjectedScript* injectedScript = getInjectedScript(context, sessionId);
397 if (!injectedScript) {
398 reportError(context, tryCatch,
"cannot find context with specified id");
401 (*preview)->setBodyGetterId(
402 injectedScript->
bindObject(bodyFunction, groupName));
static MaybeLocal< Function > New(Local< Context > context, FunctionCallback callback, Local< Value > data=Local< Value >(), int length=0, ConstructorBehavior behavior=ConstructorBehavior::kAllow, SideEffectType side_effect_type=SideEffectType::kHasSideEffect)
static Local< Integer > New(Isolate *isolate, int32_t value)
Local< Value > ThrowException(Local< Value > exception)
static V8_WARN_UNUSED_RESULT MaybeLocal< String > Stringify(Local< Context > context, Local< Value > json_object, Local< String > gap=Local< String >())
static V8_WARN_UNUSED_RESULT MaybeLocal< Value > Parse(Local< Context > context, Local< String > json_string)
V8_INLINE Local< S > As() const
V8_WARN_UNUSED_RESULT V8_INLINE bool ToLocal(Local< S > *out) const
static Local< Object > New(Isolate *isolate)
V8_WARN_UNUSED_RESULT Maybe< bool > Set(Local< Context > context, Local< Value > key, Local< Value > value)
bool StringEquals(Local< String > str) const
static Local< String > Concat(Isolate *isolate, Local< String > left, Local< String > right)
Local< v8::Message > Message() const
V8_INLINE bool IsEmpty() const
String16 bindObject(v8::Local< v8::Value >, const String16 &groupName)
static std::unique_ptr< V8ConsoleMessage > createForConsoleAPI(v8::Local< v8::Context > v8Context, int contextId, int groupId, V8InspectorImpl *inspector, double timestamp, ConsoleAPIType, v8::MemorySpan< const v8::Local< v8::Value > > arguments, const String16 &consoleContext, std::unique_ptr< V8StackTraceImpl >)
base::Vector< const DirectHandle< Object > > args
v8_inspector::V8Inspector * GetInspector(Isolate *isolate)
void generateCustomPreview(v8::Isolate *isolate, int sessionId, const String16 &groupName, v8::Local< v8::Object > object, v8::MaybeLocal< v8::Value > maybeConfig, int maxDepth, std::unique_ptr< CustomPreview > *preview)
String16 toProtocolString(v8::Isolate *isolate, v8::Local< v8::String > value)
const int kMaxCustomPreviewDepth
v8::Local< v8::String > toV8String(v8::Isolate *isolate, const String16 &string)
bool ToLocal(v8::internal::MaybeDirectHandle< v8::internal::Object > maybe, Local< T > *local)
V8_INLINE Local< Primitive > Undefined(Isolate *isolate)
#define DCHECK(condition)
std::unique_ptr< ValueMirror > value