Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(339)

Side by Side Diff: webkit/port/bindings/v8/V8WorkerCustom.cpp

Issue 17246: Add V8 bindings for Worker (Part I). (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/port/bindings/v8/Threading.cpp ('k') | webkit/port/bindings/v8/WorkerScriptController.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2008, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 #if ENABLE(WORKERS)
31
32 #include "config.h"
33
34 #include "v8_binding.h"
35 #include "v8_custom.h"
36 #include "v8_events.h"
37 #include "v8_proxy.h"
38
39 #include "V8Document.h"
40 #include "V8HTMLDocument.h"
41
42 #include "ExceptionCode.h"
43 #include "MessagePort.h"
44 #include "Worker.h"
45
46 namespace WebCore {
47
48 CALLBACK_FUNC_DECL(WorkerConstructor) {
49 INC_STATS(L"DOM.Worker.Constructor");
50
51 if (!args.IsConstructCall()) {
52 V8Proxy::ThrowError(V8Proxy::TYPE_ERROR,
53 "DOM object constructor cannot be called as a function.");
54 return v8::Undefined();
55 }
56
57 if (args.Length() == 0) {
58 V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
59 return v8::Undefined();
60 }
61
62 v8::TryCatch try_catch;
63 v8::Handle<v8::String> script_url = args[0]->ToString();
64 if (try_catch.HasCaught()) {
65 v8::ThrowException(try_catch.Exception());
66 return v8::Undefined();
67 }
68 if (script_url.IsEmpty()) {
69 return v8::Undefined();
70 }
71
72 // Get the document.
73 Frame* frame = V8Proxy::retrieveFrame();
74 if (!frame)
75 return v8::Undefined();
76 Document* document = frame->document();
77
78 // Create the worker object.
79 // Note: it's OK to let this RefPtr go out of scope because we also call
80 // SetDOMWrapper(), which effectively holds a reference to obj.
81 ExceptionCode ec = 0;
82 RefPtr<Worker> obj = Worker::create(
83 ToWebCoreString(script_url), document, ec);
84
85 // Setup the standard wrapper object internal fields.
86 v8::Handle<v8::Object> wrapper_object = args.Holder();
87 V8Proxy::SetDOMWrapper(
88 wrapper_object, V8ClassIndex::WORKER, obj.get());
89
90 obj->ref();
91 V8Proxy::SetJSWrapperForDOMObject(
92 obj.get(), v8::Persistent<v8::Object>::New(wrapper_object));
93
94 return wrapper_object;
95 }
96
97 // TODO(mbelshe) - merge these with XHR's CreateHiddenXHRDependency
98
99 // Use an array to hold dependents. It works like a ref-counted scheme.
100 // A value can be added more than once to the xhr object.
101 static void CreateHiddenDependency(v8::Local<v8::Object> object,
102 v8::Local<v8::Value> value) {
103 ASSERT(V8Proxy::GetDOMWrapperType(object) ==
104 V8ClassIndex::WORKER);
105 v8::Local<v8::Value> cache =
106 object->GetInternalField(V8Custom::kWorkerRequestCacheIndex);
107 if (cache->IsNull() || cache->IsUndefined()) {
108 cache = v8::Array::New();
109 object->SetInternalField(V8Custom::kWorkerRequestCacheIndex, cache);
110 }
111
112 v8::Local<v8::Array> cache_array = v8::Local<v8::Array>::Cast(cache);
113 cache_array->Set(v8::Integer::New(cache_array->Length()), value);
114 }
115
116 static void RemoveHiddenDependency(v8::Local<v8::Object> object,
117 v8::Local<v8::Value> value) {
118 ASSERT(V8Proxy::GetDOMWrapperType(object) == V8ClassIndex::WORKER);
119 v8::Local<v8::Value> cache =
120 object->GetInternalField(V8Custom::kWorkerRequestCacheIndex);
121 ASSERT(cache->IsArray());
122 v8::Local<v8::Array> cache_array = v8::Local<v8::Array>::Cast(cache);
123 for (int i = cache_array->Length() - 1; i >= 0; i--) {
124 v8::Local<v8::Value> cached = cache_array->Get(v8::Integer::New(i));
125 if (cached->StrictEquals(value)) {
126 cache_array->Delete(i);
127 return;
128 }
129 }
130
131 // We should only get here if we try to remove an event listener that was
132 // never added.
133 }
134
135 ACCESSOR_GETTER(WorkerOnmessage) {
136 INC_STATS(L"DOM.Worker.onmessage._get");
137 Worker* imp = V8Proxy::ToNativeObject<Worker>(
138 V8ClassIndex::WORKER, info.Holder());
139 if (imp->onmessage()) {
140 V8ObjectEventListener* listener =
141 static_cast<V8ObjectEventListener*>(imp->onmessage());
142 v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
143 return v8_listener;
144 }
145 return v8::Undefined();
146 }
147
148 ACCESSOR_SETTER(WorkerOnmessage) {
149 INC_STATS(L"DOM.Worker.onmessage._set");
150 Worker* imp = V8Proxy::ToNativeObject<Worker>(
151 V8ClassIndex::WORKER, info.Holder());
152 V8ObjectEventListener* old_listener =
153 static_cast<V8ObjectEventListener*>(imp->onmessage());
154 if (value->IsNull()) {
155 if (old_listener) {
156 v8::Local<v8::Object> old_v8_listener = old_listener->GetListenerObject();
157 RemoveHiddenDependency(info.Holder(), old_v8_listener);
158 }
159
160 // Clear the listener
161 imp->setOnmessage(0);
162
163 } else {
164 V8Proxy* proxy = V8Proxy::retrieve(imp->scriptExecutionContext());
165 if (!proxy)
166 return;
167
168 RefPtr<EventListener> listener =
169 proxy->FindOrCreateObjectEventListener(value, false);
170 if (listener) {
171 if (old_listener) {
172 v8::Local<v8::Object> old_v8_listener =
173 old_listener->GetListenerObject();
174 RemoveHiddenDependency(info.Holder(), old_v8_listener);
175 }
176
177 imp->setOnmessage(listener);
178 CreateHiddenDependency(info.Holder(), value);
179 }
180 }
181 }
182
183 ACCESSOR_GETTER(WorkerOnerror) {
184 INC_STATS(L"DOM.Worker.onerror._get");
185 Worker* imp = V8Proxy::ToNativeObject<Worker>(
186 V8ClassIndex::WORKER, info.Holder());
187 if (imp->onerror()) {
188 V8ObjectEventListener* listener =
189 static_cast<V8ObjectEventListener*>(imp->onerror());
190 v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
191 return v8_listener;
192 }
193 return v8::Undefined();
194 }
195
196 ACCESSOR_SETTER(WorkerOnerror) {
197 INC_STATS(L"DOM.Worker.onerror._set");
198 Worker* imp = V8Proxy::ToNativeObject<Worker>(
199 V8ClassIndex::WORKER, info.Holder());
200 V8ObjectEventListener* old_listener =
201 static_cast<V8ObjectEventListener*>(imp->onerror());
202 if (value->IsNull()) {
203 if (old_listener) {
204 v8::Local<v8::Object> old_v8_listener =
205 old_listener->GetListenerObject();
206 RemoveHiddenDependency(info.Holder(), old_v8_listener);
207 }
208
209 // Clear the listener
210 imp->setOnerror(0);
211 } else {
212 V8Proxy* proxy = V8Proxy::retrieve(imp->scriptExecutionContext());
213 if (!proxy)
214 return;
215
216 RefPtr<EventListener> listener =
217 proxy->FindOrCreateObjectEventListener(value, false);
218 if (listener) {
219 if (old_listener) {
220 v8::Local<v8::Object> old_v8_listener = old_listener->GetListenerObject( );
221 RemoveHiddenDependency(info.Holder(), old_v8_listener);
222 }
223
224 imp->setOnerror(listener);
225 CreateHiddenDependency(info.Holder(), value);
226 }
227 }
228 }
229
230 CALLBACK_FUNC_DECL(WorkerAddEventListener) {
231 INC_STATS(L"DOM.Worker.addEventListener()");
232 Worker* imp = V8Proxy::ToNativeObject<Worker>(
233 V8ClassIndex::WORKER, args.Holder());
234
235 V8Proxy* proxy = V8Proxy::retrieve(imp->scriptExecutionContext());
236 if (!proxy)
237 return v8::Undefined();
238
239 RefPtr<EventListener> listener =
240 proxy->FindOrCreateObjectEventListener(args[1], false);
241 if (listener) {
242 String type = ToWebCoreString(args[0]);
243 bool useCapture = args[2]->BooleanValue();
244 imp->addEventListener(type, listener, useCapture);
245
246 CreateHiddenDependency(args.Holder(), args[1]);
247 }
248 return v8::Undefined();
249 }
250
251 CALLBACK_FUNC_DECL(WorkerRemoveEventListener) {
252 INC_STATS(L"DOM.Worker.removeEventListener()");
253 Worker* imp = V8Proxy::ToNativeObject<Worker>(
254 V8ClassIndex::WORKER, args.Holder());
255
256 V8Proxy* proxy = V8Proxy::retrieve(imp->scriptExecutionContext());
257 if (!proxy)
258 return v8::Undefined(); // probably leaked
259
260 RefPtr<EventListener> listener =
261 proxy->FindObjectEventListener(args[1], false);
262
263 if (listener) {
264 String type = ToWebCoreString(args[0]);
265 bool useCapture = args[2]->BooleanValue();
266 imp->removeEventListener(type, listener.get(), useCapture);
267
268 RemoveHiddenDependency(args.Holder(), args[1]);
269 }
270
271 return v8::Undefined();
272 }
273
274 } // namespace WebCore
275
276 #endif // ENABLE(WORKERS)
OLDNEW
« no previous file with comments | « webkit/port/bindings/v8/Threading.cpp ('k') | webkit/port/bindings/v8/WorkerScriptController.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698