Prevent assertion/duplicate loads for non-deferred subtitute-data loads
authorvestbo@webkit.org <vestbo@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Jul 2010 10:47:04 +0000 (10:47 +0000)
committervestbo@webkit.org <vestbo@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Jul 2010 10:47:04 +0000 (10:47 +0000)
Reviewed by Darin Adler.

https://bugs.webkit.org/show_bug.cgi?id=30879

MainResourceLoader uses the member m_initialRequest to store requests for future
deferred loads. When doing the actual load in handleDataLoadNow(), we therefore
have to clear this request so that subsequent entries into the loader will not
start yet another load.

This can happen as a result of a PageGroupLoadDeferrer going out of scope when
returning from Chrome::runJavaScriptAlert(), which calls setDeferredLoading(false),
but only in the case of using both substitute-data and non-deferred main resource
load together. That's why two new DRT functions were added:

 * queueLoadHTMLString()
 * setDeferMainResourceLoad()

The change adds DRT hooks for Mac, Win and Qt for these two functions. For Mac
and Win the hook uses new SPI in WebDataSource. For Qt a new static member was
added to the FrameLoaderClientQt and accessed though DumpRenderTreeSupportQt.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@63191 268f45cc-cd09-0410-ab3c-d52691b4dbfc

33 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/loader/non-deferred-substitute-load-expected.txt [new file with mode: 0644]
LayoutTests/fast/loader/non-deferred-substitute-load.html [new file with mode: 0644]
LayoutTests/platform/chromium/test_expectations.txt
LayoutTests/platform/gtk/Skipped
WebCore/ChangeLog
WebCore/loader/MainResourceLoader.cpp
WebKit/mac/ChangeLog
WebKit/mac/WebView/WebDataSource.mm
WebKit/mac/WebView/WebDataSourcePrivate.h
WebKit/qt/ChangeLog
WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp
WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h
WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h
WebKit/win/ChangeLog
WebKit/win/Interfaces/IWebDataSource.idl
WebKit/win/WebDataSource.cpp
WebKit/win/WebDataSource.h
WebKitTools/ChangeLog
WebKitTools/DumpRenderTree/LayoutTestController.cpp
WebKitTools/DumpRenderTree/LayoutTestController.h
WebKitTools/DumpRenderTree/WorkQueueItem.h
WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp
WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm
WebKitTools/DumpRenderTree/mac/WorkQueueItemMac.mm
WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
WebKitTools/DumpRenderTree/qt/WorkQueueItemQt.cpp
WebKitTools/DumpRenderTree/qt/WorkQueueItemQt.h
WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp
WebKitTools/DumpRenderTree/win/WorkQueueItemWin.cpp
WebKitTools/DumpRenderTree/wx/WorkQueueItemWx.cpp

index dc21c41..6ccfdb0 100644 (file)
@@ -1,3 +1,33 @@
+2010-07-07  Tor Arne Vestbø  <tor.arne.vestbo@nokia.com>
+
+        Reviewed by Darin Adler.
+
+        Prevent assertion/duplicate loads for non-deferred subtitute-data loads
+
+        https://bugs.webkit.org/show_bug.cgi?id=30879
+
+        MainResourceLoader uses the member m_initialRequest to store requests for future
+        deferred loads. When doing the actual load in handleDataLoadNow(), we therefore
+        have to clear this request so that subsequent entries into the loader will not
+        start yet another load.
+
+        This can happen as a result of a PageGroupLoadDeferrer going out of scope when
+        returning from Chrome::runJavaScriptAlert(), which calls setDeferredLoading(false),
+        but only in the case of using both substitute-data and non-deferred main resource
+        load together. That's why two new DRT functions were added:
+
+         * queueLoadHTMLString()
+         * setDeferMainResourceLoad()
+
+        The change adds DRT hooks for Mac, Win and Qt for these two functions. For Mac
+        and Win the hook uses new SPI in WebDataSource. For Qt a new static member was
+        added to the FrameLoaderClientQt and accessed though DumpRenderTreeSupportQt.
+
+        * fast/loader/non-deferred-substitute-load-expected.txt: Added.
+        * fast/loader/non-deferred-substitute-load.html: Added.
+        * platform/chromium/test_expectations.txt:
+        * platform/gtk/Skipped:
+
 2010-07-13  Yoshiki Hayashi  <yhayashi@google.com>
 
         Reviewed by Kent Tamura.
diff --git a/LayoutTests/fast/loader/non-deferred-substitute-load-expected.txt b/LayoutTests/fast/loader/non-deferred-substitute-load-expected.txt
new file mode 100644 (file)
index 0000000..8072cf2
--- /dev/null
@@ -0,0 +1,2 @@
+ALERT: Triggering bug through JS-alert
+PASS
diff --git a/LayoutTests/fast/loader/non-deferred-substitute-load.html b/LayoutTests/fast/loader/non-deferred-substitute-load.html
new file mode 100644 (file)
index 0000000..a60f2bc
--- /dev/null
@@ -0,0 +1,15 @@
+<p>This tests that using substitute load in combination with non-deferred main resource loading will not cause
+assertions or duplicate loads, which can happen if the substitute document contains JavaScript-alerts.</p>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.setDeferMainResourceDataLoad(false);
+    layoutTestController.queueLoadHTMLString("<script>if (typeof(hasBeenLoaded) != 'undefined') {" +
+        "document.getElementById('result').innerHTML = 'FAILURE';" +
+    "} else { " +
+        "hasBeenLoaded = true; document.write('<div id=result>PASS</div>'); alert('Triggering bug through JS-alert'); }" +
+    "<\/script>");
+} else
+    document.write('This test must be run by DumpRenderTree!')
+</script>
+
index bae3937..2274df5 100644 (file)
@@ -207,6 +207,10 @@ WONTFIX SKIP : java/lc3 = TEXT
 // TODO: move to platform/chromium-linux/.
 WONTFIX SKIP MAC WIN : platform/chromium/fast/text/chromium-linux-fontconfig-renderstyle.html = FAIL
 
+// Needs DRT queueLoadHTMLString and setDeferMainResourceLoad-implementations
+// See: https://bugs.webkit.org/show_bug.cgi?id=42151
+SKIP : fast/loader/non-deferred-substitute-load.html = FAIL
+
 // -----------------------------------------------------------------
 // WONTFIX TESTS
 // -----------------------------------------------------------------
index 2c5ba04..bcc3f32 100644 (file)
@@ -5212,6 +5212,10 @@ fast/forms/textarea-appearance-wrap.html
 # https://bugs.webkit.org/show_bug.cgi?id=30584
 svg/custom/font-face-not-in-document.svg
 
+# Needs DRT queueLoadHTMLString and setDeferMainResourceLoad-implementations
+# https://bugs.webkit.org/show_bug.cgi?id=42152
+fast/loader/non-deferred-substitute-load.html
+
 # Probably related to https://bugs.webkit.org/show_bug.cgi?id=27637
 http/tests/security/mixedContent/insecure-plugin-in-iframe.html
 http/tests/loading/basic-auth-resend-wrong-credentials.html 
index cf53535..c9afeaa 100644 (file)
@@ -1,3 +1,33 @@
+2010-07-07  Tor Arne Vestbø  <tor.arne.vestbo@nokia.com>
+
+        Reviewed by Darin Adler.
+
+        Prevent assertion/duplicate loads for non-deferred subtitute-data loads
+
+        https://bugs.webkit.org/show_bug.cgi?id=30879
+
+        MainResourceLoader uses the member m_initialRequest to store requests for future
+        deferred loads. When doing the actual load in handleDataLoadNow(), we therefore
+        have to clear this request so that subsequent entries into the loader will not
+        start yet another load.
+
+        This can happen as a result of a PageGroupLoadDeferrer going out of scope when
+        returning from Chrome::runJavaScriptAlert(), which calls setDeferredLoading(false),
+        but only in the case of using both substitute-data and non-deferred main resource
+        load together. That's why two new DRT functions were added:
+
+         * queueLoadHTMLString()
+         * setDeferMainResourceLoad()
+
+        The change adds DRT hooks for Mac, Win and Qt for these two functions. For Mac
+        and Win the hook uses new SPI in WebDataSource. For Qt a new static member was
+        added to the FrameLoaderClientQt and accessed though DumpRenderTreeSupportQt.
+
+        Test: fast/loader/non-deferred-substitute-load.html
+
+        * loader/MainResourceLoader.cpp:
+        (WebCore::MainResourceLoader::handleDataLoadNow):
+
 2010-07-13  Yoshiki Hayashi  <yhayashi@google.com>
 
         Reviewed by Kent Tamura.
index 0a5bf40..6f57a73 100644 (file)
@@ -464,6 +464,10 @@ void MainResourceLoader::handleDataLoadNow(MainResourceLoaderTimer*)
     KURL url = m_substituteData.responseURL();
     if (url.isEmpty())
         url = m_initialRequest.url();
+
+    // Clear the initial request here so that subsequent entries into the
+    // loader will not think there's still a deferred load left to do.
+    m_initialRequest = ResourceRequest();
         
     ResourceResponse response(url, m_substituteData.mimeType(), m_substituteData.content()->size(), m_substituteData.textEncoding(), "");
     didReceiveResponse(response);
index bd82ff4..adb6f23 100644 (file)
@@ -1,3 +1,32 @@
+2010-07-07  Tor Arne Vestbø  <tor.arne.vestbo@nokia.com>
+
+        Reviewed by Darin Adler.
+
+        Prevent assertion/duplicate loads for non-deferred subtitute-data loads
+
+        https://bugs.webkit.org/show_bug.cgi?id=30879
+
+        MainResourceLoader uses the member m_initialRequest to store requests for future
+        deferred loads. When doing the actual load in handleDataLoadNow(), we therefore
+        have to clear this request so that subsequent entries into the loader will not
+        start yet another load.
+
+        This can happen as a result of a PageGroupLoadDeferrer going out of scope when
+        returning from Chrome::runJavaScriptAlert(), which calls setDeferredLoading(false),
+        but only in the case of using both substitute-data and non-deferred main resource
+        load together. That's why two new DRT functions were added:
+
+         * queueLoadHTMLString()
+         * setDeferMainResourceLoad()
+
+        The change adds DRT hooks for Mac, Win and Qt for these two functions. For Mac
+        and Win the hook uses new SPI in WebDataSource. For Qt a new static member was
+        added to the FrameLoaderClientQt and accessed though DumpRenderTreeSupportQt.
+
+        * WebView/WebDataSource.mm:
+        (-[WebDataSource _setDeferMainResourceDataLoad:]):
+        * WebView/WebDataSourcePrivate.h:
+
 2010-07-13  Philippe Normand  <pnormand@igalia.com>
 
         Rubber-stamped by Xan Lopez.
index b16aaa8..02dbc2c 100644 (file)
@@ -211,6 +211,16 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl
 #endif
 }
 
+- (void)_setDeferMainResourceDataLoad:(BOOL)flag
+{
+    DocumentLoader* loader = [self _documentLoader];
+
+    if (!loader)
+        return;
+
+    loader->setDeferMainResourceDataLoad(flag);
+}
+
 @end
 
 @implementation WebDataSource (WebInternal)
index ae8d4cf..df9c61e 100644 (file)
@@ -37,4 +37,6 @@
 
 - (BOOL)_transferApplicationCache:(NSString*)destinationBundleIdentifier;
 
+- (void)_setDeferMainResourceDataLoad:(BOOL)flag;
+
 @end
index e67abca..160240f 100644 (file)
@@ -1,3 +1,35 @@
+2010-07-07  Tor Arne Vestbø  <tor.arne.vestbo@nokia.com>
+
+        Reviewed by Darin Adler.
+
+        Prevent assertion/duplicate loads for non-deferred subtitute-data loads
+
+        https://bugs.webkit.org/show_bug.cgi?id=30879
+
+        MainResourceLoader uses the member m_initialRequest to store requests for future
+        deferred loads. When doing the actual load in handleDataLoadNow(), we therefore
+        have to clear this request so that subsequent entries into the loader will not
+        start yet another load.
+
+        This can happen as a result of a PageGroupLoadDeferrer going out of scope when
+        returning from Chrome::runJavaScriptAlert(), which calls setDeferredLoading(false),
+        but only in the case of using both substitute-data and non-deferred main resource
+        load together. That's why two new DRT functions were added:
+
+         * queueLoadHTMLString()
+         * setDeferMainResourceLoad()
+
+        The change adds DRT hooks for Mac, Win and Qt for these two functions. For Mac
+        and Win the hook uses new SPI in WebDataSource. For Qt a new static member was
+        added to the FrameLoaderClientQt and accessed though DumpRenderTreeSupportQt.
+
+        * WebCoreSupport/DumpRenderTreeSupportQt.cpp:
+        (DumpRenderTreeSupportQt::setDeferMainResourceDataLoad):
+        * WebCoreSupport/DumpRenderTreeSupportQt.h:
+        * WebCoreSupport/FrameLoaderClientQt.cpp:
+        (WebCore::FrameLoaderClientQt::createDocumentLoader):
+        * WebCoreSupport/FrameLoaderClientQt.h:
+
 2010-07-09  Yael Aharon  <yael.aharon@nokia.com>
 
         Reviewed by Laszlo Gombos.
index 99f5653..a83e1a5 100644 (file)
@@ -547,6 +547,11 @@ void DumpRenderTreeSupportQt::setWillSendRequestClearHeaders(const QStringList&
     FrameLoaderClientQt::sendRequestClearHeaders = headers;
 }
 
+void DumpRenderTreeSupportQt::setDeferMainResourceDataLoad(bool b)
+{
+    FrameLoaderClientQt::deferMainResourceDataLoad = b;
+}
+
 void DumpRenderTreeSupportQt::setCustomPolicyDelegate(bool enabled, bool permissive)
 {
     FrameLoaderClientQt::policyDelegateEnabled = enabled;
index 2ff1fc8..188c405 100644 (file)
@@ -116,6 +116,8 @@ public:
     static void setWillSendRequestReturnsNull(bool b);
     static void setWillSendRequestClearHeaders(const QStringList& headers);
 
+    static void setDeferMainResourceDataLoad(bool b);
+
     static void dumpEditingCallbacks(bool b);
     static void dumpSetAcceptsEditing(bool b);
 
index 0348251..fc0f6c3 100644 (file)
@@ -157,6 +157,7 @@ bool FrameLoaderClientQt::dumpResourceLoadCallbacks = false;
 bool FrameLoaderClientQt::sendRequestReturnsNullOnRedirect = false;
 bool FrameLoaderClientQt::sendRequestReturnsNull = false;
 bool FrameLoaderClientQt::dumpResourceResponseMIMETypes = false;
+bool FrameLoaderClientQt::deferMainResourceDataLoad = true;
 
 QStringList FrameLoaderClientQt::sendRequestClearHeaders;
 QString FrameLoaderClientQt::dumpResourceLoadCallbacksPath;
@@ -878,7 +879,7 @@ bool FrameLoaderClientQt::shouldFallBack(const WebCore::ResourceError&)
 WTF::PassRefPtr<WebCore::DocumentLoader> FrameLoaderClientQt::createDocumentLoader(const WebCore::ResourceRequest& request, const SubstituteData& substituteData)
 {
     RefPtr<DocumentLoader> loader = DocumentLoader::create(request, substituteData);
-    if (substituteData.isValid())
+    if (!deferMainResourceDataLoad || substituteData.isValid())
         loader->setDeferMainResourceDataLoad(false);
     return loader.release();
 }
index b4a3c7e..ec672f5 100644 (file)
@@ -221,6 +221,7 @@ public:
     static QStringList sendRequestClearHeaders;
     static bool policyDelegateEnabled;
     static bool policyDelegatePermissive;
+    static bool deferMainResourceDataLoad;
 
 private:
     Frame *m_frame;
index e1b7248..635a610 100644 (file)
@@ -1,3 +1,33 @@
+2010-07-07  Tor Arne Vestbø  <tor.arne.vestbo@nokia.com>
+
+        Reviewed by Darin Adler.
+
+        Prevent assertion/duplicate loads for non-deferred subtitute-data loads
+
+        https://bugs.webkit.org/show_bug.cgi?id=30879
+
+        MainResourceLoader uses the member m_initialRequest to store requests for future
+        deferred loads. When doing the actual load in handleDataLoadNow(), we therefore
+        have to clear this request so that subsequent entries into the loader will not
+        start yet another load.
+
+        This can happen as a result of a PageGroupLoadDeferrer going out of scope when
+        returning from Chrome::runJavaScriptAlert(), which calls setDeferredLoading(false),
+        but only in the case of using both substitute-data and non-deferred main resource
+        load together. That's why two new DRT functions were added:
+
+         * queueLoadHTMLString()
+         * setDeferMainResourceLoad()
+
+        The change adds DRT hooks for Mac, Win and Qt for these two functions. For Mac
+        and Win the hook uses new SPI in WebDataSource. For Qt a new static member was
+        added to the FrameLoaderClientQt and accessed though DumpRenderTreeSupportQt.
+
+        * Interfaces/IWebDataSource.idl:
+        * WebDataSource.cpp:
+        (WebDataSource::setDeferMainResourceDataLoad):
+        * WebDataSource.h:
+
 2010-07-12  Steve Falkenburg  <sfalken@apple.com>
 
         Reviewed by Alice Liu.
index 15bea1a..dd78d7e 100644 (file)
@@ -214,4 +214,5 @@ interface IWebDataSourcePrivate : IUnknown
     HRESULT overrideEncoding([out, retval] BSTR* encoding);
     HRESULT setOverrideEncoding([in] BSTR encoding);
     HRESULT mainDocumentError([out, retval] IWebError** error);
+    HRESULT setDeferMainResourceDataLoad([in] BOOL flag);
 }
index 4ec1fd3..566f174 100644 (file)
@@ -119,6 +119,16 @@ HRESULT STDMETHODCALLTYPE WebDataSource::mainDocumentError(
     return S_OK;
 }
 
+HRESULT STDMETHODCALLTYPE WebDataSource::setDeferMainResourceDataLoad(
+    /* [in] */ BOOL flag)
+{
+    if (!m_loader)
+        return E_FAIL;
+
+    m_loader->setDeferMainResourceDataLoad(flag);
+    return S_OK;
+}
+
 // IUnknown -------------------------------------------------------------------
 
 HRESULT STDMETHODCALLTYPE WebDataSource::QueryInterface(REFIID riid, void** ppvObject)
index 70998ae..3baa024 100644 (file)
@@ -110,6 +110,9 @@ public:
     virtual HRESULT STDMETHODCALLTYPE mainDocumentError(
         /* [retval][out] */ IWebError** error);
 
+    virtual HRESULT STDMETHODCALLTYPE setDeferMainResourceDataLoad(
+        /* [in] */ BOOL flag);
+
     // WebDataSource
     WebDocumentLoader* documentLoader() const;
 protected:
index df11b39..ecb02c6 100644 (file)
@@ -1,3 +1,61 @@
+2010-07-07  Tor Arne Vestbø  <tor.arne.vestbo@nokia.com>
+
+        Reviewed by Darin Adler.
+
+        Prevent assertion/duplicate loads for non-deferred subtitute-data loads
+
+        https://bugs.webkit.org/show_bug.cgi?id=30879
+
+        MainResourceLoader uses the member m_initialRequest to store requests for future
+        deferred loads. When doing the actual load in handleDataLoadNow(), we therefore
+        have to clear this request so that subsequent entries into the loader will not
+        start yet another load.
+
+        This can happen as a result of a PageGroupLoadDeferrer going out of scope when
+        returning from Chrome::runJavaScriptAlert(), which calls setDeferredLoading(false),
+        but only in the case of using both substitute-data and non-deferred main resource
+        load together. That's why two new DRT functions were added:
+
+         * queueLoadHTMLString()
+         * setDeferMainResourceLoad()
+
+        The change adds DRT hooks for Mac, Win and Qt for these two functions. For Mac
+        and Win the hook uses new SPI in WebDataSource. For Qt a new static member was
+        added to the FrameLoaderClientQt and accessed though DumpRenderTreeSupportQt.
+
+        * DumpRenderTree/LayoutTestController.cpp:
+        (LayoutTestController::LayoutTestController):
+        (queueLoadHTMLStringCallback):
+        (setDeferMainResourceDataLoadCallback):
+        (LayoutTestController::staticFunctions):
+        (LayoutTestController::queueLoadHTMLString):
+        * DumpRenderTree/LayoutTestController.h:
+        (LayoutTestController::deferMainResourceDataLoad):
+        (LayoutTestController::setDeferMainResourceDataLoad):
+        * DumpRenderTree/WorkQueueItem.h:
+        (LoadHTMLStringItem::LoadHTMLStringItem):
+        * DumpRenderTree/gtk/WorkQueueItemGtk.cpp:
+        (LoadHTMLStringItem::invoke):
+        * DumpRenderTree/mac/ResourceLoadDelegate.mm:
+        (-[ResourceLoadDelegate webView:resource:willSendRequest:redirectResponse:fromDataSource:]):
+        * DumpRenderTree/mac/WorkQueueItemMac.mm:
+        (LoadHTMLStringItem::invoke):
+        * DumpRenderTree/qt/LayoutTestControllerQt.cpp:
+        (LayoutTestController::reset):
+        (LayoutTestController::setDeferMainResourceDataLoad):
+        (LayoutTestController::queueLoadHTMLString):
+        * DumpRenderTree/qt/LayoutTestControllerQt.h:
+        * DumpRenderTree/qt/WorkQueueItemQt.cpp:
+        (LoadHTMLStringItem::invoke):
+        * DumpRenderTree/qt/WorkQueueItemQt.h:
+        (LoadHTMLStringItem::LoadHTMLStringItem):
+        * DumpRenderTree/win/ResourceLoadDelegate.cpp:
+        (ResourceLoadDelegate::willSendRequest):
+        * DumpRenderTree/win/WorkQueueItemWin.cpp:
+        (LoadHTMLStringItem::invoke):
+        * DumpRenderTree/wx/WorkQueueItemWx.cpp:
+        (LoadHTMLStringItem::invoke):
+
 2010-07-13  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Nikolas Zimmermann.
index cd294bc..26a68c0 100644 (file)
@@ -78,6 +78,7 @@ LayoutTestController::LayoutTestController(const std::string& testPathOrURL, con
     , m_geolocationPermission(false)
     , m_handlesAuthenticationChallenges(false)
     , m_isPrinting(false)
+    , m_deferMainResourceDataLoad(true)
     , m_testPathOrURL(testPathOrURL)
     , m_expectedPixelHash(expectedPixelHash)
 {
@@ -734,6 +735,28 @@ static JSValueRef queueLoadCallback(JSContextRef context, JSObjectRef function,
     return JSValueMakeUndefined(context);
 }
 
+static JSValueRef queueLoadHTMLStringCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    // Has Mac & Windows implementation
+    if (argumentCount < 1)
+        return JSValueMakeUndefined(context);
+
+    JSRetainPtr<JSStringRef> content(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+    ASSERT(!*exception);
+
+    JSRetainPtr<JSStringRef> baseURL;
+    if (argumentCount >= 2) {
+        baseURL.adopt(JSValueToStringCopy(context, arguments[1], exception));
+        ASSERT(!*exception);
+    } else
+        baseURL.adopt(JSStringCreateWithUTF8CString(""));
+
+    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+    controller->queueLoadHTMLString(content.get(), baseURL.get());
+
+    return JSValueMakeUndefined(context);
+}
+
 static JSValueRef queueReloadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     // Has mac & windows implementation
@@ -915,6 +938,18 @@ static JSValueRef setDatabaseQuotaCallback(JSContextRef context, JSObjectRef fun
     return JSValueMakeUndefined(context);
 }
 
+static JSValueRef setDeferMainResourceDataLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    // Has Mac and Windows implementation
+    if (argumentCount < 1)
+        return JSValueMakeUndefined(context);
+
+    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+    controller->setDeferMainResourceDataLoad(JSValueToBoolean(context, arguments[0]));
+
+    return JSValueMakeUndefined(context);
+}
+
 static JSValueRef setDomainRelaxationForbiddenForURLSchemeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     // Has Mac and Windows implementation
@@ -1754,6 +1789,7 @@ JSStaticFunction* LayoutTestController::staticFunctions()
         { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "queueLoadHTMLString", queueLoadHTMLStringCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "queueLoadingScript", queueLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "queueNonLoadingScript", queueNonLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -1774,6 +1810,7 @@ JSStaticFunction* LayoutTestController::staticFunctions()
         { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
+        { "setDeferMainResourceDataLoad", setDeferMainResourceDataLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setDomainRelaxationForbiddenForURLScheme", setDomainRelaxationForbiddenForURLSchemeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setEditingBehavior", setEditingBehaviorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setFrameFlatteningEnabled", setFrameFlatteningEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -1822,6 +1859,11 @@ JSStaticFunction* LayoutTestController::staticFunctions()
     return staticFunctions;
 }
 
+void LayoutTestController::queueLoadHTMLString(JSStringRef content, JSStringRef baseURL)
+{
+    WorkQueue::shared()->queue(new LoadHTMLStringItem(content, baseURL));
+}
+
 void LayoutTestController::queueBackNavigation(int howFarBack)
 {
     WorkQueue::shared()->queue(new BackItem(howFarBack));
index 16eda2c..ec0894d 100644 (file)
@@ -70,6 +70,7 @@ public:
     void queueBackNavigation(int howFarBackward);
     void queueForwardNavigation(int howFarForward);
     void queueLoad(JSStringRef url, JSStringRef target);
+    void queueLoadHTMLString(JSStringRef content, JSStringRef baseURL);
     void queueLoadingScript(JSStringRef script);
     void queueNonLoadingScript(JSStringRef script);
     void queueReload();
@@ -230,6 +231,9 @@ public:
     bool globalFlag() const { return m_globalFlag; }
     void setGlobalFlag(bool globalFlag) { m_globalFlag = globalFlag; }
     
+    bool deferMainResourceDataLoad() const { return m_deferMainResourceDataLoad; }
+    void setDeferMainResourceDataLoad(bool flag) { m_deferMainResourceDataLoad = flag; }
+
     const std::string& testPathOrURL() const { return m_testPathOrURL; }
     const std::string& expectedPixelHash() const { return m_expectedPixelHash; }
     
@@ -316,6 +320,7 @@ private:
     bool m_geolocationPermission;
     bool m_handlesAuthenticationChallenges;
     bool m_isPrinting;
+    bool m_deferMainResourceDataLoad;
 
     std::string m_authenticationUsername;
     std::string m_authenticationPassword; 
index 56be377..34276c8 100644 (file)
@@ -53,6 +53,21 @@ private:
     JSRetainPtr<JSStringRef> m_target;
 };
 
+class LoadHTMLStringItem : public WorkQueueItem {
+public:
+    LoadHTMLStringItem(const JSStringRef content, const JSStringRef baseURL)
+        : m_content(content)
+        , m_baseURL(baseURL)
+    {
+    }
+
+private:
+    virtual bool invoke() const;
+
+    JSRetainPtr<JSStringRef> m_content;
+    JSRetainPtr<JSStringRef> m_baseURL;
+};
+
 class ReloadItem : public WorkQueueItem {
 private:
     virtual bool invoke() const;
index e0e0ffb..afe81be 100644 (file)
@@ -56,6 +56,11 @@ bool LoadItem::invoke() const
     return true;
 }
 
+bool LoadHTMLStringItem::invoke() const
+{
+    return false;
+}
+
 bool ReloadItem::invoke() const
 {
     webkit_web_frame_reload(mainFrame);
index fca65f9..10fa0f3 100644 (file)
@@ -33,6 +33,7 @@
 #import "LayoutTestController.h"
 #import <WebKit/WebKit.h>
 #import <WebKit/WebTypesInternal.h>
+#import <WebKit/WebDataSourcePrivate.h>
 #import <wtf/Assertions.h>
 
 using namespace std;
@@ -131,6 +132,10 @@ using namespace std;
         printf("%s\n", [string UTF8String]);
     }
 
+    if (!done && !gLayoutTestController->deferMainResourceDataLoad()) {
+        [dataSource _setDeferMainResourceDataLoad:false];
+    }
+
     if (!done && gLayoutTestController->willSendRequestReturnsNull())
         return nil;
 
index 4e39a5a..797afb7 100644 (file)
@@ -54,6 +54,15 @@ bool LoadItem::invoke() const
     return true;
 }
 
+bool LoadHTMLStringItem::invoke() const
+{
+    RetainPtr<CFStringRef> contentCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, m_content.get()));
+    RetainPtr<CFStringRef> baseURLCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, m_baseURL.get()));
+
+    [mainFrame loadHTMLString:(NSString *)contentCF.get() baseURL:[NSURL URLWithString:(NSString *)baseURLCF.get()]];
+    return true;
+}
+
 bool ReloadItem::invoke() const
 {
     [[mainFrame webView] reload:nil];
index dd11428..3a6229f 100644 (file)
@@ -72,6 +72,7 @@ void LayoutTestController::reset()
     DumpRenderTreeSupportQt::dumpFrameLoader(false);
     DumpRenderTreeSupportQt::dumpResourceLoadCallbacks(false);
     DumpRenderTreeSupportQt::dumpResourceResponseMIMETypes(false);
+    DumpRenderTreeSupportQt::setDeferMainResourceDataLoad(true);
     DumpRenderTreeSupportQt::setWillSendRequestReturnsNullOnRedirect(false);
     DumpRenderTreeSupportQt::setWillSendRequestReturnsNull(false);
     DumpRenderTreeSupportQt::setWillSendRequestClearHeaders(QStringList());
@@ -249,6 +250,11 @@ void LayoutTestController::setWillSendRequestClearHeader(const QStringList& head
     DumpRenderTreeSupportQt::setWillSendRequestClearHeaders(headers);
 }
 
+void LayoutTestController::setDeferMainResourceDataLoad(bool defer)
+{
+    DumpRenderTreeSupportQt::setDeferMainResourceDataLoad(defer);
+}
+
 void LayoutTestController::queueBackNavigation(int howFarBackward)
 {
     //qDebug() << ">>>queueBackNavigation" << howFarBackward;
@@ -269,6 +275,11 @@ void LayoutTestController::queueLoad(const QString& url, const QString& target)
     WorkQueue::shared()->queue(new LoadItem(absoluteUrl, target, m_drt->webPage()));
 }
 
+void LayoutTestController::queueLoadHTMLString(const QString& content, const QString& baseURL)
+{
+    WorkQueue::shared()->queue(new LoadHTMLStringItem(content, baseURL, m_drt->webPage()));
+}
+
 void LayoutTestController::queueReload()
 {
     //qDebug() << ">>>queueReload";
index 76bc802..4e95381 100644 (file)
@@ -112,6 +112,7 @@ public slots:
     void queueBackNavigation(int howFarBackward);
     void queueForwardNavigation(int howFarForward);
     void queueLoad(const QString& url, const QString& target = QString());
+    void queueLoadHTMLString(const QString& content, const QString& baseURL = QString());
     void queueReload();
     void queueLoadingScript(const QString& script);
     void queueNonLoadingScript(const QString& script);
@@ -148,6 +149,7 @@ public slots:
     void resetLoadFinished() { m_loadFinished = false; }
     void setWindowIsKey(bool isKey);
     void setMainFrameIsFirstResponder(bool isFirst);
+    void setDeferMainResourceDataLoad(bool);
     void setJavaScriptCanAccessClipboard(bool enable);
     void setXSSAuditorEnabled(bool enable);
     void setCaretBrowsingEnabled(bool enable);
index 067e6aa..d1baf08 100644 (file)
@@ -60,6 +60,18 @@ bool LoadItem::invoke() const
     return true;
 }
 
+bool LoadHTMLStringItem::invoke() const
+{
+    Q_ASSERT(m_webPage);
+
+    QWebFrame* frame = m_webPage->mainFrame();
+    if (!frame)
+        return false;
+
+    frame->setHtml(m_content, QUrl(m_baseURL));
+    return true;
+}
+
 bool ReloadItem::invoke() const
 {
     //qDebug() << ">>>ReloadItem::invoke";
index 94da5e1..97c9b04 100644 (file)
@@ -64,6 +64,22 @@ private:
     QString m_target;
 };
 
+class LoadHTMLStringItem : public WorkQueueItem {
+public:
+    LoadHTMLStringItem(const QString& content, const QString &baseURL, QWebPage *page)
+        : WorkQueueItem(page)
+        , m_content(content)
+        , m_baseURL(baseURL)
+    {
+    }
+
+private:
+    virtual bool invoke() const;
+
+    QString m_content;
+    QString m_baseURL;
+};
+
 class ReloadItem : public WorkQueueItem {
 public:
     ReloadItem(QWebPage *page)
index ce01933..49231bd 100644 (file)
@@ -250,6 +250,13 @@ HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::willSendRequest(
             descriptionSuitableForTestResult(redirectResponse).c_str());
     }
 
+    if (!done && !gLayoutTestController->deferMainResourceDataLoad()) {
+        COMPtr<IWebDataSourcePrivate> dataSourcePrivate(Query, dataSource);
+        if (!dataSourcePrivate)
+            return E_FAIL;
+        dataSourcePrivate->setDeferMainResourceDataLoad(FALSE);
+    }
+
     if (!done && gLayoutTestController->willSendRequestReturnsNull()) {
         *newRequest = 0;
         return S_OK;
index 7c60d3d..a24ca37 100644 (file)
@@ -81,6 +81,22 @@ bool LoadItem::invoke() const
     return true;
 }
 
+bool LoadHTMLStringItem::invoke() const
+{
+    wstring content = jsStringRefToWString(m_content.get());
+    wstring baseURL = jsStringRefToWString(m_baseURL.get());
+
+    BSTR contentBSTR = SysAllocString(content.c_str());
+    BSTR baseURLBSTR = SysAllocString(baseURL.c_str());
+
+    frame->loadHTMLString(contentBSTR, baseURLBSTR);
+
+    SysFreeString(contentBSTR);
+    SysFreeString(baseURLBSTR);
+
+    return true;
+}
+
 bool ReloadItem::invoke() const
 {
     COMPtr<IWebView> webView;
index 3e8da19..e6ecb75 100644 (file)
@@ -36,6 +36,11 @@ bool LoadItem::invoke() const
     return false;
 }
 
+bool LoadHTMLStringItem::invoke() const
+{
+    return false;
+}
+
 bool ReloadItem::invoke() const
 {
     return false;