PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
{
    if (url.string().isEmpty())
        return 0;

    Frame* coreFrame = core(m_webFrame);
    ASSERT(coreFrame);

    WebFrame* webFrame = WebFrame::createInstance();
    //webFrame->ref();

    RefPtr<Frame> childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement);
    childFrame->ref();

    coreFrame->tree()->appendChild(childFrame);
    childFrame->tree()->setName(name);
    childFrame->init();

    // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
    if (!childFrame->page()) {
        delete webFrame;
        return 0;
    }

    childFrame->loader()->loadURLIntoChildFrame(url, referrer, childFrame.get());

    // The frame's onload handler may have removed it from the document.
    if (!childFrame->tree()->parent()) {
        delete webFrame;
        return 0;
    }

    return childFrame.release();
}
Example #2
0
v8::Handle<v8::Value> V8TestSerializedScriptValueInterface::constructorCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.TestSerializedScriptValueInterface.Constructor");

    if (!args.IsConstructCall())
        return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);

    if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
        return args.Holder();
    if (args.Length() < 2)
        return throwError("Not enough arguments", V8Proxy::TypeError);
    STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, hello, MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined));
    bool valueDidThrow = false;
    RefPtr<SerializedScriptValue> value = SerializedScriptValue::create(args[1], 0, 0, valueDidThrow);
    if (valueDidThrow)
        return v8::Undefined();

    RefPtr<TestSerializedScriptValueInterface> impl = TestSerializedScriptValueInterface::create(hello, value);
    v8::Handle<v8::Object> wrapper = args.Holder();

    V8DOMWrapper::setDOMWrapper(wrapper, &info, impl.get());
    impl->ref();
    V8DOMWrapper::setJSWrapperForDOMObject(impl.get(), v8::Persistent<v8::Object>::New(wrapper));
    return args.Holder();
}
Example #3
0
v8::Handle<v8::Value> V8TestInterface::constructorCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.TestInterface.Constructor");

    if (!args.IsConstructCall())
        return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);

    if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
        return args.Holder();
    if (args.Length() < 1)
        return throwError("Not enough arguments", V8Proxy::TypeError);

    ExceptionCode ec = 0;
    STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, str1, MAYBE_MISSING_PARAMETER(args, 0, MissingIsUndefined));
    STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, str2, MAYBE_MISSING_PARAMETER(args, 1, MissingIsUndefined));

    ScriptExecutionContext* context = getScriptExecutionContext();
    if (!context)
        return throwError("TestInterface constructor's associated context is not available", V8Proxy::ReferenceError);

    RefPtr<TestInterface> obj = TestInterface::create(context, str1, str2, ec);
    if (ec)
        goto fail;

    V8DOMWrapper::setDOMWrapper(args.Holder(), &info, obj.get());
    obj->ref();
    V8DOMWrapper::setJSWrapperForActiveDOMObject(obj.get(), v8::Persistent<v8::Object>::New(args.Holder()));
    return args.Holder();
  fail:
    return throwError(ec);
}
v8::Handle<v8::Value> V8Custom::v8HTMLAudioElementConstructorCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.HTMLAudioElement.Contructor");

    if (!args.IsConstructCall())
        return throwError("DOM object constructor cannot be called as a function.");

    Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
    if (!frame)
        return throwError("Audio constructor associated frame is unavailable", V8Proxy::ReferenceError);

    Document* document = frame->document();
    if (!document)
        return throwError("Audio constructor associated document is unavailable", V8Proxy::ReferenceError);

    // Make sure the document is added to the DOM Node map. Otherwise, the HTMLAudioElement instance
    // may end up being the only node in the map and get garbage-ccollected prematurely.
    V8DOMWrapper::convertNodeToV8Object(document);

    RefPtr<HTMLAudioElement> audio = new HTMLAudioElement(HTMLNames::audioTag, document);
    audio->setAutobuffer(true);
    if (args.Length() > 0) {
        audio->setSrc(toWebCoreString(args[0]));
        audio->scheduleLoad();
    }

    V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::NODE), audio.get());
    audio->ref();
    V8DOMWrapper::setJSWrapperForDOMNode(audio.get(), v8::Persistent<v8::Object>::New(args.Holder()));
    return args.Holder();
}
static v8::Handle<v8::Value> v8HTMLAudioElementConstructorCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.HTMLAudioElement.Contructor");

    if (!args.IsConstructCall())
        return throwError("DOM object constructor cannot be called as a function.");

    Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
    if (!frame)
        return throwError("Audio constructor associated frame is unavailable", V8Proxy::ReferenceError);

    Document* document = frame->document();
    if (!document)
        return throwError("Audio constructor associated document is unavailable", V8Proxy::ReferenceError);

    // Make sure the document is added to the DOM Node map. Otherwise, the HTMLAudioElement instance
    // may end up being the only node in the map and get garbage-collected prematurely.
    toV8(document);


    String src;
    if (args.Length() > 0)
        src = toWebCoreString(args[0]);
    RefPtr<HTMLAudioElement> audio = HTMLAudioElement::createForJSConstructor(document, src);

    V8DOMWrapper::setDOMWrapper(args.Holder(), &V8HTMLAudioElementConstructor::info, audio.get());
    audio->ref();
    V8DOMWrapper::setJSWrapperForDOMNode(audio.get(), v8::Persistent<v8::Object>::New(args.Holder()));
    return args.Holder();
}
Example #6
0
v8::Handle<v8::Value> V8AudioContext::constructorCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.AudioContext.Contructor");

    if (!args.IsConstructCall())
        return throwError("AudioContext constructor cannot be called as a function.", V8Proxy::TypeError);

    if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
        return args.Holder();

    Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
    if (!frame)
        return throwError("AudioContext constructor associated frame is unavailable", V8Proxy::ReferenceError);

    Document* document = frame->document();
    if (!document)
        return throwError("AudioContext constructor associated document is unavailable", V8Proxy::ReferenceError);

    RefPtr<AudioContext> audioContext;
    
    if (!args.Length()) {
        // Constructor for default AudioContext which talks to audio hardware.
        audioContext = AudioContext::create(document);
        if (!audioContext.get())
            return throwError("audio resources unavailable for AudioContext construction", V8Proxy::SyntaxError);
    } else {
        // Constructor for offline (render-target) AudioContext which renders into an AudioBuffer.
        // new AudioContext(in unsigned long numberOfChannels, in unsigned long numberOfFrames, in float sampleRate);
        if (args.Length() < 3)
            return throwError("Not enough arguments", V8Proxy::SyntaxError);

        bool ok = false;

        int32_t numberOfChannels = toInt32(args[0], ok);
        if (!ok || numberOfChannels <= 0 || numberOfChannels > 10)
            return throwError("Invalid number of channels", V8Proxy::SyntaxError);

        int32_t numberOfFrames = toInt32(args[1], ok);
        if (!ok || numberOfFrames <= 0)
            return throwError("Invalid number of frames", V8Proxy::SyntaxError);

        float sampleRate = toFloat(args[2]);
        if (sampleRate <= 0)
            return throwError("Invalid sample rate", V8Proxy::SyntaxError);

        ExceptionCode ec = 0;
        audioContext = AudioContext::createOfflineContext(document, numberOfChannels, numberOfFrames, sampleRate, ec);
        if (ec)
            return throwError(ec);
    }

    if (!audioContext.get())
        return throwError("Error creating AudioContext", V8Proxy::SyntaxError);
    
    // Transform the holder into a wrapper object for the audio context.
    V8DOMWrapper::setDOMWrapper(args.Holder(), &info, audioContext.get());
    audioContext->ref();
    
    return args.Holder();
}
PassRefPtr<DatabaseContext> DatabaseContext::create(ExecutionContext* context)
{
    RefPtr<DatabaseContext> self = adoptRef(new DatabaseContext(context));
#if !defined(S_DATABASE_TRACKER)
    self->ref(); // Is deref()-ed on contextDestroyed().
#endif
    return self.release();
}
Example #8
0
PassRefPtr<ScriptStateForTesting> ScriptStateForTesting::create(v8::Handle<v8::Context> context, PassRefPtr<DOMWrapperWorld> world)
{
    RefPtr<ScriptStateForTesting> scriptState = adoptRef(new ScriptStateForTesting(context, world));
    // This ref() is for keeping this ScriptState alive as long as the v8::Context is alive.
    // This is deref()ed in the weak callback of the v8::Context.
    scriptState->ref();
    return scriptState;
}
Example #9
0
PassRefPtr<WebFrame> WebFrame::create(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
{
    RefPtr<WebFrame> frame = adoptRef(new WebFrame(page, frameName, ownerElement));
    
    // Add explict ref() that will be balanced in WebFrameLoaderClient::frameLoaderDestroyed().
    frame->ref();
    
    return frame.release();
}
Example #10
0
PassRefPtr<ScriptState> ScriptState::create(v8::Local<v8::Context> context,
                                            PassRefPtr<DOMWrapperWorld> world) {
  RefPtr<ScriptState> scriptState =
      adoptRef(new ScriptState(context, std::move(world)));
  // This ref() is for keeping this ScriptState alive as long as the v8::Context
  // is alive.  This is deref()ed in the weak callback of the v8::Context.
  scriptState->ref();
  return scriptState;
}
Example #11
0
PassRefPtr<WebFrame> WebFrame::create(std::unique_ptr<WebFrameLoaderClient> frameLoaderClient)
{
    RefPtr<WebFrame> frame = adoptRef(new WebFrame(std::move(frameLoaderClient)));

    // Add explict ref() that will be balanced in WebFrameLoaderClient::frameLoaderDestroyed().
    frame->ref();

    return frame.release();
}
Example #12
0
PassRefPtr<FileStreamProxy> FileStreamProxy::create(ScriptExecutionContext* context, FileStreamClient* client)
{
    RefPtr<FileStreamProxy> proxy = adoptRef(new FileStreamProxy(context, client));

    // Hold an ref so that the instance will not get deleted while there are tasks on the file thread.
    // This is balanced by the deref in derefProxyOnContext below.
    proxy->ref();

    proxy->fileThread()->postTask(createFileThreadTask(proxy.get(), &FileStreamProxy::startOnFileThread));

    return proxy.release();
}
Example #13
0
PassRefPtr<AsyncFileStream> AsyncFileStream::create(FileStreamClient* client)
{
    RefPtr<AsyncFileStream> proxy = adoptRef(new AsyncFileStream(client));

    // Hold a reference so that the instance will not get deleted while there are tasks on the file thread.
    // This is balanced by the deref in derefProxyOnContext below.
    proxy->ref();

    fileThread()->postTask(createFileThreadTask(proxy.get(), &AsyncFileStream::startOnFileThread));

    return proxy.release();
}
v8::Handle<v8::Value> V8NotificationCenter::createNotificationCallback(const v8::Arguments& args)
{
    INC_STATS(L"DOM.NotificationCenter.CreateNotification()");
    NotificationCenter* notificationCenter = V8NotificationCenter::toNative(args.Holder());

    ExceptionCode ec = 0;
    RefPtr<Notification> notification = notificationCenter->createNotification(toWebCoreString(args[0]), toWebCoreString(args[1]), toWebCoreString(args[2]), ec);

    if (ec)
        return throwError(ec);

    notification->ref();
    return toV8(notification.get());
}
static v8::Handle<v8::Value> v8HTMLImageElementConstructorCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.HTMLImageElement.Contructor");

    if (!args.IsConstructCall())
        return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);

    if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
        return args.Holder();

    Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
    if (!frame)
        return throwError("Image constructor associated frame is unavailable", V8Proxy::ReferenceError);

    Document* document = frame->document();
    if (!document)
        return throwError("Image constructor associated document is unavailable", V8Proxy::ReferenceError);

    // Make sure the document is added to the DOM Node map. Otherwise, the HTMLImageElement instance
    // may end up being the only node in the map and get garbage-ccollected prematurely.
    // FIXME: The correct way to do this would be to make HTMLImageElement derive from
    // ActiveDOMObject and use its interface to keep its wrapper alive. Then we would
    // remove this code and the special case in isObservableThroughDOM.
    toV8(document);

    int width;
    int height;
    int* optionalWidth = 0;
    int* optionalHeight = 0;
    if (args.Length() > 0) {
        width = toInt32(args[0]);
        optionalWidth = &width;
    }
    if (args.Length() > 1) {
        height = toInt32(args[1]);
        optionalHeight = &height;
    }

    RefPtr<HTMLImageElement> image = HTMLImageElement::createForJSConstructor(document, optionalWidth, optionalHeight);
    V8DOMWrapper::setDOMWrapper(args.Holder(), &V8HTMLImageElementConstructor::info, image.get());
    image->ref();
    V8DOMWrapper::setJSWrapperForDOMNode(image.get(), v8::Persistent<v8::Object>::New(args.Holder()));
    return args.Holder();
}
v8::Handle<v8::Value> V8SharedWorker::constructorCallback(const v8::Arguments& args)
{
    INC_STATS(L"DOM.SharedWorker.Constructor");

    if (!args.IsConstructCall())
        return throwError("DOM object constructor cannot be called as a function.");

    if (!args.Length())
        return throwError("Not enough arguments", V8Proxy::SyntaxError);

    v8::TryCatch tryCatch;
    v8::Handle<v8::String> scriptUrl = args[0]->ToString();
    String name;
    if (args.Length() > 1)
        name = toWebCoreString(args[1]->ToString());

    if (tryCatch.HasCaught())
        return throwError(tryCatch.Exception());

    if (scriptUrl.IsEmpty())
        return v8::Undefined();

    // Get the script execution context.
    ScriptExecutionContext* context = getScriptExecutionContext();
    if (!context)
        return v8::Undefined();

    // Create the SharedWorker object.
    // Note: it's OK to let this RefPtr go out of scope because we also call SetDOMWrapper(), which effectively holds a reference to obj.
    ExceptionCode ec = 0;
    RefPtr<SharedWorker> obj = SharedWorker::create(toWebCoreString(scriptUrl), name, context, ec);
    if (ec)
        return throwError(ec);

    // Setup the standard wrapper object internal fields.
    v8::Handle<v8::Object> wrapperObject = args.Holder();
    V8DOMWrapper::setDOMWrapper(wrapperObject, &info, obj.get());

    obj->ref();
    V8DOMWrapper::setJSWrapperForActiveDOMObject(obj.get(), v8::Persistent<v8::Object>::New(wrapperObject));

    return wrapperObject;
}
static v8::Handle<v8::Value> v8HTMLOptionElementConstructorCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.HTMLOptionElement.Contructor");

    if (!args.IsConstructCall())
        return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);

    if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
        return args.Holder();

    Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
    if (!frame)
        return throwError("Option constructor associated frame is unavailable", V8Proxy::ReferenceError);

    Document* document = frame->document();
    if (!document)
        return throwError("Option constructor associated document is unavailable", V8Proxy::ReferenceError);

    String data;
    String value;
    bool defaultSelected = false;
    bool selected = false;
    if (args.Length() > 0 && !args[0]->IsUndefined())
        data = toWebCoreString(args[0]);
    if (args.Length() > 1 && !args[1]->IsUndefined())
        value = toWebCoreString(args[1]);
    if (args.Length() > 2)
        defaultSelected = args[2]->BooleanValue();
    if (args.Length() > 3)
        selected = args[3]->BooleanValue();

    ExceptionCode ec = 0;
    RefPtr<HTMLOptionElement> option = HTMLOptionElement::createForJSConstructor(document, data, value, defaultSelected, selected, ec);

    if (ec)
        throwError(ec);

    V8DOMWrapper::setDOMWrapper(args.Holder(), &V8HTMLOptionElementConstructor::info, option.get());
    option->ref();
    V8DOMWrapper::setJSWrapperForDOMNode(option.get(), v8::Persistent<v8::Object>::New(args.Holder()));
    return args.Holder();
}
v8::Handle<v8::Value> V8XMLHttpRequest::constructorCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.XMLHttpRequest.Constructor");

    if (!args.IsConstructCall())
        return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);

    // Expect no parameters.
    // Allocate a XMLHttpRequest object as its internal field.
    ScriptExecutionContext* context = getScriptExecutionContext();
    if (!context)
        return throwError("XMLHttpRequest constructor's associated context is not available", V8Proxy::ReferenceError);
    RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context);
    V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::XMLHTTPREQUEST), xmlHttpRequest.get());

    // Add object to the wrapper map.
    xmlHttpRequest->ref();
    V8DOMWrapper::setJSWrapperForActiveDOMObject(xmlHttpRequest.get(), v8::Persistent<v8::Object>::New(args.Holder()));
    return args.Holder();
}
v8::Handle<v8::Value> V8FileReader::constructorCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.FileReader.Constructor");

    if (!args.IsConstructCall())
        return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);

    // Expect no parameters.
    // Allocate a FileReader object as its internal field.
    ScriptExecutionContext* context = getScriptExecutionContext();
    if (!context)
        return throwError("FileReader constructor's associated context is not available", V8Proxy::ReferenceError);
    RefPtr<FileReader> fileReader = FileReader::create(context);
    V8DOMWrapper::setDOMWrapper(args.Holder(), &info, fileReader.get());

    // Add object to the wrapper map.
    fileReader->ref();
    V8DOMWrapper::setJSWrapperForActiveDOMObject(fileReader.get(), v8::Persistent<v8::Object>::New(args.Holder()));
    return args.Holder();
}
Example #20
0
static v8::Handle<v8::Value> V8TestNamedConstructorConstructorCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.TestNamedConstructor.Constructor");

    if (!args.IsConstructCall())
        return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);

    if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
        return args.Holder();

    Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
    if (!frame)
        return throwError("TestNamedConstructor constructor associated frame is unavailable", V8Proxy::ReferenceError);

    Document* document = frame->document();

    // Make sure the document is added to the DOM Node map. Otherwise, the TestNamedConstructor instance
    // may end up being the only node in the map and get garbage-collected prematurely.
    toV8(document);

    if (args.Length() < 1)
        return throwError("Not enough arguments", V8Proxy::TypeError);

    ExceptionCode ec = 0;
    STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, str1, MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined));
    STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, str2, MAYBE_MISSING_PARAMETER(args, 1, DefaultIsUndefined));
    STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, str3, MAYBE_MISSING_PARAMETER(args, 2, DefaultIsNullString));

    RefPtr<TestNamedConstructor> impl = TestNamedConstructor::createForJSConstructor(document, str1, str2, str3, ec);
    v8::Handle<v8::Object> wrapper = args.Holder();
    if (ec)
        goto fail;

    V8DOMWrapper::setDOMWrapper(wrapper, &V8TestNamedConstructorConstructor::info, impl.get());
    impl->ref();
    V8DOMWrapper::setJSWrapperForActiveDOMObject(impl.get(), v8::Persistent<v8::Object>::New(wrapper));
    return args.Holder();
  fail:
    return throwError(ec);
}
PassRefPtr<DatabaseContext> DatabaseManager::existingDatabaseContextFor(ScriptExecutionContext* context)
{
    std::lock_guard<std::mutex> lock(m_mutex);

    ASSERT(m_databaseContextRegisteredCount >= 0);
    ASSERT(m_databaseContextInstanceCount >= 0);
    ASSERT(m_databaseContextRegisteredCount <= m_databaseContextInstanceCount);

    RefPtr<DatabaseContext> databaseContext = adoptRef(m_contextMap.get(context));
    if (databaseContext) {
        // If we're instantiating a new DatabaseContext, the new instance would
        // carry a new refCount of 1. The client expects this and will simply
        // adoptRef the databaseContext without ref'ing it.
        //     However, instead of instantiating a new instance, we're reusing
        // an existing one that corresponds to the specified ScriptExecutionContext.
        // Hence, that new refCount need to be attributed to the reused instance
        // to ensure that the refCount is accurate when the client adopts the ref.
        // We do this by ref'ing the reused databaseContext before returning it.
        databaseContext->ref();
    }
    return databaseContext.release();
}
PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
{
    Frame* coreFrame = core(m_webFrame);
    ASSERT(coreFrame);

    RefPtr<WebFrame> webFrame = adoptRef(WebFrame::createInstance());
    webFrame->ref();

    RefPtr<Frame> childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement);

    coreFrame->tree()->appendChild(childFrame);
    childFrame->tree()->setName(name);
    childFrame->init();

    loadURLIntoChild(URL, referrer, webFrame.get());

    // The frame's onload handler may have removed it from the document.
    if (!childFrame->tree()->parent())
        return 0;

    return childFrame.release();
}
Example #23
0
PassRefPtr<DatabaseContext> DatabaseContext::create(ExecutionContext* context)
{
    RefPtr<DatabaseContext> self = adoptRef(new DatabaseContext(context));
    self->ref(); // Is deref()-ed on contextDestroyed().
    return self.release();
}
Example #24
0
v8::Handle<v8::Value> V8WebSocket::constructorCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.WebSocket.Constructor");

    if (!args.IsConstructCall())
        return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);

    if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
        return args.Holder();

    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 = getScriptExecutionContext();
    if (!context)
        return throwError("WebSocket constructor's associated frame is not available", V8Proxy::ReferenceError);

    const KURL& url = context->completeURL(toWebCoreString(urlstring));

    RefPtr<WebSocket> webSocket = WebSocket::create(context);
    ExceptionCode ec = 0;

    if (args.Length() < 2)
        webSocket->connect(url, ec);
    else {
        v8::Local<v8::Value> protocolsValue = args[1];
        if (protocolsValue->IsArray()) {
            Vector<String> protocols;
            v8::Local<v8::Array> protocolsArray = v8::Local<v8::Array>::Cast(protocolsValue);
            for (uint32_t i = 0; i < protocolsArray->Length(); ++i) {
                v8::TryCatch tryCatchProtocol;
                v8::Handle<v8::String> protocol = protocolsArray->Get(v8::Int32::New(i))->ToString();
                if (tryCatchProtocol.HasCaught())
                    return throwError(tryCatchProtocol.Exception());
                protocols.append(toWebCoreString(protocol));
            }
            webSocket->connect(url, protocols, ec);
        } else {
            v8::TryCatch tryCatchProtocol;
            v8::Handle<v8::String> protocol = protocolsValue->ToString();
            if (tryCatchProtocol.HasCaught())
                return throwError(tryCatchProtocol.Exception());
            webSocket->connect(url, toWebCoreString(protocol), ec);
        }
    }
    if (ec)
        return throwError(ec);

    // Setup the standard wrapper object internal fields.
    V8DOMWrapper::setDOMWrapper(args.Holder(), &info, webSocket.get());

    // Add object to the wrapper map.
    webSocket->ref();
    V8DOMWrapper::setJSWrapperForActiveDOMObject(webSocket.get(), v8::Persistent<v8::Object>::New(args.Holder()));

    return args.Holder();
}