blob: e16d33a10faa316a7ced72b25ea2eeed7393ca4e [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/bindings/core/v8/v8_object_parser.h"
#include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
namespace blink {
bool V8ObjectParser::ParsePrototype(v8::Local<v8::Context> context,
v8::Local<v8::Function> constructor,
v8::Local<v8::Object>* prototype,
ExceptionState* exception_state) {
v8::Isolate* isolate = context->GetIsolate();
v8::TryCatch block(isolate);
v8::Local<v8::Value> prototype_value;
if (!constructor->Get(context, V8AtomicString(isolate, "prototype"))
.ToLocal(&prototype_value)) {
exception_state->RethrowV8Exception(block.Exception());
return false;
}
if (prototype_value->IsNullOrUndefined()) {
exception_state->ThrowTypeError(
"The 'prototype' object on the class does not exist.");
return false;
}
if (!prototype_value->IsObject()) {
exception_state->ThrowTypeError(
"The 'prototype' property on the class is not an object.");
return false;
}
*prototype = v8::Local<v8::Object>::Cast(prototype_value);
return true;
}
bool V8ObjectParser::ParseFunction(v8::Local<v8::Context> context,
v8::Local<v8::Object> prototype,
const AtomicString function_name,
v8::Local<v8::Function>* function,
ExceptionState* exception_state) {
v8::Isolate* isolate = context->GetIsolate();
v8::TryCatch block(isolate);
v8::Local<v8::Value> function_value;
if (!prototype->Get(context, V8AtomicString(isolate, function_name))
.ToLocal(&function_value)) {
exception_state->RethrowV8Exception(block.Exception());
return false;
}
if (function_value->IsNullOrUndefined()) {
exception_state->ThrowTypeError(
"The '" + function_name +
"' property on the prototype does not exist.");
return false;
}
if (!function_value->IsFunction()) {
exception_state->ThrowTypeError(
"The '" + function_name +
"' property on the prototype is not a function.");
return false;
}
*function = v8::Local<v8::Function>::Cast(function_value);
return true;
}
bool V8ObjectParser::ParseGeneratorFunction(v8::Local<v8::Context> context,
v8::Local<v8::Object> prototype,
const AtomicString function_name,
v8::Local<v8::Function>* function,
ExceptionState* exception_state) {
v8::Isolate* isolate = context->GetIsolate();
v8::TryCatch block(isolate);
v8::Local<v8::Value> function_value;
if (!prototype->Get(context, V8AtomicString(isolate, function_name))
.ToLocal(&function_value)) {
exception_state->RethrowV8Exception(block.Exception());
return false;
}
if (function_value->IsNullOrUndefined()) {
exception_state->ThrowTypeError(
"The '" + function_name +
"' property on the prototype does not exist.");
return false;
}
if (!function_value->IsGeneratorFunction()) {
exception_state->ThrowTypeError(
"The '" + function_name +
"' property on the prototype is not a generator function.");
return false;
}
*function = v8::Local<v8::Function>::Cast(function_value);
return true;
}
bool V8ObjectParser::ParseCSSPropertyList(
v8::Local<v8::Context> context,
v8::Local<v8::Function> constructor,
const AtomicString list_name,
Vector<CSSPropertyID>* native_properties,
Vector<AtomicString>* custom_properties,
ExceptionState* exception_state) {
v8::Isolate* isolate = context->GetIsolate();
v8::TryCatch block(isolate);
v8::Local<v8::Value> list_value;
if (!constructor->Get(context, V8AtomicString(isolate, list_name))
.ToLocal(&list_value)) {
exception_state->RethrowV8Exception(block.Exception());
return false;
}
if (!list_value->IsNullOrUndefined()) {
Vector<String> properties =
NativeValueTraits<IDLSequence<IDLString>>::NativeValue(
isolate, list_value, *exception_state);
if (exception_state->HadException())
return false;
for (const auto& property : properties) {
CSSPropertyID property_id = cssPropertyID(property);
if (property_id == CSSPropertyVariable) {
custom_properties->push_back(std::move(property));
} else if (property_id != CSSPropertyInvalid) {
native_properties->push_back(std::move(property_id));
}
}
}
return true;
}
} // namespace blink