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) |
+ |
+ |