WebKit:
authorsullivan <sullivan@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Mar 2004 19:02:10 +0000 (19:02 +0000)
committersullivan <sullivan@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Mar 2004 19:02:10 +0000 (19:02 +0000)
        First cut at WebKit support for showing error pages for unreachable URLs.
        This doesn't work quite right with the back/forward list yet, but is
        good enough for demos.

        Reviewed by Darin.

        * WebView.subproj/WebBaseResourceHandleDelegate.m:
        (-[WebBaseResourceHandleDelegate didReceiveResponse:]):
        use new _webDataRequextExternalURL to share code

        * WebView.subproj/WebDataProtocol.h:
        Three new methods (all internal to WebKit):
        -[NSURLRequest _webDataRequestUnreachableURL], -[NSURLRequest _webDataRequestExternalURL],
        -[NSURLRequest _webDataRequestSetUnreachableURL]
        * WebView.subproj/WebDataProtocol.m:
        new unreachableURL field of WebDataRequestParameters
        (-[WebDataRequestParameters copyWithZone:]):
        copy new field
        (-[WebDataRequestParameters dealloc]):
        release new field
        (-[NSURLRequest _webDataRequestUnreachableURL]):
        read new field
        (-[NSURLRequest _webDataRequestExternalURL]):
        new method, returns baseURL or "about:blank" for webdata protocol requests. This
        was done in multiple places previously.
        (-[NSURLRequest _webDataRequestExternalRequest]):
        now calls _webDataRequestExternalURL to share code
        (-[NSMutableURLRequest _webDataRequestSetUnreachableURL:]):
        write new field

        * WebView.subproj/WebDataSource.m:
        (-[WebDataSource unreachableURL]):
        new method, might become API; returns the unreachable URL, if any, for which this datasource
        holds placeholder content
        (-[WebDataSource _URLForHistory]):
        new method, returns the URL to be stored in History for this dataSource. This returns nil
        for run-of-the-mill WebDataProtocol URLs (replacing code elsewhere that checked for this
        case) but returns the unreachableURL for the case where this datasource holds placeholder
        content.
        (-[WebDataSource _setTitle:]):
        now calls _URLForHistory

        * WebView.subproj/WebDataSourcePrivate.h:
        added unreachableURL in the should-become-API section, and _URLForHistory elsewhere

        * WebView.subproj/WebFrame.m:
        (-[WebFrame loadPlaceholderHTMLString:baseURL:unreachableURL:]):
        new should-become-API method for displaying an error page for an unreachable URL
        (-[WebFrame loadPropertyList:]):
        updated to pass nil for unreachableURL
        (-[WebFrame _webDataRequestForData:MIMEType:textEncodingName:baseURL:unreachableURL:]):
        added unreachableURL parameter, which gets set on the data request
        (-[WebFrame _addBackForwardItemClippedAtTarget:]):
        use _URLForHistory instead of just checking for WebDataProtocol
        (-[WebFrame _createItem:]):
        use unreachableURL if there is one
        (-[WebFrame _transitionToCommitted:]):
        use _URLForHistory instead of just checking for WebDataProtocol
        (-[WebFrame _isLoadComplete]):
        check whether a new load has started in the delegate callback and if so, don't
        reset the loading state here
        (-[WebFrame _loadData:MIMEType:textEncodingName:baseURL:unreachableURL:]):
        added unreachableURL parameter, which gets passed through
        (-[WebFrame loadData:MIMEType:textEncodingName:baseURL:]):
        send nil unreachableURL parameter
        (-[WebFrame _loadHTMLString:baseURL:unreachableURL:]):
        new bottleneck method for loadHTMLString:baseURL: and loadPlaceholderHTMLString:baseURL:unreachableURL:;
        this is the guts of loadHTMLString:baseURL: with the new unreachableURL parameter passed through
        (-[WebFrame loadHTMLString:baseURL:]):
        now calls new bottleneck method

        * WebView.subproj/WebFramePrivate.h:
        added loadPlaceholderString:baseURL:unreachableURL: to should-be-API section; added unreachableURL
        parameter to _webDataRequestForData:MIMEType:textEncodingName:baseURL:

WebBrowser:

        First cut at WebBrowser support for showing error pages for unreachable URLs.
        This doesn't work quite right with the back/forward list yet, but is
        good enough for demos. The old sheet-using code remains intact, and there's
        a menu item in the Debug menu to try the new way (old way is still default
        for now).

        Reviewed by Darin.

        * PreferenceKeys.h:
        added DebugDisplayErrorsAsPagesPreferenceKey; also deleted a couple of unused
        old preference keys.

        * BrowserWebController.h:
        added showErrorPageForURL:withTitle:message:

        * BrowserWebController.m:
        (-[BrowserWebView webView:unableToImplementPolicyWithError:frame:]):
        use showErrorPageForURL:... if the preference is set that way
        (-[BrowserWebView errorPageHTMLWithTitle:message:]):
        new method, returns an HTML string for the error page. This will eventually be
        done reading resources from disk no doubt, but for now we just display a simple
        page that has the same text as the sheet.
        (-[BrowserWebView showErrorPageForURL:withTitle:message:]):
        new method, uses new loadPlaceholderHTMLString:baseURL:unreachableURL: to put
        up an error page in the webview
        (-[BrowserWebView expectedOrCurrentURL]):
        use unreachableURL if there is one

        * Debug/DebugUtilities.m:
        (-[DebugUtilities createDebugMenu]):
        add menu item "Show Page Load Errors Inline"
        (-[NSApplication validate_toggleDisplayLoadErrorsAsPages:]):
        new method, sets the checkmark on the new menu item appropriately
        (-[NSApplication toggleDisplayLoadErrorsAsPages:]):
        new method, toggles the state of the preference

        * LoadProgressMonitor.m:
        (-[LoadProgressMonitor _createProgressEntryWithRequest:dataSource:]):
        use unreachableURL if there is one
        (-[LoadProgressMonitor webView:resource:didReceiveResponse:fromDataSource:]):
        ditto

        * LocationChangeError.m:
        (-[LocationChangeHandler displayOrRememberLocationChangeError:forDataSource:]):
        use showErrorPage:... if the preference is set that way

        * LocationChangeHandler.m:
        (-[LocationChangeHandler webView:locationChangeDone:forDataSource:]):
        use previously-fetched local variable "frame" rather than getting it from
        the dataSource again. This is not only trivially faster in the normal case,
        but also avoids a bug when the code earlier in this method triggers another
        page load (as in the showErrorPage:... case).

        * English.lproj/Localizable.strings:
        updated for these changes

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

WebKit/ChangeLog
WebKit/WebView.subproj/WebBaseResourceHandleDelegate.m
WebKit/WebView.subproj/WebDataProtocol.h
WebKit/WebView.subproj/WebDataProtocol.m
WebKit/WebView.subproj/WebDataSource.m
WebKit/WebView.subproj/WebDataSourcePrivate.h
WebKit/WebView.subproj/WebFrame.m
WebKit/WebView.subproj/WebFramePrivate.h
WebKit/WebView.subproj/WebLoader.m

index c7af75adb317617f4fe664ebf48759d1d2e30e9c..e1fa7f127b3a5a00ab9b80576421b22757105c06 100644 (file)
@@ -1,3 +1,80 @@
+2004-03-05  John Sullivan  <sullivan@apple.com>
+
+        First cut at WebKit support for showing error pages for unreachable URLs.
+        This doesn't work quite right with the back/forward list yet, but is
+        good enough for demos.
+
+        Reviewed by Darin.
+
+        * WebView.subproj/WebBaseResourceHandleDelegate.m:
+        (-[WebBaseResourceHandleDelegate didReceiveResponse:]):
+        use new _webDataRequextExternalURL to share code
+        
+        * WebView.subproj/WebDataProtocol.h:
+        Three new methods (all internal to WebKit):
+        -[NSURLRequest _webDataRequestUnreachableURL], -[NSURLRequest _webDataRequestExternalURL],
+        -[NSURLRequest _webDataRequestSetUnreachableURL]
+        * WebView.subproj/WebDataProtocol.m:
+        new unreachableURL field of WebDataRequestParameters
+        (-[WebDataRequestParameters copyWithZone:]):
+        copy new field
+        (-[WebDataRequestParameters dealloc]):
+        release new field
+        (-[NSURLRequest _webDataRequestUnreachableURL]):
+        read new field
+        (-[NSURLRequest _webDataRequestExternalURL]):
+        new method, returns baseURL or "about:blank" for webdata protocol requests. This
+        was done in multiple places previously.
+        (-[NSURLRequest _webDataRequestExternalRequest]):
+        now calls _webDataRequestExternalURL to share code
+        (-[NSMutableURLRequest _webDataRequestSetUnreachableURL:]):
+        write new field
+        
+        * WebView.subproj/WebDataSource.m:
+        (-[WebDataSource unreachableURL]):
+        new method, might become API; returns the unreachable URL, if any, for which this datasource
+        holds placeholder content
+        (-[WebDataSource _URLForHistory]):
+        new method, returns the URL to be stored in History for this dataSource. This returns nil
+        for run-of-the-mill WebDataProtocol URLs (replacing code elsewhere that checked for this
+        case) but returns the unreachableURL for the case where this datasource holds placeholder
+        content.
+        (-[WebDataSource _setTitle:]):
+        now calls _URLForHistory
+        
+        * WebView.subproj/WebDataSourcePrivate.h:
+        added unreachableURL in the should-become-API section, and _URLForHistory elsewhere
+        
+        * WebView.subproj/WebFrame.m:
+        (-[WebFrame loadPlaceholderHTMLString:baseURL:unreachableURL:]):
+        new should-become-API method for displaying an error page for an unreachable URL
+        (-[WebFrame loadPropertyList:]):
+        updated to pass nil for unreachableURL
+        (-[WebFrame _webDataRequestForData:MIMEType:textEncodingName:baseURL:unreachableURL:]):
+        added unreachableURL parameter, which gets set on the data request
+        (-[WebFrame _addBackForwardItemClippedAtTarget:]):
+        use _URLForHistory instead of just checking for WebDataProtocol
+        (-[WebFrame _createItem:]):
+        use unreachableURL if there is one
+        (-[WebFrame _transitionToCommitted:]):
+        use _URLForHistory instead of just checking for WebDataProtocol
+        (-[WebFrame _isLoadComplete]):
+        check whether a new load has started in the delegate callback and if so, don't
+        reset the loading state here
+        (-[WebFrame _loadData:MIMEType:textEncodingName:baseURL:unreachableURL:]):
+        added unreachableURL parameter, which gets passed through
+        (-[WebFrame loadData:MIMEType:textEncodingName:baseURL:]):
+        send nil unreachableURL parameter
+        (-[WebFrame _loadHTMLString:baseURL:unreachableURL:]):
+        new bottleneck method for loadHTMLString:baseURL: and loadPlaceholderHTMLString:baseURL:unreachableURL:;
+        this is the guts of loadHTMLString:baseURL: with the new unreachableURL parameter passed through
+        (-[WebFrame loadHTMLString:baseURL:]):
+        now calls new bottleneck method
+        
+        * WebView.subproj/WebFramePrivate.h:
+        added loadPlaceholderString:baseURL:unreachableURL: to should-be-API section; added unreachableURL
+        parameter to _webDataRequestForData:MIMEType:textEncodingName:baseURL:
+
 2004-03-04  Chris Blumenberg  <cblu@apple.com>
 
        - Made image dragging and copying always work without needing to re-download by using the data source's WebResource of the image instead of relying on the Foundation cache.
index 844b8455ae6f3c750a83a5f7e433023eea1e4882..2449c3d43d63714ad63c5c856772af1053303de6 100644 (file)
     // anything including possibly releasing self; one example of this is 3266216
     [self retain]; 
 
-    // If the URL is one of our whacky applewebdata URLs that
+    // If the URL is one of our whacky applewebdata URLs then
     // fake up a substitute URL to present to the delegate.
     if([WebDataProtocol _webIsDataProtocolURL:[r URL]]) {
-       NSURL *baseURL = [request _webDataRequestBaseURL];
-        if (baseURL == nil) {
-            baseURL = [NSURL URLWithString:@"about:blank"];
-       }
-        r = [[[NSURLResponse alloc] initWithURL:baseURL MIMEType:[r MIMEType] expectedContentLength:[r expectedContentLength] textEncodingName:[r textEncodingName]] autorelease];
+        r = [[[NSURLResponse alloc] initWithURL:[request _webDataRequestExternalURL] MIMEType:[r MIMEType] expectedContentLength:[r expectedContentLength] textEncodingName:[r textEncodingName]] autorelease];
     }
 
     [r retain];
index e262868ba7b05955a6c67d3932d7fe0c9045ec13..e0fd8c04a13f601682732b40ba6de5b3747a997b 100644 (file)
@@ -20,6 +20,8 @@
 @interface NSURLRequest (WebDataRequest)
 + (NSURL *)_webDataRequestURLForData:(NSData *)data;
 - (NSURL *)_webDataRequestBaseURL;
+- (NSURL *)_webDataRequestUnreachableURL;
+- (NSURL *)_webDataRequestExternalURL;
 - (NSData *)_webDataRequestData;
 - (NSString *)_webDataRequestEncoding;
 - (NSString *)_webDataRequestMIMEType;
@@ -31,5 +33,6 @@
 - (void)_webDataRequestSetEncoding:(NSString *)encoding;
 - (void)_webDataRequestSetMIMEType:(NSString *)MIMEType;
 - (void)_webDataRequestSetBaseURL:(NSURL *)baseURL;
+- (void)_webDataRequestSetUnreachableURL:(NSURL *)unreachableURL;
 @end
 
index 94c781b3ad571d9c9b3c751a960a209d77dd773c..9829cbf8f295ede713a13f21beaba93c07ae0cdf 100644 (file)
@@ -21,6 +21,7 @@ static NSString *WebDataRequestPropertyKey = @"WebDataRequest";
     NSString *MIMEType;
     NSString *encoding;
     NSURL *baseURL;
+    NSURL *unreachableURL;
 }
 @end
 
@@ -32,6 +33,7 @@ static NSString *WebDataRequestPropertyKey = @"WebDataRequest";
     newInstance->data = [data copyWithZone:zone];
     newInstance->encoding = [encoding copyWithZone:zone];
     newInstance->baseURL = [baseURL copyWithZone:zone];
+    newInstance->unreachableURL = [unreachableURL copyWithZone:zone];
     newInstance->MIMEType = [MIMEType copyWithZone:zone];
     return newInstance;
 }
@@ -42,6 +44,7 @@ static NSString *WebDataRequestPropertyKey = @"WebDataRequest";
     [MIMEType release];
     [encoding release];
     [baseURL release];
+    [unreachableURL release];
     [super dealloc];
 }
 
@@ -95,6 +98,26 @@ static NSString *WebDataRequestPropertyKey = @"WebDataRequest";
     return parameters ? parameters->baseURL : nil;
 }
 
+- (NSURL *)_webDataRequestUnreachableURL
+{
+    WebDataRequestParameters *parameters = [self _webDataRequestParametersForReading];
+    return parameters ? parameters->unreachableURL : nil;
+}
+
+- (NSURL *)_webDataRequestExternalURL
+{
+    WebDataRequestParameters *parameters = [self _webDataRequestParametersForReading];
+    if (!parameters) {
+        return nil;
+    }
+    
+    if (parameters->baseURL) {
+        return parameters->baseURL;
+    }
+    
+    return [NSURL URLWithString:@"about:blank"];
+}
+
 - (NSMutableURLRequest *)_webDataRequestExternalRequest
 {
     WebDataRequestParameters *parameters = [self _webDataRequestParametersForReading];
@@ -102,11 +125,7 @@ static NSString *WebDataRequestPropertyKey = @"WebDataRequest";
     
     if (parameters){
         newRequest = [[self mutableCopyWithZone:[self zone]] autorelease];
-        NSURL *baseURL = [self _webDataRequestBaseURL];
-        if (baseURL)
-            [newRequest setURL:baseURL]; 
-        else
-            [newRequest setURL:[NSURL URLWithString:@"about:blank"]];
+        [newRequest setURL:[self _webDataRequestExternalURL]];
     } 
     return newRequest;
 }
@@ -154,6 +173,13 @@ static NSString *WebDataRequestPropertyKey = @"WebDataRequest";
     parameters->baseURL = [baseURL retain];
 }
 
+- (void)_webDataRequestSetUnreachableURL:(NSURL *)unreachableURL
+{
+    WebDataRequestParameters *parameters = [self _webDataRequestParametersForWriting];
+    [parameters->unreachableURL release];
+    parameters->unreachableURL = [unreachableURL retain];
+}
+
 @end
 
 
index 3f2334e6d611650e54eb29bf231940cebeac3346..bc9374095920cf651175961643f541e4a3ffbd92 100644 (file)
     return [self _propertyListWithData:data subresourceURLStrings:[_private->subresources allKeys]];
 }
 
+- (NSURL *)unreachableURL
+{
+    return [_private->originalRequest _webDataRequestUnreachableURL];
+}
+
 - (NSFileWrapper *)_fileWrapperForURL:(NSURL *)URL
 {
     if ([URL isFileURL]) {
     return _private->loadingStartedTime;
 }
 
+- (NSURL *)_URLForHistory
+{
+    // Return the URL to be used for history and B/F list.
+    // Returns nil for WebDataProtocol URLs that aren't placeholders 
+    // for unreachable URLs, because these can't be stored in history.
+    NSURL *URL = [_private->originalRequestCopy URL];
+    if ([WebDataProtocol _webIsDataProtocolURL:URL]) {
+        URL = [_private->originalRequestCopy _webDataRequestUnreachableURL];
+    }
+    
+    return [URL _webkit_canonicalize];
+}
+
 - (void)_setTitle:(NSString *)title
 {
     NSString *trimmed;
     
     // The title doesn't get communicated to the WebView until we are committed.
     if (_private->committed) {
-        WebHistoryItem *entry;
-        NSURL *canonURL = [[[self _originalRequest] URL] _webkit_canonicalize];
-        entry = [[WebHistory optionalSharedHistory] itemForURL: canonURL];
-        [entry setTitle: _private->pageTitle];
-
-        // Must update the entries in the back-forward list too.
-        [_private->ourBackForwardItems makeObjectsPerformSelector:@selector(setTitle:) withObject:_private->pageTitle];
-
-        [[_private->webView _frameLoadDelegateForwarder] webView:_private->webView
-                                                         didReceiveTitle:_private->pageTitle
-                                                                forFrame:[self webFrame]];
+        NSURL *URLForHistory = [self _URLForHistory];
+        if (URLForHistory != nil) {
+            WebHistoryItem *entry = [[WebHistory optionalSharedHistory] itemForURL:URLForHistory];
+            [entry setTitle: _private->pageTitle];
+            
+            // Must update the entries in the back-forward list too.
+            [_private->ourBackForwardItems makeObjectsPerformSelector:@selector(setTitle:) withObject:_private->pageTitle];
+            
+            [[_private->webView _frameLoadDelegateForwarder] webView:_private->webView
+                                                     didReceiveTitle:_private->pageTitle
+                                                            forFrame:[self webFrame]];
+        }
     }
 }
 
index 355da8e2b4499e31fcaebe10ead3780963f4dd4a..93fc9d60b2d5aeb092974a1920d2197e22c72f68 100644 (file)
 - (void)addSubresource:(WebResource *)subresource;
 - (void)addSubresources:(NSArray *)subresources;
 - (id)propertyList;
+- (NSURL *)unreachableURL;
 
 - (NSFileWrapper *)_fileWrapperForURL:(NSURL *)URL;
 
 - (void)_startLoading;
 - (void)_stopLoading;
 - (NSURL *)_URL;
+- (NSURL *)_URLForHistory;
 - (WebView *)_webView;
 - (void)_setRepresentation:(id<WebDocumentRepresentation>)representation;
 - (void)_setWebView:(WebView *)webView;
index 98e5d7b2dabb45c3e8053d9375861a5b2a16c761..3e853d239962846ff9bd20efdc7a3e6cf6adb014 100644 (file)
@@ -124,7 +124,7 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
 
 @interface WebFrame (ForwardDecls)
 - (void)_loadRequest:(NSURLRequest *)request triggeringAction:(NSDictionary *)action loadType:(WebFrameLoadType)loadType formState:(WebFormState *)formState;
-
+- (void)_loadHTMLString:(NSString *)string baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL;
 - (NSDictionary *)_actionInformationForLoadType:(WebFrameLoadType)loadType isFormSubmission:(BOOL)isFormSubmission event:(NSEvent *)event originalURL:(NSURL *)URL;
 
 - (void)_saveScrollPositionToItem:(WebHistoryItem *)item;
@@ -257,6 +257,11 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
 
 @implementation WebFrame (WebPrivate)
 
+- (void)loadPlaceholderHTMLString:(NSString *)string baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL
+{
+    [self _loadHTMLString:string baseURL:URL unreachableURL:unreachableURL];
+}
+
 - (void)loadPropertyList:(id)propertyList
 {
     if ([propertyList isKindOfClass:[NSDictionary class]]) {
@@ -267,7 +272,8 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
                 NSURLRequest *request = [self _webDataRequestForData:[resource data] 
                                                             MIMEType:[resource MIMEType]
                                                     textEncodingName:[resource textEncodingName]
-                                                             baseURL:[resource URL]];
+                                                             baseURL:[resource URL]
+                                                      unreachableURL:nil];
                 [resource release];
                 NSArray *subresourcePropertyLists = [propertyList objectForKey:WebSubresourcesKey];
                 [self _loadRequest:request subresources:subresourcePropertyLists ? [WebResource _resourcesFromPropertyLists:subresourcePropertyLists] : nil];
@@ -276,13 +282,14 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
     }
 }
 
-- (NSURLRequest *)_webDataRequestForData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName: (NSString *)encodingName baseURL:(NSURL *)URL
+- (NSURLRequest *)_webDataRequestForData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName: (NSString *)encodingName baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL
 {
     NSURL *fakeURL = [NSURLRequest _webDataRequestURLForData: data];
     NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL: fakeURL] autorelease];
     [request _webDataRequestSetData:data];
     [request _webDataRequestSetEncoding:encodingName];
     [request _webDataRequestSetBaseURL:URL];
+    [request _webDataRequestSetUnreachableURL:unreachableURL];
     [request _webDataRequestSetMIMEType:MIMEType?MIMEType:@"text/html"];
     return request;
 }
@@ -319,7 +326,7 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
 // helper method used in various nav cases below
 - (void)_addBackForwardItemClippedAtTarget:(BOOL)doClip
 {
-    if (![WebDataProtocol _webIsDataProtocolURL:[[[[[self webView] mainFrame] dataSource] response] URL]]) {
+    if ([[self dataSource] _URLForHistory] != nil) {
         WebHistoryItem *bfItem = [[[self webView] mainFrame] _createItemTreeWithTargetFrame:self clippedAtTarget:doClip];
         LOG (BackForward, "for frame %@, adding item  %@\n", [self name], bfItem);
         [[[self webView] backForwardList] addItem:bfItem];
@@ -339,7 +346,10 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
     else {
         request = [dataSrc request];
     }
-    URL = [request URL];
+    URL = [dataSrc unreachableURL];
+    if (URL == nil) {
+        URL = [request URL];
+    }
 
     LOG (History, "creating item for %@", request);
     
@@ -371,7 +381,10 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
 }
 
 /*
-    In the case of saving state about a page with frames, we store a tree of items that mirrors the frame tree.  The item that was the target of the user's navigation is designated as the "targetItem".  When this method is called with doClip=YES we're able to create the whole tree except for the target's children, which will be loaded in the future.  That part of the tree will be filled out as the child loads are committed.
+    In the case of saving state about a page with frames, we store a tree of items that mirrors the frame tree.  
+    The item that was the target of the user's navigation is designated as the "targetItem".  
+    When this method is called with doClip=YES we're able to create the whole tree except for the target's children, 
+    which will be loaded in the future.  That part of the tree will be filled out as the child loads are committed.
 */
 - (WebHistoryItem *)_createItemTreeWithTargetFrame:(WebFrame *)targetFrame clippedAtTarget:(BOOL)doClip
 {
@@ -747,9 +760,9 @@ NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";
                 
             case WebFrameLoadTypeStandard:
                 if (![ds _isClientRedirect]) {
-                    // Add item to history.
-                    NSURL *URL = [[[ds _originalRequest] URL] _webkit_canonicalize];
-                    if (![URL _web_isEmpty] && ![WebDataProtocol _webIsDataProtocolURL:URL] ){
+                    // Add item to history and BF list
+                    NSURL *URL = [ds _URLForHistory];
+                    if (URL && ![URL _web_isEmpty]){
                         entry = [[WebHistory optionalSharedHistory] addItemForURL:URL];
                         if (ptitle)
                             [entry setTitle: ptitle];
@@ -1006,14 +1019,18 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
                     [[[self webView] _frameLoadDelegateForwarder] webView:_private->webView
                                           didFailProvisionalLoadWithError:[pd _mainDocumentError]
                                                                  forFrame:self];
-
-                    // We know the provisional data source didn't cut the muster, release it.
-                    [_private->provisionalDataSource _stopLoading];
-                    [self _setProvisionalDataSource:nil];
                     
-                    [[self webView] _progressCompleted: self];
-    
-                    [self _setState:WebFrameStateComplete];
+                    [pd _stopLoading];
+                    // Finish resetting the load state, but only if another load hasn't been started by the
+                    // delegate callback.
+                    if (pd == _private->provisionalDataSource) {
+                        [self _setProvisionalDataSource:nil];
+                        
+                        [[self webView] _progressCompleted: self];
+                        
+                        [self _setState:WebFrameStateComplete];
+                    }
+
                     return;
                 }
             }
@@ -2505,16 +2522,23 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
     [self _loadRequest:request subresources:nil];
 }
 
-- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)URL;
+- (void)_loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL
 {
     NSURLRequest *request = [self _webDataRequestForData:data 
                                                 MIMEType:MIMEType 
                                         textEncodingName:encodingName 
-                                                 baseURL:URL];
+                                                 baseURL:URL
+                                          unreachableURL:unreachableURL];
     [self loadRequest:request];
 }
 
-- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)URL
+
+- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)URL
+{
+    [self _loadData:data MIMEType:MIMEType textEncodingName:encodingName baseURL:URL unreachableURL:nil];
+}
+
+- (void)_loadHTMLString:(NSString *)string baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL
 {
     CFStringEncoding cfencoding = CFStringGetFastestEncoding((CFStringRef)string);
     NSStringEncoding nsencoding = CFStringConvertEncodingToNSStringEncoding(cfencoding);
@@ -2522,14 +2546,19 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
     
     if (!cfencodingName || nsencoding == kCFStringEncodingInvalidId){
         NSData *data = [string dataUsingEncoding: NSUnicodeStringEncoding];
-        [self loadData:data MIMEType:nil textEncodingName:@"utf-16" baseURL:URL];
+        [self _loadData:data MIMEType:nil textEncodingName:@"utf-16" baseURL:URL unreachableURL:unreachableURL];
     }
     else {
         NSData *data = [string dataUsingEncoding: nsencoding];
-        [self loadData:data MIMEType:nil textEncodingName:(NSString *)cfencodingName baseURL:URL];
+        [self _loadData:data MIMEType:nil textEncodingName:(NSString *)cfencodingName baseURL:URL unreachableURL:unreachableURL];
     }
 }
 
+- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)URL
+{
+    [self _loadHTMLString:string baseURL:URL unreachableURL:nil];
+}
+
 - (void)stopLoading
 {
     // If this method is called from within this method, infinite recursion can occur (3442218). Avoid this.
index 7b6c685505fab7063e7c94b18566d17226a4576b..6666270bffff2356190ad255fbe326f8bd657931 100644 (file)
@@ -117,7 +117,10 @@ extern NSString *WebPageCacheDocumentViewKey;
 // API Considerations:
 - (void)loadPropertyList:(id)HTMLPropertyList;
 
-- (NSURLRequest *)_webDataRequestForData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)URL;
+// unreachableURL represents a URL that couldn't be loaded; the HTML string acts as an error page for that URL
+- (void)loadPlaceholderHTMLString:(NSString *)string baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL;
+
+- (NSURLRequest *)_webDataRequestForData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)URL unreachableURL:(NSURL *)unreachableURL;
 - (void)_loadRequest:(NSURLRequest *)request subresources:(NSArray *)subresources;
 
 - (void)_setWebView:(WebView *)webView;
index 844b8455ae6f3c750a83a5f7e433023eea1e4882..2449c3d43d63714ad63c5c856772af1053303de6 100644 (file)
     // anything including possibly releasing self; one example of this is 3266216
     [self retain]; 
 
-    // If the URL is one of our whacky applewebdata URLs that
+    // If the URL is one of our whacky applewebdata URLs then
     // fake up a substitute URL to present to the delegate.
     if([WebDataProtocol _webIsDataProtocolURL:[r URL]]) {
-       NSURL *baseURL = [request _webDataRequestBaseURL];
-        if (baseURL == nil) {
-            baseURL = [NSURL URLWithString:@"about:blank"];
-       }
-        r = [[[NSURLResponse alloc] initWithURL:baseURL MIMEType:[r MIMEType] expectedContentLength:[r expectedContentLength] textEncodingName:[r textEncodingName]] autorelease];
+        r = [[[NSURLResponse alloc] initWithURL:[request _webDataRequestExternalURL] MIMEType:[r MIMEType] expectedContentLength:[r expectedContentLength] textEncodingName:[r textEncodingName]] autorelease];
     }
 
     [r retain];