LayoutTests:
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 May 2007 12:31:42 +0000 (12:31 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 May 2007 12:31:42 +0000 (12:31 +0000)
        Reviewed by Oliver.

        - new test case for:
        <rdar://problem/5063277> blank screen after login to Citibank Online (accessing document before frame starts loading cancels load)
        <rdar://problem/5159541> REGRESSION (r20972): Wall Street Journal pages replaced by advertisements (13465)

        (The test case covers both scenarios.)

        * http/tests/misc/frame-access-during-load-expected.checksum: Added.
        * http/tests/misc/frame-access-during-load-expected.png: Added.
        * http/tests/misc/frame-access-during-load-expected.txt: Added.
        * http/tests/misc/frame-access-during-load.html: Added.

        - test results beneficially or harmlessly changed as a result of the above fixes

        * css2.1/t0801-c412-hz-box-00-b-a-expected.checksum:
        * css2.1/t0801-c412-hz-box-00-b-a-expected.png:
        * css2.1/t0801-c412-hz-box-00-b-a-expected.txt: This reflects an <object> containing
        an image now creating an image renderer.

        * dom/xhtml/level2/html/HTMLIFrameElement11-expected.txt: This is updated to a slightly
        less bad failure for access to a frame that's not loaded yet.

        The following test results now reflect the frame removal that the test was testing:

        * fast/dom/clientWidthAfterDocumentIsRemoved-expected.checksum:
        * fast/dom/clientWidthAfterDocumentIsRemoved-expected.png:
        * fast/dom/clientWidthAfterDocumentIsRemoved-expected.txt:
        * fast/dom/replaceChild-expected.checksum:
        * fast/dom/replaceChild-expected.png:
        * fast/dom/replaceChild-expected.txt:

        The following tests results now reflect empty document content for iframes that never load anything:

        * fast/events/focusingUnloadedFrame-expected.txt:
        * tables/mozilla_expected_failures/bugs/bug137388-1-expected.txt:
        * tables/mozilla_expected_failures/bugs/bug137388-2-expected.txt:

WebCore:

        Reviewed by Oliver.

        - WebCore part of fix for:
        <rdar://problem/5063277> blank screen after login to Citibank Online (accessing document before frame starts loading cancels load)
        <rdar://problem/5159541> REGRESSION (r20972): Wall Street Journal pages replaced by advertisements (13465)

        The basic approach is to have Frames start out containing an empty document instead of absolutely nothing,
        so there is no need to initialize them on demand. Various side effects of that cause both of these bugs.

        However, this caused many regressions so I had to fix the fallout.

        * WebCore.exp: fix symbol exports
        * bindings/js/kjs_window.cpp:
        (KJS::createNewWindow): useless "created" bool (we don't need it here)
        (KJS::WindowFunc::callAsFunction): detect if we created a new frame, because if so,
        we need to initialize the domain (can't count on it not having a document), also
        don't try to make a new document for it.
        Also, stop properly.
        * css/cssstyleselector.cpp:
        (WebCore::CSSStyleSelector::CSSStyleSelector): don't count on document having a view here
        * html/HTMLObjectElement.cpp:
        (WebCore::HTMLObjectElement::isImageType): Ask client, to match how other <object> renderer
        decisions are made.
        * loader/FrameLoader.cpp:
        (WebCore::FrameLoader::FrameLoader): Initialize new data members
        (WebCore::FrameLoader::init): Do the slightly tricky sequence of steps to properly make
        an empty document with everything hooked up.
        (WebCore::FrameLoader::createWindow): Added "created" bool.
        (WebCore::FrameLoader::stopLoading): (whitespace change)
        (WebCore::FrameLoader::begin): Don't try to create an empty document.
        (WebCore::FrameLoader::finishedParsing): If creating an initial empty document, don't
        do any of this work.
        (WebCore::FrameLoader::checkCompleted): Do checkLoadComplete() as well.
        (WebCore::FrameLoader::baseURL): don't check for null document
        (WebCore::FrameLoader::baseTarget): ditto
        (WebCore::FrameLoader::completeURL): ditto
        (WebCore::FrameLoader::didTellBridgeAboutLoad): ditto
        (WebCore::FrameLoader::scheduleLocationChange): determine duringLoad differently; doc won't
        be null.
        (WebCore::FrameLoader::gotoAnchor): don't check for null document
        (WebCore::FrameLoader::canTarget): don't check for null document
        (WebCore::FrameLoader::stopForUserCancel): new method for explicit stops like window.stop().
        (WebCore::FrameLoader::transitionToCommitted): check for pre-loaded state properly
        (WebCore::FrameLoader::createEmptyDocument): removed
        (WebCore::FrameLoader::checkLoadCompleteForThisFrame): don't send delegate callbacks when making initial
        doc.
        (WebCore::FrameLoader::tokenizerProcessedData): Assume document; just checkCompleted now that it
        does checkLoadComplete.
        (WebCore::FrameLoader::receivedMainResourceError): assume document
        (WebCore::FrameLoader::saveDocumentState): Assume there's a document except during initial load
        (WebCore::FrameLoader::mainReceivedCompleteError): do checkCompleted, not checkLoadComplete
        (WebCore::FrameLoader::continueLoadWithData): assume document
        * loader/FrameLoader.h:
        * loader/MainResourceLoader.cpp:
        (WebCore::MainResourceLoader::receivedError): Add more ref protection and do things in a slightly
        different order.
        * page/DOMWindow.cpp:
        (WebCore::DOMWindow::document): don't force document creation, just assert there is one.
        * page/Frame.cpp:
        (WebCore::Frame::init): Added init method.
        (WebCore::Frame::pageDestroyed): when a frame is removed, make sure to check if the parent is
        done loading.
        * page/Frame.h:
        * page/mac/WebCoreFrameBridge.mm:
        (-[WebCoreFrameBridge stringByEvaluatingJavaScriptFromString:forceUserGesture:]): No need to force
        document.
        (-[WebCoreFrameBridge aeDescByEvaluatingJavaScriptFromString:]): ditto
        * platform/graphics/svg/SVGImage.cpp:
        (WebCore::SVGImage::dataChanged): init the frame
        * rendering/RenderPart.cpp:
        (WebCore::RenderPart::updateWidgetPosition): If a subframe needs layout, then lay it out even
        if the bounds did not change; the content size might be wrong.
        * rendering/RenderTreeAsText.cpp:
        (WebCore::externalRepresentation): Don't crash if the frame lacks a view.

WebKit:

        Reviewed by Oliver.

        - WebKit part of fix for:
        <rdar://problem/5063277> blank screen after login to Citibank Online (accessing document before frame starts loading cancels load)
        <rdar://problem/5159541> REGRESSION (r20972): Wall Street Journal pages replaced by advertisements (13465)

        The basic approach is to have Frames start out containing an empty document instead of absolutely nothing,
        so there is no need to initialize them on demand. Various side effects of that cause both of these bugs.

        However, this caused many regressions so I had to fix the fallout.

        * WebCoreSupport/WebChromeClient.mm:
        (WebChromeClient::takeFocus): Avoid focus cycle problems (can happen in DumpRenderTree
        with initial empty document now).
        * WebCoreSupport/WebFrameBridge.mm:
        (-[WebFrameBridge finishInitializingWithPage:frameName:frameView:ownerElement:]): init the frame.
        (-[WebFrameBridge determineObjectFromMIMEType:URL:]): return image type when appropriate
        * WebView/WebFrame.mm:
        (-[WebFrame stopLoading]): use stopForUserCancel().
        * WebView/WebFrameView.mm:
        (-[WebFrameView _makeDocumentViewForDataSource:]): assume html when no mime type available.
        * WebView/WebView.mm:
        (-[WebView becomeFirstResponder]): Track whether we are becoming first responder from
        outside the view.
        (-[WebView _becomingFirstResponderFromOutside]): Return this value.
        * WebView/WebViewInternal.h:

WebKitTools:

        Reviewed by Oliver.

        - don't clear events whenever an EventSendingController goes away, only do it at predictable times,
        since destroying a subframe can make one go away

        (Discovered while fixing:

        <rdar://problem/5063277> blank screen after login to Citibank Online (accessing document before frame starts loading cancels load)
        <rdar://problem/5159541> REGRESSION (r20972): Wall Street Journal pages replaced by advertisements (13465)

        * DumpRenderTree/DumpRenderTree.m:
        (runTest): explicitly clear saved events after every page load
        * DumpRenderTree/EventSendingController.h:
        * DumpRenderTree/EventSendingController.m:
        (-[EventSendingController dealloc]): don't clear saved events here...
        (+[EventSendingController clearSavedEvents]): do it here
        * Scripts/check-for-global-initializers:

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

45 files changed:
LayoutTests/ChangeLog
LayoutTests/css2.1/t0801-c412-hz-box-00-b-a-expected.checksum
LayoutTests/css2.1/t0801-c412-hz-box-00-b-a-expected.png
LayoutTests/css2.1/t0801-c412-hz-box-00-b-a-expected.txt
LayoutTests/dom/xhtml/level2/html/HTMLIFrameElement11-expected.txt
LayoutTests/fast/dom/clientWidthAfterDocumentIsRemoved-expected.checksum
LayoutTests/fast/dom/clientWidthAfterDocumentIsRemoved-expected.png
LayoutTests/fast/dom/clientWidthAfterDocumentIsRemoved-expected.txt
LayoutTests/fast/dom/replaceChild-expected.checksum
LayoutTests/fast/dom/replaceChild-expected.png
LayoutTests/fast/dom/replaceChild-expected.txt
LayoutTests/fast/events/focusingUnloadedFrame-expected.txt
LayoutTests/http/tests/misc/frame-access-during-load-expected.checksum [new file with mode: 0644]
LayoutTests/http/tests/misc/frame-access-during-load-expected.png [new file with mode: 0644]
LayoutTests/http/tests/misc/frame-access-during-load-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/misc/frame-access-during-load.html [new file with mode: 0644]
LayoutTests/tables/mozilla_expected_failures/bugs/bug137388-1-expected.txt
LayoutTests/tables/mozilla_expected_failures/bugs/bug137388-2-expected.txt
WebCore/ChangeLog
WebCore/WebCore.exp
WebCore/bindings/js/kjs_window.cpp
WebCore/css/cssstyleselector.cpp
WebCore/html/HTMLObjectElement.cpp
WebCore/loader/FrameLoader.cpp
WebCore/loader/FrameLoader.h
WebCore/loader/MainResourceLoader.cpp
WebCore/page/DOMWindow.cpp
WebCore/page/Frame.cpp
WebCore/page/Frame.h
WebCore/page/mac/WebCoreFrameBridge.mm
WebCore/platform/graphics/svg/SVGImage.cpp
WebCore/rendering/RenderPart.cpp
WebCore/rendering/RenderTreeAsText.cpp
WebKit/ChangeLog
WebKit/WebCoreSupport/WebChromeClient.mm
WebKit/WebCoreSupport/WebFrameBridge.mm
WebKit/WebView/WebFrame.mm
WebKit/WebView/WebFrameView.mm
WebKit/WebView/WebView.mm
WebKit/WebView/WebViewInternal.h
WebKitTools/ChangeLog
WebKitTools/DumpRenderTree/DumpRenderTree.m
WebKitTools/DumpRenderTree/EventSendingController.h
WebKitTools/DumpRenderTree/EventSendingController.m
WebKitTools/Scripts/check-for-global-initializers

index 62cf68e17807701290a4788c78987a00fe60b08b..e915ff81150839fdeedebb3edb3ee51db747e823 100644 (file)
@@ -1,3 +1,43 @@
+2007-05-08  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Oliver.
+        
+        - new test case for:
+        <rdar://problem/5063277> blank screen after login to Citibank Online (accessing document before frame starts loading cancels load)
+        <rdar://problem/5159541> REGRESSION (r20972): Wall Street Journal pages replaced by advertisements (13465)
+
+        (The test case covers both scenarios.)
+
+        * http/tests/misc/frame-access-during-load-expected.checksum: Added.
+        * http/tests/misc/frame-access-during-load-expected.png: Added.
+        * http/tests/misc/frame-access-during-load-expected.txt: Added.
+        * http/tests/misc/frame-access-during-load.html: Added.
+
+        - test results beneficially or harmlessly changed as a result of the above fixes
+
+        * css2.1/t0801-c412-hz-box-00-b-a-expected.checksum:
+        * css2.1/t0801-c412-hz-box-00-b-a-expected.png:
+        * css2.1/t0801-c412-hz-box-00-b-a-expected.txt: This reflects an <object> containing
+        an image now creating an image renderer.
+
+        * dom/xhtml/level2/html/HTMLIFrameElement11-expected.txt: This is updated to a slightly
+        less bad failure for access to a frame that's not loaded yet.
+
+        The following test results now reflect the frame removal that the test was testing:
+        
+        * fast/dom/clientWidthAfterDocumentIsRemoved-expected.checksum:
+        * fast/dom/clientWidthAfterDocumentIsRemoved-expected.png:
+        * fast/dom/clientWidthAfterDocumentIsRemoved-expected.txt:
+        * fast/dom/replaceChild-expected.checksum:
+        * fast/dom/replaceChild-expected.png:
+        * fast/dom/replaceChild-expected.txt:
+
+        The following tests results now reflect empty document content for iframes that never load anything:
+        
+        * fast/events/focusingUnloadedFrame-expected.txt:
+        * tables/mozilla_expected_failures/bugs/bug137388-1-expected.txt:
+        * tables/mozilla_expected_failures/bugs/bug137388-2-expected.txt:
+
 2007-05-10  Brady Eidson <beidson@apple.com>
 
         Reviewed by Oliver
index e2dab35945520080dbb6b8838740342a4617ed23..3b73741ce89c7d10a3ec82f84728abc1d30d1f41 100644 (file)
@@ -1 +1 @@
-428a9c3ebe2494341b8a6722291ee4a8
\ No newline at end of file
+9c92c10fcd15faf0f6d97fa8263b336b
\ No newline at end of file
index 00d0f454889aad847736d4fcb50a40ff813c844d..8e27f6bba30614b3282be7010ddeae2f00f1f272 100644 (file)
Binary files a/LayoutTests/css2.1/t0801-c412-hz-box-00-b-a-expected.png and b/LayoutTests/css2.1/t0801-c412-hz-box-00-b-a-expected.png differ
index 02ef9035b1d31716995d26d4c3143287d30f12ea..baed2e62bb96a27bc5cfeba74891d5bc7fcce723 100644 (file)
@@ -1,21 +1,15 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x276
-  RenderBlock {HTML} at (0,0) size 800x276
-    RenderBody {BODY} at (8,16) size 784x244
+layer at (0,0) size 800x166
+  RenderBlock {HTML} at (0,0) size 800x166
+    RenderBody {BODY} at (8,16) size 784x134
       RenderBlock {P} at (0,0) size 784x18
         RenderText {#text} at (0,0) size 283x18
           text run at (0,0) width 283: "The two diagrams below should be identical."
-      RenderBlock {DIV} at (0,34) size 784x210
+      RenderBlock {DIV} at (0,34) size 784x100
         RenderBlock {P} at (40,0) size 520x40 [color=#0000FF] [bgcolor=#00FFFF] [border: none (40px solid #FF00FF) none (40px solid #FF00FF)]
           RenderText {#text} at (80,0) size 360x40
             text run at (80,0) width 360: "X X X X X"
-        RenderBlock {P} at (0,56) size 784x154
-          RenderPartObject {OBJECT} at (0,0) size 300x150
-            layer at (0,0) size 600x135
-              RenderView at (0,0) size 300x135
-            layer at (0,0) size 600x44
-              RenderBlock {HTML} at (0,0) size 300x44
-                RenderBody {BODY} at (0,0) size 300x44
-                  RenderImage {IMG} at (0,0) size 600x40
+        RenderBlock {P} at (0,56) size 784x44
+          RenderImage {OBJECT} at (0,0) size 600x40
           RenderText {#text} at (0,0) size 0x0
index 964aaf993441b64d2de09e750d87f43c28be0a6b..4e07407a4c88d6bf374edbd87bc49c3d1f3926ec 100644 (file)
@@ -1,4 +1,4 @@
 Test   http://www.w3.org/2001/DOM-Test-Suite/level2/html/HTMLIFrameElement11
-Status error
-Message        TypeError: Undefined value
+Status failure
+Message        titleLink: assertEquals failed, actual , expected NIST DOM HTML Test - FRAME.
 
index 2863a100bb36f042f547326b3909707daebfc869..7bb0ff9e0bc3ef2253be9e3061cd757361f8fba9 100644 (file)
@@ -1 +1 @@
-b0d65e6d722ae42afd88e73711847b6e
\ No newline at end of file
+8209202c03a1a3c14187d06b28d16299
\ No newline at end of file
index 44b02ad4ed5755f3c6ebbd9fb7b0a29ed235ba82..66c723ba2461c36543233f5d216d6a776a4895db 100644 (file)
Binary files a/LayoutTests/fast/dom/clientWidthAfterDocumentIsRemoved-expected.png and b/LayoutTests/fast/dom/clientWidthAfterDocumentIsRemoved-expected.png differ
index d6f9107d5c62322efb51c7689153da824628e97f..71a5e42da50f899511ec052667f7fb057ffda66f 100644 (file)
@@ -2,16 +2,10 @@ layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderBlock {HTML} at (0,0) size 800x600
-    RenderBody {BODY} at (8,8) size 784x584
+    RenderBody {BODY} at (8,8) size 784x576
       RenderBlock {P} at (0,0) size 784x18
         RenderText {#text} at (0,0) size 212x18
           text run at (0,0) width 212: "This test passes if it doesn't crash!"
-      RenderBlock (anonymous) at (0,34) size 784x154
-        RenderPartObject {IFRAME} at (0,0) size 304x154 [border: (2px inset #000000)]
-          layer at (0,0) size 300x150
-            RenderView at (0,0) size 300x150
-          layer at (0,0) size 300x8
-            RenderBlock {HTML} at (0,0) size 300x8
-              RenderBody {BODY} at (8,8) size 284x0
+      RenderBlock (anonymous) at (0,34) size 784x0
         RenderText {#text} at (0,0) size 0x0
         RenderText {#text} at (0,0) size 0x0
index efdac781776e4911862f05962fda58526a33e340..626be878bfa708a0acf87e85eb81787657a79bb9 100644 (file)
@@ -1 +1 @@
-ad439a096df9257efc427a8cfa84277e
\ No newline at end of file
+1abdc7e7be0e3914553cf6443452cd2a
\ No newline at end of file
index 69034e3022ba32d7d7aae838c2aecedb8a46afbb..5bca5a6aaca89ce3b4ddec461c6a7fc917365623 100644 (file)
Binary files a/LayoutTests/fast/dom/replaceChild-expected.png and b/LayoutTests/fast/dom/replaceChild-expected.png differ
index 5c10603497634db3e100142cbe3a1ec81c32adfd..1577d89a13027ce0d8ff238b45381834e69549ca 100644 (file)
@@ -1,19 +1,13 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x152
-  RenderBlock {HTML} at (0,0) size 800x152
-    RenderBody {BODY} at (0,0) size 800x152 [bgcolor=#CCFFCC]
-      RenderBlock {DIV} at (0,0) size 800x152
-        RenderPartObject {IFRAME} at (0,0) size 152x152 [border: (1px solid #000000)]
-          layer at (0,0) size 150x150
-            RenderView at (0,0) size 150x150
-          layer at (0,0) size 150x52
-            RenderBlock {HTML} at (0,0) size 150x52
-              RenderBody {BODY} at (8,8) size 134x36
-                RenderBlock {DIV} at (0,0) size 134x36
-                  RenderBlock {DIV} at (0,0) size 134x18
-                    RenderText {#text} at (0,0) size 33x18
-                      text run at (0,0) width 33: "test 1"
-                  RenderBlock {DIV} at (0,18) size 134x18
-                    RenderText {#text} at (0,0) size 33x18
-                      text run at (0,0) width 33: "test 2"
+layer at (0,0) size 800x36
+  RenderBlock {HTML} at (0,0) size 800x36
+    RenderBody {BODY} at (0,0) size 800x36 [bgcolor=#CCFFCC]
+      RenderBlock {DIV} at (0,0) size 800x36
+        RenderBlock {DIV} at (0,0) size 800x36
+          RenderBlock {DIV} at (0,0) size 800x18
+            RenderText {#text} at (0,0) size 33x18
+              text run at (0,0) width 33: "test 1"
+          RenderBlock {DIV} at (0,18) size 800x18
+            RenderText {#text} at (0,0) size 33x18
+              text run at (0,0) width 33: "test 2"
index 2faaef400a20cd2be05289907606685e2cc2c935..a663c917a887fe1bca8e31155811cfc7cb34473b 100644 (file)
@@ -21,3 +21,8 @@ layer at (0,0) size 800x600
               RenderText {#text} at (0,0) size 0x0
               RenderText {#text} at (0,0) size 0x0
       RenderFrame {FRAME} at (0,0) size 0x0
+        layer at (0,0) size 8x8
+          RenderView at (0,0) size 0x0
+        layer at (0,0) size 8x8
+          RenderBlock {HTML} at (0,0) size 0x8
+            RenderBody {BODY} at (8,8) size 0x0
diff --git a/LayoutTests/http/tests/misc/frame-access-during-load-expected.checksum b/LayoutTests/http/tests/misc/frame-access-during-load-expected.checksum
new file mode 100644 (file)
index 0000000..6b17436
--- /dev/null
@@ -0,0 +1 @@
+bb3f4fc836407714e9c8a31142489c8c
\ No newline at end of file
diff --git a/LayoutTests/http/tests/misc/frame-access-during-load-expected.png b/LayoutTests/http/tests/misc/frame-access-during-load-expected.png
new file mode 100644 (file)
index 0000000..94f7f70
Binary files /dev/null and b/LayoutTests/http/tests/misc/frame-access-during-load-expected.png differ
diff --git a/LayoutTests/http/tests/misc/frame-access-during-load-expected.txt b/LayoutTests/http/tests/misc/frame-access-during-load-expected.txt
new file mode 100644 (file)
index 0000000..1040763
--- /dev/null
@@ -0,0 +1,43 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x576
+      RenderBlock {P} at (0,0) size 784x36
+        RenderText {#text} at (0,0) size 780x36
+          text run at (0,0) width 134: "This test verifies that "
+          text run at (134,0) width 646: "accessing a frame's document while it is still loading does not prevent the load, but can access at least a"
+          text run at (0,18) width 177: "temporary empty document."
+      RenderBlock (anonymous) at (0,52) size 784x116
+        RenderPartObject {IFRAME} at (0,0) size 300x40
+          layer at (0,0) size 300x40
+            RenderView at (0,0) size 300x40
+          layer at (0,0) size 300x40
+            RenderBlock {HTML} at (0,0) size 300x40
+              RenderBody {BODY} at (8,8) size 284x24
+                RenderText {#text} at (0,0) size 71x18
+                  text run at (0,0) width 71: "SUCCESS"
+                RenderText {#text} at (0,0) size 0x0
+                RenderText {#text} at (0,0) size 0x0
+        RenderBR {BR} at (300,40) size 0x0
+        RenderPartObject {IFRAME} at (0,40) size 300x40
+          layer at (0,0) size 300x40
+            RenderView at (0,0) size 300x40
+          layer at (0,0) size 300x40
+            RenderBlock {HTML} at (0,0) size 300x40
+              RenderBody {BODY} at (8,8) size 284x24
+                RenderText {#text} at (0,0) size 71x18
+                  text run at (0,0) width 71: "SUCCESS"
+                RenderText {#text} at (0,0) size 0x0
+                RenderText {#text} at (0,0) size 0x0
+        RenderBR {BR} at (300,80) size 0x0
+        RenderText {#text} at (0,80) size 164x18
+          text run at (0,80) width 164: "[object HTMLDocument]"
+        RenderBR {BR} at (164,94) size 0x0
+        RenderText {#text} at (0,98) size 164x18
+          text run at (0,98) width 164: "[object HTMLDocument]"
+      RenderBlock {P} at (0,184) size 784x18
+        RenderText {#text} at (0,0) size 614x18
+          text run at (0,0) width 614: "If this test passes, you should see SUCCESS twice, followed by [object HTMLDocument] twice."
+        RenderText {#text} at (0,0) size 0x0
+        RenderText {#text} at (0,0) size 0x0
diff --git a/LayoutTests/http/tests/misc/frame-access-during-load.html b/LayoutTests/http/tests/misc/frame-access-during-load.html
new file mode 100644 (file)
index 0000000..ad70271
--- /dev/null
@@ -0,0 +1,15 @@
+<html>
+<body>
+<p>This test verifies that  accessing a frame's document while it is still loading does not prevent the load, but can
+access at least a temporary empty document.</p>
+<iframe frameborder=0 height=40 id="frame1" src="resources/success.html"></iframe><br>
+<iframe frameborder=0 height=40 id="frame2" src="resources/success.html"></iframe><br>
+<script>
+document.write(frames[0].document);
+document.write('<br>');
+document.write(document.getElementById("frame2").contentDocument);
+</script>
+<p>If this test passes, you should see SUCCESS twice, followed by [object HTMLDocument] twice.
+
+</body>
+</html>
index 9e0dfe734808974b8c1204ac7b25f9796b59dece..a3e2ac00749e5b212142a3920389bfc019a8ced1 100644 (file)
@@ -8,4 +8,9 @@ layer at (0,0) size 800x600
           RenderTableRow {TR} at (0,2) size 310x6
             RenderTableCell {TD} at (2,2) size 306x6 [r=0 c=0 rs=1 cs=1]
               RenderPartObject {IFRAME} at (1,1) size 308x4 [border: (2px inset #000000)]
+                layer at (0,0) size 289x8
+                  RenderView at (0,0) size 289x0
+                layer at (0,0) size 289x8
+                  RenderBlock {HTML} at (0,0) size 289x8
+                    RenderBody {BODY} at (8,8) size 273x0
               RenderText {#text} at (0,0) size 0x0
index 19fb1c0be1d7f36e2a58adf23866934cdf3846fa..4de8b8b70ff6f0dab3ec433c9fd7c1213d192c48 100644 (file)
@@ -8,6 +8,11 @@ layer at (0,0) size 785x648
           RenderTableRow {TR} at (0,2) size 310x306
             RenderTableCell {TD} at (2,2) size 306x306 [r=0 c=0 rs=1 cs=1]
               RenderPartObject {IFRAME} at (1,1) size 308x304 [border: (2px inset #000000)]
+                layer at (0,0) size 304x300
+                  RenderView at (0,0) size 304x300
+                layer at (0,0) size 304x300
+                  RenderBlock {HTML} at (0,0) size 304x300
+                    RenderBody {BODY} at (8,8) size 288x284
               RenderText {#text} at (0,0) size 0x0
       RenderTable {TABLE} at (0,310) size 606x306
         RenderTableSection {TBODY} at (0,0) size 606x306
@@ -20,6 +25,11 @@ layer at (0,0) size 785x648
           RenderTableRow {TR} at (0,2) size 310x6
             RenderTableCell {TD} at (2,2) size 306x6 [r=0 c=0 rs=1 cs=1]
               RenderPartObject {IFRAME} at (1,1) size 308x4 [border: (2px inset #000000)]
+                layer at (0,0) size 289x8
+                  RenderView at (0,0) size 289x0
+                layer at (0,0) size 289x8
+                  RenderBlock {HTML} at (0,0) size 289x8
+                    RenderBody {BODY} at (8,8) size 273x0
               RenderText {#text} at (0,0) size 0x0
       RenderTable {TABLE} at (0,626) size 606x6
         RenderTableSection {TBODY} at (0,0) size 606x6
index a26850331139fcb1edcbc206db33c5202bddc1bd..ef7f031da38fe37ec7f13b20bd8d26e879af7566 100644 (file)
@@ -1,3 +1,80 @@
+2007-05-10  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Oliver.
+
+        - WebCore part of fix for:
+        <rdar://problem/5063277> blank screen after login to Citibank Online (accessing document before frame starts loading cancels load)
+        <rdar://problem/5159541> REGRESSION (r20972): Wall Street Journal pages replaced by advertisements (13465)
+
+        The basic approach is to have Frames start out containing an empty document instead of absolutely nothing,
+        so there is no need to initialize them on demand. Various side effects of that cause both of these bugs.
+        
+        However, this caused many regressions so I had to fix the fallout.
+        
+        * WebCore.exp: fix symbol exports
+        * bindings/js/kjs_window.cpp:
+        (KJS::createNewWindow): useless "created" bool (we don't need it here)
+        (KJS::WindowFunc::callAsFunction): detect if we created a new frame, because if so,
+        we need to initialize the domain (can't count on it not having a document), also
+        don't try to make a new document for it.
+        Also, stop properly.
+        * css/cssstyleselector.cpp:
+        (WebCore::CSSStyleSelector::CSSStyleSelector): don't count on document having a view here
+        * html/HTMLObjectElement.cpp:
+        (WebCore::HTMLObjectElement::isImageType): Ask client, to match how other <object> renderer
+        decisions are made.
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::FrameLoader): Initialize new data members
+        (WebCore::FrameLoader::init): Do the slightly tricky sequence of steps to properly make
+        an empty document with everything hooked up.
+        (WebCore::FrameLoader::createWindow): Added "created" bool.
+        (WebCore::FrameLoader::stopLoading): (whitespace change)
+        (WebCore::FrameLoader::begin): Don't try to create an empty document.
+        (WebCore::FrameLoader::finishedParsing): If creating an initial empty document, don't
+        do any of this work.
+        (WebCore::FrameLoader::checkCompleted): Do checkLoadComplete() as well.
+        (WebCore::FrameLoader::baseURL): don't check for null document
+        (WebCore::FrameLoader::baseTarget): ditto
+        (WebCore::FrameLoader::completeURL): ditto
+        (WebCore::FrameLoader::didTellBridgeAboutLoad): ditto
+        (WebCore::FrameLoader::scheduleLocationChange): determine duringLoad differently; doc won't
+        be null.
+        (WebCore::FrameLoader::gotoAnchor): don't check for null document
+        (WebCore::FrameLoader::canTarget): don't check for null document
+        (WebCore::FrameLoader::stopForUserCancel): new method for explicit stops like window.stop().
+        (WebCore::FrameLoader::transitionToCommitted): check for pre-loaded state properly
+        (WebCore::FrameLoader::createEmptyDocument): removed
+        (WebCore::FrameLoader::checkLoadCompleteForThisFrame): don't send delegate callbacks when making initial
+        doc.
+        (WebCore::FrameLoader::tokenizerProcessedData): Assume document; just checkCompleted now that it
+        does checkLoadComplete.
+        (WebCore::FrameLoader::receivedMainResourceError): assume document
+        (WebCore::FrameLoader::saveDocumentState): Assume there's a document except during initial load
+        (WebCore::FrameLoader::mainReceivedCompleteError): do checkCompleted, not checkLoadComplete
+        (WebCore::FrameLoader::continueLoadWithData): assume document
+        * loader/FrameLoader.h:
+        * loader/MainResourceLoader.cpp:
+        (WebCore::MainResourceLoader::receivedError): Add more ref protection and do things in a slightly
+        different order.
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::document): don't force document creation, just assert there is one.
+        * page/Frame.cpp:
+        (WebCore::Frame::init): Added init method.
+        (WebCore::Frame::pageDestroyed): when a frame is removed, make sure to check if the parent is
+        done loading.
+        * page/Frame.h:
+        * page/mac/WebCoreFrameBridge.mm:
+        (-[WebCoreFrameBridge stringByEvaluatingJavaScriptFromString:forceUserGesture:]): No need to force
+        document.
+        (-[WebCoreFrameBridge aeDescByEvaluatingJavaScriptFromString:]): ditto
+        * platform/graphics/svg/SVGImage.cpp:
+        (WebCore::SVGImage::dataChanged): init the frame
+        * rendering/RenderPart.cpp:
+        (WebCore::RenderPart::updateWidgetPosition): If a subframe needs layout, then lay it out even
+        if the bounds did not change; the content size might be wrong.
+        * rendering/RenderTreeAsText.cpp:
+        (WebCore::externalRepresentation): Don't crash if the frame lacks a view.
+
 2007-05-10  David Hyatt  <hyatt@apple.com>
 
         Fix for:
index e02d199050ebe3ad4c2e8a8cd9112d811867f02c..ef432e2e17df4a8579466f6444e20ac969bfd43b 100644 (file)
@@ -145,6 +145,7 @@ __ZN7WebCore11FrameLoader14detachChildrenEv
 __ZN7WebCore11FrameLoader14scrollToAnchorERKNS_4KURLE
 __ZN7WebCore11FrameLoader14stopAllLoadersEv
 __ZN7WebCore11FrameLoader16detachFromParentEv
+__ZN7WebCore11FrameLoader17stopForUserCancelEv
 __ZN7WebCore11FrameLoader18currentHistoryItemEv
 __ZN7WebCore11FrameLoader18shouldHideReferrerERKNS_4KURLERKNS_6StringE
 __ZN7WebCore11FrameLoader20continueLoadWithDataEPNS_12SharedBufferERKNS_6StringES5_RKNS_4KURLE
@@ -359,6 +360,7 @@ __ZN7WebCore5Frame20setSelectionFromNoneEv
 __ZN7WebCore5Frame20windowScriptNPObjectEv
 __ZN7WebCore5Frame21setProhibitsScrollingEb
 __ZN7WebCore5Frame26dashboardRegionsDictionaryEv
+__ZN7WebCore5Frame4initEv
 __ZN7WebCore5Frame9setBridgeEP18WebCoreFrameBridge
 __ZN7WebCore5FrameC1EPNS_4PageEPNS_21HTMLFrameOwnerElementEPNS_17FrameLoaderClientE
 __ZN7WebCore5Image10getNSImageEv
index 091e988b49fc0f116ce68f9bbd84c1beee8273ff..901f79bb795bf03df234e30c465b3ba7ab370caf 100644 (file)
@@ -611,7 +611,8 @@ static Frame* createNewWindow(ExecState* exec, Window* openerWindow, const Depre
     // do an isSafeScript call using the window we create, which can't be done before creating it.
     // We'd have to resolve all those issues to pass the URL instead of "".
 
-    Frame* newFrame = openerFrame->loader()->createWindow(frameRequest, windowFeatures);
+    bool created;
+    Frame* newFrame = openerFrame->loader()->createWindow(frameRequest, windowFeatures, created);
     if (!newFrame)
         return 0;
 
@@ -1690,21 +1691,15 @@ JSValue *WindowFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const Li
       
       // request window (new or existing if framename is set)
       frameRequest.resourceRequest().setHTTPReferrer(activeFrame->loader()->outgoingReferrer());
-      Frame* newFrame = frame->loader()->createWindow(frameRequest, windowFeatures);
+      bool created;
+      Frame* newFrame = frame->loader()->createWindow(frameRequest, windowFeatures, created);
       if (!newFrame)
           return jsUndefined();
       newFrame->loader()->setOpener(frame);
       newFrame->loader()->setOpenedByJavaScript();
-      
-      if (!newFrame->document()) {
-          Document* oldDoc = frame->document();
-          if (oldDoc && oldDoc->baseURL() != 0)
-              newFrame->loader()->begin(oldDoc->baseURL());
-          else
-              newFrame->loader()->begin();
-          newFrame->loader()->write("<HTML><BODY>");
-          newFrame->loader()->end();          
-          if (oldDoc) {
+
+      if (created) {
+          if (Document* oldDoc = frame->document()) {
               newFrame->document()->setDomain(oldDoc->domain(), true);
               newFrame->document()->setBaseURL(oldDoc->baseURL());
           }
@@ -1863,7 +1858,7 @@ JSValue *WindowFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const Li
     return result;
   }
   case Window::Stop:
-        frame->loader()->stopAllLoaders();
+        frame->loader()->stopForUserCancel();
         return jsUndefined();
   case Window::Find:
       if (!window->isSafeScript(exec))
index e18cdf1bf15d1626182a80a5203a3480d153b93a..8fa5a1523f0fe2227ee02c94db57468275545a0e 100644 (file)
@@ -225,7 +225,7 @@ CSSStyleSelector::CSSStyleSelector(Document* doc, const String& userStyleSheet,
 
     view = doc->view();
     strictParsing = _strictParsing;
-    settings = view ? view->frame()->settings() : 0;
+    settings = doc->frame() ? doc->frame()->settings() : 0;
     if (!defaultStyle)
         loadDefaultStyle();
 
index 08c0d663c5dec712adcaeb5096321f90928253d7..be957d59666e22d2cd660d41f63f1e09e2fe0b2f 100644 (file)
@@ -28,6 +28,8 @@
 #include "EventNames.h"
 #include "ExceptionCode.h"
 #include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
 #include "FrameView.h"
 #include "HTMLFormElement.h"
 #include "HTMLDocument.h"
@@ -294,7 +296,9 @@ bool HTMLObjectElement::isImageType()
                 m_serviceType = "text/plain"; // Data URLs with no MIME type are considered text/plain.
         }
     }
-    
+    if (document()->frame())
+        return document()->frame()->loader()->client()->objectContentType(KURL(m_url.deprecatedString()), m_serviceType) == ObjectContentImage;
+
     return Image::supportsType(m_serviceType);
 }
 
index bb6b28a1488b981526b069e7e49f68902d3093e3..3c93d93ffa6439c83c9f78fb867f024deb643e93 100644 (file)
@@ -230,6 +230,8 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)
     , m_checkCompletedTimer(this, &FrameLoader::checkCompletedTimerFired)
     , m_opener(0)
     , m_openedByJavaScript(false)
+    , m_creatingInitialEmptyDocument(false)
+    , m_committedFirstRealDocumentLoad(false)
 #if USE(LOW_BANDWIDTH_DISPLAY)
     , m_useLowBandwidthDisplay(true)
     , m_finishedParsingDuringLowBandwidthDisplay(false)
@@ -249,6 +251,22 @@ FrameLoader::~FrameLoader()
     m_client->frameLoaderDestroyed();
 }
 
+void FrameLoader::init()
+{
+    // this somewhat odd set of steps is needed to give the frame an initial empty document
+    m_creatingInitialEmptyDocument = true;
+    setPolicyDocumentLoader(m_client->createDocumentLoader(ResourceRequest(String("")), SubstituteData()).get());
+    setProvisionalDocumentLoader(m_policyDocumentLoader.get());
+    setState(FrameStateProvisional);
+    m_provisionalDocumentLoader->finishedLoading();
+    begin();
+    write("<body>");
+    end();
+    m_frame->document()->cancelParsing();
+    m_creatingInitialEmptyDocument = false;
+    m_wasLoadEventEmitted = true;
+}
+
 void FrameLoader::setDefersLoading(bool defers)
 {
     if (m_documentLoader)
@@ -260,7 +278,7 @@ void FrameLoader::setDefersLoading(bool defers)
     m_client->setDefersLoading(defers);
 }
 
-Frame* FrameLoader::createWindow(const FrameLoadRequest& request, const WindowFeatures& features)
+Frame* FrameLoader::createWindow(const FrameLoadRequest& request, const WindowFeatures& features, bool& created)
 { 
     ASSERT(!features.dialog || request.frameName().isEmpty());
 
@@ -269,6 +287,7 @@ Frame* FrameLoader::createWindow(const FrameLoadRequest& request, const WindowFe
             if (!request.resourceRequest().url().isEmpty())
                 frame->loader()->load(request, true, 0, 0, HashMap<String, String>());
             frame->page()->chrome()->focus();
+            created = false;
             return frame;
         }
 
@@ -312,6 +331,7 @@ Frame* FrameLoader::createWindow(const FrameLoadRequest& request, const WindowFe
 
     page->chrome()->show();
 
+    created = true;
     return frame;
 }
 
@@ -532,7 +552,7 @@ void FrameLoader::stopLoading(bool sendUnload)
 {
     if (m_frame->document() && m_frame->document()->tokenizer())
         m_frame->document()->tokenizer()->stopParsing();
-  
+
     if (sendUnload) {
         if (m_frame->document()) {
             if (m_wasLoadEventEmitted && !m_wasUnloadEventEmitted) {
@@ -817,9 +837,6 @@ void FrameLoader::begin()
 
 void FrameLoader::begin(const KURL& url)
 {
-    if (m_workingURL.isEmpty())
-        createEmptyDocument(); // Creates an empty document if we don't have one already
-
     clear();
     partClearedInBegin();
 
@@ -842,6 +859,9 @@ void FrameLoader::begin(const KURL& url)
     RefPtr<Document> document = DOMImplementation::instance()->createDocument(m_responseMIMEType, m_frame, m_frame->inViewSourceMode());
     m_frame->setDocument(document);
 
+    if (!m_creatingInitialEmptyDocument)
+        m_committedFirstRealDocumentLoad = true;
+
     document->setURL(m_URL.url());
     // We prefer m_baseURL over m_URL because m_URL changes when we are
     // about to load a new page.
@@ -1087,6 +1107,9 @@ void FrameLoader::gotoAnchor()
 
 void FrameLoader::finishedParsing()
 {
+    if (m_creatingInitialEmptyDocument)
+        return;
+
     // This can be called from the Frame's destructor, in which case we shouldn't protect ourselves
     // because doing so will cause us to re-enter the destructor when protector goes out of scope.
     RefPtr<Frame> protector = m_frame->refCount() > 0 ? m_frame : 0;
@@ -1149,6 +1172,8 @@ void FrameLoader::checkCompleted()
         startRedirectionTimer();
 
     completed();
+    if (m_frame->page())
+        checkLoadComplete();
 }
 
 void FrameLoader::checkCompletedTimerFired(Timer<FrameLoader>*)
@@ -1189,22 +1214,19 @@ void FrameLoader::checkEmitLoadEvent()
 
 KURL FrameLoader::baseURL() const
 {
-    if (!m_frame->document())
-        return KURL();
+    ASSERT(m_frame->document());
     return m_frame->document()->baseURL();
 }
 
 String FrameLoader::baseTarget() const
 {
-    if (!m_frame->document())
-        return String();
+    ASSERT(m_frame->document());
     return m_frame->document()->baseTarget();
 }
 
 KURL FrameLoader::completeURL(const String& url)
 {
-    if (!m_frame->document())
-        return url.deprecatedString();
+    ASSERT(m_frame->document());
     return m_frame->document()->completeURL(url).deprecatedString();
 }
 
@@ -1231,13 +1253,16 @@ void FrameLoader::scheduleLocationChange(const String& url, const String& referr
 
     // Handle a location change of a page with no document as a special case.
     // This may happen when a frame changes the location of another frame.
-    bool duringLoad = !m_frame->document();
+    bool duringLoad = !m_committedFirstRealDocumentLoad;
 
     // If a redirect was scheduled during a load, then stop the current load.
     // Otherwise when the current load transitions from a provisional to a 
     // committed state, pending redirects may be cancelled. 
-    if (duringLoad)
+    if (duringLoad) {
+        if (m_provisionalDocumentLoader)
+            m_provisionalDocumentLoader->stopLoading();
         stopLoading(true);   
+    }
 
     ScheduledRedirection::Type type = duringLoad
         ? ScheduledRedirection::locationChangeDuringLoad : ScheduledRedirection::locationChange;
@@ -1361,8 +1386,7 @@ String FrameLoader::encoding() const
 
 bool FrameLoader::gotoAnchor(const String& name)
 {
-    if (!m_frame->document())
-        return false;
+    ASSERT(m_frame->document());
 
     Node* anchorNode = m_frame->document()->getElementById(AtomicString(name));
     if (!anchorNode)
@@ -1718,14 +1742,6 @@ void FrameLoader::stopRedirectionTimer()
     }
 }
 
-void FrameLoader::updateBaseURLForEmptyDocument()
-{
-    HTMLFrameOwnerElement* owner = m_frame->ownerElement();
-    // FIXME: Should embed be included?
-    if (owner && (owner->hasTagName(iframeTag) || owner->hasTagName(objectTag) || owner->hasTagName(embedTag)))
-        m_frame->document()->setBaseURL(m_frame->tree()->parent()->document()->baseURL());
-}
-
 void FrameLoader::completed()
 {
     RefPtr<Frame> protect(m_frame);
@@ -2170,9 +2186,8 @@ bool FrameLoader::canTarget(Frame* target) const
     if (m_frame->page() == target->page())
         return true;
 
-    String domain;
-    if (Document* document = m_frame->document())
-        domain = document->domain();
+    ASSERT(m_frame->document());
+    String domain = m_frame->document()->domain();
     // Allow if the request is made from a local file.
     if (domain.isEmpty())
         return true;
@@ -2216,6 +2231,13 @@ void FrameLoader::stopAllLoaders()
     m_inStopAllLoaders = false;    
 }
 
+void FrameLoader::stopForUserCancel()
+{
+    stopAllLoaders();
+    if (m_frame->page())
+        checkLoadComplete();
+}
+
 void FrameLoader::cancelPendingArchiveLoad(ResourceLoader* loader)
 {
     m_client->cancelPendingArchiveLoad(loader);
@@ -2378,7 +2400,8 @@ void FrameLoader::transitionToCommitted(PassRefPtr<CachedPage> cachedPage)
     // JavaScript. If the script initiates a new load, we need to abandon the current load,
     // or the two will stomp each other.
     DocumentLoader* pdl = m_provisionalDocumentLoader.get();
-    closeURL();
+    if (m_documentLoader)
+        closeURL();
     if (pdl != m_provisionalDocumentLoader)
         return;
 
@@ -2443,6 +2466,10 @@ void FrameLoader::transitionToCommitted(PassRefPtr<CachedPage> cachedPage)
 
     // Tell the client we've committed this URL.
     ASSERT(m_client->hasFrameView());
+
+    if (m_creatingInitialEmptyDocument)
+        return;
+
     m_client->dispatchDidCommitLoad();
     
     // If we have a title let the WebView know about it.
@@ -2748,6 +2775,9 @@ void FrameLoader::checkLoadCompleteForThisFrame()
                     && m_frame->page() && m_frame->page()->backForwardList())
                 restoreScrollPositionAndViewState();
 
+            if (m_creatingInitialEmptyDocument)
+                return;
+
             const ResourceError& error = dl->mainDocumentError();
             if (!error.isNull())
                 m_client->dispatchDidFailLoad(error);
@@ -2915,22 +2945,12 @@ String FrameLoader::userAgent(const KURL& url) const
     return m_client->userAgent(url);
 }
 
-void FrameLoader::createEmptyDocument()
-{
-    // Although it's not completely clear from the name of this function,
-    // it does nothing if we already have a document, and just creates an
-    // empty one if we have no document at all.
-    if (!m_frame->document()) {
-        loadEmptyDocumentSynchronously();
-        updateBaseURLForEmptyDocument();
-    }
-}
-
 void FrameLoader::tokenizerProcessedData()
 {
-    if (m_frame->document())
-        checkCompleted();
-    checkLoadComplete();
+    ASSERT(m_frame->page());
+    ASSERT(m_frame->document());
+
+    checkCompleted();
 }
 
 void FrameLoader::didTellBridgeAboutLoad(const String& URL)
@@ -3168,9 +3188,7 @@ void FrameLoader::receivedMainResourceError(const ResourceError& error, bool isC
         // We might have made a page cache item, but now we're bailing out due to an error before we ever
         // transitioned to the new page (before WebFrameState == commit).  The goal here is to restore any state
         // so that the existing view (that wenever got far enough to replace) can continue being used.
-        Document* document = m_frame->document();
-        if (document)
-            document->setInPageCache(false);
+        m_frame->document()->setInPageCache(false);
         invalidateCurrentItemCachedPage();
         
         // Call clientRedirectCancelledOrFinished here so that the frame load delegate is notified that the redirect's
@@ -3732,9 +3750,13 @@ void FrameLoader::invalidateCurrentItemCachedPage()
 
 void FrameLoader::saveDocumentState()
 {
+    if (m_creatingInitialEmptyDocument)
+        return;
+
     // Do not save doc state if the page has a password field and a form that would be submitted via https.
     Document* document = m_frame->document();
-    if (document && document->hasPasswordField() && document->hasSecureForm())
+    ASSERT(document);
+    if (document->hasPasswordField() && document->hasSecureForm())
         return;
         
     // For a standard page load, we will have a previous item set, which will be used to
@@ -4174,7 +4196,7 @@ void FrameLoader::mainReceivedCompleteError(DocumentLoader* loader, const Resour
 {
     loader->setPrimaryLoadComplete(true);
     m_client->dispatchDidLoadMainResource(activeDocumentLoader());
-    checkLoadComplete();
+    checkCompleted();
 }
 
 void FrameLoader::mainReceivedError(const ResourceError& error, bool isComplete)
@@ -4375,8 +4397,7 @@ void FrameLoader::continueLoadWithData(SharedBuffer* buffer, const String& mimeT
         encoding = textEncoding;
     setEncoding(encoding, userChosen);
 
-    if (!m_frame->document())
-        return;
+    ASSERT(m_frame->document());
 
     addData(buffer->data(), buffer->size());
 }
index de95d991dd3739d24d7927d796a20a59175a6cd0..5c283c094deee367a35aa9ed7a4c16e0c5068d2e 100644 (file)
@@ -131,6 +131,8 @@ namespace WebCore {
         FrameLoader(Frame*, FrameLoaderClient*);
         ~FrameLoader();
 
+        void init();
+
         Frame* frame() const { return m_frame; }
 
         // FIXME: This is not cool, people.
@@ -162,7 +164,7 @@ namespace WebCore {
 
         static bool shouldHideReferrer(const KURL& url, const String& referrer);
 
-        Frame* createWindow(const FrameLoadRequest&, const WindowFeatures&);
+        Frame* createWindow(const FrameLoadRequest&, const WindowFeatures&, bool& created);
 
         void loadResourceSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data);
 
@@ -170,6 +172,7 @@ namespace WebCore {
 
         // Also not cool.
         void stopAllLoaders();
+        void stopForUserCancel();
         void cancelPendingArchiveLoad(ResourceLoader*);
 
         bool isLoadingMainResource() const;
@@ -330,8 +333,6 @@ namespace WebCore {
 
         Widget* createJavaAppletWidget(const IntSize&, Element*, const HashMap<String, String>& args);
 
-        void createEmptyDocument();
-
         void partClearedInBegin(); 
         void restoreDocumentState();
 
@@ -620,6 +621,9 @@ namespace WebCore {
 
         bool m_openedByJavaScript;
 
+        bool m_creatingInitialEmptyDocument;
+        bool m_committedFirstRealDocumentLoad;
+
         RefPtr<HistoryItem> m_currentHistoryItem;
         RefPtr<HistoryItem> m_previousHistoryItem;
         RefPtr<HistoryItem> m_provisionalHistoryItem;
index 9b67dd2b6eb7ddd39c85e89b1ee033a07fc5f974..2feaa01fcc6a8db12820ebab428a0d161a18edba 100644 (file)
@@ -62,16 +62,19 @@ void MainResourceLoader::receivedError(const ResourceError& error)
 {
     // Calling receivedMainResourceError will likely result in the last reference to this object to go away.
     RefPtr<MainResourceLoader> protect(this);
-
-    frameLoader()->receivedMainResourceError(error, true);
+    RefPtr<Frame> protectFrame(m_frame);
 
     if (!cancelled()) {
         ASSERT(!reachedTerminalState());
         frameLoader()->didFailToLoad(this, error);
+    }
+    
+    frameLoader()->receivedMainResourceError(error, true);
 
+    if (!cancelled()) {
         releaseResources();
     }
-    
+
     ASSERT(reachedTerminalState());
 }
 
index 0582abe3d7204b972a41a3d6260e237672ac708e..7f2f74d73c97126553ac369dfa5f43603c3c7b42 100644 (file)
@@ -58,13 +58,8 @@ Document* DOMWindow::document() const
 {
     if (!m_frame)
         return 0;
-    
-    if (!m_frame->document()) {
-        m_frame->loader()->createEmptyDocument();
-        m_frame->loader()->begin();
-        m_frame->loader()->write("<HTML><BODY>");
-        m_frame->loader()->end();
-    }
+
+    ASSERT(m_frame->document());
     return m_frame->document();
 }
 
index 38eb666b7cfdf1bc3810a04579791e8e099c8c5e..6820a9ec9554d266cdb320a1f5ede5049d85d897 100644 (file)
@@ -252,6 +252,11 @@ Frame::~Frame()
     d = 0;
 }
 
+void Frame::init()
+{
+    d->m_loader->init();
+}
+
 FrameLoader* Frame::loader() const
 {
     return d->m_loader;
@@ -1712,6 +1717,9 @@ EventHandler* Frame::eventHandler() const
 
 void Frame::pageDestroyed()
 {
+    if (Frame* parent = tree()->parent())
+        parent->loader()->checkLoadComplete();
+
     if (d->m_page && d->m_page->focusController()->focusedFrame() == this)
         d->m_page->focusController()->setFocusedFrame(0);
 
index 3291cddcac6b3529fbfa2510c714175451fca972..9f92350e74cb794801503ae59ed1e0b5f1c4ff1e 100644 (file)
@@ -123,6 +123,8 @@ public:
     virtual void setView(FrameView*);
     virtual ~Frame();
     
+    void init();
+
 #if PLATFORM(MAC)    
     void setBridge(WebCoreFrameBridge*);
     WebCoreFrameBridge* bridge() const;
index e4b4ae3536e8320d13cd08954b3f71f22e6a0d7a..873c4265f3d015ef503ea05385fbfdfe476dd5c0 100644 (file)
@@ -681,7 +681,7 @@ static HTMLFormElement *formElementFromDOMElement(DOMElement *element)
 
 - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture
 {
-    m_frame->loader()->createEmptyDocument();
+    ASSERT(m_frame->document());
     JSValue* result = m_frame->loader()->executeScript(0, string, forceUserGesture);
     if (!result)
         return 0;
@@ -691,7 +691,7 @@ static HTMLFormElement *formElementFromDOMElement(DOMElement *element)
 
 - (NSAppleEventDescriptor *)aeDescByEvaluatingJavaScriptFromString:(NSString *)string
 {
-    m_frame->loader()->createEmptyDocument();
+    ASSERT(m_frame->document());
     JSValue* result = m_frame->loader()->executeScript(0, string, true);
     if (!result) // FIXME: pass errors
         return 0;
index c024e0dfade84d12cb3f3aa7b97bc25250bebab4..e2d7514c1c171921d6032f2ea60bb5194947093e 100644 (file)
@@ -136,6 +136,7 @@ bool SVGImage::dataChanged(bool allDataReceived)
         // The Cache code does not know about CachedImages holding Frames and won't know to break the cycle.
         m_page.set(new Page(dummyChromeClient, dummyContextMenuClient, dummyEditorClient, dummyDragClient));
         m_frame = new Frame(m_page.get(), 0, dummyFrameLoaderClient);
+        m_frame->init();
         m_frameView = new FrameView(m_frame.get());
         m_frameView->deref(); // FIXME: FrameView starts with a refcount of 1
         m_frame->setView(m_frameView.get());
index 688c56ead7add778597a9927ce26af5ec3f25685..7b454e9572bb75319b5911a1b86b7369b9442429 100644 (file)
@@ -97,16 +97,22 @@ void RenderPart::updateWidgetPosition()
     width = m_width - borderLeft() - borderRight() - paddingLeft() - paddingRight();
     height = m_height - borderTop() - borderBottom() - paddingTop() - paddingBottom();
     IntRect newBounds(x,y,width,height);
-    if (newBounds != m_widget->frameGeometry()) {
+    bool boundsChanged = newBounds != m_widget->frameGeometry();
+    if (boundsChanged) {
         // The widget changed positions.  Update the frame geometry.
         RenderArena *arena = ref();
         element()->ref();
         m_widget->setFrameGeometry(newBounds);
         element()->deref();
         deref(arena);
-        
-        if (m_widget && m_widget->isFrameView())
-            static_cast<FrameView*>(m_widget)->layout();
+    }
+
+    // if the frame bounds got changed, or if view needs layout (possibly indicating
+    // content size is wrong) we have to do a layout to set the right widget size
+    if (m_widget && m_widget->isFrameView()) {
+        FrameView* frameView = static_cast<FrameView*>(m_widget);
+        if (boundsChanged || frameView->needsLayout())
+            frameView->layout();
     }
 }
 
index 514d3d989772d3be7bd8e1719a52d5336ccb849e..9dbdec1a9de1a8faa34ac744545d77fe3e5396e2 100644 (file)
@@ -485,7 +485,8 @@ DeprecatedString externalRepresentation(RenderObject* o)
 #if ENABLE(SVG)
         writeRenderResources(ts, o->document());
 #endif
-        o->view()->frameView()->layout();
+        if (o->view()->frameView())
+            o->view()->frameView()->layout();
         RenderLayer* l = o->layer();
         if (l) {
             writeLayers(ts, l, l, IntRect(l->xPos(), l->yPos(), l->width(), l->height()));
index 1c00133e3fd5658dcd58d4e8fd3d4ccf3dfc1967..b111fc84e4254420bbb872449d0e7013c5c0833d 100644 (file)
@@ -1,3 +1,32 @@
+2007-05-10  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Oliver.
+
+        - WebKit part of fix for:
+        <rdar://problem/5063277> blank screen after login to Citibank Online (accessing document before frame starts loading cancels load)
+        <rdar://problem/5159541> REGRESSION (r20972): Wall Street Journal pages replaced by advertisements (13465)
+
+        The basic approach is to have Frames start out containing an empty document instead of absolutely nothing,
+        so there is no need to initialize them on demand. Various side effects of that cause both of these bugs.
+        
+        However, this caused many regressions so I had to fix the fallout.
+
+        * WebCoreSupport/WebChromeClient.mm:
+        (WebChromeClient::takeFocus): Avoid focus cycle problems (can happen in DumpRenderTree
+        with initial empty document now).
+        * WebCoreSupport/WebFrameBridge.mm:
+        (-[WebFrameBridge finishInitializingWithPage:frameName:frameView:ownerElement:]): init the frame.
+        (-[WebFrameBridge determineObjectFromMIMEType:URL:]): return image type when appropriate
+        * WebView/WebFrame.mm:
+        (-[WebFrame stopLoading]): use stopForUserCancel().
+        * WebView/WebFrameView.mm:
+        (-[WebFrameView _makeDocumentViewForDataSource:]): assume html when no mime type available.
+        * WebView/WebView.mm:
+        (-[WebView becomeFirstResponder]): Track whether we are becoming first responder from
+        outside the view.
+        (-[WebView _becomingFirstResponderFromOutside]): Return this value.
+        * WebView/WebViewInternal.h:
+
 2007-05-09  Oliver Hunt  <oliver@apple.com>
 
         rs=Adele.
index b554d5dc6b59651afb6d6a1b232fcd61685da71a..98f67f753adc165dc693e765d93001750bd6b25a 100644 (file)
@@ -116,9 +116,16 @@ void WebChromeClient::takeFocus(FocusDirection direction)
         // view of the last view in its key view loop. This makes m_webView
         // behave as if it had no subviews, which is the behavior we want.
         NSView *lastView = [m_webView _findLastViewInKeyViewLoop];
+        // avoid triggering assertions if the WebView is the only thing in the key loop
+        if ([m_webView _becomingFirstResponderFromOutside] && m_webView == [lastView nextValidKeyView])
+            return;
         [[m_webView window] selectKeyViewFollowingView:lastView];
-    } else
+    } else {
+        // avoid triggering assertions if the WebView is the only thing in the key loop
+        if ([m_webView _becomingFirstResponderFromOutside] && m_webView == [m_webView previousValidKeyView])
+            return;
         [[m_webView window] selectKeyViewPrecedingView:m_webView];
+    }
 }
 
 Page* WebChromeClient::createWindow(Frame*, const FrameLoadRequest& request)
index 0afedc95f5e48032e00f6c3176f97bfc16681c32..ac23a3a4d50b43f8ed510980c625a94a0b3dfeb0 100644 (file)
@@ -143,6 +143,7 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
     m_frame = new Frame(page, ownerElement, new WebFrameLoaderClient(_frame));
     m_frame->setBridge(self);
     m_frame->tree()->setName(name);
+    m_frame->init();
     
     [self setTextSizeMultiplier:[webView textSizeMultiplier]];
 
@@ -649,7 +650,7 @@ static BOOL loggedObjectCacheSize = NO;
         return ObjectElementFrame; // Go ahead and hope that we can display the content.
 
     if (MimeTypeRegistry::isSupportedImageMIMEType(MIMEType))
-        return ObjectElementFrame;
+        return ObjectElementImage;
 
     if ([[self webView] _isMIMETypeRegisteredAsPlugin:MIMEType])
         return ObjectElementPlugin;
index cd11d182b64a6a0821335a52409ec2b85d59fc0a..41fc052de83eee8a06984397af747d8e5bab3007 100644 (file)
@@ -847,7 +847,7 @@ static NSURL *createUniqueWebDataURL()
 - (void)stopLoading
 {
     if (FrameLoader* frameLoader = [self _frameLoader])
-        frameLoader->stopAllLoaders();
+        frameLoader->stopForUserCancel();
 }
 
 - (void)reload
index 6eaed0ed88711741348349dea122245cc2d1ab3b..7a408db64b37b153cd6eecab95848ace8e3cbfc9 100644 (file)
@@ -169,8 +169,11 @@ enum {
 }
 
 -(NSView <WebDocumentView> *)_makeDocumentViewForDataSource:(WebDataSource *)dataSource
-{    
-    Class viewClass = [[self class] _viewClassForMIMEType:[[dataSource response] MIMEType]];
+{
+    NSString* MIMEType = [[dataSource response] MIMEType];
+    if (!MIMEType)
+        MIMEType = @"text/html";
+    Class viewClass = [[self class] _viewClassForMIMEType:MIMEType];
     NSView <WebDocumentView> *documentView;
     if (viewClass) {
         // If the dataSource's representation has already been created, and it is also the
index 77389e9f001d555fed154110c096bc8531cb138c..a5e54dc8ae161bcaa02333293453356f2e017fe6 100644 (file)
@@ -248,6 +248,10 @@ static int pluginDatabaseClientCount = 0;
 - (BOOL)_shouldAutoscrollForDraggingInfo:(id)dragInfo;
 @end
 
+@interface NSWindow (AppKitSecretsIKnow) 
+- (id)_oldFirstResponderBeforeBecoming;
+@end
+
 @interface NSObject (ValidateWithoutDelegate)
 - (BOOL)validateUserInterfaceItemWithoutDelegate:(id <NSValidatedUserInterfaceItem>)item;
 @end
@@ -299,6 +303,7 @@ static int pluginDatabaseClientCount = 0;
     BOOL editable;
     BOOL tabKeyCyclesThroughElementsChanged;
     BOOL becomingFirstResponder;
+    BOOL becomingFirstResponderFromOutside;
     BOOL hoverFeedbackSuspended;
 
     NSColor *backgroundColor;
@@ -2257,12 +2262,17 @@ NS_ENDHANDLER
     // WebFrameView has very similar code.
     NSWindow *window = [self window];
     WebFrameView *mainFrameView = [[self mainFrame] frameView];
+
+    NSResponder *previousFirstResponder = [[self window] _oldFirstResponderBeforeBecoming];
+    BOOL fromOutside = ![previousFirstResponder isKindOfClass:[NSView class]] || (![(NSView *)previousFirstResponder isDescendantOf:self] && previousFirstResponder != self);
     
     if ([window keyViewSelectionDirection] == NSSelectingPrevious) {
         NSView *previousValidKeyView = [self previousValidKeyView];
         if ((previousValidKeyView != self) && (previousValidKeyView != mainFrameView)) {
             _private->becomingFirstResponder = YES;
+            _private->becomingFirstResponderFromOutside = fromOutside;
             [window makeFirstResponder:previousValidKeyView];
+            _private->becomingFirstResponderFromOutside = NO;
             _private->becomingFirstResponder = NO;
             return YES;
         } else {
@@ -2272,7 +2282,9 @@ NS_ENDHANDLER
     
     if ([mainFrameView acceptsFirstResponder]) {
         _private->becomingFirstResponder = YES;
+        _private->becomingFirstResponderFromOutside = fromOutside;
         [window makeFirstResponder:mainFrameView];
+        _private->becomingFirstResponderFromOutside = NO;
         _private->becomingFirstResponder = NO;
         return YES;
     } 
@@ -3581,6 +3593,11 @@ static WebFrameView *containingFrameView(NSView *view)
 
 @implementation WebView (WebViewInternal)
 
+- (BOOL)_becomingFirstResponderFromOutside
+{
+    return _private->becomingFirstResponderFromOutside;
+}
+
 - (NSString *)_userVisibleBundleVersionFromFullVersion:(NSString *)fullVersion
 {
     // If the version is 4 digits long or longer, then the first digit represents
index aff7dce0e201364cac59f2ef4c8166547f4710b6..f87a3588421b9c8b23b89f810ce1260e5de19f08 100644 (file)
@@ -109,4 +109,5 @@ WebResourceDelegateImplementationCache WebViewGetResourceLoadDelegateImplementat
 - (void)_addObject:(id)object forIdentifier:(unsigned long)identifier;
 - (id)_objectForIdentifier:(unsigned long)identifier;
 - (void)_removeObjectForIdentifier:(unsigned long)identifier;
+- (BOOL)_becomingFirstResponderFromOutside;
 @end
index 94a48ad1ca1a8869198776f712753a7effd87c7f..114a0c73c2541b18e78737f041a7d01f9aee58d3 100644 (file)
@@ -1,3 +1,23 @@
+2007-05-08  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Oliver.
+        
+        - don't clear events whenever an EventSendingController goes away, only do it at predictable times, 
+        since destroying a subframe can make one go away
+        
+        (Discovered while fixing:
+        
+        <rdar://problem/5063277> blank screen after login to Citibank Online (accessing document before frame starts loading cancels load)
+        <rdar://problem/5159541> REGRESSION (r20972): Wall Street Journal pages replaced by advertisements (13465)
+
+        * DumpRenderTree/DumpRenderTree.m:
+        (runTest): explicitly clear saved events after every page load
+        * DumpRenderTree/EventSendingController.h:
+        * DumpRenderTree/EventSendingController.m:
+        (-[EventSendingController dealloc]): don't clear saved events here...
+        (+[EventSendingController clearSavedEvents]): do it here
+        * Scripts/check-for-global-initializers:
+
 2007-05-10  Mark Rowe  <mrowe@apple.com>
 
         Build fix for DumpRenderTree. Enable Objective-C exceptions in Release configuration.
index b47ddd3217093be22ff30d3429a4a340f9d289d0..7c32da28ae8ec725b2cbeddd14df963fcce18630 100644 (file)
@@ -1551,6 +1551,7 @@ static void runTest(const char *pathOrURL)
         [pool release];
     }
     pool = [[NSAutoreleasePool alloc] init];
+    [EventSendingController clearSavedEvents];
     [[frame webView] setSelectedDOMRange:nil affinity:NSSelectionAffinityDownstream];
     
     if (closeRemainingWindowsWhenComplete) {
index a92eec955c6be4769411b0582398f90baa6248b2..d9e1783c6fbac6ed6a893a888704c0316aaa0364 100644 (file)
@@ -41,6 +41,7 @@
 
 + (void)saveEvent:(NSInvocation *)event;
 + (void)replaySavedEvents;
++ (void)clearSavedEvents;
 
 - (void)enableDOMUIEventLogging:(WebScriptObject *)node;
 
index 9d7b6efac97e176c95b3e08b0dd2793468899d3b..b56546939e1e98ebd864c9cbd6f70c10aa98f06c 100644 (file)
@@ -146,8 +146,6 @@ BOOL replayingSavedEvents;
 
 - (void)dealloc
 {
-    [savedMouseEvents release];
-    savedMouseEvents = nil;
     [super dealloc];
 }
 
@@ -329,6 +327,12 @@ BOOL replayingSavedEvents;
     replayingSavedEvents = NO;
 }
 
++ (void)clearSavedEvents
+{
+    [savedMouseEvents release];
+    savedMouseEvents = nil;
+}
+
 - (void)keyDown:(NSString *)character withModifiers:(WebScriptObject *)modifiers
 {
     NSString *modifier = nil;
index aba21d4c6577f0e80e12999059043aa1ef99b2d2..dd679c2b6a89540f9472e77cc79a9098868d5557 100755 (executable)
@@ -81,6 +81,8 @@ for my $file (sort @files) {
         my $shortName = $file;
         $shortName =~ s/.*\///;
 
+       next if $shortName eq "array_object.o";
+
         # Special cases for files that have initializers in debug builds.
         if ($configuration eq "Debug") {
             if ($target eq "JavaScriptCore") {