#ifndef SASS_TYPES_SASS_VALUE_WRAPPER_H #define SASS_TYPES_SASS_VALUE_WRAPPER_H #include #include #include #include "value.h" #include "factory.h" namespace SassTypes { // 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 SassValueWrapper : public SassTypes::Value { */ class SassValueWrapper : public SassTypes::Value { public: static char const* get_constructor_name() { return "SassValue"; } SassValueWrapper(Sass_Value* v) : Value(v) { } v8::Local get_js_object(); static v8::Local get_constructor(); static v8::Local get_constructor_template(); static NAN_METHOD(New); static Sass_Value *fail(const char *, Sass_Value **); /* private: */ static Nan::Persistent constructor; }; template Nan::Persistent SassValueWrapper::constructor; template v8::Local SassValueWrapper::get_js_object() { if (this->persistent().IsEmpty()) { v8::Local wrapper = Nan::NewInstance(T::get_constructor()).ToLocalChecked(); this->Wrap(wrapper); } return this->handle(); } template v8::Local SassValueWrapper::get_constructor_template() { Nan::EscapableHandleScope scope; v8::Local tpl = Nan::New(New); tpl->SetClassName(Nan::New(T::get_constructor_name()).ToLocalChecked()); tpl->InstanceTemplate()->SetInternalFieldCount(1); T::initPrototype(tpl); return scope.Escape(tpl); } template v8::Local SassValueWrapper::get_constructor() { if (constructor.IsEmpty()) { constructor.Reset(Nan::GetFunction(T::get_constructor_template()).ToLocalChecked()); } return Nan::New(constructor); } template NAN_METHOD(SassValueWrapper::New) { std::vector> localArgs(info.Length()); for (auto i = 0; i < info.Length(); ++i) { localArgs[i] = info[i]; } if (info.IsConstructCall()) { Sass_Value* value; if (T::construct(localArgs, &value) != NULL) { T* obj = new T(value); sass_delete_value(value); obj->Wrap(info.This()); info.GetReturnValue().Set(info.This()); } else { return Nan::ThrowError(Nan::New(sass_error_get_message(value)).ToLocalChecked()); } } else { v8::Local cons = T::get_constructor(); v8::Local inst; if (Nan::NewInstance(cons, info.Length(), &localArgs[0]).ToLocal(&inst)) { info.GetReturnValue().Set(inst); } else { info.GetReturnValue().Set(Nan::Undefined()); } } } template Sass_Value *SassValueWrapper::fail(const char *reason, Sass_Value **out) { *out = sass_make_error(reason); return NULL; } } #endif