void InjectedScript::getProperties(ErrorString* errorString, v8::Local<v8::Object> object, const String16& groupName, bool ownProperties, bool accessorPropertiesOnly, bool generatePreview, std::unique_ptr<Array<PropertyDescriptor>>* properties, Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { v8::HandleScope handles(m_context->isolate()); V8FunctionCall function(m_context->inspector(), m_context->context(), v8Value(), "getProperties"); function.appendArgument(object); function.appendArgument(groupName); function.appendArgument(ownProperties); function.appendArgument(accessorPropertiesOnly); function.appendArgument(generatePreview); v8::TryCatch tryCatch(m_context->isolate()); v8::Local<v8::Value> resultValue = function.callWithoutExceptionHandling(); if (tryCatch.HasCaught()) { *exceptionDetails = createExceptionDetails(tryCatch.Message()); // FIXME: make properties optional *properties = Array<PropertyDescriptor>::create(); return; } std::unique_ptr<protocol::Value> protocolValue = toProtocolValue(m_context->context(), resultValue); if (hasInternalError(errorString, !protocolValue)) return; protocol::ErrorSupport errors(errorString); std::unique_ptr<Array<PropertyDescriptor>> result = Array<PropertyDescriptor>::parse(protocolValue.get(), &errors); if (!hasInternalError(errorString, errors.hasErrors())) *properties = std::move(result); }
std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable(v8::Local<v8::Value> table, v8::Local<v8::Value> columns) const { v8::HandleScope handles(m_context->isolate()); V8FunctionCall function(m_context->inspector(), m_context->context(), v8Value(), "wrapTable"); function.appendArgument(table); if (columns.IsEmpty()) function.appendArgument(false); else function.appendArgument(columns); bool hadException = false; v8::Local<v8::Value> r = function.call(hadException); if (hadException) return nullptr; protocol::ErrorSupport errors; return protocol::Runtime::RemoteObject::parse(toProtocolValue(m_context->context(), r).get(), &errors); }
std::unique_ptr<protocol::Value> toProtocolValue(v8::Local<v8::Context> context, v8::Local<v8::Value> value, int maxDepth) { if (value.IsEmpty()) { NOTREACHED(); return nullptr; } if (!maxDepth) return nullptr; maxDepth--; if (value->IsNull() || value->IsUndefined()) return protocol::Value::null(); if (value->IsBoolean()) return protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value()); if (value->IsNumber()) return protocol::FundamentalValue::create(value.As<v8::Number>()->Value()); if (value->IsString()) return protocol::StringValue::create(toProtocolString(value.As<v8::String>())); if (value->IsArray()) { v8::Local<v8::Array> array = value.As<v8::Array>(); std::unique_ptr<protocol::ListValue> inspectorArray = protocol::ListValue::create(); uint32_t length = array->Length(); for (uint32_t i = 0; i < length; i++) { v8::Local<v8::Value> value; if (!array->Get(context, i).ToLocal(&value)) return nullptr; std::unique_ptr<protocol::Value> element = toProtocolValue(context, value, maxDepth); if (!element) return nullptr; inspectorArray->pushValue(std::move(element)); } return std::move(inspectorArray); } if (value->IsObject()) { std::unique_ptr<protocol::DictionaryValue> jsonObject = protocol::DictionaryValue::create(); v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value); v8::Local<v8::Array> propertyNames; if (!object->GetPropertyNames(context).ToLocal(&propertyNames)) return nullptr; uint32_t length = propertyNames->Length(); for (uint32_t i = 0; i < length; i++) { v8::Local<v8::Value> name; if (!propertyNames->Get(context, i).ToLocal(&name)) return nullptr; // FIXME(yurys): v8::Object should support GetOwnPropertyNames if (name->IsString()) { v8::Maybe<bool> hasRealNamedProperty = object->HasRealNamedProperty(context, v8::Local<v8::String>::Cast(name)); if (!hasRealNamedProperty.IsJust() || !hasRealNamedProperty.FromJust()) continue; } v8::Local<v8::String> propertyName; if (!name->ToString(context).ToLocal(&propertyName)) continue; v8::Local<v8::Value> property; if (!object->Get(context, name).ToLocal(&property)) return nullptr; std::unique_ptr<protocol::Value> propertyValue = toProtocolValue(context, property, maxDepth); if (!propertyValue) return nullptr; jsonObject->setValue(toProtocolString(propertyName), std::move(propertyValue)); } return std::move(jsonObject); } NOTREACHED(); return nullptr; }
std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapObject(ErrorString* errorString, v8::Local<v8::Value> value, const String16& groupName, bool forceValueType, bool generatePreview) const { v8::HandleScope handles(m_context->isolate()); v8::Local<v8::Value> wrappedObject; if (!wrapValue(errorString, value, groupName, forceValueType, generatePreview).ToLocal(&wrappedObject)) return nullptr; protocol::ErrorSupport errors; std::unique_ptr<protocol::Runtime::RemoteObject> remoteObject = protocol::Runtime::RemoteObject::parse(toProtocolValue(m_context->context(), wrappedObject).get(), &errors); if (!remoteObject) *errorString = "Object has too long reference chain"; return remoteObject; }