Remove setDefersLoading infrastructure from WebKit2
[WebKit-https.git] / Tools / WebKitTestRunner / WorkQueueManager.cpp
1 /*
2  * Copyright (C) 2012 Intel Corporation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WorkQueueManager.h"
28
29 #include "PlatformWebView.h"
30 #include "TestController.h"
31 #include <WebKit/WKPage.h>
32 #include <WebKit/WKPagePrivate.h>
33 #include <WebKit/WKRetainPtr.h>
34 #include <stdio.h>
35 #include <wtf/text/CString.h>
36
37 namespace WTR {
38
39 static inline WKPageRef mainPage()
40 {
41     return TestController::singleton().mainWebView()->page();
42 }
43
44 static inline bool goToItemAtIndex(int index)
45 {
46     WKBackForwardListRef backForwardList = WKPageGetBackForwardList(mainPage());
47     ASSERT(backForwardList);
48
49     WKBackForwardListItemRef listItem = WKBackForwardListGetItemAtIndex(backForwardList, index);
50     if (!listItem)
51         return false;
52
53     WKPageGoToBackForwardListItem(mainPage(), listItem);
54
55     return true;
56 }
57
58 class WorkQueueItem {
59 public:
60     enum Type {
61         Loading,
62         NonLoading
63     };
64
65     virtual ~WorkQueueItem() { }
66     virtual Type invoke() const = 0;
67 };
68
69 // Required by WKPageRunJavaScriptInMainFrame().
70 static void runJavaScriptFunction(WKSerializedScriptValueRef, WKErrorRef, void*)
71 {
72 }
73
74 template <WorkQueueItem::Type type>
75 class ScriptItem : public WorkQueueItem {
76 public:
77     explicit ScriptItem(const String& script)
78         : m_script(AdoptWK, WKStringCreateWithUTF8CString(script.utf8().data()))
79     {
80     }
81
82     WorkQueueItem::Type invoke() const
83     {
84         WKPageRunJavaScriptInMainFrame(mainPage(), m_script.get(), 0, runJavaScriptFunction);
85         return type;
86     }
87
88     WKRetainPtr<WKStringRef> m_script;
89 };
90
91 class NavigationItem : public WorkQueueItem {
92 public:
93     explicit NavigationItem(int index) : m_index(index) { }
94
95     WorkQueueItem::Type invoke() const
96     {
97         return goToItemAtIndex(m_index) ? WorkQueueItem::Loading : WorkQueueItem::NonLoading;
98     }
99
100     unsigned m_index;
101 };
102
103 WorkQueueManager::WorkQueueManager()
104     : m_processing(false)
105 {
106 }
107
108 WorkQueueManager::~WorkQueueManager()
109 {
110 }
111
112 void WorkQueueManager::clearWorkQueue()
113 {
114     m_processing = false;
115     m_workQueue.clear();
116 }
117
118 bool WorkQueueManager::processWorkQueue()
119 {
120     m_processing = false;
121     while (!m_processing && !m_workQueue.isEmpty()) {
122         std::unique_ptr<WorkQueueItem> item(m_workQueue.takeFirst());
123         m_processing = (item->invoke() == WorkQueueItem::Loading);
124     }
125
126     return !m_processing;
127 }
128
129 void WorkQueueManager::queueLoad(const String& url, const String& target, bool shouldOpenExternalURLs)
130 {
131     class LoadItem : public WorkQueueItem {
132     public:
133         LoadItem(const String& url, const String& target, bool shouldOpenExternalURLs)
134             : m_url(AdoptWK, WKURLCreateWithUTF8CString(url.utf8().data()))
135             , m_target(target)
136             , m_shouldOpenExternalURLs(shouldOpenExternalURLs)
137         {
138         }
139
140         WorkQueueItem::Type invoke() const
141         {
142             if (!m_target.isEmpty()) {
143                 // FIXME: Use target. Some layout tests cannot pass as they rely on this functionality.
144                 fprintf(stderr, "queueLoad for a specific target is not implemented.\n");
145                 return WorkQueueItem::NonLoading;
146             }
147             WKPageLoadURLWithShouldOpenExternalURLsPolicy(mainPage(), m_url.get(), m_shouldOpenExternalURLs);
148             return WorkQueueItem::Loading;
149         }
150
151         WKRetainPtr<WKURLRef> m_url;
152         String m_target;
153         bool m_shouldOpenExternalURLs;
154     };
155
156     enqueue(new LoadItem(url, target, shouldOpenExternalURLs));
157 }
158
159 void WorkQueueManager::queueLoadHTMLString(const String& content, const String& baseURL, const String& unreachableURL)
160 {
161     class LoadHTMLStringItem : public WorkQueueItem {
162     public:
163         LoadHTMLStringItem(const String& content, const String& baseURL, const String& unreachableURL)
164             : m_content(AdoptWK, WKStringCreateWithUTF8CString(content.utf8().data()))
165             , m_baseURL(AdoptWK, WKURLCreateWithUTF8CString(baseURL.utf8().data()))
166             , m_unreachableURL(AdoptWK, WKURLCreateWithUTF8CString(unreachableURL.utf8().data()))
167         {
168         }
169
170         WorkQueueItem::Type invoke() const
171         {
172             WKPageLoadAlternateHTMLString(mainPage(), m_content.get(), m_baseURL.get(), m_unreachableURL.get());
173             return WorkQueueItem::Loading;
174         }
175
176         WKRetainPtr<WKStringRef> m_content;
177         WKRetainPtr<WKURLRef> m_baseURL;
178         WKRetainPtr<WKURLRef> m_unreachableURL;
179     };
180
181     enqueue(new LoadHTMLStringItem(content, baseURL, unreachableURL));
182 }
183
184 void WorkQueueManager::queueBackNavigation(unsigned howFarBackward)
185 {
186     enqueue(new NavigationItem(-howFarBackward));
187 }
188
189 void WorkQueueManager::queueForwardNavigation(unsigned howFarForward)
190 {
191     enqueue(new NavigationItem(howFarForward));
192 }
193
194 void WorkQueueManager::queueReload()
195 {
196     class ReloadItem : public WorkQueueItem {
197     public:
198         WorkQueueItem::Type invoke() const
199         {
200             WKPageReload(mainPage());
201             return WorkQueueItem::Loading;
202         }
203     };
204
205     enqueue(new ReloadItem());
206 }
207
208 void WorkQueueManager::queueLoadingScript(const String& script)
209 {
210     enqueue(new ScriptItem<WorkQueueItem::Loading>(script));
211 }
212
213 void WorkQueueManager::queueNonLoadingScript(const String& script)
214 {
215     enqueue(new ScriptItem<WorkQueueItem::NonLoading>(script));
216 }
217
218 void WorkQueueManager::enqueue(WorkQueueItem* item)
219 {
220     ASSERT(item);
221     if (m_processing) {
222         fprintf(stderr, "Attempt to enqueue a work item while queue is being processed.\n");
223         delete item;
224         return;
225     }
226
227     m_workQueue.append(std::unique_ptr<WorkQueueItem>(item));
228 }
229
230 } // namespace WTR