WorkQueueManager.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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. #include "config.h"
  26. #include "WorkQueueManager.h"
  27. #include "PlatformWebView.h"
  28. #include "TestController.h"
  29. #include <WebKit2/WKPage.h>
  30. #include <WebKit2/WKRetainPtr.h>
  31. #include <stdio.h>
  32. #include <wtf/PassOwnPtr.h>
  33. #include <wtf/text/CString.h>
  34. namespace WTR {
  35. static inline WKPageRef mainPage()
  36. {
  37. return TestController::shared().mainWebView()->page();
  38. }
  39. static inline bool goToItemAtIndex(int index)
  40. {
  41. WKBackForwardListRef backForwardList = WKPageGetBackForwardList(mainPage());
  42. ASSERT(backForwardList);
  43. WKBackForwardListItemRef listItem = WKBackForwardListGetItemAtIndex(backForwardList, index);
  44. if (!listItem)
  45. return false;
  46. WKPageGoToBackForwardListItem(mainPage(), listItem);
  47. return true;
  48. }
  49. class WorkQueueItem {
  50. public:
  51. enum Type {
  52. Loading,
  53. NonLoading
  54. };
  55. virtual ~WorkQueueItem() { }
  56. virtual Type invoke() const = 0;
  57. };
  58. // Required by WKPageRunJavaScriptInMainFrame().
  59. static void runJavaScriptFunction(WKSerializedScriptValueRef, WKErrorRef, void*)
  60. {
  61. }
  62. template <WorkQueueItem::Type type>
  63. class ScriptItem : public WorkQueueItem {
  64. public:
  65. explicit ScriptItem(const String& script)
  66. : m_script(AdoptWK, WKStringCreateWithUTF8CString(script.utf8().data()))
  67. {
  68. }
  69. WorkQueueItem::Type invoke() const
  70. {
  71. WKPageRunJavaScriptInMainFrame(mainPage(), m_script.get(), 0, runJavaScriptFunction);
  72. return type;
  73. }
  74. WKRetainPtr<WKStringRef> m_script;
  75. };
  76. class NavigationItem : public WorkQueueItem {
  77. public:
  78. explicit NavigationItem(int index) : m_index(index) { }
  79. WorkQueueItem::Type invoke() const
  80. {
  81. return goToItemAtIndex(m_index) ? WorkQueueItem::Loading : WorkQueueItem::NonLoading;
  82. }
  83. unsigned m_index;
  84. };
  85. WorkQueueManager::WorkQueueManager()
  86. : m_processing(false)
  87. {
  88. }
  89. WorkQueueManager::~WorkQueueManager()
  90. {
  91. }
  92. void WorkQueueManager::clearWorkQueue()
  93. {
  94. m_processing = false;
  95. m_workQueue.clear();
  96. }
  97. bool WorkQueueManager::processWorkQueue()
  98. {
  99. m_processing = false;
  100. while (!m_processing && !m_workQueue.isEmpty()) {
  101. OwnPtr<WorkQueueItem> item(m_workQueue.takeFirst());
  102. m_processing = (item->invoke() == WorkQueueItem::Loading);
  103. }
  104. return !m_processing;
  105. }
  106. void WorkQueueManager::queueLoad(const String& url, const String& target)
  107. {
  108. class LoadItem : public WorkQueueItem {
  109. public:
  110. LoadItem(const String& url, const String& target)
  111. : m_url(AdoptWK, WKURLCreateWithUTF8CString(url.utf8().data()))
  112. , m_target(target)
  113. {
  114. }
  115. WorkQueueItem::Type invoke() const
  116. {
  117. if (!m_target.isEmpty()) {
  118. // FIXME: Use target. Some layout tests cannot pass as they rely on this functionality.
  119. fprintf(stderr, "queueLoad for a specific target is not implemented.\n");
  120. return WorkQueueItem::NonLoading;
  121. }
  122. WKPageLoadURL(mainPage(), m_url.get());
  123. return WorkQueueItem::Loading;
  124. }
  125. WKRetainPtr<WKURLRef> m_url;
  126. String m_target;
  127. };
  128. enqueue(new LoadItem(url, target));
  129. }
  130. void WorkQueueManager::queueLoadHTMLString(const String& content, const String& baseURL, const String& unreachableURL)
  131. {
  132. class LoadHTMLStringItem : public WorkQueueItem {
  133. public:
  134. LoadHTMLStringItem(const String& content, const String& baseURL, const String& unreachableURL)
  135. : m_content(AdoptWK, WKStringCreateWithUTF8CString(content.utf8().data()))
  136. , m_baseURL(AdoptWK, WKURLCreateWithUTF8CString(baseURL.utf8().data()))
  137. , m_unreachableURL(AdoptWK, WKURLCreateWithUTF8CString(unreachableURL.utf8().data()))
  138. {
  139. }
  140. WorkQueueItem::Type invoke() const
  141. {
  142. WKPageLoadAlternateHTMLString(mainPage(), m_content.get(), m_baseURL.get(), m_unreachableURL.get());
  143. return WorkQueueItem::Loading;
  144. }
  145. WKRetainPtr<WKStringRef> m_content;
  146. WKRetainPtr<WKURLRef> m_baseURL;
  147. WKRetainPtr<WKURLRef> m_unreachableURL;
  148. };
  149. enqueue(new LoadHTMLStringItem(content, baseURL, unreachableURL));
  150. }
  151. void WorkQueueManager::queueBackNavigation(unsigned howFarBackward)
  152. {
  153. enqueue(new NavigationItem(-howFarBackward));
  154. }
  155. void WorkQueueManager::queueForwardNavigation(unsigned howFarForward)
  156. {
  157. enqueue(new NavigationItem(howFarForward));
  158. }
  159. void WorkQueueManager::queueReload()
  160. {
  161. class ReloadItem : public WorkQueueItem {
  162. public:
  163. WorkQueueItem::Type invoke() const
  164. {
  165. WKPageReload(mainPage());
  166. return WorkQueueItem::Loading;
  167. }
  168. };
  169. enqueue(new ReloadItem());
  170. }
  171. void WorkQueueManager::queueLoadingScript(const String& script)
  172. {
  173. enqueue(new ScriptItem<WorkQueueItem::Loading>(script));
  174. }
  175. void WorkQueueManager::queueNonLoadingScript(const String& script)
  176. {
  177. enqueue(new ScriptItem<WorkQueueItem::NonLoading>(script));
  178. }
  179. void WorkQueueManager::enqueue(WorkQueueItem* item)
  180. {
  181. ASSERT(item);
  182. if (m_processing) {
  183. fprintf(stderr, "Attempt to enqueue a work item while queue is being processed.\n");
  184. delete item;
  185. return;
  186. }
  187. m_workQueue.append(adoptPtr(item));
  188. }
  189. } // namespace WTR