Left: | ||
Right: |
OLD | NEW |
---|---|
1 #include <vector> | |
2 #include <stdexcept> | |
3 | |
1 #include "GlobalJsObject.h" | 4 #include "GlobalJsObject.h" |
5 #include "Thread.h" | |
2 | 6 |
3 using namespace AdblockPlus; | 7 using namespace AdblockPlus; |
4 | 8 |
9 namespace | |
10 { | |
11 class TimeoutThread : public Thread | |
12 { | |
13 public: | |
14 TimeoutThread(v8::Isolate* const isolate, const v8::Arguments& arguments) | |
15 : isolate(isolate) | |
16 { | |
17 if (arguments.Length() < 2) | |
18 throw std::runtime_error("setTimeout requires at least 2 parameters"); | |
19 | |
20 const v8::Local<v8::Value> functionValue = arguments[0]; | |
21 if (!functionValue->IsFunction()) | |
22 throw std::runtime_error("No valid function passed to setTimeout"); | |
Wladimir Palant
2013/04/08 14:03:47
Nit: I think the canonical message is: "First argu
| |
23 | |
24 const v8::Local<v8::Value> delayValue = arguments[1]; | |
25 if (!delayValue->IsNumber()) | |
26 throw std::runtime_error("No valid delay passed to setTimeout"); | |
Wladimir Palant
2013/04/08 14:03:47
Nit: I think the canonical message is: "Second arg
| |
27 | |
28 function = v8::Persistent<v8::Function>::New( | |
29 isolate, v8::Local<v8::Function>::Cast(functionValue)); | |
30 delay = delayValue->ToNumber()->Value(); | |
31 for (int i = 2; i < arguments.Length(); i++) | |
32 { | |
33 const Value argument = Value::New(isolate, arguments[i]); | |
34 functionArguments.push_back(argument); | |
35 } | |
36 } | |
37 | |
38 ~TimeoutThread() | |
39 { | |
40 function.Dispose(isolate); | |
41 for (Values::iterator it = functionArguments.begin(); | |
42 it != functionArguments.end(); it++) | |
43 it->Dispose(isolate); | |
44 } | |
45 | |
46 void Run() | |
47 { | |
48 Sleep(delay); | |
49 const v8::Locker locker(isolate); | |
50 const v8::HandleScope handleScope; | |
51 function->Call(function, functionArguments.size(), &functionArguments[0]); | |
52 delete this; | |
53 } | |
54 | |
55 private: | |
56 typedef v8::Persistent<v8::Value> Value; | |
57 typedef std::vector<Value> Values; | |
58 | |
59 v8::Isolate* const isolate; | |
60 v8::Persistent<v8::Function> function; | |
61 int delay; | |
62 Values functionArguments; | |
63 }; | |
64 | |
65 v8::Handle<v8::Value> SetTimeoutCallback(const v8::Arguments& arguments) | |
66 { | |
67 TimeoutThread* timeoutThread; | |
68 try | |
69 { | |
70 timeoutThread = new TimeoutThread(v8::Isolate::GetCurrent(), arguments); | |
71 } | |
72 catch (const std::exception& e) | |
73 { | |
74 return v8::ThrowException(v8::String::New(e.what())); | |
75 } | |
76 timeoutThread->Start(); | |
77 | |
78 // We should actually return the timer ID here, which could be | |
79 // used via clearTimeout(). But since we don't seem to need | |
80 // clearTimeout(), we can save that for later. | |
81 return v8::Undefined(); | |
82 } | |
83 } | |
84 | |
5 v8::Handle<v8::ObjectTemplate> GlobalJsObject::Create( | 85 v8::Handle<v8::ObjectTemplate> GlobalJsObject::Create( |
6 ErrorCallback& errorCallback) | 86 ErrorCallback& errorCallback) |
7 { | 87 { |
8 const v8::Locker locker(v8::Isolate::GetCurrent()); | 88 const v8::Locker locker(v8::Isolate::GetCurrent()); |
9 v8::HandleScope handleScope; | 89 v8::HandleScope handleScope; |
10 const v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); | 90 const v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); |
11 const v8::Handle<v8::ObjectTemplate> console = | 91 const v8::Handle<v8::ObjectTemplate> console = |
12 AdblockPlus::ConsoleJsObject::Create(errorCallback); | 92 AdblockPlus::ConsoleJsObject::Create(errorCallback); |
13 global->Set(v8::String::New("console"), console); | 93 global->Set(v8::String::New("console"), console); |
94 const v8::Handle<v8::FunctionTemplate> setTimeoutFunction = | |
95 v8::FunctionTemplate::New(SetTimeoutCallback); | |
96 global->Set(v8::String::New("setTimeout"), setTimeoutFunction); | |
14 return handleScope.Close(global); | 97 return handleScope.Close(global); |
15 } | 98 } |
OLD | NEW |