diff options
Diffstat (limited to 'Tools/WebKitTestRunner/WorkQueueManager.cpp')
-rw-r--r-- | Tools/WebKitTestRunner/WorkQueueManager.cpp | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/Tools/WebKitTestRunner/WorkQueueManager.cpp b/Tools/WebKitTestRunner/WorkQueueManager.cpp new file mode 100644 index 000000000..63f491b47 --- /dev/null +++ b/Tools/WebKitTestRunner/WorkQueueManager.cpp @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2012 Intel Corporation. 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 INC. AND ITS 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 APPLE INC. OR ITS 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 "WorkQueueManager.h" + +#include "PlatformWebView.h" +#include "TestController.h" +#include <WebKit/WKPage.h> +#include <WebKit/WKPagePrivate.h> +#include <WebKit/WKRetainPtr.h> +#include <stdio.h> +#include <wtf/text/CString.h> + +namespace WTR { + +static inline WKPageRef mainPage() +{ + return TestController::singleton().mainWebView()->page(); +} + +static inline bool goToItemAtIndex(int index) +{ + WKBackForwardListRef backForwardList = WKPageGetBackForwardList(mainPage()); + ASSERT(backForwardList); + + WKBackForwardListItemRef listItem = WKBackForwardListGetItemAtIndex(backForwardList, index); + if (!listItem) + return false; + + WKPageGoToBackForwardListItem(mainPage(), listItem); + + return true; +} + +class WorkQueueItem { +public: + enum Type { + Loading, + NonLoading + }; + + virtual ~WorkQueueItem() { } + virtual Type invoke() const = 0; +}; + +// Required by WKPageRunJavaScriptInMainFrame(). +static void runJavaScriptFunction(WKSerializedScriptValueRef, WKErrorRef, void*) +{ +} + +template <WorkQueueItem::Type type> +class ScriptItem : public WorkQueueItem { +public: + explicit ScriptItem(const String& script) + : m_script(AdoptWK, WKStringCreateWithUTF8CString(script.utf8().data())) + { + } + + WorkQueueItem::Type invoke() const + { + WKPageRunJavaScriptInMainFrame(mainPage(), m_script.get(), 0, runJavaScriptFunction); + return type; + } + + WKRetainPtr<WKStringRef> m_script; +}; + +class NavigationItem : public WorkQueueItem { +public: + explicit NavigationItem(int index) : m_index(index) { } + + WorkQueueItem::Type invoke() const + { + return goToItemAtIndex(m_index) ? WorkQueueItem::Loading : WorkQueueItem::NonLoading; + } + + unsigned m_index; +}; + +WorkQueueManager::WorkQueueManager() + : m_processing(false) +{ +} + +WorkQueueManager::~WorkQueueManager() +{ +} + +void WorkQueueManager::clearWorkQueue() +{ + m_processing = false; + m_workQueue.clear(); +} + +bool WorkQueueManager::processWorkQueue() +{ + m_processing = false; + while (!m_processing && !m_workQueue.isEmpty()) { + std::unique_ptr<WorkQueueItem> item(m_workQueue.takeFirst()); + m_processing = (item->invoke() == WorkQueueItem::Loading); + } + + return !m_processing; +} + +void WorkQueueManager::queueLoad(const String& url, const String& target, bool shouldOpenExternalURLs) +{ + class LoadItem : public WorkQueueItem { + public: + LoadItem(const String& url, const String& target, bool shouldOpenExternalURLs) + : m_url(AdoptWK, WKURLCreateWithUTF8CString(url.utf8().data())) + , m_target(target) + , m_shouldOpenExternalURLs(shouldOpenExternalURLs) + { + } + + WorkQueueItem::Type invoke() const + { + if (!m_target.isEmpty()) { + // FIXME: Use target. Some layout tests cannot pass as they rely on this functionality. + fprintf(stderr, "queueLoad for a specific target is not implemented.\n"); + return WorkQueueItem::NonLoading; + } + WKPageLoadURLWithShouldOpenExternalURLsPolicy(mainPage(), m_url.get(), m_shouldOpenExternalURLs); + return WorkQueueItem::Loading; + } + + WKRetainPtr<WKURLRef> m_url; + String m_target; + bool m_shouldOpenExternalURLs; + }; + + enqueue(new LoadItem(url, target, shouldOpenExternalURLs)); +} + +void WorkQueueManager::queueLoadHTMLString(const String& content, const String& baseURL, const String& unreachableURL) +{ + class LoadHTMLStringItem : public WorkQueueItem { + public: + LoadHTMLStringItem(const String& content, const String& baseURL, const String& unreachableURL) + : m_content(AdoptWK, WKStringCreateWithUTF8CString(content.utf8().data())) + , m_baseURL(AdoptWK, WKURLCreateWithUTF8CString(baseURL.utf8().data())) + , m_unreachableURL(AdoptWK, WKURLCreateWithUTF8CString(unreachableURL.utf8().data())) + { + } + + WorkQueueItem::Type invoke() const + { + WKPageLoadAlternateHTMLString(mainPage(), m_content.get(), m_baseURL.get(), m_unreachableURL.get()); + return WorkQueueItem::Loading; + } + + WKRetainPtr<WKStringRef> m_content; + WKRetainPtr<WKURLRef> m_baseURL; + WKRetainPtr<WKURLRef> m_unreachableURL; + }; + + enqueue(new LoadHTMLStringItem(content, baseURL, unreachableURL)); +} + +void WorkQueueManager::queueBackNavigation(unsigned howFarBackward) +{ + enqueue(new NavigationItem(-howFarBackward)); +} + +void WorkQueueManager::queueForwardNavigation(unsigned howFarForward) +{ + enqueue(new NavigationItem(howFarForward)); +} + +void WorkQueueManager::queueReload() +{ + class ReloadItem : public WorkQueueItem { + public: + WorkQueueItem::Type invoke() const + { + WKPageReload(mainPage()); + return WorkQueueItem::Loading; + } + }; + + enqueue(new ReloadItem()); +} + +void WorkQueueManager::queueLoadingScript(const String& script) +{ + enqueue(new ScriptItem<WorkQueueItem::Loading>(script)); +} + +void WorkQueueManager::queueNonLoadingScript(const String& script) +{ + enqueue(new ScriptItem<WorkQueueItem::NonLoading>(script)); +} + +void WorkQueueManager::enqueue(WorkQueueItem* item) +{ + ASSERT(item); + if (m_processing) { + fprintf(stderr, "Attempt to enqueue a work item while queue is being processed.\n"); + delete item; + return; + } + + m_workQueue.append(std::unique_ptr<WorkQueueItem>(item)); +} + +} // namespace WTR |