This repository has been archived by the owner on Dec 16, 2023. It is now read-only.
/
windowcontext.cc
119 lines (99 loc) · 3.87 KB
/
windowcontext.cc
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <v8.h>
#include <node.h>
using namespace node;
using namespace v8;
class WindowContext: ObjectWrap {
private:
// V8 Context we evaluate all code in.
Persistent<Context> context;
// Global scope provides access to properties and methods.
Persistent<Object> global;
public:
static Persistent<FunctionTemplate> s_ct;
static void Init(Handle<Object> target) {
Local<FunctionTemplate> t = FunctionTemplate::New(New);
s_ct = Persistent<FunctionTemplate>::New(t);
s_ct->InstanceTemplate()->SetInternalFieldCount(1);
s_ct->SetClassName(String::NewSymbol("WindowContext"));
Local<ObjectTemplate> instance_t = t->InstanceTemplate();
instance_t->SetAccessor(String::New("global"), GetGlobal);
NODE_SET_PROTOTYPE_METHOD(s_ct, "evaluate", Evaluate);
target->Set(String::NewSymbol("WindowContext"), s_ct->GetFunction());
}
// Create a new wrapper context around the global object.
WindowContext(Handle<Object> global) {
Handle<ObjectTemplate> tmpl = ObjectTemplate::New();
this->global = Persistent<Object>::New(global);
tmpl->SetNamedPropertyHandler(GetProperty, SetProperty, NULL, DeleteProperty, EnumerateProperties, this->global);
context = Context::New(NULL, tmpl);
}
~WindowContext() {
global.Dispose();
context.Dispose();
}
// Takes single argument, the global object.
static Handle<Value> New(const Arguments& args) {
WindowContext* wc = new WindowContext(Handle<Object>::Cast(args[0]));
wc->Wrap(args.This());
return args.This();
}
// Returns the global object.
static Handle<Value> GetGlobal(Local<String> name, const AccessorInfo& info) {
WindowContext* wc = ObjectWrap::Unwrap<WindowContext>(info.This());
return wc->global;
}
// Evaluate expression or function in this context. First argument is either
// a function or a script (String). In the later case, second argument
// specifies filename.
static Handle<Value> Evaluate(const Arguments& args) {
WindowContext* wc = ObjectWrap::Unwrap<WindowContext>(args.This());
Handle<Value> result;
wc->context->Enter();
if (args[0]->IsFunction()) {
// Execute function in the global scope.
Function *fn = Function::Cast(*args[0]);
result = fn->Call(wc->global, 0, NULL);
} else {
// Coerce argument into a string and execute that as a function.
Local<String> source = args[0]->ToString();
Local<String> filename = args[1]->ToString();
Handle<Script> script = Script::New(source, filename);
result = script->Run();
}
wc->context->Exit();
HandleScope scope;
return scope.Close(result);
}
// Returns the value of a property from the global scope.
static Handle<Value> GetProperty(Local<String> name, const AccessorInfo &info) {
HandleScope scope;
Local<Object> self = Local<Object>::Cast(info.Data());
Handle<Value> result = self->Get(name);
return scope.Close(result);
}
// Sets the value of a property in the global scope.
static Handle<Value> SetProperty(Local<String> name, Local<Value> value, const AccessorInfo &info) {
Local<Object> self = Local<Object>::Cast(info.Data());
self->Set(name, value);
return value;
}
// Deletes a property from the global scope.
static Handle<Boolean> DeleteProperty(Local<String> name, const AccessorInfo &info) {
Local<Object> self = Local<Object>::Cast(info.Data());
Handle<Boolean> result = Boolean::New(self->Delete(name));
return result;
}
// Enumerate all named properties in the global scope.
static Handle<Array> EnumerateProperties(const AccessorInfo &info) {
Local<Object> self = Local<Object>::Cast(info.Data());
Handle<Array> names = self->GetPropertyNames();
return names;
}
};
Persistent<FunctionTemplate> WindowContext::s_ct;
extern "C" {
static void init(Handle<Object> target) {
WindowContext::Init(target);
}
NODE_MODULE(windowcontext, init);
}