| Index: third_party/WebKit/WebCore/dom/Worker.cpp
 | 
| ===================================================================
 | 
| --- third_party/WebKit/WebCore/dom/Worker.cpp	(revision 9391)
 | 
| +++ third_party/WebKit/WebCore/dom/Worker.cpp	(working copy)
 | 
| @@ -1,204 +1,204 @@
 | 
| -/*
 | 
| - * Copyright (C) 2008 Apple 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:
 | 
| - * 1. Redistributions of source code must retain the above copyright
 | 
| - *    notice, this list of conditions and the following disclaimer.
 | 
| - * 2. 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.
 | 
| - *
 | 
| - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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"
 | 
| -
 | 
| -#if ENABLE(WORKERS)
 | 
| -
 | 
| -#include "Worker.h"
 | 
| -
 | 
| -#include "CachedScript.h"
 | 
| -#include "DOMWindow.h"
 | 
| -#include "DocLoader.h"
 | 
| -#include "Document.h"
 | 
| -#include "EventException.h"
 | 
| -#include "EventListener.h"
 | 
| -#include "EventNames.h"
 | 
| -#include "ExceptionCode.h"
 | 
| -#include "Frame.h"
 | 
| -#include "FrameLoader.h"
 | 
| -#include "MessageEvent.h"
 | 
| -#include "SecurityOrigin.h"
 | 
| -#include "WorkerContext.h"
 | 
| -#include "WorkerMessagingProxy.h"
 | 
| -#include "WorkerThread.h"
 | 
| -#include <wtf/MainThread.h>
 | 
| -
 | 
| -namespace WebCore {
 | 
| -
 | 
| -Worker::Worker(const String& url, Document* doc, ExceptionCode& ec)
 | 
| -    : ActiveDOMObject(doc, this)
 | 
| -    , m_messagingProxy(new WorkerMessagingProxy(doc, this))
 | 
| -{
 | 
| -    m_scriptURL = doc->completeURL(url);
 | 
| -    if (url.isEmpty() || !m_scriptURL.isValid()) {
 | 
| -        ec = SYNTAX_ERR;
 | 
| -        return;
 | 
| -    }
 | 
| -
 | 
| -    if (!doc->securityOrigin()->canAccess(SecurityOrigin::create(m_scriptURL).get())) {
 | 
| -        ec = SECURITY_ERR;
 | 
| -        return;
 | 
| -    }
 | 
| -
 | 
| -    m_cachedScript = doc->docLoader()->requestScript(m_scriptURL, document()->charset());
 | 
| -    if (!m_cachedScript) {
 | 
| -        dispatchErrorEvent();
 | 
| -        return;
 | 
| -    }
 | 
| -
 | 
| -    setPendingActivity(this);  // The worker context does not exist while loading, so we much ensure that the worker object is not collected, as well as its event listeners.
 | 
| -    m_cachedScript->addClient(this);
 | 
| -}
 | 
| -
 | 
| -Worker::~Worker()
 | 
| -{
 | 
| -    ASSERT(isMainThread());
 | 
| -    ASSERT(scriptExecutionContext()); // The context is protected by messaging proxy, so it cannot be destroyed while a Worker exists.
 | 
| -    m_messagingProxy->workerObjectDestroyed();
 | 
| -}
 | 
| -
 | 
| -Document* Worker::document() const
 | 
| -{
 | 
| -    ASSERT(scriptExecutionContext()->isDocument());
 | 
| -    return static_cast<Document*>(scriptExecutionContext());
 | 
| -}
 | 
| -
 | 
| -void Worker::postMessage(const String& message)
 | 
| -{
 | 
| -    m_messagingProxy->postMessageToWorkerContext(message);
 | 
| -}
 | 
| -
 | 
| -void Worker::terminate()
 | 
| -{
 | 
| -    m_messagingProxy->terminate();
 | 
| -}
 | 
| -
 | 
| -bool Worker::canSuspend() const
 | 
| -{
 | 
| -    // FIXME: It is not currently possible to suspend a worker, so pages with workers can not go into page cache.
 | 
| -    return false;
 | 
| -}
 | 
| -
 | 
| -void Worker::stop()
 | 
| -{
 | 
| -    terminate();
 | 
| -}
 | 
| -
 | 
| -bool Worker::hasPendingActivity() const
 | 
| -{
 | 
| -    return m_messagingProxy->workerThreadHasPendingActivity() || ActiveDOMObject::hasPendingActivity();
 | 
| -}
 | 
| -
 | 
| -void Worker::notifyFinished(CachedResource* unusedResource)
 | 
| -{
 | 
| -    ASSERT_UNUSED(unusedResource, unusedResource == m_cachedScript);
 | 
| -
 | 
| -    if (m_cachedScript->errorOccurred())
 | 
| -        dispatchErrorEvent();
 | 
| -    else {
 | 
| -        String userAgent = document()->frame() ? document()->frame()->loader()->userAgent(m_scriptURL) : String();
 | 
| -        RefPtr<WorkerThread> thread = WorkerThread::create(m_scriptURL, userAgent, m_cachedScript->script(), m_messagingProxy);
 | 
| -        m_messagingProxy->workerThreadCreated(thread);
 | 
| -        thread->start();
 | 
| -    }
 | 
| -
 | 
| -    m_cachedScript->removeClient(this);
 | 
| -    m_cachedScript = 0;
 | 
| -
 | 
| -    unsetPendingActivity(this);
 | 
| -}
 | 
| -
 | 
| -void Worker::dispatchErrorEvent()
 | 
| -{
 | 
| -    RefPtr<Event> evt = Event::create(eventNames().errorEvent, false, true);
 | 
| -    if (m_onErrorListener) {
 | 
| -        evt->setTarget(this);
 | 
| -        evt->setCurrentTarget(this);
 | 
| -        m_onErrorListener->handleEvent(evt.get(), true);
 | 
| -    }
 | 
| -
 | 
| -    ExceptionCode ec = 0;
 | 
| -    dispatchEvent(evt.release(), ec);
 | 
| -    ASSERT(!ec);
 | 
| -}
 | 
| -
 | 
| -void Worker::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
 | 
| -{
 | 
| -    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
 | 
| -    if (iter == m_eventListeners.end()) {
 | 
| -        ListenerVector listeners;
 | 
| -        listeners.append(eventListener);
 | 
| -        m_eventListeners.add(eventType, listeners);
 | 
| -    } else {
 | 
| -        ListenerVector& listeners = iter->second;
 | 
| -        for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
 | 
| -            if (*listenerIter == eventListener)
 | 
| -                return;
 | 
| -        }
 | 
| -        
 | 
| -        listeners.append(eventListener);
 | 
| -        m_eventListeners.add(eventType, listeners);
 | 
| -    }    
 | 
| -}
 | 
| -
 | 
| -void Worker::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
 | 
| -{
 | 
| -    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
 | 
| -    if (iter == m_eventListeners.end())
 | 
| -        return;
 | 
| -    
 | 
| -    ListenerVector& listeners = iter->second;
 | 
| -    for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
 | 
| -        if (*listenerIter == eventListener) {
 | 
| -            listeners.remove(listenerIter - listeners.begin());
 | 
| -            return;
 | 
| -        }
 | 
| -    }
 | 
| -}
 | 
| -
 | 
| -bool Worker::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
 | 
| -{
 | 
| -    if (!event || event->type().isEmpty()) {
 | 
| -        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
 | 
| -        return true;
 | 
| -    }
 | 
| -
 | 
| -    ListenerVector listenersCopy = m_eventListeners.get(event->type());
 | 
| -    for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
 | 
| -        event->setTarget(this);
 | 
| -        event->setCurrentTarget(this);
 | 
| -        listenerIter->get()->handleEvent(event.get(), false);
 | 
| -    }
 | 
| -
 | 
| -    return !event->defaultPrevented();
 | 
| -}
 | 
| -
 | 
| -} // namespace WebCore
 | 
| -
 | 
| -#endif // ENABLE(WORKERS)
 | 
| -
 | 
| -
 | 
| +/*
 | 
| + * Copyright (C) 2008 Apple 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:
 | 
| + * 1. Redistributions of source code must retain the above copyright
 | 
| + *    notice, this list of conditions and the following disclaimer.
 | 
| + * 2. 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.
 | 
| + *
 | 
| + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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"
 | 
| +
 | 
| +#if ENABLE(WORKERS)
 | 
| +
 | 
| +#include "Worker.h"
 | 
| +
 | 
| +#include "CachedScript.h"
 | 
| +#include "DOMWindow.h"
 | 
| +#include "DocLoader.h"
 | 
| +#include "Document.h"
 | 
| +#include "EventException.h"
 | 
| +#include "EventListener.h"
 | 
| +#include "EventNames.h"
 | 
| +#include "ExceptionCode.h"
 | 
| +#include "Frame.h"
 | 
| +#include "FrameLoader.h"
 | 
| +#include "MessageEvent.h"
 | 
| +#include "SecurityOrigin.h"
 | 
| +#include "WorkerContext.h"
 | 
| +#include "WorkerMessagingProxy.h"
 | 
| +#include "WorkerThread.h"
 | 
| +#include <wtf/MainThread.h>
 | 
| +
 | 
| +namespace WebCore {
 | 
| +
 | 
| +Worker::Worker(const String& url, Document* doc, ExceptionCode& ec)
 | 
| +    : ActiveDOMObject(doc, this)
 | 
| +    , m_messagingProxy(new WorkerMessagingProxy(doc, this))
 | 
| +{
 | 
| +    m_scriptURL = doc->completeURL(url);
 | 
| +    if (url.isEmpty() || !m_scriptURL.isValid()) {
 | 
| +        ec = SYNTAX_ERR;
 | 
| +        return;
 | 
| +    }
 | 
| +
 | 
| +    if (!doc->securityOrigin()->canAccess(SecurityOrigin::create(m_scriptURL).get())) {
 | 
| +        ec = SECURITY_ERR;
 | 
| +        return;
 | 
| +    }
 | 
| +
 | 
| +    m_cachedScript = doc->docLoader()->requestScript(m_scriptURL, document()->charset());
 | 
| +    if (!m_cachedScript) {
 | 
| +        dispatchErrorEvent();
 | 
| +        return;
 | 
| +    }
 | 
| +
 | 
| +    setPendingActivity(this);  // The worker context does not exist while loading, so we much ensure that the worker object is not collected, as well as its event listeners.
 | 
| +    m_cachedScript->addClient(this);
 | 
| +}
 | 
| +
 | 
| +Worker::~Worker()
 | 
| +{
 | 
| +    ASSERT(isMainThread());
 | 
| +    ASSERT(scriptExecutionContext()); // The context is protected by messaging proxy, so it cannot be destroyed while a Worker exists.
 | 
| +    m_messagingProxy->workerObjectDestroyed();
 | 
| +}
 | 
| +
 | 
| +Document* Worker::document() const
 | 
| +{
 | 
| +    ASSERT(scriptExecutionContext()->isDocument());
 | 
| +    return static_cast<Document*>(scriptExecutionContext());
 | 
| +}
 | 
| +
 | 
| +void Worker::postMessage(const String& message)
 | 
| +{
 | 
| +    m_messagingProxy->postMessageToWorkerContext(message);
 | 
| +}
 | 
| +
 | 
| +void Worker::terminate()
 | 
| +{
 | 
| +    m_messagingProxy->terminateWorkerContext();
 | 
| +}
 | 
| +
 | 
| +bool Worker::canSuspend() const
 | 
| +{
 | 
| +    // FIXME: It is not currently possible to suspend a worker, so pages with workers can not go into page cache.
 | 
| +    return false;
 | 
| +}
 | 
| +
 | 
| +void Worker::stop()
 | 
| +{
 | 
| +    terminate();
 | 
| +}
 | 
| +
 | 
| +bool Worker::hasPendingActivity() const
 | 
| +{
 | 
| +    return m_messagingProxy->hasPendingActivity() || ActiveDOMObject::hasPendingActivity();
 | 
| +}
 | 
| +
 | 
| +void Worker::notifyFinished(CachedResource* unusedResource)
 | 
| +{
 | 
| +    ASSERT_UNUSED(unusedResource, unusedResource == m_cachedScript);
 | 
| +
 | 
| +    if (m_cachedScript->errorOccurred())
 | 
| +        dispatchErrorEvent();
 | 
| +    else {
 | 
| +        String userAgent = document()->frame() ? document()->frame()->loader()->userAgent(m_scriptURL) : String();
 | 
| +        RefPtr<WorkerThread> thread = WorkerThread::create(m_scriptURL, userAgent, m_cachedScript->script(), m_messagingProxy);
 | 
| +        m_messagingProxy->workerThreadCreated(thread);
 | 
| +        thread->start();
 | 
| +    }
 | 
| +
 | 
| +    m_cachedScript->removeClient(this);
 | 
| +    m_cachedScript = 0;
 | 
| +
 | 
| +    unsetPendingActivity(this);
 | 
| +}
 | 
| +
 | 
| +void Worker::dispatchErrorEvent()
 | 
| +{
 | 
| +    RefPtr<Event> evt = Event::create(eventNames().errorEvent, false, true);
 | 
| +    if (m_onErrorListener) {
 | 
| +        evt->setTarget(this);
 | 
| +        evt->setCurrentTarget(this);
 | 
| +        m_onErrorListener->handleEvent(evt.get(), true);
 | 
| +    }
 | 
| +
 | 
| +    ExceptionCode ec = 0;
 | 
| +    dispatchEvent(evt.release(), ec);
 | 
| +    ASSERT(!ec);
 | 
| +}
 | 
| +
 | 
| +void Worker::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
 | 
| +{
 | 
| +    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
 | 
| +    if (iter == m_eventListeners.end()) {
 | 
| +        ListenerVector listeners;
 | 
| +        listeners.append(eventListener);
 | 
| +        m_eventListeners.add(eventType, listeners);
 | 
| +    } else {
 | 
| +        ListenerVector& listeners = iter->second;
 | 
| +        for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
 | 
| +            if (*listenerIter == eventListener)
 | 
| +                return;
 | 
| +        }
 | 
| +        
 | 
| +        listeners.append(eventListener);
 | 
| +        m_eventListeners.add(eventType, listeners);
 | 
| +    }    
 | 
| +}
 | 
| +
 | 
| +void Worker::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
 | 
| +{
 | 
| +    EventListenersMap::iterator iter = m_eventListeners.find(eventType);
 | 
| +    if (iter == m_eventListeners.end())
 | 
| +        return;
 | 
| +    
 | 
| +    ListenerVector& listeners = iter->second;
 | 
| +    for (ListenerVector::const_iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
 | 
| +        if (*listenerIter == eventListener) {
 | 
| +            listeners.remove(listenerIter - listeners.begin());
 | 
| +            return;
 | 
| +        }
 | 
| +    }
 | 
| +}
 | 
| +
 | 
| +bool Worker::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
 | 
| +{
 | 
| +    if (!event || event->type().isEmpty()) {
 | 
| +        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
 | 
| +        return true;
 | 
| +    }
 | 
| +
 | 
| +    ListenerVector listenersCopy = m_eventListeners.get(event->type());
 | 
| +    for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
 | 
| +        event->setTarget(this);
 | 
| +        event->setCurrentTarget(this);
 | 
| +        listenerIter->get()->handleEvent(event.get(), false);
 | 
| +    }
 | 
| +
 | 
| +    return !event->defaultPrevented();
 | 
| +}
 | 
| +
 | 
| +} // namespace WebCore
 | 
| +
 | 
| +#endif // ENABLE(WORKERS)
 | 
| +
 | 
| +
 | 
| 
 |