Index: WebCore/bindings/v8/custom/V8WebSocketCustom.cpp |
diff --git a/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d8127d8d3ecf94441124a7579cc30c468429a564 |
--- /dev/null |
+++ b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp |
@@ -0,0 +1,223 @@ |
+/* |
+ * Copyright (C) 2009 Google Inc. All rights reserved. |
+ * |
+ * Redistribution and use in source and binary forms, with or without |
+ * modification, are permitted provided that the following conditions are |
+ * met: |
+ * |
+ * * Redistributions of source code must retain the above copyright |
+ * notice, this list of conditions and the following disclaimer. |
+ * * Redistributions in binary form must reproduce the above |
+ * copyright notice, this list of conditions and the following disclaimer |
+ * in the documentation and/or other materials provided with the |
+ * distribution. |
+ * * Neither the name of Google Inc. nor the names of its |
+ * contributors may be used to endorse or promote products derived from |
+ * this software without specific prior written permission. |
+ * |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ */ |
+ |
+#include "config.h" |
+#include "WebSocket.h" |
+ |
+#include "V8Binding.h" |
+#include "V8ObjectEventListener.h" |
+#include "V8Proxy.h" |
+#include "V8Utilities.h" |
+ |
+namespace WebCore { |
+ |
+ACCESSOR_GETTER(WebSocketOnopen) |
+{ |
+ INC_STATS("DOM.WebSocket.onopen._get"); |
+ WebSocket* websocket = V8Proxy::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, info.Holder()); |
+ if (websocket->onopen()) { |
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(websocket->onopen()); |
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject(); |
+ return v8Listener; |
+ } |
+ return v8::Null(); |
+} |
+ |
+ACCESSOR_SETTER(WebSocketOnopen) |
+{ |
+ INC_STATS("DOM.WebSocket.onopen._set"); |
+ WebSocket* websocket = V8Proxy::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, info.Holder()); |
+ if (value->IsNull()) { |
+ if (websocket->onopen()) { |
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(websocket->onopen()); |
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject(); |
+ removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kWebSocketCacheIndex); |
+ } |
+ // Clear the listener. |
+ websocket->setOnopen(0); |
+ } else { |
+ RefPtr<EventListener> listener = getEventListener(websocket, value, false); |
+ if (listener) { |
+ websocket->setOnopen(listener); |
+ createHiddenDependency(info.Holder(), value, V8Custom::kWebSocketCacheIndex); |
+ } |
+ } |
+} |
+ |
+ACCESSOR_GETTER(WebSocketOnmessage) |
+{ |
+ INC_STATS("DOM.WebSocket.onmessage._get"); |
+ WebSocket* websocket = V8Proxy::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, info.Holder()); |
+ if (websocket->onmessage()) { |
+ RefPtr<V8ObjectEventListener> listener = static_cast<V8ObjectEventListener*>(websocket->onmessage()); |
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject(); |
+ return v8Listener; |
+ } |
+ return v8::Null(); |
+} |
+ |
+ACCESSOR_SETTER(WebSocketOnmessage) |
+{ |
+ INC_STATS("DOM.WebSocket.onmessage._set"); |
+ WebSocket* websocket = V8Proxy::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, info.Holder()); |
+ if (value->IsNull()) { |
+ if (websocket->onmessage()) { |
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(websocket->onmessage()); |
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject(); |
+ removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kWebSocketCacheIndex); |
+ } |
+ // Clear the listener. |
+ websocket->setOnmessage(0); |
+ } else { |
+ RefPtr<EventListener> listener = getEventListener(websocket, value, false); |
+ if (listener) { |
+ websocket->setOnmessage(listener); |
+ createHiddenDependency(info.Holder(), value, V8Custom::kWebSocketCacheIndex); |
+ } |
+ } |
+} |
+ |
+ACCESSOR_GETTER(WebSocketOnclose) |
+{ |
+ INC_STATS("DOM.WebSocket.onclose._get"); |
+ WebSocket* websocket = V8Proxy::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, info.Holder()); |
+ if (websocket->onclose()) { |
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(websocket->onclose()); |
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject(); |
+ return v8Listener; |
+ } |
+ return v8::Null(); |
+} |
+ |
+ACCESSOR_SETTER(WebSocketOnclose) |
+{ |
+ INC_STATS("DOM.WebSocket.onclose._set"); |
+ WebSocket* websocket = V8Proxy::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, info.Holder()); |
+ if (value->IsNull()) { |
+ if (websocket->onclose()) { |
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(websocket->onclose()); |
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject(); |
+ removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kWebSocketCacheIndex); |
+ } |
+ // Clear the listener. |
+ websocket->setOnclose(0); |
+ } else { |
+ RefPtr<EventListener> listener = getEventListener(websocket, value, false); |
+ if (listener) { |
+ websocket->setOnclose(listener); |
+ createHiddenDependency(info.Holder(), value, V8Custom::kWebSocketCacheIndex); |
+ } |
+ } |
+} |
+ |
+// ??? AddEventListener, RemoveEventListener |
+ |
+CALLBACK_FUNC_DECL(WebSocketConstructor) |
+{ |
+ INC_STATS("DOM.WebSocket.Constructor"); |
+ |
+ if (!args.IsConstructCall()) |
+ return throwError("DOM object custructor cannot be called as a function."); |
+ if (args.Length() == 0) |
+ return throwError("Not enough arguments", V8Proxy::SyntaxError); |
+ |
+ v8::TryCatch tryCatch; |
+ v8::Handle<v8::String> urlstring = args[0]->ToString(); |
+ if (tryCatch.HasCaught()) |
+ return throwError(tryCatch.Exception()); |
+ if (urlstring.IsEmpty()) |
+ return throwError("Empty URL", V8Proxy::SyntaxError); |
+ |
+ // Get the script execution context. |
+ ScriptExecutionContext* context = 0; |
+ // TODO(ukai): worker? |
+ Frame* frame = V8Proxy::retrieveFrame(); |
+ if (!frame) |
+ return thowError("WebSocket constructor associated frame is unavailable", V8Proxy::ReferenceError); |
+ context = frame->document(); |
+ if (!context) |
+ return thowError("WebSocket constructor associated document is unavailable", V8Proxy::ReferenceError); |
+ |
+ const KURL& url = context->completeURL(toWebCoreString(urlstring)); |
+ |
+ RefPtr<WebSocket> websocket = WebSocket::create(context); |
+ |
+ if (args.Length() < 2) |
+ websocket->connect(url, ec); |
+ else { |
+ v8::TryCzatch tryCatchProtocol; |
+ v8::Handle<v8::String> protocol = args[1]->ToString(); |
+ if (tryCatchProtocol.HasCaught()) |
+ return throwError(tryCatchProtocol.Exception()); |
+ if (protocol.IsEmpty()) |
+ return throwError("protocol is empty", V8Proxy::SyntaxError); |
+ websocket->connect(url, toWebCoreString(protocol), ec); |
+ } |
+ if (ec) |
+ return throwError(ec); |
+ |
+ // Setup the standard wrapper object internal fields. |
+ v8::Handle<v8::Object> wrapperObject = args.Holder(); |
+ V8Proxy::setDOMWrapper(wrapperObject, V8ClassIndex::WEBSOCKET, websocket.get()); |
+ |
+ websocket->ref(); |
+ V8Proxy::setJSWrapperForActiveDOMObject(websocket.get(), v8::Persistent<v8::Object>::New(wrapperObject)); |
+ |
+ return wrapperObject; |
+} |
+ |
+CALLBACK_FUNC_DECL(WebSocketSend) |
+{ |
+ INC_STATS("DOM.WebSocket.send()"); |
+ WebSocket* websocket = V8Proxy::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, args.Holder()); |
+ |
+ ExceptionCode ec = 0; |
+ bool ret = false; |
+ if (args.Length() < 1) |
+ return throwError("Not enough arguments", V8Proxy::SyntaxError); |
+ else { |
+ String msg = toWebCoreString(args[0]); |
+ ret = websocket->send(msg, ec); |
+ } |
+ if (ec) |
+ return throwError(ec); |
+ return v8Boolean(ret); |
+} |
+ |
+CALLBACK_FUNC_DEC(WebSocketClose) |
+{ |
+ INC_STATS("DOM.WebSocket.close()"); |
+ WebSocket* websocket = V8Proxy::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, args.Holder()); |
+ |
+ websocket->close(); |
+ return v8::Undefined(); |
+} |
+ |
+} // namespace WebCore |