diff options
author | Feng Qian <> | 2009-04-10 18:11:29 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-04-10 18:11:29 -0700 |
commit | 8f72e70a9fd78eec56623b3a62e68f16b7b27e28 (patch) | |
tree | 181bf9a400c30a1bf34ea6d72560e8d00111d549 /WebCore/workers/WorkerContext.cpp | |
parent | 7ed56f225e0ade046e1c2178977f72b2d896f196 (diff) | |
download | external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.zip external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.tar.gz external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.tar.bz2 |
AI 145796: Land the WebKit merge @r42026.
Automated import of CL 145796
Diffstat (limited to 'WebCore/workers/WorkerContext.cpp')
-rw-r--r-- | WebCore/workers/WorkerContext.cpp | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/WebCore/workers/WorkerContext.cpp b/WebCore/workers/WorkerContext.cpp new file mode 100644 index 0000000..69ef472 --- /dev/null +++ b/WebCore/workers/WorkerContext.cpp @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * 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: + * 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 "WorkerContext.h" + +#include "ActiveDOMObject.h" +#include "DOMTimer.h" +#include "DOMWindow.h" +#include "Event.h" +#include "EventException.h" +#include "MessageEvent.h" +#include "NotImplemented.h" +#include "ResourceRequest.h" +#include "ScriptSourceCode.h" +#include "ScriptValue.h" +#include "SecurityOrigin.h" +#include "ThreadableLoader.h" +#include "WorkerImportScriptsClient.h" +#include "WorkerLocation.h" +#include "WorkerNavigator.h" +#include "WorkerObjectProxy.h" +#include "WorkerThread.h" +#include "XMLHttpRequestException.h" +#include <wtf/RefPtr.h> + +namespace WebCore { + +WorkerContext::WorkerContext(const KURL& url, const String& userAgent, WorkerThread* thread) + : m_url(url) + , m_userAgent(userAgent) + , m_location(WorkerLocation::create(url)) + , m_script(new WorkerScriptController(this)) + , m_thread(thread) +{ + setSecurityOrigin(SecurityOrigin::create(url)); +} + +WorkerContext::~WorkerContext() +{ + ASSERT(currentThread() == m_thread->threadID()); + + m_thread->workerObjectProxy()->workerContextDestroyed(); +} + +ScriptExecutionContext* WorkerContext::scriptExecutionContext() const +{ + return const_cast<WorkerContext*>(this); +} + +const KURL& WorkerContext::virtualURL() const +{ + return m_url; +} + +KURL WorkerContext::virtualCompleteURL(const String& url) const +{ + return completeURL(url); +} + +KURL WorkerContext::completeURL(const String& url) const +{ + // Always return a null URL when passed a null string. + // FIXME: Should we change the KURL constructor to have this behavior? + if (url.isNull()) + return KURL(); + // Always use UTF-8 in Workers. + return KURL(m_location->url(), url); +} + +String WorkerContext::userAgent(const KURL&) const +{ + return m_userAgent; +} + +WorkerNavigator* WorkerContext::navigator() const +{ + if (!m_navigator) + m_navigator = WorkerNavigator::create(m_userAgent); + return m_navigator.get(); +} + +bool WorkerContext::hasPendingActivity() const +{ + ActiveDOMObjectsMap& activeObjects = activeDOMObjects(); + ActiveDOMObjectsMap::const_iterator activeObjectsEnd = activeObjects.end(); + for (ActiveDOMObjectsMap::const_iterator iter = activeObjects.begin(); iter != activeObjectsEnd; ++iter) { + if (iter->first->hasPendingActivity()) + return true; + } + return false; +} + +void WorkerContext::reportException(const String& errorMessage, int lineNumber, const String& sourceURL) +{ + m_thread->workerObjectProxy()->postExceptionToWorkerObject(errorMessage, lineNumber, sourceURL); +} + +void WorkerContext::addMessage(MessageDestination destination, MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL) +{ + m_thread->workerObjectProxy()->postConsoleMessageToWorkerObject(destination, source, level, message, lineNumber, sourceURL); +} + +void WorkerContext::resourceRetrievedByXMLHttpRequest(unsigned long, const ScriptString&) +{ + // FIXME: The implementation is pending the fixes in https://bugs.webkit.org/show_bug.cgi?id=23175 + notImplemented(); +} + +void WorkerContext::scriptImported(unsigned long, const String&) +{ + // FIXME: The implementation is pending the fixes in https://bugs.webkit.org/show_bug.cgi?id=23175 + notImplemented(); +} + +void WorkerContext::postMessage(const String& message) +{ + m_thread->workerObjectProxy()->postMessageToWorkerObject(message); +} + +void WorkerContext::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 WorkerContext::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 WorkerContext::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(); +} + +void WorkerContext::postTask(PassRefPtr<Task> task) +{ + thread()->runLoop().postTask(task); +} + +int WorkerContext::installTimeout(ScheduledAction* action, int timeout, bool singleShot) +{ + return DOMTimer::install(scriptExecutionContext(), action, timeout, singleShot); +} + +void WorkerContext::removeTimeout(int timeoutId) +{ + DOMTimer::removeById(scriptExecutionContext(), timeoutId); +} + +void WorkerContext::dispatchMessage(const String& message) +{ + RefPtr<Event> evt = MessageEvent::create(message, "", "", 0, 0); + + if (m_onmessageListener.get()) { + evt->setTarget(this); + evt->setCurrentTarget(this); + m_onmessageListener->handleEvent(evt.get(), false); + } + + ExceptionCode ec = 0; + dispatchEvent(evt.release(), ec); + ASSERT(!ec); +} + +void WorkerContext::importScripts(const Vector<String>& urls, const String& callerURL, int callerLine, ExceptionCode& ec) +{ + ec = 0; + Vector<String>::const_iterator urlsEnd = urls.end(); + Vector<KURL> completedURLs; + for (Vector<String>::const_iterator it = urls.begin(); it != urlsEnd; ++it) { + const KURL& url = scriptExecutionContext()->completeURL(*it); + if (!url.isValid()) { + ec = SYNTAX_ERR; + return; + } + completedURLs.append(url); + } + String securityOrigin = scriptExecutionContext()->securityOrigin()->toString(); + Vector<KURL>::const_iterator end = completedURLs.end(); + + for (Vector<KURL>::const_iterator it = completedURLs.begin(); it != end; ++it) { + ResourceRequest request(*it); + request.setHTTPMethod("GET"); + request.setHTTPOrigin(securityOrigin); + WorkerImportScriptsClient client(scriptExecutionContext(), *it, callerURL, callerLine); + ThreadableLoader::loadResourceSynchronously(scriptExecutionContext(), request, client); + + // If the fetching attempt failed, throw a NETWORK_ERR exception and abort all these steps. + if (client.failed()) { + ec = XMLHttpRequestException::NETWORK_ERR; + return; + } + + ScriptValue exception; + m_script->evaluate(ScriptSourceCode(client.script(), *it), &exception); + if (!exception.hasNoValue()) { + m_script->setException(exception); + return; + } + } +} + +} // namespace WebCore + +#endif // ENABLE(WORKERS) |