// Copyright 2017 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. #ifndef GIN_DATA_OBJECT_BUILDER_H_ #define GIN_DATA_OBJECT_BUILDER_H_ #include #include "base/check.h" #include "base/strings/string_piece.h" #include "gin/converter.h" #include "gin/gin_export.h" #include "v8/include/v8.h" namespace gin { // Constructs a JavaScript object with a series of data properties. // (As with default data properties in JavaScript, these properties are // configurable, writable and enumerable.) // // Values are automatically converted using gin::Converter, though if // using a type where the conversion may fail, callers must convert ahead of // time. // // This class avoids the pitfall of using v8::Object::Set, which may invoke // setters on the object prototype. // // Expected usage: // v8::Local object = gin::DataObjectBuilder(isolate) // .Set("boolean", true) // .Set("integer", 42) // .Build(); // // Because this builder class contains local handles, callers must ensure it // does not outlive the scope in which it is created. class GIN_EXPORT DataObjectBuilder { public: explicit DataObjectBuilder(v8::Isolate* isolate); DataObjectBuilder(const DataObjectBuilder&) = delete; DataObjectBuilder& operator=(const DataObjectBuilder&) = delete; template DataObjectBuilder& Set(base::StringPiece key, T&& value) { DCHECK(!object_.IsEmpty()); v8::Local v8_key = StringToSymbol(isolate_, key); v8::Local v8_value = ConvertToV8(isolate_, std::forward(value)); CHECK(object_->CreateDataProperty(context_, v8_key, v8_value).ToChecked()); return *this; } template DataObjectBuilder& Set(uint32_t index, T&& value) { DCHECK(!object_.IsEmpty()); v8::Local v8_value = ConvertToV8(isolate_, std::forward(value)); CHECK(object_->CreateDataProperty(context_, index, v8_value).ToChecked()); return *this; } v8::Local Build() { DCHECK(!object_.IsEmpty()); v8::Local result = object_; object_.Clear(); return result; } private: v8::Isolate* isolate_; v8::Local context_; v8::Local object_; }; } // namespace gin #endif // GIN_DATA_OBJECT_BUILDER_H_