b0634b92940dd04823db20bcb3c29440f8a7bede
[WebKit-https.git] / WebCore / bindings / js / JSWorkerContextCustom.cpp
1 /*
2  * Copyright (C) 2008 Apple Inc. 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27
28 #if ENABLE(WORKERS)
29
30 #include "JSWorkerContext.h"
31
32 #include "JSDOMBinding.h"
33 #include "JSEventListener.h"
34 #include "ScheduledAction.h"
35 #include "WorkerContext.h"
36 #include <interpreter/Interpreter.h>
37
38 using namespace JSC;
39
40 namespace WebCore {
41
42 bool JSWorkerContext::customGetOwnPropertySlot(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertySlot& slot)
43 {
44     // Look for overrides before looking at any of our own properties.
45     if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot))
46         return true;
47     return false;
48 }
49
50 void JSWorkerContext::mark()
51 {
52     Base::mark();
53
54     markActiveObjectsForContext(*globalData(), scriptExecutionContext());
55
56     if (JSEventListener* listener = static_cast<JSEventListener*>(impl()->onmessage()))
57         listener->mark();
58
59     typedef WorkerContext::EventListenersMap EventListenersMap;
60     typedef WorkerContext::ListenerVector ListenerVector;
61     EventListenersMap& eventListeners = impl()->eventListeners();
62     for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
63         for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
64             JSEventListener* listener = static_cast<JSEventListener*>(vecIter->get());
65             listener->mark();
66         }
67     }
68 }
69
70 JSValuePtr JSWorkerContext::self(ExecState*) const
71 {
72     return JSValuePtr(this);
73 }
74
75 void JSWorkerContext::setSelf(ExecState* exec, JSValuePtr value)
76 {
77     putDirect(Identifier(exec, "self"), value);
78 }
79
80 JSValuePtr JSWorkerContext::importScripts(ExecState* exec, const ArgList& args)
81 {
82     if (!args.size())
83         return jsUndefined();
84
85     Vector<String> urls;
86     for (unsigned i = 0; i < args.size(); i++) {
87         urls.append(args.at(exec, i).toString(exec));
88         if (exec->hadException())
89             return jsUndefined();
90     }
91     ExceptionCode ec = 0;
92     int signedLineNumber;
93     intptr_t sourceID;
94     UString sourceURL;
95     JSValuePtr function;
96     exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, sourceURL, function);
97
98     impl()->importScripts(urls, sourceURL, signedLineNumber >= 0 ? signedLineNumber : 0, ec);
99     setDOMException(exec, ec);
100     return jsUndefined();
101 }
102
103 JSValuePtr JSWorkerContext::addEventListener(ExecState* exec, const ArgList& args)
104 {
105     RefPtr<JSEventListener> listener = findOrCreateJSEventListener(exec, args.at(exec, 1));
106     if (!listener)
107         return jsUndefined();
108     impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec));
109     return jsUndefined();
110 }
111
112 JSValuePtr JSWorkerContext::removeEventListener(ExecState* exec, const ArgList& args)
113 {
114     JSEventListener* listener = findJSEventListener(exec, args.at(exec, 1));
115     if (!listener)
116         return jsUndefined();
117     impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec));
118     return jsUndefined();
119 }
120
121 static JSValuePtr setTimeoutOrInterval(ExecState* exec, WorkerContext* workerContext, const ArgList& args, bool singleShot)
122 {
123     JSValuePtr v = args.at(exec, 0);
124     int delay = args.at(exec, 1).toInt32(exec);
125     if (v.isString())
126         return jsNumber(exec, workerContext->installTimeout(new ScheduledAction(asString(v)->value()), delay, singleShot));
127     CallData callData;
128     if (v.getCallData(callData) == CallTypeNone)
129         return jsUndefined();
130     ArgList argsTail;
131     args.getSlice(2, argsTail);
132     return jsNumber(exec, workerContext->installTimeout(new ScheduledAction(exec, v, argsTail), delay, singleShot));
133 }
134
135 JSValuePtr JSWorkerContext::setTimeout(ExecState* exec, const ArgList& args)
136 {
137     return setTimeoutOrInterval(exec, impl(), args, true);
138 }
139
140 JSValuePtr JSWorkerContext::clearTimeout(ExecState* exec, const ArgList& args)
141 {
142     impl()->removeTimeout(args.at(exec, 0).toInt32(exec));
143     return jsUndefined();
144 }
145
146 JSValuePtr JSWorkerContext::setInterval(ExecState* exec, const ArgList& args)
147 {
148     return setTimeoutOrInterval(exec, impl(), args, false);
149 }
150
151 JSValuePtr JSWorkerContext::clearInterval(ExecState* exec, const ArgList& args)
152 {
153     impl()->removeTimeout(args.at(exec, 0).toInt32(exec));
154     return jsUndefined();
155 }
156
157 } // namespace WebCore
158
159 #endif // ENABLE(WORKERS)