tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebCore / bindings / v8 / custom / V8WebSocketCustom.cpp
1 /*
2  * Copyright (C) 2011 Google 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 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
31 #include "config.h"
32
33 #if ENABLE(WEB_SOCKETS)
34
35 #include "V8WebSocket.h"
36
37 #include "ExceptionCode.h"
38 #include "Frame.h"
39 #include "Settings.h"
40 #include "V8ArrayBuffer.h"
41 #include "V8Binding.h"
42 #include "V8Blob.h"
43 #include "V8Proxy.h"
44 #include "V8Utilities.h"
45 #include "WebSocket.h"
46 #include "WebSocketChannel.h"
47 #include "WorkerContext.h"
48 #include "WorkerContextExecutionProxy.h"
49 #include <wtf/MathExtras.h>
50 #include <wtf/Vector.h>
51
52 namespace WebCore {
53
54 v8::Handle<v8::Value> V8WebSocket::constructorCallback(const v8::Arguments& args)
55 {
56     INC_STATS("DOM.WebSocket.Constructor");
57
58     if (!args.IsConstructCall())
59         return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);
60
61     if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
62         return args.Holder();
63
64     if (args.Length() == 0)
65         return throwError("Not enough arguments", V8Proxy::SyntaxError);
66
67     v8::TryCatch tryCatch;
68     v8::Handle<v8::String> urlstring = args[0]->ToString();
69     if (tryCatch.HasCaught())
70         return throwError(tryCatch.Exception());
71     if (urlstring.IsEmpty())
72         return throwError("Empty URL", V8Proxy::SyntaxError);
73
74     // Get the script execution context.
75     ScriptExecutionContext* context = getScriptExecutionContext();
76     if (!context)
77         return throwError("WebSocket constructor's associated frame is not available", V8Proxy::ReferenceError);
78
79     const KURL& url = context->completeURL(toWebCoreString(urlstring));
80
81     RefPtr<WebSocket> webSocket = WebSocket::create(context);
82     ExceptionCode ec = 0;
83
84     if (args.Length() < 2)
85         webSocket->connect(url, ec);
86     else {
87         v8::Local<v8::Value> protocolsValue = args[1];
88         if (protocolsValue->IsArray()) {
89             Vector<String> protocols;
90             v8::Local<v8::Array> protocolsArray = v8::Local<v8::Array>::Cast(protocolsValue);
91             for (uint32_t i = 0; i < protocolsArray->Length(); ++i) {
92                 v8::TryCatch tryCatchProtocol;
93                 v8::Handle<v8::String> protocol = protocolsArray->Get(v8::Int32::New(i))->ToString();
94                 if (tryCatchProtocol.HasCaught())
95                     return throwError(tryCatchProtocol.Exception());
96                 protocols.append(toWebCoreString(protocol));
97             }
98             webSocket->connect(url, protocols, ec);
99         } else {
100             v8::TryCatch tryCatchProtocol;
101             v8::Handle<v8::String> protocol = protocolsValue->ToString();
102             if (tryCatchProtocol.HasCaught())
103                 return throwError(tryCatchProtocol.Exception());
104             webSocket->connect(url, toWebCoreString(protocol), ec);
105         }
106     }
107     if (ec)
108         return throwError(ec);
109
110     // Setup the standard wrapper object internal fields.
111     V8DOMWrapper::setDOMWrapper(args.Holder(), &info, webSocket.get());
112
113     // Add object to the wrapper map.
114     webSocket->ref();
115     V8DOMWrapper::setJSWrapperForActiveDOMObject(webSocket.get(), v8::Persistent<v8::Object>::New(args.Holder()));
116
117     return args.Holder();
118 }
119
120 v8::Handle<v8::Value> V8WebSocket::sendCallback(const v8::Arguments& args)
121 {
122     INC_STATS("DOM.WebSocket.send()");
123
124     if (!args.Length())
125         return throwError("Not enough arguments", V8Proxy::SyntaxError);
126
127     WebSocket* webSocket = V8WebSocket::toNative(args.Holder());
128     v8::Handle<v8::Value> message = args[0];
129     ExceptionCode ec = 0;
130     bool result;
131     if (V8ArrayBuffer::HasInstance(message)) {
132         ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(message));
133         ASSERT(arrayBuffer);
134         result = webSocket->send(arrayBuffer, ec);
135     } else if (V8Blob::HasInstance(message)) {
136         Blob* blob = V8Blob::toNative(v8::Handle<v8::Object>::Cast(message));
137         ASSERT(blob);
138         result = webSocket->send(blob, ec);
139     } else {
140         v8::TryCatch tryCatch;
141         v8::Handle<v8::String> stringMessage = message->ToString();
142         if (tryCatch.HasCaught())
143             return throwError(tryCatch.Exception());
144         result = webSocket->send(toWebCoreString(stringMessage), ec);
145     }
146     if (ec)
147         return throwError(ec);
148
149     return v8Boolean(result);
150 }
151
152 v8::Handle<v8::Value> V8WebSocket::closeCallback(const v8::Arguments& args)
153 {
154     // FIXME: We should implement [Clamp] for IDL binding code generator, and
155     // remove this custom method.
156     WebSocket* webSocket = toNative(args.Holder());
157     int argumentCount = args.Length();
158     int code = WebSocketChannel::CloseEventCodeNotSpecified;
159     String reason = "";
160     if (argumentCount >= 1) {
161         double x = args[0]->NumberValue();
162         double maxValue = static_cast<double>(std::numeric_limits<uint16_t>::max());
163         double minValue = static_cast<double>(std::numeric_limits<uint16_t>::min());
164         if (isnan(x))
165             x = 0.0;
166         else
167             x = clampTo(x, minValue, maxValue);
168         code = clampToInteger(x);
169         if (argumentCount >= 2) {
170             v8::TryCatch tryCatch;
171             v8::Handle<v8::String> reasonValue = args[1]->ToString();
172             if (tryCatch.HasCaught())
173                 return throwError(tryCatch.Exception());
174             reason = toWebCoreString(reasonValue);
175         }
176     }
177     ExceptionCode ec = 0;
178     webSocket->close(code, reason, ec);
179     if (ec)
180         return throwError(ec);
181     return v8::Undefined();
182 }
183
184 }  // namespace WebCore
185
186 #endif  // ENABLE(WEB_SOCKETS)