232 lines
6.7 KiB
C++
232 lines
6.7 KiB
C++
/*
|
|
* 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 "StringFunctions.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(toWK(script))
|
|
{
|
|
}
|
|
|
|
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(toWK(content))
|
|
, 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
|