Commit d96ad377 by Marcin Cieslak

Update to io.js 3.0.0, use nan 2.0

The code has been updated to meet
the requirements of the updated V8 engine
as provided by io.js.

In some cases additional EscapableHandleScope
has been provided.

SassValueWrapper<T>::New has been changed:
in case of instance construction via
the function call "sass.types.Color(0,0,0)"
instead of "new sass.types.Color(0,0,0)"
the "new" part is no longer executed by
falling through. This should not be necessary
because the constructor is called by
the NewInstance call anyway.

This fixes the following error:

FATAL ERROR: v8::Object::SetAlignedPointerInInternalField() Internal field out of bounds
parent 34db8709
......@@ -55,7 +55,7 @@
"glob": "^5.0.13",
"meow": "^3.3.0",
"mkdirp": "^0.5.1",
"nan": "^1.8.4",
"nan": "^2.0.0",
"npmconf": "^2.1.2",
"pangyp": "^2.2.1",
"request": "^2.58.0",
......
......@@ -37,12 +37,12 @@ union Sass_Value* sass_custom_function(const union Sass_Value* s_args, Sass_Func
}
}
void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx_w, bool is_file, bool is_sync) {
NanScope();
void ExtractOptions(v8::Local<v8::Object> options, void* cptr, sass_context_wrapper* ctx_w, bool is_file, bool is_sync) {
Nan::HandleScope scope;
struct Sass_Context* ctx;
NanAssignPersistent(ctx_w->result, options->Get(NanNew("result"))->ToObject());
ctx_w->result.Reset(Nan::Get(options, Nan::New("result").ToLocalChecked()).ToLocalChecked()->ToObject());
if (is_file) {
ctx_w->fctx = (struct Sass_File_Context*) cptr;
......@@ -61,52 +61,52 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx
ctx_w->request.data = ctx_w;
// async (callback) style
Local<Function> success_callback = Local<Function>::Cast(options->Get(NanNew("success")));
Local<Function> error_callback = Local<Function>::Cast(options->Get(NanNew("error")));
v8::Local<v8::Function> success_callback = v8::Local<v8::Function>::Cast(Nan::Get(options, Nan::New("success").ToLocalChecked()).ToLocalChecked());
v8::Local<v8::Function> error_callback = v8::Local<v8::Function>::Cast(Nan::Get(options, Nan::New("error").ToLocalChecked()).ToLocalChecked());
ctx_w->success_callback = new NanCallback(success_callback);
ctx_w->error_callback = new NanCallback(error_callback);
ctx_w->success_callback = new Nan::Callback(success_callback);
ctx_w->error_callback = new Nan::Callback(error_callback);
}
if (!is_file) {
ctx_w->file = create_string(options->Get(NanNew("file")));
ctx_w->file = create_string(Nan::Get(options, Nan::New("file").ToLocalChecked()));
sass_option_set_input_path(sass_options, ctx_w->file);
}
int indent_len = options->Get(NanNew("indentWidth"))->Int32Value();
int indent_len = Nan::Get(options, Nan::New("indentWidth").ToLocalChecked()).ToLocalChecked()->Int32Value();
ctx_w->indent = (char*)malloc(indent_len + 1);
strcpy(ctx_w->indent, std::string(
indent_len,
options->Get(NanNew("indentType"))->Int32Value() == 1 ? '\t' : ' '
Nan::Get(options, Nan::New("indentType").ToLocalChecked()).ToLocalChecked()->Int32Value() == 1 ? '\t' : ' '
).c_str());
ctx_w->linefeed = create_string(options->Get(NanNew("linefeed")));
ctx_w->include_path = create_string(options->Get(NanNew("includePaths")));
ctx_w->out_file = create_string(options->Get(NanNew("outFile")));
ctx_w->source_map = create_string(options->Get(NanNew("sourceMap")));
ctx_w->source_map_root = create_string(options->Get(NanNew("sourceMapRoot")));
ctx_w->linefeed = create_string(Nan::Get(options, Nan::New("linefeed").ToLocalChecked()));
ctx_w->include_path = create_string(Nan::Get(options, Nan::New("includePaths").ToLocalChecked()));
ctx_w->out_file = create_string(Nan::Get(options, Nan::New("outFile").ToLocalChecked()));
ctx_w->source_map = create_string(Nan::Get(options, Nan::New("sourceMap").ToLocalChecked()));
ctx_w->source_map_root = create_string(Nan::Get(options, Nan::New("sourceMapRoot").ToLocalChecked()));
sass_option_set_output_path(sass_options, ctx_w->out_file);
sass_option_set_output_style(sass_options, (Sass_Output_Style)options->Get(NanNew("style"))->Int32Value());
sass_option_set_is_indented_syntax_src(sass_options, options->Get(NanNew("indentedSyntax"))->BooleanValue());
sass_option_set_source_comments(sass_options, options->Get(NanNew("sourceComments"))->BooleanValue());
sass_option_set_omit_source_map_url(sass_options, options->Get(NanNew("omitSourceMapUrl"))->BooleanValue());
sass_option_set_source_map_embed(sass_options, options->Get(NanNew("sourceMapEmbed"))->BooleanValue());
sass_option_set_source_map_contents(sass_options, options->Get(NanNew("sourceMapContents"))->BooleanValue());
sass_option_set_output_style(sass_options, (Sass_Output_Style)Nan::Get(options, Nan::New("style").ToLocalChecked()).ToLocalChecked()->Int32Value());
sass_option_set_is_indented_syntax_src(sass_options, Nan::Get(options, Nan::New("indentedSyntax").ToLocalChecked()).ToLocalChecked()->BooleanValue());
sass_option_set_source_comments(sass_options, Nan::Get(options, Nan::New("sourceComments").ToLocalChecked()).ToLocalChecked()->BooleanValue());
sass_option_set_omit_source_map_url(sass_options, Nan::Get(options, Nan::New("omitSourceMapUrl").ToLocalChecked()).ToLocalChecked()->BooleanValue());
sass_option_set_source_map_embed(sass_options, Nan::Get(options, Nan::New("sourceMapEmbed").ToLocalChecked()).ToLocalChecked()->BooleanValue());
sass_option_set_source_map_contents(sass_options, Nan::Get(options, Nan::New("sourceMapContents").ToLocalChecked()).ToLocalChecked()->BooleanValue());
sass_option_set_source_map_file(sass_options, ctx_w->source_map);
sass_option_set_source_map_root(sass_options, ctx_w->source_map_root);
sass_option_set_include_path(sass_options, ctx_w->include_path);
sass_option_set_precision(sass_options, options->Get(NanNew("precision"))->Int32Value());
sass_option_set_precision(sass_options, Nan::Get(options, Nan::New("precision").ToLocalChecked()).ToLocalChecked()->Int32Value());
sass_option_set_indent(sass_options, ctx_w->indent);
sass_option_set_linefeed(sass_options, ctx_w->linefeed);
Local<Value> importer_callback = options->Get(NanNew("importer"));
v8::Local<v8::Value> importer_callback = Nan::Get(options, Nan::New("importer").ToLocalChecked()).ToLocalChecked();
if (importer_callback->IsFunction()) {
Local<Function> importer = Local<Function>::Cast(importer_callback);
auto bridge = std::make_shared<CustomImporterBridge>(new NanCallback(importer), ctx_w->is_sync);
v8::Local<v8::Function> importer = v8::Local<v8::Function>::Cast(importer_callback);
auto bridge = std::make_shared<CustomImporterBridge>(new Nan::Callback(importer), ctx_w->is_sync);
ctx_w->importer_bridges.push_back(bridge);
Sass_Importer_List c_importers = sass_make_importer_list(1);
......@@ -115,13 +115,13 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx
sass_option_set_c_importers(sass_options, c_importers);
}
else if (importer_callback->IsArray()) {
Handle<Array> importers = Handle<Array>::Cast(importer_callback);
v8::Local<v8::Array> importers = v8::Local<v8::Array>::Cast(importer_callback);
Sass_Importer_List c_importers = sass_make_importer_list(importers->Length());
for (size_t i = 0; i < importers->Length(); ++i) {
Local<Function> callback = Local<Function>::Cast(importers->Get(static_cast<uint32_t>(i)));
v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(Nan::Get(importers, static_cast<uint32_t>(i)).ToLocalChecked());
auto bridge = std::make_shared<CustomImporterBridge>(new NanCallback(callback), ctx_w->is_sync);
auto bridge = std::make_shared<CustomImporterBridge>(new Nan::Callback(callback), ctx_w->is_sync);
ctx_w->importer_bridges.push_back(bridge);
c_importers[i] = sass_make_importer(sass_importer, importers->Length() - i - 1, bridge.get());
......@@ -130,19 +130,19 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx
sass_option_set_c_importers(sass_options, c_importers);
}
Local<Value> custom_functions = options->Get(NanNew("functions"));
v8::Local<v8::Value> custom_functions = Nan::Get(options, Nan::New("functions").ToLocalChecked()).ToLocalChecked();
if (custom_functions->IsObject()) {
Local<Object> functions = Local<Object>::Cast(custom_functions);
Local<Array> signatures = functions->GetOwnPropertyNames();
v8::Local<v8::Object> functions = v8::Local<v8::Object>::Cast(custom_functions);
v8::Local<v8::Array> signatures = Nan::GetOwnPropertyNames(functions).ToLocalChecked();
unsigned num_signatures = signatures->Length();
Sass_Function_List fn_list = sass_make_function_list(num_signatures);
for (unsigned i = 0; i < num_signatures; i++) {
Local<String> signature = Local<String>::Cast(signatures->Get(NanNew(i)));
Local<Function> callback = Local<Function>::Cast(functions->Get(signature));
v8::Local<v8::String> signature = v8::Local<v8::String>::Cast(Nan::Get(signatures, Nan::New(i)).ToLocalChecked());
v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(Nan::Get(functions, signature).ToLocalChecked());
auto bridge = std::make_shared<CustomFunctionBridge>(new NanCallback(callback), ctx_w->is_sync);
auto bridge = std::make_shared<CustomFunctionBridge>(new Nan::Callback(callback), ctx_w->is_sync);
ctx_w->function_bridges.push_back(bridge);
Sass_Function_Entry fn = sass_make_function(create_string(signature), sass_custom_function, bridge.get());
......@@ -154,48 +154,51 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx
}
void GetStats(sass_context_wrapper* ctx_w, Sass_Context* ctx) {
NanScope();
Nan::HandleScope scope;
char** included_files = sass_context_get_included_files(ctx);
Handle<Array> arr = NanNew<Array>();
v8::Local<v8::Array> arr = Nan::New<v8::Array>();
if (included_files) {
for (int i = 0; included_files[i] != nullptr; ++i) {
arr->Set(i, NanNew<String>(included_files[i]));
Nan::Set(arr, i, Nan::New<v8::String>(included_files[i]).ToLocalChecked());
}
}
NanNew(ctx_w->result)->Get(NanNew("stats"))->ToObject()->Set(NanNew("includedFiles"), arr);
Nan::Set(Nan::Get(Nan::New(ctx_w->result), Nan::New("stats").ToLocalChecked()).ToLocalChecked()->ToObject(), Nan::New("includedFiles").ToLocalChecked(), arr);
}
int GetResult(sass_context_wrapper* ctx_w, Sass_Context* ctx, bool is_sync = false) {
NanScope();
Nan::HandleScope scope;
v8::Local<v8::Object> result;
int status = sass_context_get_error_status(ctx);
result = Nan::New(ctx_w->result);
if (status == 0) {
const char* css = sass_context_get_output_string(ctx);
const char* map = sass_context_get_source_map_string(ctx);
NanNew(ctx_w->result)->Set(NanNew("css"), NanNewBufferHandle(css, static_cast<uint32_t>(strlen(css))));
Nan::Set(result, Nan::New("css").ToLocalChecked(), Nan::CopyBuffer(css, static_cast<uint32_t>(strlen(css))).ToLocalChecked());
GetStats(ctx_w, ctx);
if (map) {
NanNew(ctx_w->result)->Set(NanNew("map"), NanNewBufferHandle(map, static_cast<uint32_t>(strlen(map))));
Nan::Set(result, Nan::New("map").ToLocalChecked(), Nan::CopyBuffer(map, static_cast<uint32_t>(strlen(map))).ToLocalChecked());
}
}
else if (is_sync) {
NanNew(ctx_w->result)->Set(NanNew("error"), NanNew<String>(sass_context_get_error_json(ctx)));
Nan::Set(result, Nan::New("error").ToLocalChecked(), Nan::New<v8::String>(sass_context_get_error_json(ctx)).ToLocalChecked());
}
return status;
}
void MakeCallback(uv_work_t* req) {
NanScope();
Nan::HandleScope scope;
TryCatch try_catch;
Nan::TryCatch try_catch;
sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);
struct Sass_Context* ctx;
......@@ -215,23 +218,22 @@ void MakeCallback(uv_work_t* req) {
else if (ctx_w->error_callback) {
// if error, do callback(error)
const char* err = sass_context_get_error_json(ctx);
Local<Value> argv[] = {
NanNew<String>(err)
v8::Local<v8::Value> argv[] = {
Nan::New<v8::String>(err).ToLocalChecked()
};
ctx_w->error_callback->Call(1, argv);
}
if (try_catch.HasCaught()) {
node::FatalException(try_catch);
Nan::FatalException(try_catch);
}
sass_free_context_wrapper(ctx_w);
}
NAN_METHOD(render) {
NanScope();
Local<Object> options = args[0]->ToObject();
char* source_string = create_string(options->Get(NanNew("data")));
v8::Local<v8::Object> options = info[0]->ToObject();
char* source_string = create_string(Nan::Get(options, Nan::New("data").ToLocalChecked()));
struct Sass_Data_Context* dctx = sass_make_data_context(source_string);
sass_context_wrapper* ctx_w = sass_make_context_wrapper();
......@@ -241,14 +243,13 @@ NAN_METHOD(render) {
assert(status == 0);
NanReturnUndefined();
return;
}
NAN_METHOD(render_sync) {
NanScope();
Local<Object> options = args[0]->ToObject();
char* source_string = create_string(options->Get(NanNew("data")));
v8::Local<v8::Object> options = info[0]->ToObject();
char* source_string = create_string(Nan::Get(options, Nan::New("data").ToLocalChecked()));
struct Sass_Data_Context* dctx = sass_make_data_context(source_string);
struct Sass_Context* ctx = sass_data_context_get_context(dctx);
sass_context_wrapper* ctx_w = sass_make_context_wrapper();
......@@ -261,14 +262,13 @@ NAN_METHOD(render_sync) {
sass_free_context_wrapper(ctx_w);
NanReturnValue(NanNew<Boolean>(result == 0));
info.GetReturnValue().Set(Nan::New<v8::Boolean>(result == 0));
}
NAN_METHOD(render_file) {
NanScope();
Local<Object> options = args[0]->ToObject();
char* input_path = create_string(options->Get(NanNew("file")));
v8::Local<v8::Object> options = info[0]->ToObject();
char* input_path = create_string(Nan::Get(options, Nan::New("file").ToLocalChecked()));
struct Sass_File_Context* fctx = sass_make_file_context(input_path);
sass_context_wrapper* ctx_w = sass_make_context_wrapper();
......@@ -278,14 +278,13 @@ NAN_METHOD(render_file) {
assert(status == 0);
NanReturnUndefined();
return;
}
NAN_METHOD(render_file_sync) {
NanScope();
Local<Object> options = args[0]->ToObject();
char* input_path = create_string(options->Get(NanNew("file")));
v8::Local<v8::Object> options = info[0]->ToObject();
char* input_path = create_string(Nan::Get(options, Nan::New("file").ToLocalChecked()));
struct Sass_File_Context* fctx = sass_make_file_context(input_path);
struct Sass_Context* ctx = sass_file_context_get_context(fctx);
sass_context_wrapper* ctx_w = sass_make_context_wrapper();
......@@ -298,20 +297,19 @@ NAN_METHOD(render_file_sync) {
free(input_path);
sass_free_context_wrapper(ctx_w);
NanReturnValue(NanNew<Boolean>(result == 0));
info.GetReturnValue().Set(Nan::New<v8::Boolean>(result == 0));
}
NAN_METHOD(libsass_version) {
NanScope();
NanReturnValue(NanNew<String>(libsass_version()));
info.GetReturnValue().Set(Nan::New<v8::String>(libsass_version()).ToLocalChecked());
}
void RegisterModule(v8::Handle<v8::Object> target) {
NODE_SET_METHOD(target, "render", render);
NODE_SET_METHOD(target, "renderSync", render_sync);
NODE_SET_METHOD(target, "renderFile", render_file);
NODE_SET_METHOD(target, "renderFileSync", render_file_sync);
NODE_SET_METHOD(target, "libsassVersion", libsass_version);
void RegisterModule(v8::Local<v8::Object> target) {
Nan::SetMethod(target, "render", render);
Nan::SetMethod(target, "renderSync", render_sync);
Nan::SetMethod(target, "renderFile", render_file);
Nan::SetMethod(target, "renderFileSync", render_file_sync);
Nan::SetMethod(target, "libsassVersion", libsass_version);
SassTypes::Factory::initExports(target);
}
......
......@@ -8,12 +8,10 @@
#define COMMA ,
using namespace v8;
template <typename T, typename L = void*>
class CallbackBridge {
public:
CallbackBridge(NanCallback*, bool);
CallbackBridge(Nan::Callback*, bool);
virtual ~CallbackBridge();
// Executes the callback
......@@ -22,12 +20,12 @@ class CallbackBridge {
protected:
// We will expose a bridge object to the JS callback that wraps this instance so we don't loose context.
// This is the V8 constructor for such objects.
static Handle<Function> get_wrapper_constructor();
static Nan::MaybeLocal<v8::Function> get_wrapper_constructor();
static void async_gone(uv_handle_t *handle);
static NAN_METHOD(New);
static NAN_METHOD(ReturnCallback);
static Persistent<Function> wrapper_constructor;
Persistent<Object> wrapper;
static Nan::Persistent<v8::Function> wrapper_constructor;
Nan::Persistent<v8::Object> wrapper;
// The callback that will get called in the main thread after the worker thread used for the sass
// compilation step makes a call to uv_async_send()
......@@ -36,12 +34,12 @@ class CallbackBridge {
// The V8 values sent to our ReturnCallback must be read on the main thread not the sass worker thread.
// This gives a chance to specialized subclasses to transform those values into whatever makes sense to
// sass before we resume the worker thread.
virtual T post_process_return_value(Handle<Value>) const =0;
virtual T post_process_return_value(v8::Local<v8::Value>) const =0;
virtual std::vector<Handle<Value>> pre_process_args(std::vector<L>) const =0;
virtual std::vector<v8::Local<v8::Value>> pre_process_args(std::vector<L>) const =0;
NanCallback* callback;
Nan::Callback* callback;
bool is_sync;
std::mutex cv_mutex;
......@@ -53,10 +51,10 @@ class CallbackBridge {
};
template <typename T, typename L>
Persistent<Function> CallbackBridge<T, L>::wrapper_constructor;
Nan::Persistent<v8::Function> CallbackBridge<T, L>::wrapper_constructor;
template <typename T, typename L>
CallbackBridge<T, L>::CallbackBridge(NanCallback* callback, bool is_sync) : callback(callback), is_sync(is_sync) {
CallbackBridge<T, L>::CallbackBridge(Nan::Callback* callback, bool is_sync) : callback(callback), is_sync(is_sync) {
// This assumes the main thread will be the one instantiating the bridge
if (!is_sync) {
this->async = new uv_async_t;
......@@ -64,14 +62,15 @@ CallbackBridge<T, L>::CallbackBridge(NanCallback* callback, bool is_sync) : call
uv_async_init(uv_default_loop(), this->async, (uv_async_cb) dispatched_async_uv_callback);
}
NanAssignPersistent(wrapper, NanNew(CallbackBridge<T, L>::get_wrapper_constructor())->NewInstance());
NanSetInternalFieldPointer(NanNew(wrapper), 0, this);
v8::Local<v8::Function> func = CallbackBridge<T, L>::get_wrapper_constructor().ToLocalChecked();
wrapper.Reset(Nan::NewInstance(func).ToLocalChecked());
Nan::SetInternalFieldPointer(Nan::New(wrapper), 0, this);
}
template <typename T, typename L>
CallbackBridge<T, L>::~CallbackBridge() {
delete this->callback;
NanDisposePersistent(this->wrapper);
this->wrapper.Reset();
if (!is_sync) {
uv_close((uv_handle_t*)this->async, &async_gone);
......@@ -81,13 +80,13 @@ CallbackBridge<T, L>::~CallbackBridge() {
template <typename T, typename L>
T CallbackBridge<T, L>::operator()(std::vector<void*> argv) {
// argv.push_back(wrapper);
if (this->is_sync) {
std::vector<Handle<Value>> argv_v8 = pre_process_args(argv);
argv_v8.push_back(NanNew(wrapper));
Nan::EscapableHandleScope scope;
std::vector<v8::Local<v8::Value>> argv_v8 = pre_process_args(argv);
argv_v8.push_back(Nan::New(wrapper));
return this->post_process_return_value(
NanNew<Value>(this->callback->Call(argv_v8.size(), &argv_v8[0]))
scope.Escape(this->callback->Call(argv_v8.size(), &argv_v8[0]))
);
}
......@@ -105,27 +104,26 @@ template <typename T, typename L>
void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) {
CallbackBridge* bridge = static_cast<CallbackBridge*>(req->data);
NanScope();
TryCatch try_catch;
Nan::HandleScope scope;
Nan::TryCatch try_catch;
std::vector<Handle<Value>> argv_v8 = bridge->pre_process_args(bridge->argv);
argv_v8.push_back(NanNew(bridge->wrapper));
std::vector<v8::Local<v8::Value>> argv_v8 = bridge->pre_process_args(bridge->argv);
argv_v8.push_back(Nan::New(bridge->wrapper));
NanNew<Value>(bridge->callback->Call(argv_v8.size(), &argv_v8[0]));
bridge->callback->Call(argv_v8.size(), &argv_v8[0]);
if (try_catch.HasCaught()) {
node::FatalException(try_catch);
Nan::FatalException(try_catch);
}
}
template <typename T, typename L>
NAN_METHOD(CallbackBridge<T COMMA L>::ReturnCallback) {
NanScope();
CallbackBridge<T, L>* bridge = static_cast<CallbackBridge<T, L>*>(NanGetInternalFieldPointer(args.This(), 0));
TryCatch try_catch;
CallbackBridge<T, L>* bridge = static_cast<CallbackBridge<T, L>*>(Nan::GetInternalFieldPointer(info.This(), 0));
Nan::TryCatch try_catch;
bridge->return_value = bridge->post_process_return_value(args[0]);
bridge->return_value = bridge->post_process_return_value(info[0]);
{
std::lock_guard<std::mutex> lock(bridge->cv_mutex);
......@@ -135,33 +133,32 @@ NAN_METHOD(CallbackBridge<T COMMA L>::ReturnCallback) {
bridge->condition_variable.notify_all();
if (try_catch.HasCaught()) {
node::FatalException(try_catch);
Nan::FatalException(try_catch);
}
NanReturnUndefined();
return;
}
template <typename T, typename L>
Handle<Function> CallbackBridge<T, L>::get_wrapper_constructor() {
Nan::MaybeLocal<v8::Function> CallbackBridge<T, L>::get_wrapper_constructor() {
if (wrapper_constructor.IsEmpty()) {
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New);
tpl->SetClassName(NanNew("CallbackBridge"));
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->SetClassName(Nan::New("CallbackBridge").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
tpl->PrototypeTemplate()->Set(
NanNew("success"),
NanNew<FunctionTemplate>(ReturnCallback)->GetFunction()
Nan::SetPrototypeTemplate(tpl, "success",
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(ReturnCallback)).ToLocalChecked()
);
NanAssignPersistent(wrapper_constructor, tpl->GetFunction());
wrapper_constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked());
}
return NanNew(wrapper_constructor);
return Nan::New(wrapper_constructor);
}
template <typename T, typename L>
NAN_METHOD(CallbackBridge<T COMMA L>::New) {
NanScope();
NanReturnValue(args.This());
info.GetReturnValue().Set(info.This());
}
template <typename T, typename L>
......
......@@ -3,12 +3,18 @@
#include <string.h>
#include "create_string.h"
char* create_string(Local<Value> value) {
char* create_string(Nan::MaybeLocal<v8::Value> maybevalue) {
v8::Local<v8::Value> value;
if (maybevalue.ToLocal(&value)) {
if (value->IsNull() || !value->IsString()) {
return 0;
}
} else {
return 0;
}
String::Utf8Value string(value);
v8::String::Utf8Value string(value);
char *str = (char *)malloc(string.length() + 1);
strcpy(str, *string);
return str;
......
......@@ -3,8 +3,6 @@
#include <nan.h>
using namespace v8;
char* create_string(Local<Value>);
char* create_string(Nan::MaybeLocal<v8::Value>);
#endif
......@@ -2,7 +2,7 @@
#include "custom_function_bridge.h"
#include "sass_types/factory.h"
Sass_Value* CustomFunctionBridge::post_process_return_value(Handle<Value> val) const {
Sass_Value* CustomFunctionBridge::post_process_return_value(v8::Local<v8::Value> val) const {
try {
return SassTypes::Factory::unwrap(val)->get_sass_value();
}
......@@ -11,8 +11,8 @@ Sass_Value* CustomFunctionBridge::post_process_return_value(Handle<Value> val) c
}
}
std::vector<Handle<Value>> CustomFunctionBridge::pre_process_args(std::vector<void*> in) const {
std::vector<Handle<Value>> argv = std::vector<Handle<Value>>();
std::vector<v8::Local<v8::Value>> CustomFunctionBridge::pre_process_args(std::vector<void*> in) const {
std::vector<v8::Local<v8::Value>> argv = std::vector<v8::Local<v8::Value>>();
for (void* value : in) {
argv.push_back(SassTypes::Factory::create(static_cast<Sass_Value*>(value))->get_js_object());
......
......@@ -5,15 +5,13 @@
#include <sass_context.h>
#include "callback_bridge.h"
using namespace v8;
class CustomFunctionBridge : public CallbackBridge<Sass_Value*> {
public:
CustomFunctionBridge(NanCallback* cb, bool is_sync) : CallbackBridge<Sass_Value*>(cb, is_sync) {}
CustomFunctionBridge(Nan::Callback* cb, bool is_sync) : CallbackBridge<Sass_Value*>(cb, is_sync) {}
private:
Sass_Value* post_process_return_value(Handle<Value>) const;
std::vector<Handle<Value>> pre_process_args(std::vector<void*>) const;
Sass_Value* post_process_return_value(v8::Local<v8::Value>) const;
std::vector<v8::Local<v8::Value>> pre_process_args(std::vector<void*>) const;
};
#endif
......@@ -2,19 +2,17 @@
#include "custom_importer_bridge.h"
#include "create_string.h"
SassImportList CustomImporterBridge::post_process_return_value(Handle<Value> val) const {
SassImportList CustomImporterBridge::post_process_return_value(v8::Local<v8::Value> returned_value) const {
SassImportList imports = 0;
NanScope();
Local<Value> returned_value = NanNew(val);
Nan::HandleScope scope;
if (returned_value->IsArray()) {
Handle<Array> array = Handle<Array>::Cast(returned_value);
v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(returned_value);
imports = sass_make_import_list(array->Length());
for (size_t i = 0; i < array->Length(); ++i) {
Local<Value> value = array->Get(static_cast<uint32_t>(i));
v8::Local<v8::Value> value = Nan::Get(array, static_cast<uint32_t>(i)).ToLocalChecked();
if (!value->IsObject()) {
auto entry = sass_make_import_entry(0, 0, 0);
......@@ -22,10 +20,10 @@ SassImportList CustomImporterBridge::post_process_return_value(Handle<Value> val
continue;
}
Local<Object> object = Local<Object>::Cast(value);
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
if (value->IsNativeError()) {
char* message = create_string(object->Get(NanNew<String>("message")));
char* message = create_string(Nan::Get(object, Nan::New<v8::String>("message").ToLocalChecked()));
imports[i] = sass_make_import_entry(0, 0, 0);
......@@ -38,8 +36,8 @@ SassImportList CustomImporterBridge::post_process_return_value(Handle<Value> val
}
else if (returned_value->IsNativeError()) {
imports = sass_make_import_list(1);
Local<Object> object = Local<Object>::Cast(returned_value);
char* message = create_string(object->Get(NanNew<String>("message")));
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(returned_value);
char* message = create_string(Nan::Get(object, Nan::New<v8::String>("message").ToLocalChecked()));
imports[0] = sass_make_import_entry(0, 0, 0);
......@@ -47,36 +45,42 @@ SassImportList CustomImporterBridge::post_process_return_value(Handle<Value> val
}
else if (returned_value->IsObject()) {
imports = sass_make_import_list(1);
imports[0] = get_importer_entry(Local<Object>::Cast(returned_value));
imports[0] = get_importer_entry(v8::Local<v8::Object>::Cast(returned_value));
}
return imports;
}
Sass_Import* CustomImporterBridge::get_importer_entry(const Local<Object>& object) const {
auto returned_file = object->Get(NanNew<String>("file"));
if (!returned_file->IsUndefined() && !returned_file->IsString()) {
Sass_Import* CustomImporterBridge::check_returned_string(Nan::MaybeLocal<v8::Value> value, const char *msg) const
{
v8::Local<v8::Value> checked;
if (value.ToLocal(&checked)) {
if (!checked->IsUndefined() && !checked->IsString()) {
goto err;
} else {
return nullptr;
}
}
err:
auto entry = sass_make_import_entry(0, 0, 0);
sass_import_set_error(entry, "returned value of `file` must be a string", -1, -1);
sass_import_set_error(entry, msg, -1, -1);
return entry;
}
}
auto returned_contents = object->Get(NanNew<String>("contents"));
Sass_Import* CustomImporterBridge::get_importer_entry(const v8::Local<v8::Object>& object) const {
auto returned_file = Nan::Get(object, Nan::New<v8::String>("file").ToLocalChecked());
auto returned_contents = Nan::Get(object, Nan::New<v8::String>("contents").ToLocalChecked()).ToLocalChecked();
auto returned_map = Nan::Get(object, Nan::New<v8::String>("map").ToLocalChecked());
Sass_Import *err;
if (!returned_contents->IsUndefined() && !returned_contents->IsString()) {
auto entry = sass_make_import_entry(0, 0, 0);
sass_import_set_error(entry, "returned value of `contents` must be a string", -1, -1);
return entry;
}
if ((err = check_returned_string(returned_file, "returned value of `file` must be a string")))
return err;
auto returned_map = object->Get(NanNew<String>("map"));
if ((err = check_returned_string(returned_contents, "returned value of `contents` must be a string")))
return err;
if (!returned_map->IsUndefined() && !returned_map->IsString()) {
auto entry = sass_make_import_entry(0, 0, 0);
sass_import_set_error(entry, "returned value of `map` must be a string", -1, -1);
return entry;
}
if ((err = check_returned_string(returned_map, "returned value of `returned_map` must be a string")))
return err;
char* path = create_string(returned_file);
char* contents = create_string(returned_contents);
......@@ -85,11 +89,11 @@ Sass_Import* CustomImporterBridge::get_importer_entry(const Local<Object>& objec
return sass_make_import_entry(path, contents, srcmap);
}
std::vector<Handle<Value>> CustomImporterBridge::pre_process_args(std::vector<void*> in) const {
std::vector<Handle<Value>> out;
std::vector<v8::Local<v8::Value>> CustomImporterBridge::pre_process_args(std::vector<void*> in) const {
std::vector<v8::Local<v8::Value>> out;
for (void* ptr : in) {
out.push_back(NanNew<String>((char const*)ptr));
out.push_back(Nan::New<v8::String>((char const*)ptr).ToLocalChecked());
}
return out;
......
......@@ -5,18 +5,17 @@
#include <sass_context.h>
#include "callback_bridge.h"
using namespace v8;
typedef Sass_Import_List SassImportList;
class CustomImporterBridge : public CallbackBridge<SassImportList> {
public:
CustomImporterBridge(NanCallback* cb, bool is_sync) : CallbackBridge<SassImportList>(cb, is_sync) {}
CustomImporterBridge(Nan::Callback* cb, bool is_sync) : CallbackBridge<SassImportList>(cb, is_sync) {}
private:
SassImportList post_process_return_value(Handle<Value>) const;
Sass_Import* get_importer_entry(const Local<Object>&) const;
std::vector<Handle<Value>> pre_process_args(std::vector<void*>) const;
SassImportList post_process_return_value(v8::Local<v8::Value>) const;
Sass_Import* check_returned_string(Nan::MaybeLocal<v8::Value> value, const char *msg) const;
Sass_Import* get_importer_entry(const v8::Local<v8::Object>&) const;
std::vector<v8::Local<v8::Value>> pre_process_args(std::vector<void*>) const;
};
#endif
......@@ -37,7 +37,7 @@ extern "C" {
delete ctx_w->error_callback;
delete ctx_w->success_callback;
NanDisposePersistent(ctx_w->result);
ctx_w->result.Reset();
free(ctx_w->include_path);
free(ctx_w->linefeed);
......
......@@ -14,8 +14,6 @@
extern "C" {
#endif
using namespace v8;
void compile_data(struct Sass_Data_Context* dctx);
void compile_file(struct Sass_File_Context* fctx);
void compile_it(uv_work_t* req);
......@@ -41,9 +39,9 @@ extern "C" {
uv_work_t request;
// v8 and nan related
Persistent<Object> result;
NanCallback* error_callback;
NanCallback* success_callback;
Nan::Persistent<v8::Object> result;
Nan::Callback* error_callback;
Nan::Callback* success_callback;
std::vector<std::shared_ptr<CustomFunctionBridge>> function_bridges;
std::vector<std::shared_ptr<CustomImporterBridge>> importer_bridges;
......
#include <nan.h>
#include "boolean.h"
using namespace v8;
namespace SassTypes
{
Persistent<Function> Boolean::constructor;
Nan::Persistent<v8::Function> Boolean::constructor;
bool Boolean::constructor_locked = false;
Boolean::Boolean(bool v) : value(v) {}
......@@ -15,59 +13,63 @@ namespace SassTypes
return v ? instance_true : instance_false;
}
Handle<Function> Boolean::get_constructor() {
v8::Local<v8::Function> Boolean::get_constructor() {
Nan::EscapableHandleScope scope;
v8::Local<v8::Function> conslocal;
if (constructor.IsEmpty()) {
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New);
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->SetClassName(NanNew("SassBoolean"));
tpl->SetClassName(Nan::New("SassBoolean").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
tpl->PrototypeTemplate()->Set(NanNew("getValue"), NanNew<FunctionTemplate>(GetValue)->GetFunction());
Nan::SetPrototypeTemplate(tpl, "getValue", Nan::GetFunction(Nan::New<v8::FunctionTemplate>(GetValue)).ToLocalChecked());
NanAssignPersistent(constructor, tpl->GetFunction());
constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked());
conslocal = Nan::New(constructor);
NanAssignPersistent(get_singleton(false).js_object, NanNew(constructor)->NewInstance());
NanSetInternalFieldPointer(NanNew(get_singleton(false).js_object), 0, &get_singleton(false));
NanNew(constructor)->Set(NanNew("FALSE"), NanNew(get_singleton(false).js_object));
get_singleton(false).js_object.Reset(conslocal->NewInstance());
Nan::SetInternalFieldPointer(Nan::New(get_singleton(false).js_object), 0, &get_singleton(false));
Nan::Set(conslocal, Nan::New("FALSE").ToLocalChecked(), Nan::New(get_singleton(false).js_object));
NanAssignPersistent(get_singleton(true).js_object, NanNew(constructor)->NewInstance());
NanSetInternalFieldPointer(NanNew(get_singleton(true).js_object), 0, &get_singleton(true));
NanNew(constructor)->Set(NanNew("TRUE"), NanNew(get_singleton(true).js_object));
get_singleton(true).js_object.Reset(conslocal->NewInstance());
Nan::SetInternalFieldPointer(Nan::New(get_singleton(true).js_object), 0, &get_singleton(true));
Nan::Set(conslocal, Nan::New("TRUE").ToLocalChecked(), Nan::New(get_singleton(true).js_object));
constructor_locked = true;
} else {
conslocal = Nan::New(constructor);
}
return NanNew(constructor);
return scope.Escape(conslocal);
}
Sass_Value* Boolean::get_sass_value() {
return sass_make_boolean(value);
}
Local<Object> Boolean::get_js_object() {
return NanNew(this->js_object);
v8::Local<v8::Object> Boolean::get_js_object() {
Nan::EscapableHandleScope scope;
return scope.Escape(Nan::New(this->js_object));
}
NAN_METHOD(Boolean::New) {
NanScope();
if (args.IsConstructCall()) {
if (info.IsConstructCall()) {
if (constructor_locked) {
return NanThrowError(NanNew("Cannot instantiate SassBoolean"));
return Nan::ThrowError(Nan::New("Cannot instantiate SassBoolean").ToLocalChecked());
}
}
else {
if (args.Length() != 1 || !args[0]->IsBoolean()) {
return NanThrowError(NanNew("Expected one boolean argument"));
if (info.Length() != 1 || !info[0]->IsBoolean()) {
return Nan::ThrowError(Nan::New("Expected one boolean argument").ToLocalChecked());
}
NanReturnValue(NanNew(get_singleton(args[0]->ToBoolean()->Value()).get_js_object()));
info.GetReturnValue().Set((get_singleton(info[0]->ToBoolean()->Value()).get_js_object()));
}
NanReturnUndefined();
return;
}
NAN_METHOD(Boolean::GetValue) {
NanScope();
NanReturnValue(NanNew(static_cast<Boolean*>(Factory::unwrap(args.This()))->value));
info.GetReturnValue().Set(Nan::New(static_cast<Boolean*>(Factory::unwrap(info.This()))->value));
}
}
......@@ -7,15 +7,13 @@
namespace SassTypes
{
using namespace v8;
class Boolean : public Value {
class Boolean : public SassTypes::Value {
public:
static Boolean& get_singleton(bool);
static Handle<Function> get_constructor();
static v8::Local<v8::Function> get_constructor();
Sass_Value* get_sass_value();
Local<Object> get_js_object();
v8::Local<v8::Object> get_js_object();
static NAN_METHOD(New);
static NAN_METHOD(GetValue);
......@@ -24,9 +22,9 @@ namespace SassTypes
Boolean(bool);
bool value;
Persistent<Object> js_object;
Nan::Persistent<v8::Object> js_object;
static Persistent<Function> constructor;
static Nan::Persistent<v8::Function> constructor;
static bool constructor_locked;
};
}
......
#include <nan.h>
#include "color.h"
using namespace v8;
namespace SassTypes
{
Color::Color(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Color::construct(const std::vector<Local<v8::Value>> raw_val) {
Sass_Value* Color::construct(const std::vector<v8::Local<v8::Value>> raw_val) {
double a = 1.0, r = 0, g = 0, b = 0;
unsigned argb;
......@@ -52,86 +50,82 @@ namespace SassTypes
return sass_make_color(r, g, b, a);
}
void Color::initPrototype(Handle<ObjectTemplate> proto) {
proto->Set(NanNew("getR"), NanNew<FunctionTemplate>(GetR)->GetFunction());
proto->Set(NanNew("getG"), NanNew<FunctionTemplate>(GetG)->GetFunction());
proto->Set(NanNew("getB"), NanNew<FunctionTemplate>(GetB)->GetFunction());
proto->Set(NanNew("getA"), NanNew<FunctionTemplate>(GetA)->GetFunction());
proto->Set(NanNew("setR"), NanNew<FunctionTemplate>(SetR)->GetFunction());
proto->Set(NanNew("setG"), NanNew<FunctionTemplate>(SetG)->GetFunction());
proto->Set(NanNew("setB"), NanNew<FunctionTemplate>(SetB)->GetFunction());
proto->Set(NanNew("setA"), NanNew<FunctionTemplate>(SetA)->GetFunction());
void Color::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
Nan::SetPrototypeMethod(proto, "getR", GetR);
Nan::SetPrototypeMethod(proto, "getG", GetG);
Nan::SetPrototypeMethod(proto, "getB", GetB);
Nan::SetPrototypeMethod(proto, "getA", GetA);
Nan::SetPrototypeMethod(proto, "setR", SetR);
Nan::SetPrototypeMethod(proto, "setG", SetG);
Nan::SetPrototypeMethod(proto, "setB", SetB);
Nan::SetPrototypeMethod(proto, "setA", SetA);
}
NAN_METHOD(Color::GetR) {
NanScope();
NanReturnValue(NanNew(sass_color_get_r(unwrap(args.This())->value)));
info.GetReturnValue().Set(Nan::New(sass_color_get_r(unwrap(info.This())->value)));
}
NAN_METHOD(Color::GetG) {
NanScope();
NanReturnValue(NanNew(sass_color_get_g(unwrap(args.This())->value)));
info.GetReturnValue().Set(Nan::New(sass_color_get_g(unwrap(info.This())->value)));
}
NAN_METHOD(Color::GetB) {
NanScope();
NanReturnValue(NanNew(sass_color_get_b(unwrap(args.This())->value)));
info.GetReturnValue().Set(Nan::New(sass_color_get_b(unwrap(info.This())->value)));
}
NAN_METHOD(Color::GetA) {
NanScope();
NanReturnValue(NanNew(sass_color_get_a(unwrap(args.This())->value)));
info.GetReturnValue().Set(Nan::New(sass_color_get_a(unwrap(info.This())->value)));
}
NAN_METHOD(Color::SetR) {
if (args.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument"));
if (info.Length() != 1) {
return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
}
if (!args[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied value should be a number"));
if (!info[0]->IsNumber()) {
return Nan::ThrowError(Nan::New("Supplied value should be a number").ToLocalChecked());
}
sass_color_set_r(unwrap(args.This())->value, args[0]->ToNumber()->Value());
NanReturnUndefined();
sass_color_set_r(unwrap(info.This())->value, info[0]->ToNumber()->Value());
return;
}
NAN_METHOD(Color::SetG) {
if (args.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument"));
if (info.Length() != 1) {
return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
}
if (!args[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied value should be a number"));
if (!info[0]->IsNumber()) {
return Nan::ThrowError(Nan::New("Supplied value should be a number").ToLocalChecked());
}
sass_color_set_g(unwrap(args.This())->value, args[0]->ToNumber()->Value());
NanReturnUndefined();
sass_color_set_g(unwrap(info.This())->value, info[0]->ToNumber()->Value());
return;
}
NAN_METHOD(Color::SetB) {
if (args.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument"));
if (info.Length() != 1) {
return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
}
if (!args[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied value should be a number"));
if (!info[0]->IsNumber()) {
return Nan::ThrowError(Nan::New("Supplied value should be a number").ToLocalChecked());
}
sass_color_set_b(unwrap(args.This())->value, args[0]->ToNumber()->Value());
NanReturnUndefined();
sass_color_set_b(unwrap(info.This())->value, info[0]->ToNumber()->Value());
return;
}
NAN_METHOD(Color::SetA) {
if (args.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument"));
if (info.Length() != 1) {
return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
}
if (!args[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied value should be a number"));
if (!info[0]->IsNumber()) {
return Nan::ThrowError(Nan::New("Supplied value should be a number").ToLocalChecked());
}
sass_color_set_a(unwrap(args.This())->value, args[0]->ToNumber()->Value());
NanReturnUndefined();
sass_color_set_a(unwrap(info.This())->value, info[0]->ToNumber()->Value());
return;
}
}
......@@ -6,15 +6,13 @@
namespace SassTypes
{
using namespace v8;
class Color : public SassValueWrapper<Color> {
public:
Color(Sass_Value*);
static char const* get_constructor_name() { return "SassColor"; }
static Sass_Value* construct(const std::vector<Local<v8::Value>>);
static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>);
static void initPrototype(Handle<ObjectTemplate>);
static void initPrototype(v8::Local<v8::FunctionTemplate>);
static NAN_METHOD(GetR);
static NAN_METHOD(GetG);
......
......@@ -2,13 +2,11 @@
#include "error.h"
#include "../create_string.h"
using namespace v8;
namespace SassTypes
{
Error::Error(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Error::construct(const std::vector<Local<v8::Value>> raw_val) {
Sass_Value* Error::construct(const std::vector<v8::Local<v8::Value>> raw_val) {
char const* value = "";
if (raw_val.size() >= 1) {
......@@ -22,5 +20,5 @@ namespace SassTypes
return sass_make_error(value);
}
void Error::initPrototype(Handle<ObjectTemplate>) {}
void Error::initPrototype(v8::Local<v8::FunctionTemplate>) {}
}
......@@ -6,15 +6,13 @@
namespace SassTypes
{
using namespace v8;
class Error : public SassValueWrapper<Error> {
public:
Error(Sass_Value*);
static char const* get_constructor_name() { return "SassError"; }
static Sass_Value* construct(const std::vector<Local<v8::Value>>);
static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>);
static void initPrototype(Handle<ObjectTemplate>);
static void initPrototype(v8::Local<v8::FunctionTemplate>);
};
}
......
......@@ -10,11 +10,9 @@
#include "null.h"
#include "error.h"
using namespace v8;
namespace SassTypes
{
Value* Factory::create(Sass_Value* v) {
SassTypes::Value* Factory::create(Sass_Value* v) {
switch (sass_value_get_tag(v)) {
case SASS_NUMBER:
return new Number(v);
......@@ -45,26 +43,27 @@ namespace SassTypes
}
}
void Factory::initExports(Handle<Object> exports) {
Local<Object> types = NanNew<Object>();
exports->Set(NanNew("types"), types);
void Factory::initExports(v8::Local<v8::Object> exports) {
Nan::EscapableHandleScope scope;
v8::Local<v8::Object> types = Nan::New<v8::Object>();
types->Set(NanNew("Number"), Number::get_constructor());
types->Set(NanNew("String"), String::get_constructor());
types->Set(NanNew("Color"), Color::get_constructor());
types->Set(NanNew("Boolean"), Boolean::get_constructor());
types->Set(NanNew("List"), List::get_constructor());
types->Set(NanNew("Map"), Map::get_constructor());
types->Set(NanNew("Null"), Null::get_constructor());
types->Set(NanNew("Error"), Error::get_constructor());
Nan::Set(types, Nan::New("Number").ToLocalChecked(), Number::get_constructor());
Nan::Set(types, Nan::New("String").ToLocalChecked(), String::get_constructor());
Nan::Set(types, Nan::New("Color").ToLocalChecked(), Color::get_constructor());
Nan::Set(types, Nan::New("Boolean").ToLocalChecked(), Boolean::get_constructor());
Nan::Set(types, Nan::New("List").ToLocalChecked(), List::get_constructor());
Nan::Set(types, Nan::New("Map").ToLocalChecked(), Map::get_constructor());
Nan::Set(types, Nan::New("Null").ToLocalChecked(), Null::get_constructor());
Nan::Set(types, Nan::New("Error").ToLocalChecked(), Error::get_constructor());
Nan::Set(exports, Nan::New<v8::String>("types").ToLocalChecked(), scope.Escape(types));
}
Value* Factory::unwrap(Handle<v8::Value> obj) {
Value* Factory::unwrap(v8::Local<v8::Value> obj) {
// Todo: non-SassValue objects could easily fall under that condition, need to be more specific.
if (!obj->IsObject() || obj->ToObject()->InternalFieldCount() != 1) {
throw std::invalid_argument("A SassValue object was expected.");
}
return static_cast<Value*>(NanGetInternalFieldPointer(obj->ToObject(), 0));
return static_cast<Value*>(Nan::GetInternalFieldPointer(obj->ToObject(), 0));
}
}
......@@ -7,15 +7,13 @@
namespace SassTypes
{
using namespace v8;
// This is the guru that knows everything about instantiating the right subclass of SassTypes::Value
// to wrap a given Sass_Value object.
class Factory {
public:
static void initExports(Handle<Object>);
static void initExports(v8::Local<v8::Object>);
static Value* create(Sass_Value*);
static Value* unwrap(Handle<v8::Value>);
static Value* unwrap(v8::Local<v8::Value>);
};
}
......
#include <nan.h>
#include "list.h"
using namespace v8;
namespace SassTypes
{
List::List(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* List::construct(const std::vector<Local<v8::Value>> raw_val) {
Sass_Value* List::construct(const std::vector<v8::Local<v8::Value>> raw_val) {
size_t length = 0;
bool comma = true;
......@@ -30,74 +28,71 @@ namespace SassTypes
return sass_make_list(length, comma ? SASS_COMMA : SASS_SPACE);
}
void List::initPrototype(Handle<ObjectTemplate> proto) {
proto->Set(NanNew("getLength"), NanNew<FunctionTemplate>(GetLength)->GetFunction());
proto->Set(NanNew("getSeparator"), NanNew<FunctionTemplate>(GetSeparator)->GetFunction());
proto->Set(NanNew("setSeparator"), NanNew<FunctionTemplate>(SetSeparator)->GetFunction());
proto->Set(NanNew("getValue"), NanNew<FunctionTemplate>(GetValue)->GetFunction());
proto->Set(NanNew("setValue"), NanNew<FunctionTemplate>(SetValue)->GetFunction());
void List::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
Nan::SetPrototypeMethod(proto, "getLength", GetLength);
Nan::SetPrototypeMethod(proto, "getSeparator", GetSeparator);
Nan::SetPrototypeMethod(proto, "setSeparator", SetSeparator);
Nan::SetPrototypeMethod(proto, "getValue", GetValue);
Nan::SetPrototypeMethod(proto, "setValue", SetValue);
}
NAN_METHOD(List::GetValue) {
NanScope();
if (args.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument"));
if (info.Length() != 1) {
return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
}
if (!args[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied index should be an integer"));
if (!info[0]->IsNumber()) {
return Nan::ThrowError(Nan::New("Supplied index should be an integer").ToLocalChecked());
}
Sass_Value* list = unwrap(args.This())->value;
size_t index = args[0]->ToInt32()->Value();
Sass_Value* list = unwrap(info.This())->value;
size_t index = info[0]->ToInt32()->Value();
if (index >= sass_list_get_length(list)) {
return NanThrowError(NanNew("Out of bound index"));
return Nan::ThrowError(Nan::New("Out of bound index").ToLocalChecked());
}
NanReturnValue(Factory::create(sass_list_get_value(list, args[0]->ToInt32()->Value()))->get_js_object());
info.GetReturnValue().Set(Factory::create(sass_list_get_value(list, info[0]->ToInt32()->Value()))->get_js_object());
}
NAN_METHOD(List::SetValue) {
if (args.Length() != 2) {
return NanThrowError(NanNew("Expected two arguments"));
if (info.Length() != 2) {
return Nan::ThrowError(Nan::New("Expected two arguments").ToLocalChecked());
}
if (!args[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied index should be an integer"));
if (!info[0]->IsNumber()) {
return Nan::ThrowError(Nan::New("Supplied index should be an integer").ToLocalChecked());
}
if (!args[1]->IsObject()) {
return NanThrowError(NanNew("Supplied value should be a SassValue object"));
if (!info[1]->IsObject()) {
return Nan::ThrowError(Nan::New("Supplied value should be a SassValue object").ToLocalChecked());
}
Value* sass_value = Factory::unwrap(args[1]);
sass_list_set_value(unwrap(args.This())->value, args[0]->ToInt32()->Value(), sass_value->get_sass_value());
NanReturnUndefined();
Value* sass_value = Factory::unwrap(info[1]);
sass_list_set_value(unwrap(info.This())->value, info[0]->ToInt32()->Value(), sass_value->get_sass_value());
return;
}
NAN_METHOD(List::GetSeparator) {
NanScope();
NanReturnValue(NanNew(sass_list_get_separator(unwrap(args.This())->value) == SASS_COMMA));
info.GetReturnValue().Set(Nan::New(sass_list_get_separator(unwrap(info.This())->value) == SASS_COMMA));
}
NAN_METHOD(List::SetSeparator) {
if (args.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument"));
if (info.Length() != 1) {
return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
}
if (!args[0]->IsBoolean()) {
return NanThrowError(NanNew("Supplied value should be a boolean"));
if (!info[0]->IsBoolean()) {
return Nan::ThrowError(Nan::New("Supplied value should be a boolean").ToLocalChecked());
}
sass_list_set_separator(unwrap(args.This())->value, args[0]->ToBoolean()->Value() ? SASS_COMMA : SASS_SPACE);
NanReturnUndefined();
sass_list_set_separator(unwrap(info.This())->value, info[0]->ToBoolean()->Value() ? SASS_COMMA : SASS_SPACE);
return;
}
NAN_METHOD(List::GetLength) {
NanScope();
NanReturnValue(NanNew<v8::Number>(sass_list_get_length(unwrap(args.This())->value)));
info.GetReturnValue().Set(Nan::New<v8::Number>(sass_list_get_length(unwrap(info.This())->value)));
}
}
......@@ -6,15 +6,13 @@
namespace SassTypes
{
using namespace v8;
class List : public SassValueWrapper<List> {
public:
List(Sass_Value*);
static char const* get_constructor_name() { return "SassList"; }
static Sass_Value* construct(const std::vector<Local<v8::Value>>);
static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>);
static void initPrototype(Handle<ObjectTemplate>);
static void initPrototype(v8::Local<v8::FunctionTemplate>);
static NAN_METHOD(GetValue);
static NAN_METHOD(SetValue);
......
#include <nan.h>
#include "map.h"
using namespace v8;
namespace SassTypes
{
Map::Map(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Map::construct(const std::vector<Local<v8::Value>> raw_val) {
Sass_Value* Map::construct(const std::vector<v8::Local<v8::Value>> raw_val) {
size_t length = 0;
if (raw_val.size() >= 1) {
......@@ -21,96 +19,93 @@ namespace SassTypes
return sass_make_map(length);
}
void Map::initPrototype(Handle<ObjectTemplate> proto) {
proto->Set(NanNew("getLength"), NanNew<FunctionTemplate>(GetLength)->GetFunction());
proto->Set(NanNew("getKey"), NanNew<FunctionTemplate>(GetKey)->GetFunction());
proto->Set(NanNew("setKey"), NanNew<FunctionTemplate>(SetKey)->GetFunction());
proto->Set(NanNew("getValue"), NanNew<FunctionTemplate>(GetValue)->GetFunction());
proto->Set(NanNew("setValue"), NanNew<FunctionTemplate>(SetValue)->GetFunction());
void Map::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
Nan::SetPrototypeMethod(proto, "getLength", GetLength);
Nan::SetPrototypeMethod(proto, "getKey", GetKey);
Nan::SetPrototypeMethod(proto, "setKey", SetKey);
Nan::SetPrototypeMethod(proto, "getValue", GetValue);
Nan::SetPrototypeMethod(proto, "setValue", SetValue);
}
NAN_METHOD(Map::GetValue) {
NanScope();
if (args.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument"));
if (info.Length() != 1) {
return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
}
if (!args[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied index should be an integer"));
if (!info[0]->IsNumber()) {
return Nan::ThrowError(Nan::New("Supplied index should be an integer").ToLocalChecked());
}
Sass_Value* map = unwrap(args.This())->value;
size_t index = args[0]->ToInt32()->Value();
Sass_Value* map = unwrap(info.This())->value;
size_t index = info[0]->ToInt32()->Value();
if (index >= sass_map_get_length(map)) {
return NanThrowError(NanNew("Out of bound index"));
return Nan::ThrowError(Nan::New("Out of bound index").ToLocalChecked());
}
NanReturnValue(NanNew(Factory::create(sass_map_get_value(map, args[0]->ToInt32()->Value()))->get_js_object()));
info.GetReturnValue().Set(Factory::create(sass_map_get_value(map, info[0]->ToInt32()->Value()))->get_js_object());
}
NAN_METHOD(Map::SetValue) {
if (args.Length() != 2) {
return NanThrowError(NanNew("Expected two arguments"));
if (info.Length() != 2) {
return Nan::ThrowError(Nan::New("Expected two arguments").ToLocalChecked());
}
if (!args[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied index should be an integer"));
if (!info[0]->IsNumber()) {
return Nan::ThrowError(Nan::New("Supplied index should be an integer").ToLocalChecked());
}
if (!args[1]->IsObject()) {
return NanThrowError(NanNew("Supplied value should be a SassValue object"));
if (!info[1]->IsObject()) {
return Nan::ThrowError(Nan::New("Supplied value should be a SassValue object").ToLocalChecked());
}
Value* sass_value = Factory::unwrap(args[1]);
sass_map_set_value(unwrap(args.This())->value, args[0]->ToInt32()->Value(), sass_value->get_sass_value());
NanReturnUndefined();
Value* sass_value = Factory::unwrap(info[1]);
sass_map_set_value(unwrap(info.This())->value, info[0]->ToInt32()->Value(), sass_value->get_sass_value());
return;
}
NAN_METHOD(Map::GetKey) {
NanScope();
if (args.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument"));
if (info.Length() != 1) {
return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
}
if (!args[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied index should be an integer"));
if (!info[0]->IsNumber()) {
return Nan::ThrowError(Nan::New("Supplied index should be an integer").ToLocalChecked());
}
Sass_Value* map = unwrap(args.This())->value;
size_t index = args[0]->ToInt32()->Value();
Sass_Value* map = unwrap(info.This())->value;
size_t index = info[0]->ToInt32()->Value();
if (index >= sass_map_get_length(map)) {
return NanThrowError(NanNew("Out of bound index"));
return Nan::ThrowError(Nan::New("Out of bound index").ToLocalChecked());
}
NanReturnValue(Factory::create(sass_map_get_key(map, args[0]->ToInt32()->Value()))->get_js_object());
info.GetReturnValue().Set(Factory::create(sass_map_get_key(map, info[0]->ToInt32()->Value()))->get_js_object());
}
NAN_METHOD(Map::SetKey) {
if (args.Length() != 2) {
return NanThrowError(NanNew("Expected two arguments"));
if (info.Length() != 2) {
return Nan::ThrowError(Nan::New("Expected two arguments").ToLocalChecked());
}
if (!args[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied index should be an integer"));
if (!info[0]->IsNumber()) {
return Nan::ThrowError(Nan::New("Supplied index should be an integer").ToLocalChecked());
}
if (!args[1]->IsObject()) {
return NanThrowError(NanNew("Supplied value should be a SassValue object"));
if (!info[1]->IsObject()) {
return Nan::ThrowError(Nan::New("Supplied value should be a SassValue object").ToLocalChecked());
}
Value* sass_value = Factory::unwrap(args[1]);
sass_map_set_key(unwrap(args.This())->value, args[0]->ToInt32()->Value(), sass_value->get_sass_value());
NanReturnUndefined();
Value* sass_value = Factory::unwrap(info[1]);
sass_map_set_key(unwrap(info.This())->value, info[0]->ToInt32()->Value(), sass_value->get_sass_value());
return;
}
NAN_METHOD(Map::GetLength) {
NanScope();
NanReturnValue(NanNew<v8::Number>(sass_map_get_length(unwrap(args.This())->value)));
info.GetReturnValue().Set(Nan::New<v8::Number>(sass_map_get_length(unwrap(info.This())->value)));
}
}
......@@ -6,15 +6,13 @@
namespace SassTypes
{
using namespace v8;
class Map : public SassValueWrapper<Map> {
public:
Map(Sass_Value*);
static char const* get_constructor_name() { return "SassMap"; }
static Sass_Value* construct(const std::vector<Local<v8::Value>>);
static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>);
static void initPrototype(Handle<ObjectTemplate>);
static void initPrototype(v8::Local<v8::FunctionTemplate>);
static NAN_METHOD(GetValue);
static NAN_METHOD(SetValue);
......
#include <nan.h>
#include "null.h"
using namespace v8;
namespace SassTypes
{
Persistent<Function> Null::constructor;
Nan::Persistent<v8::Function> Null::constructor;
bool Null::constructor_locked = false;
Null::Null() {}
......@@ -15,45 +13,49 @@ namespace SassTypes
return singleton_instance;
}
Handle<Function> Null::get_constructor() {
v8::Local<v8::Function> Null::get_constructor() {
Nan::EscapableHandleScope scope;
v8::Local<v8::Function> conslocal;
if (constructor.IsEmpty()) {
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New);
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->SetClassName(NanNew("SassNull"));
tpl->SetClassName(Nan::New("SassNull").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
NanAssignPersistent(constructor, tpl->GetFunction());
constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked());
conslocal = Nan::New(constructor);
NanAssignPersistent(get_singleton().js_object, NanNew(constructor)->NewInstance());
NanSetInternalFieldPointer(NanNew(get_singleton().js_object), 0, &get_singleton());
NanNew(constructor)->Set(NanNew("NULL"), NanNew(get_singleton().js_object));
get_singleton().js_object.Reset(conslocal->NewInstance());
Nan::SetInternalFieldPointer(Nan::New(get_singleton().js_object), 0, &get_singleton());
Nan::Set(conslocal, Nan::New("NULL").ToLocalChecked(), Nan::New(get_singleton().js_object));
constructor_locked = true;
} else {
conslocal = Nan::New(constructor);
}
return NanNew(constructor);
return scope.Escape(conslocal);
}
Sass_Value* Null::get_sass_value() {
return sass_make_null();
}
Local<Object> Null::get_js_object() {
return NanNew(this->js_object);
v8::Local<v8::Object> Null::get_js_object() {
return Nan::New(this->js_object);
}
NAN_METHOD(Null::New) {
NanScope();
if (args.IsConstructCall()) {
if (info.IsConstructCall()) {
if (constructor_locked) {
return NanThrowError(NanNew("Cannot instantiate SassNull"));
return Nan::ThrowError(Nan::New("Cannot instantiate SassNull").ToLocalChecked());
}
}
else {
NanReturnValue(NanNew(get_singleton().get_js_object()));
info.GetReturnValue().Set(get_singleton().get_js_object());
}
NanReturnUndefined();
return;
}
}
......@@ -6,24 +6,22 @@
namespace SassTypes
{
using namespace v8;
class Null : public Value {
class Null : public SassTypes::Value {
public:
static Null& get_singleton();
static Handle<Function> get_constructor();
static v8::Local<v8::Function> get_constructor();
Sass_Value* get_sass_value();
Local<Object> get_js_object();
v8::Local<v8::Object> get_js_object();
static NAN_METHOD(New);
private:
Null();
Persistent<Object> js_object;
Nan::Persistent<v8::Object> js_object;
static Persistent<Function> constructor;
static Nan::Persistent<v8::Function> constructor;
static bool constructor_locked;
};
}
......
......@@ -2,13 +2,11 @@
#include "number.h"
#include "../create_string.h"
using namespace v8;
namespace SassTypes
{
Number::Number(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Number::construct(const std::vector<Local<v8::Value>> raw_val) {
Sass_Value* Number::construct(const std::vector<v8::Local<v8::Value>> raw_val) {
double value = 0;
char const* unit = "";
......@@ -31,48 +29,45 @@ namespace SassTypes
return sass_make_number(value, unit);
}
void Number::initPrototype(Handle<ObjectTemplate> proto) {
proto->Set(NanNew("getValue"), NanNew<FunctionTemplate>(GetValue)->GetFunction());
proto->Set(NanNew("getUnit"), NanNew<FunctionTemplate>(GetUnit)->GetFunction());
proto->Set(NanNew("setValue"), NanNew<FunctionTemplate>(SetValue)->GetFunction());
proto->Set(NanNew("setUnit"), NanNew<FunctionTemplate>(SetUnit)->GetFunction());
void Number::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
Nan::SetPrototypeMethod(proto, "getValue", GetValue);
Nan::SetPrototypeMethod(proto, "getUnit", GetUnit);
Nan::SetPrototypeMethod(proto, "setValue", SetValue);
Nan::SetPrototypeMethod(proto, "setUnit", SetUnit);
}
NAN_METHOD(Number::GetValue) {
NanScope();
NanReturnValue(NanNew(sass_number_get_value(unwrap(args.This())->value)));
info.GetReturnValue().Set(Nan::New<v8::Number>(sass_number_get_value(unwrap(info.This())->value)));
}
NAN_METHOD(Number::GetUnit) {
NanScope();
NanReturnValue(NanNew(sass_number_get_unit(unwrap(args.This())->value)));
info.GetReturnValue().Set(Nan::New<v8::String>(sass_number_get_unit(unwrap(info.This())->value)).ToLocalChecked());
}
NAN_METHOD(Number::SetValue) {
NanScope();
if (args.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument"));
if (info.Length() != 1) {
return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
}
if (!args[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied value should be a number"));
if (!info[0]->IsNumber()) {
return Nan::ThrowError(Nan::New("Supplied value should be a number").ToLocalChecked());
}
sass_number_set_value(unwrap(args.This())->value, args[0]->ToNumber()->Value());
NanReturnUndefined();
sass_number_set_value(unwrap(info.This())->value, info[0]->ToNumber()->Value());
return;
}
NAN_METHOD(Number::SetUnit) {
if (args.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument"));
if (info.Length() != 1) {
return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
}
if (!args[0]->IsString()) {
return NanThrowError(NanNew("Supplied value should be a string"));
if (!info[0]->IsString()) {
return Nan::ThrowError(Nan::New("Supplied value should be a string").ToLocalChecked());
}
sass_number_set_unit(unwrap(args.This())->value, create_string(args[0]));
NanReturnUndefined();
sass_number_set_unit(unwrap(info.This())->value, create_string(info[0]));
return;
}
}
......@@ -6,15 +6,14 @@
namespace SassTypes
{
using namespace v8;
class Number : public SassValueWrapper<Number> {
public:
Number(Sass_Value*);
static char const* get_constructor_name() { return "SassNumber"; }
static Sass_Value* construct(const std::vector<Local<v8::Value>>);
static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>);
static void initPrototype(Handle<ObjectTemplate>);
static void initPrototype(v8::Local<v8::FunctionTemplate>);
static NAN_METHOD(GetValue);
static NAN_METHOD(GetUnit);
......
......@@ -9,12 +9,10 @@
namespace SassTypes
{
using namespace v8;
// Include this in any SassTypes::Value subclasses to handle all the heavy lifting of constructing JS
// objects and wrapping sass values inside them
template <class T>
class SassValueWrapper : public Value {
class SassValueWrapper : public SassTypes::Value {
public:
static char const* get_constructor_name() { return "SassValue"; }
......@@ -22,23 +20,23 @@ namespace SassTypes
virtual ~SassValueWrapper();
Sass_Value* get_sass_value();
Local<Object> get_js_object();
v8::Local<v8::Object> get_js_object();
static Handle<Function> get_constructor();
static Local<FunctionTemplate> get_constructor_template();
static v8::Local<v8::Function> get_constructor();
static v8::Local<v8::FunctionTemplate> get_constructor_template();
static NAN_METHOD(New);
protected:
Sass_Value* value;
static T* unwrap(Local<Object>);
static T* unwrap(v8::Local<v8::Object>);
private:
static Persistent<Function> constructor;
Persistent<Object> js_object;
static Nan::Persistent<v8::Function> constructor;
Nan::Persistent<v8::Object> js_object;
};
template <class T>
Persistent<Function> SassValueWrapper<T>::constructor;
Nan::Persistent<v8::Function> SassValueWrapper<T>::constructor;
template <class T>
SassValueWrapper<T>::SassValueWrapper(Sass_Value* v) {
......@@ -47,7 +45,7 @@ namespace SassTypes
template <class T>
SassValueWrapper<T>::~SassValueWrapper() {
NanDisposePersistent(this->js_object);
this->js_object.Reset();
sass_delete_value(this->value);
}
......@@ -57,74 +55,64 @@ namespace SassTypes
}
template <class T>
Local<Object> SassValueWrapper<T>::get_js_object() {
v8::Local<v8::Object> SassValueWrapper<T>::get_js_object() {
if (this->js_object.IsEmpty()) {
Local<Object> wrapper = NanNew(T::get_constructor())->NewInstance();
delete static_cast<T*>(NanGetInternalFieldPointer(wrapper, 0));
NanSetInternalFieldPointer(wrapper, 0, this);
NanAssignPersistent(this->js_object, wrapper);
v8::Local<v8::Object> wrapper = Nan::NewInstance(T::get_constructor()).ToLocalChecked();
delete static_cast<T*>(Nan::GetInternalFieldPointer(wrapper, 0));
Nan::SetInternalFieldPointer(wrapper, 0, this);
this->js_object.Reset(wrapper);
}
return NanNew(this->js_object);
return Nan::New(this->js_object);
}
template <class T>
Local<FunctionTemplate> SassValueWrapper<T>::get_constructor_template() {
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New);
tpl->SetClassName(NanNew(NanNew(T::get_constructor_name())));
v8::Local<v8::FunctionTemplate> SassValueWrapper<T>::get_constructor_template() {
Nan::EscapableHandleScope scope;
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->SetClassName(Nan::New<v8::String>(T::get_constructor_name()).ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
T::initPrototype(tpl->PrototypeTemplate());
T::initPrototype(tpl);
return tpl;
return scope.Escape(tpl);
}
template <class T>
Handle<Function> SassValueWrapper<T>::get_constructor() {
v8::Local<v8::Function> SassValueWrapper<T>::get_constructor() {
if (constructor.IsEmpty()) {
NanAssignPersistent(constructor, T::get_constructor_template()->GetFunction());
constructor.Reset(Nan::GetFunction(T::get_constructor_template()).ToLocalChecked());
}
return NanNew(constructor);
return Nan::New(constructor);
}
template <class T>
NAN_METHOD(SassValueWrapper<T>::New) {
NanScope();
if (!args.IsConstructCall()) {
unsigned argc = args.Length();
std::vector<Handle<v8::Value>> argv;
argv.reserve(argc);
for (unsigned i = 0; i < argc; i++) {
argv.push_back(args[i]);
}
NanReturnValue(NanNew(T::get_constructor())->NewInstance(argc, &argv[0]));
}
std::vector<Local<v8::Value>> localArgs(args.Length());
std::vector<v8::Local<v8::Value>> localArgs(info.Length());
for (auto i = 0; i < args.Length(); ++i) {
localArgs[i] = args[i];
for (auto i = 0; i < info.Length(); ++i) {
localArgs[i] = info[i];
}
if (info.IsConstructCall()) {
try {
Sass_Value* value = T::construct(localArgs);
T* obj = new T(value);
sass_delete_value(value);
NanSetInternalFieldPointer(args.This(), 0, obj);
NanAssignPersistent(obj->js_object, args.This());
Nan::SetInternalFieldPointer(info.This(), 0, obj);
obj->js_object.Reset(info.This());
} catch (const std::exception& e) {
return NanThrowError(NanNew(e.what()));
return Nan::ThrowError(Nan::New<v8::String>(e.what()).ToLocalChecked());
}
} else {
v8::Local<v8::Function> cons = T::get_constructor();
v8::Local<v8::Object> inst = cons->NewInstance(info.Length(), &localArgs[0]);
info.GetReturnValue().Set(inst);
}
NanReturnUndefined();
}
template <class T>
T* SassValueWrapper<T>::unwrap(Local<Object> obj) {
T* SassValueWrapper<T>::unwrap(v8::Local<v8::Object> obj) {
return static_cast<T*>(Factory::unwrap(obj));
}
}
......
......@@ -2,13 +2,11 @@
#include "string.h"
#include "../create_string.h"
using namespace v8;
namespace SassTypes
{
String::String(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* String::construct(const std::vector<Local<v8::Value>> raw_val) {
Sass_Value* String::construct(const std::vector<v8::Local<v8::Value>> raw_val) {
char const* value = "";
if (raw_val.size() >= 1) {
......@@ -22,26 +20,25 @@ namespace SassTypes
return sass_make_string(value);
}
void String::initPrototype(Handle<ObjectTemplate> proto) {
proto->Set(NanNew("getValue"), NanNew<FunctionTemplate>(GetValue)->GetFunction());
proto->Set(NanNew("setValue"), NanNew<FunctionTemplate>(SetValue)->GetFunction());
void String::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
Nan::SetPrototypeMethod(proto, "getValue", GetValue);
Nan::SetPrototypeMethod(proto, "setValue", SetValue);
}
NAN_METHOD(String::GetValue) {
NanScope();
NanReturnValue(NanNew(sass_string_get_value(unwrap(args.This())->value)));
info.GetReturnValue().Set(Nan::New<v8::String>(sass_string_get_value(unwrap(info.This())->value)).ToLocalChecked());
}
NAN_METHOD(String::SetValue) {
if (args.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument"));
if (info.Length() != 1) {
return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
}
if (!args[0]->IsString()) {
return NanThrowError(NanNew("Supplied value should be a string"));
if (!info[0]->IsString()) {
return Nan::ThrowError(Nan::New("Supplied value should be a string").ToLocalChecked());
}
sass_string_set_value(unwrap(args.This())->value, create_string(args[0]));
NanReturnUndefined();
sass_string_set_value(unwrap(info.This())->value, create_string(info[0]));
return;
}
}
......@@ -6,15 +6,13 @@
namespace SassTypes
{
using namespace v8;
class String : public SassValueWrapper<String> {
public:
String(Sass_Value*);
static char const* get_constructor_name() { return "SassString"; }
static Sass_Value* construct(const std::vector<Local<v8::Value>>);
static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>);
static void initPrototype(Handle<ObjectTemplate>);
static void initPrototype(v8::Local<v8::FunctionTemplate>);
static NAN_METHOD(GetValue);
static NAN_METHOD(SetValue);
......
......@@ -6,13 +6,11 @@
namespace SassTypes
{
using namespace v8;
// This is the interface that all sass values must comply with
class Value {
public:
virtual Sass_Value* get_sass_value() =0;
virtual Local<Object> get_js_object() =0;
virtual v8::Local<v8::Object> get_js_object() =0;
};
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment