blob: 52a351187330f1ddb2259b4ce71c308cbded2cc4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#ifndef SASS_TYPES_SASS_VALUE_WRAPPER_H
#define SASS_TYPES_SASS_VALUE_WRAPPER_H
#include <stdexcept>
#include <vector>
#include <nan.h>
#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 T>
/* 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<v8::Object> get_js_object();
static v8::Local<v8::Function> get_constructor();
static v8::Local<v8::FunctionTemplate> get_constructor_template();
static NAN_METHOD(New);
static Sass_Value *fail(const char *, Sass_Value **);
/* private: */
static Nan::Persistent<v8::Function> constructor;
};
template <class T>
Nan::Persistent<v8::Function> SassValueWrapper<T>::constructor;
template <class T>
v8::Local<v8::Object> SassValueWrapper<T>::get_js_object() {
if (this->persistent().IsEmpty()) {
v8::Local<v8::Object> wrapper = Nan::NewInstance(T::get_constructor()).ToLocalChecked();
this->Wrap(wrapper);
}
return this->handle();
}
template <class T>
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);
return scope.Escape(tpl);
}
template <class T>
v8::Local<v8::Function> SassValueWrapper<T>::get_constructor() {
if (constructor.IsEmpty()) {
constructor.Reset(Nan::GetFunction(T::get_constructor_template()).ToLocalChecked());
}
return Nan::New(constructor);
}
template <class T>
NAN_METHOD(SassValueWrapper<T>::New) {
std::vector<v8::Local<v8::Value>> 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<v8::String>(sass_error_get_message(value)).ToLocalChecked());
}
} else {
v8::Local<v8::Function> cons = T::get_constructor();
v8::Local<v8::Object> inst;
if (Nan::NewInstance(cons, info.Length(), &localArgs[0]).ToLocal(&inst)) {
info.GetReturnValue().Set(inst);
} else {
info.GetReturnValue().Set(Nan::Undefined());
}
}
}
template <class T>
Sass_Value *SassValueWrapper<T>::fail(const char *reason, Sass_Value **out) {
*out = sass_make_error(reason);
return NULL;
}
}
#endif
|