Reviewed by Adele.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Aug 2006 01:28:20 +0000 (01:28 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Aug 2006 01:28:20 +0000 (01:28 +0000)
        - refactoring of WebDataSource in preparation for moving a bunch of it to a new class

        - minimize WebDataSourceInternal.h to be only methods called from outside WebDataSource
        - reduce Private category implementation to be only the SPI methods
        - make new Internal and FileInternal categories which contain the
        remainder (depending on whether they are called from outside of
        WebDataSource)

        * WebView/WebDataSource.m:
        (-[WebDataSource _setMainDocumentError:]):
        (addTypesFromClass):
        (+[WebDataSource _representationClassForMIMEType:]):
        (-[WebDataSource _commitIfReady]):
        (-[WebDataSource _commitLoadWithData:]):
        (-[WebDataSource _doesProgressiveLoadWithMIMEType:]):
        (-[WebDataSource _addResponse:]):
        (-[WebDataSource _revertToProvisionalState]):
        (-[WebDataSource _mainDocumentError]):
        (-[WebDataSource _addSubframeArchives:]):
        (-[WebDataSource _fileWrapperForURL:]):
        (+[WebDataSource _repTypesAllowImageTypeOmission:]):
        (-[WebDataSource _decidePolicyForMIMEType:decisionListener:]):
        (-[WebDataSource _finishedLoading]):
        (-[WebDataSource _setResponse:]):
        (-[WebDataSource _setRequest:]):
        (-[WebDataSource _setupForReplaceByMIMEType:]):
        (-[WebDataSource _receivedMainResourceError:complete:]):
        (-[WebDataSource _mainReceivedError:complete:]):
        (-[WebDataSource _defersCallbacks]):
        (-[WebDataSource _downloadWithLoadingConnection:request:response:proxy:]):
        (-[WebDataSource _didFailLoadingWithError:forResource:]):
        (-[WebDataSource _didFinishLoadingForResource:]):
        (-[WebDataSource _didReceiveData:contentLength:forResource:]):
        (-[WebDataSource _didReceiveResponse:forResource:]):
        (-[WebDataSource _didCancelAuthenticationChallenge:forResource:]):
        (-[WebDataSource _didReceiveAuthenticationChallenge:forResource:]):
        (-[WebDataSource _willSendRequest:forResource:redirectResponse:]):
        (-[WebDataSource _identifierForInitialRequest:]):
        (-[WebDataSource _archivedSubresourceForURL:]):
        (-[WebDataSource _startLoading]):
        (-[WebDataSource _stopRecordingResponses]):
        (-[WebDataSource _loadingStartedTime]):
        (-[WebDataSource _replaceSelectionWithArchive:selectReplacement:]):
        (-[WebDataSource _documentFragmentWithArchive:]):
        (-[WebDataSource _documentFragmentWithImageResource:]):
        (-[WebDataSource _imageElementWithImageResource:]):
        (-[WebDataSource _title]):
        (-[WebDataSource _isStopping]):
        (-[WebDataSource _setWebFrame:]):
        (-[WebDataSource _URL]):
        (-[WebDataSource _loadFromPageCache:]):
        (-[WebDataSource _popSubframeArchiveWithName:]):
        (-[WebDataSource _setIsClientRedirect:]):
        (-[WebDataSource _setURL:]):
        (-[WebDataSource _setLastCheckedRequest:]):
        (-[WebDataSource _defersCallbacksChanged]):
        (-[WebDataSource _lastCheckedRequest]):
        (-[WebDataSource _stopLoading]):
        (-[WebDataSource _bridge]):
        (-[WebDataSource _webView]):
        (-[WebDataSource _triggeringAction]):
        (-[WebDataSource _setTriggeringAction:]):
        (-[WebDataSource __adoptRequest:]):
        (-[WebDataSource _isDocumentHTML]):
        (-[WebDataSource _stopLoadingWithError:]):
        (-[WebDataSource _setPrimaryLoadComplete:]):
        (-[WebDataSource _responses]):
        (-[WebDataSource _makeRepresentation]):
        (-[WebDataSource _isClientRedirect]):
        (-[WebDataSource _originalRequest]):
        (-[WebDataSource _URLForHistory]):
        (-[WebDataSource _addToUnarchiveState:]):
        (-[WebDataSource _setOverrideEncoding:]):
        (-[WebDataSource _setIconURL:]):
        (-[WebDataSource _setIconURL:withType:]):
        (-[WebDataSource _overrideEncoding]):
        (-[WebDataSource _setTitle:]):
        * WebView/WebDataSourceInternal.h:

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

WebKit/ChangeLog
WebKit/WebView/WebDataSource.m
WebKit/WebView/WebDataSourceInternal.h

index 118a0ff5cfd2ab4ed628d2c05f7042c05ba8246b..d8782aee9ede09fc745c700ab9bd9fc5d454e539 100644 (file)
@@ -1,3 +1,86 @@
+2006-08-23  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Adele.
+        
+        - refactoring of WebDataSource in preparation for moving a bunch of it to a new class
+        
+        - minimize WebDataSourceInternal.h to be only methods called from outside WebDataSource
+        - reduce Private category implementation to be only the SPI methods
+        - make new Internal and FileInternal categories which contain the
+        remainder (depending on whether they are called from outside of
+        WebDataSource)
+
+        * WebView/WebDataSource.m:
+        (-[WebDataSource _setMainDocumentError:]):
+        (addTypesFromClass):
+        (+[WebDataSource _representationClassForMIMEType:]):
+        (-[WebDataSource _commitIfReady]):
+        (-[WebDataSource _commitLoadWithData:]):
+        (-[WebDataSource _doesProgressiveLoadWithMIMEType:]):
+        (-[WebDataSource _addResponse:]):
+        (-[WebDataSource _revertToProvisionalState]):
+        (-[WebDataSource _mainDocumentError]):
+        (-[WebDataSource _addSubframeArchives:]):
+        (-[WebDataSource _fileWrapperForURL:]):
+        (+[WebDataSource _repTypesAllowImageTypeOmission:]):
+        (-[WebDataSource _decidePolicyForMIMEType:decisionListener:]):
+        (-[WebDataSource _finishedLoading]):
+        (-[WebDataSource _setResponse:]):
+        (-[WebDataSource _setRequest:]):
+        (-[WebDataSource _setupForReplaceByMIMEType:]):
+        (-[WebDataSource _receivedMainResourceError:complete:]):
+        (-[WebDataSource _mainReceivedError:complete:]):
+        (-[WebDataSource _defersCallbacks]):
+        (-[WebDataSource _downloadWithLoadingConnection:request:response:proxy:]):
+        (-[WebDataSource _didFailLoadingWithError:forResource:]):
+        (-[WebDataSource _didFinishLoadingForResource:]):
+        (-[WebDataSource _didReceiveData:contentLength:forResource:]):
+        (-[WebDataSource _didReceiveResponse:forResource:]):
+        (-[WebDataSource _didCancelAuthenticationChallenge:forResource:]):
+        (-[WebDataSource _didReceiveAuthenticationChallenge:forResource:]):
+        (-[WebDataSource _willSendRequest:forResource:redirectResponse:]):
+        (-[WebDataSource _identifierForInitialRequest:]):
+        (-[WebDataSource _archivedSubresourceForURL:]):
+        (-[WebDataSource _startLoading]):
+        (-[WebDataSource _stopRecordingResponses]):
+        (-[WebDataSource _loadingStartedTime]):
+        (-[WebDataSource _replaceSelectionWithArchive:selectReplacement:]):
+        (-[WebDataSource _documentFragmentWithArchive:]):
+        (-[WebDataSource _documentFragmentWithImageResource:]):
+        (-[WebDataSource _imageElementWithImageResource:]):
+        (-[WebDataSource _title]):
+        (-[WebDataSource _isStopping]):
+        (-[WebDataSource _setWebFrame:]):
+        (-[WebDataSource _URL]):
+        (-[WebDataSource _loadFromPageCache:]):
+        (-[WebDataSource _popSubframeArchiveWithName:]):
+        (-[WebDataSource _setIsClientRedirect:]):
+        (-[WebDataSource _setURL:]):
+        (-[WebDataSource _setLastCheckedRequest:]):
+        (-[WebDataSource _defersCallbacksChanged]):
+        (-[WebDataSource _lastCheckedRequest]):
+        (-[WebDataSource _stopLoading]):
+        (-[WebDataSource _bridge]):
+        (-[WebDataSource _webView]):
+        (-[WebDataSource _triggeringAction]):
+        (-[WebDataSource _setTriggeringAction:]):
+        (-[WebDataSource __adoptRequest:]):
+        (-[WebDataSource _isDocumentHTML]):
+        (-[WebDataSource _stopLoadingWithError:]):
+        (-[WebDataSource _setPrimaryLoadComplete:]):
+        (-[WebDataSource _responses]):
+        (-[WebDataSource _makeRepresentation]):
+        (-[WebDataSource _isClientRedirect]):
+        (-[WebDataSource _originalRequest]):
+        (-[WebDataSource _URLForHistory]):
+        (-[WebDataSource _addToUnarchiveState:]):
+        (-[WebDataSource _setOverrideEncoding:]):
+        (-[WebDataSource _setIconURL:]):
+        (-[WebDataSource _setIconURL:withType:]):
+        (-[WebDataSource _overrideEncoding]):
+        (-[WebDataSource _setTitle:]):
+        * WebView/WebDataSourceInternal.h:
+
 2006-08-23  Brady Eidson  <beidson@apple.com>
 
         Reviewed by John Sullivan
index dab9c22361fd36d5a4f731a0278f0f3b218d4486..20c712b5eed863e7dabc88a80d922d245d4e6b85 100644 (file)
 
 @end
 
-@implementation WebDataSource (WebPrivate)
-
-- (NSFileWrapper *)_fileWrapperForURL:(NSURL *)URL
-{
-    if ([URL isFileURL]) {
-        NSString *path = [[URL path] stringByResolvingSymlinksInPath];
-        return [[[NSFileWrapper alloc] initWithPath:path] autorelease];
-    }
-    
-    WebResource *resource = [self subresourceForURL:URL];
-    if (resource) {
-        return [resource _fileWrapperRepresentation];
-    }
-        
-    NSCachedURLResponse *cachedResponse = [[self _webView] _cachedResponseForURL:URL];
-    if (cachedResponse) {
-        NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:[cachedResponse data]] autorelease];
-        [wrapper setPreferredFilename:[[cachedResponse response] suggestedFilename]];
-        return wrapper;
-    }
-    
-    return nil;
-}
-
-- (void)_addSubframeArchives:(NSArray *)subframeArchives
-{
-    NSEnumerator *enumerator = [subframeArchives objectEnumerator];
-    WebArchive *archive;
-    while ((archive = [enumerator nextObject]) != nil)
-        [self _addToUnarchiveState:archive];
-}
-
-- (void)_addToUnarchiveState:(WebArchive *)archive
-{
-    if (!_private->unarchivingState)
-        _private->unarchivingState = [[WebUnarchivingState alloc] init];
-    [_private->unarchivingState addArchive:archive];
-}
-
-- (WebArchive *)_popSubframeArchiveWithName:(NSString *)frameName
-{
-    return [_private->unarchivingState popSubframeArchiveWithFrameName:frameName];
-}
-
-- (DOMElement *)_imageElementWithImageResource:(WebResource *)resource
-{
-    if (!resource)
-        return 0;
-
-    [self addSubresource:resource];
-    
-    DOMElement *imageElement = [[[self _bridge] DOMDocument] createElement:@"img"];
-    
-    // FIXME: calling _web_originalDataAsString on a file URL returns an absolute path. Workaround this.
-    NSURL *URL = [resource URL];
-    [imageElement setAttribute:@"src" :[URL isFileURL] ? [URL absoluteString] : [URL _web_originalDataAsString]];
-    
-    return imageElement;
-}
-
-- (DOMDocumentFragment *)_documentFragmentWithImageResource:(WebResource *)resource
-{
-    DOMElement *imageElement = [self _imageElementWithImageResource:resource];
-    if (!imageElement)
-        return 0;
-    DOMDocumentFragment *fragment = [[[self _bridge] DOMDocument] createDocumentFragment];
-    [fragment appendChild:imageElement];
-    return fragment;
-}
-
-- (DOMDocumentFragment *)_documentFragmentWithArchive:(WebArchive *)archive
-{
-    ASSERT(archive);
-    WebResource *mainResource = [archive mainResource];
-    if (mainResource) {
-        NSString *MIMEType = [mainResource MIMEType];
-        if ([WebView canShowMIMETypeAsHTML:MIMEType]) {
-            NSString *markupString = [[NSString alloc] initWithData:[mainResource data] encoding:NSUTF8StringEncoding];
-            // FIXME: seems poor form to do this as a side effect of getting a document fragment
-            [self _addToUnarchiveState:archive];
-            DOMDocumentFragment *fragment = [[self _bridge] documentFragmentWithMarkupString:markupString baseURLString:[[mainResource URL] _web_originalDataAsString]];
-            [markupString release];
-            return fragment;
-        } else if ([[WebFrameBridge supportedImageResourceMIMETypes] containsObject:MIMEType]) {
-            return [self _documentFragmentWithImageResource:mainResource];
-
-        }
-    }
-    return nil;
-}
-
-- (void)_replaceSelectionWithArchive:(WebArchive *)archive selectReplacement:(BOOL)selectReplacement
-{
-    DOMDocumentFragment *fragment = [self _documentFragmentWithArchive:archive];
-    if (fragment)
-        [[self _bridge] replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:NO matchStyle:NO];
-}
+@interface WebDataSource (WebFileInternal)
+@end
 
-- (WebView *)_webView
-{
-    return [_private->webFrame webView];
-}
+@implementation WebDataSource (WebFileInternal)
 
 - (void)_setRepresentation: (id<WebDocumentRepresentation>)representation
 {
     }
 }
 
-- (void)_setPrimaryLoadComplete:(BOOL)flag
-{
-    _private->primaryLoadComplete = flag;
-    
-    if (flag) {
-        // FIXME: We could actually load it as soon as we've parsed
-        // the HEAD section, or determined there isn't one - but
-        // there's no callback for that.
-        [self _loadIcon];
-
-        if ([[_private->webFrame _frameLoader] isLoadingMainResource]) {
-            [self _setData:[[_private->webFrame _frameLoader] mainResourceData]];
-            [[_private->webFrame _frameLoader] releaseMainResourceLoader];
-        }
-        
-        if ([WebScriptDebugServer listenerCount])
-            [[WebScriptDebugServer sharedScriptDebugServer] webView:[[self webFrame] webView] didLoadMainResourceForDataSource:self];
-    }
-}
-
 - (NSError *)_cancelledError
 {
     return [NSError _webKitErrorWithDomain:NSURLErrorDomain
                                        URL:[self _URL]];
 }
 
-// Cancels the data source's pending loads.  Conceptually, a data source only loads
-// one document at a time, but one document may have many related resources. 
-// _stopLoading will stop all loads initiated by the data source, 
-// but not loads initiated by child frames' data sources -- that's the WebFrame's job.
-- (void)_stopLoading
+- (void)_setMainDocumentError: (NSError *)error
 {
-    // Always attempt to stop the icon loader because it may still be loading after the data source
-    // is done loading and not stopping it can cause a world leak.
-    [[_private->webFrame _frameLoader] stopLoadingIcon];
-    
-    // The same goes for the bridge/part, which may still be parsing.
-    if (_private->committed)
-        [[self _bridge] stopLoading];
-
-    if (![[_private->webFrame _frameLoader] isLoading])
-        return;
-
-    [self retain];
-
-    _private->stopping = YES;
+    [error retain];
+    [_private->mainDocumentError release];
+    _private->mainDocumentError = error;
     
-    if ([[_private->webFrame _frameLoader] isLoadingMainResource]) {
-        // Stop the main resource loader and let it send the cancelled message.
-        [[_private->webFrame _frameLoader] cancelMainResourceLoad];
-    } else if ([[_private->webFrame _frameLoader] isLoadingSubresources]) {
-        // The main resource loader already finished loading. Set the cancelled error on the 
-        // document and let the subresourceLoaders send individual cancelled messages below.
-        [self _setMainDocumentError:[self _cancelledError]];
-    } else {
-        // If there are no resource loaders, we need to manufacture a cancelled message.
-        // (A back/forward navigation has no resource loaders because its resources are cached.)
-        [self _mainReceivedError:[self _cancelledError] complete:YES];
+    if (!_private->representationFinishedLoading) {
+        _private->representationFinishedLoading = YES;
+        [[self representation] receivedError:error withDataSource:self];
     }
-    
-    [[_private->webFrame _frameLoader] stopLoadingSubresources];
-    [[_private->webFrame _frameLoader] stopLoadingPlugIns];
-    
-    _private->stopping = NO;
-    
-    [self release];
 }
 
 - (void)_clearErrors
                                      didStartProvisionalLoadForFrame:[self webFrame]];
 }
 
-- (void)_loadFromPageCache:(NSDictionary *)pageCache
+static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class class, NSArray *supportTypes)
 {
-    [self _prepareForLoadStart];
-    _private->loadingFromPageCache = YES;
-    _private->committed = TRUE;
-    [[self webFrame] _commitProvisionalLoad:pageCache];
+    NSEnumerator *enumerator = [supportTypes objectEnumerator];
+    ASSERT(enumerator != nil);
+    NSString *mime = nil;
+    while ((mime = [enumerator nextObject]) != nil) {
+        // Don't clobber previously-registered classes.
+        if ([allTypes objectForKey:mime] == nil)
+            [allTypes setObject:class forKey:mime];
+    }
 }
 
-- (void)_startLoading
++ (Class)_representationClassForMIMEType:(NSString *)MIMEType
 {
-    [self _prepareForLoadStart];
-
-    if ([[_private->webFrame _frameLoader] isLoadingMainResource])
-        return;
+    Class repClass;
+    return [WebView _viewClass:nil andRepresentationClass:&repClass forMIMEType:MIMEType] ? repClass : nil;
+}
 
-    _private->loadingFromPageCache = NO;
-        
-    id identifier;
-    id resourceLoadDelegate = [[self _webView] resourceLoadDelegate];
-    if ([resourceLoadDelegate respondsToSelector:@selector(webView:identifierForInitialRequest:fromDataSource:)])
-        identifier = [resourceLoadDelegate webView:[self _webView] identifierForInitialRequest:_private->originalRequest fromDataSource:self];
-    else
-        identifier = [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:[self _webView] identifierForInitialRequest:_private->originalRequest fromDataSource:self];
-    
-    [[_private->webFrame _frameLoader] startLoadingMainResourceWithRequest:_private->request identifier:identifier];
+- (void)_commitIfReady
+{
+    if (_private->gotFirstByte && !_private->committed) {
+        _private->committed = TRUE;
+        [[self webFrame] _commitProvisionalLoad:nil];
+    }
 }
 
-- (BOOL)_isStopping
+- (void)_commitLoadWithData:(NSData *)data
 {
-    return _private->stopping;
+    // Both unloading the old page and parsing the new page may execute JavaScript which destroys the datasource
+    // by starting a new load, so retain temporarily.
+    [self retain];
+    [self _commitIfReady];
+    [[self representation] receivedData:data withDataSource:self];
+    [[[[self webFrame] frameView] documentView] dataSourceUpdated:self];
+    [self release];
 }
 
-- (double)_loadingStartedTime
+- (BOOL)_doesProgressiveLoadWithMIMEType:(NSString *)MIMEType
 {
-    return _private->loadingStartedTime;
+    return [[self webFrame] _loadType] != WebFrameLoadTypeReplace || [MIMEType isEqualToString:@"text/html"];
 }
 
-- (NSURL *)_URLForHistory
+- (void)_addResponse:(NSURLResponse *)r
 {
-    // Return the URL to be used for history and B/F list.
-    // Returns nil for WebDataProtocol URLs that aren't alternates 
-    // for unreachable URLs, because these can't be stored in history.
-    NSURL *URL = [_private->originalRequestCopy URL];
-    if ([WebDataProtocol _webIsDataProtocolURL:URL]) {
-        URL = [_private->originalRequestCopy _webDataRequestUnreachableURL];
+    if (!_private->stopRecordingResponses) {
+        if (!_private->responses)
+            _private->responses = [[NSMutableArray alloc] init];
+        [_private->responses addObject: r];
     }
-    
-    return [URL _webkit_canonicalize];
 }
 
-- (void)_setTitle:(NSString *)title
+- (void)_revertToProvisionalState
 {
-    NSString *trimmed;
-    if (title == nil) {
-        trimmed = nil;
-    } else {
-        trimmed = [title _webkit_stringByTrimmingWhitespace];
-        if ([trimmed length] == 0)
-            trimmed = nil;
-    }
-    if (trimmed == nil) {
-        if (_private->pageTitle == nil)
-            return;
-    } else {
-        if ([_private->pageTitle isEqualToString:trimmed])
-            return;
-    }
-    
-    if (!trimmed || [trimmed length] == 0)
-        return;
-        
-    [[self _webView] _willChangeValueForKey:_WebMainFrameTitleKey];
-    [_private->pageTitle release];
-    _private->pageTitle = [trimmed copy];
-    [[self _webView] _didChangeValueForKey:_WebMainFrameTitleKey];
-    
-    // The title doesn't get communicated to the WebView until we are committed.
-    if (_private->committed) {
-        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.  This must go through the WebFrame because
-            // it has the right notion of the current b/f item.
-            [[self webFrame] _setTitle:_private->pageTitle];
-            
-            [[self _webView] setMainFrameDocumentReady:YES];    // update observers with new DOMDocument
-            [[[self _webView] _frameLoadDelegateForwarder] webView:[self _webView]
-                                                     didReceiveTitle:_private->pageTitle
-                                                            forFrame:[self webFrame]];
-        }
-    }
+    [self _setRepresentation:nil];
+    [[_private->webFrame _frameLoader] setupForReplace];
+    _private->committed = NO;
 }
 
-- (NSString *)_title
-{
-    return _private->pageTitle;
-}
+@end
 
-- (void)_setURL:(NSURL *)URL
-{
-    NSMutableURLRequest *newOriginalRequest = [_private->originalRequestCopy mutableCopy];
-    [_private->originalRequestCopy release];
-    [newOriginalRequest setURL:URL];
-    _private->originalRequestCopy = newOriginalRequest;
+@implementation WebDataSource (WebPrivate)
 
-    NSMutableURLRequest *newRequest = [_private->request mutableCopy];
-    [_private->request release];
-    [newRequest setURL:URL];
-    _private->request = newRequest;
+- (NSError *)_mainDocumentError
+{
+    return _private->mainDocumentError;
 }
 
-- (void)__adoptRequest:(NSMutableURLRequest *)request
+- (void)_addSubframeArchives:(NSArray *)subframeArchives
 {
-    if (request != _private->request){
-        [_private->request release];
-        _private->request = [request retain];
-    }
+    NSEnumerator *enumerator = [subframeArchives objectEnumerator];
+    WebArchive *archive;
+    while ((archive = [enumerator nextObject]) != nil)
+        [self _addToUnarchiveState:archive];
 }
 
-- (void)_setRequest:(NSURLRequest *)request
+- (NSFileWrapper *)_fileWrapperForURL:(NSURL *)URL
 {
-    ASSERT_ARG(request, request != _private->request);
+    if ([URL isFileURL]) {
+        NSString *path = [[URL path] stringByResolvingSymlinksInPath];
+        return [[[NSFileWrapper alloc] initWithPath:path] autorelease];
+    }
     
-    // Replacing an unreachable URL with alternate content looks like a server-side
-    // redirect at this point, but we can replace a committed dataSource.
-    BOOL handlingUnreachableURL = [request _webDataRequestUnreachableURL] != nil;
-    if (handlingUnreachableURL) {
-        _private->committed = NO;
+    WebResource *resource = [self subresourceForURL:URL];
+    if (resource) {
+        return [resource _fileWrapperRepresentation];
     }
     
-    // We should never be getting a redirect callback after the data
-    // source is committed, except in the unreachable URL case. It 
-    // would be a WebFoundation bug if it sent a redirect callback after commit.
-    ASSERT(!_private->committed);
-
-    NSURLRequest *oldRequest = _private->request;
-
-    _private->request = [request mutableCopy];
-
-    // Only send webView:didReceiveServerRedirectForProvisionalLoadForFrame: if URL changed.
-    // Also, don't send it when replacing unreachable URLs with alternate content.
-    if (!handlingUnreachableURL && ![[oldRequest URL] isEqual: [request URL]]) {
-        LOG(Redirect, "Server redirect to: %@", [request URL]);
-        [[[self _webView] _frameLoadDelegateForwarder] webView:[self _webView]
-                      didReceiveServerRedirectForProvisionalLoadForFrame:[self webFrame]];
+    NSCachedURLResponse *cachedResponse = [[self _webView] _cachedResponseForURL:URL];
+    if (cachedResponse) {
+        NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:[cachedResponse data]] autorelease];
+        [wrapper setPreferredFilename:[[cachedResponse response] suggestedFilename]];
+        return wrapper;
     }
-        
-    [oldRequest release];
-}
-
-- (void)_setResponse:(NSURLResponse *)response
-{
-    [_private->response release];
-    _private->response = [response retain];
-}
-
-- (void)_setOverrideEncoding:(NSString *)overrideEncoding
-{
-    NSString *copy = [overrideEncoding copy];
-    [_private->overrideEncoding release];
-    _private->overrideEncoding = copy;
-}
-
-- (NSString *)_overrideEncoding
-{
-    return [[_private->overrideEncoding copy] autorelease];
-}
-
-- (void)_setIsClientRedirect:(BOOL)flag
-{
-    _private->isClientRedirect = flag;
-}
-
-- (BOOL)_isClientRedirect
-{
-    return _private->isClientRedirect;
+    
+    return nil;
 }
 
-- (void)_setMainDocumentError: (NSError *)error
-{
-    [error retain];
-    [_private->mainDocumentError release];
-    _private->mainDocumentError = error;
-
-    if (!_private->representationFinishedLoading) {
-        _private->representationFinishedLoading = YES;
-        [[self representation] receivedError:error withDataSource:self];
-    }
-}
+@end
 
-static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class class, NSArray *supportTypes)
-{
-    NSEnumerator *enumerator = [supportTypes objectEnumerator];
-    ASSERT(enumerator != nil);
-    NSString *mime = nil;
-    while ((mime = [enumerator nextObject]) != nil) {
-        // Don't clobber previously-registered classes.
-        if ([allTypes objectForKey:mime] == nil)
-            [allTypes setObject:class forKey:mime];
-    }
-}
+@implementation WebDataSource (WebInternal)
 
 + (NSMutableDictionary *)_repTypesAllowImageTypeOmission:(BOOL)allowImageTypeOmission
 {
@@ -625,7 +374,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class class,
     if (!repTypes) {
         repTypes = [[NSMutableDictionary alloc] init];
         addTypesFromClass(repTypes, [WebHTMLRepresentation class], [WebHTMLRepresentation supportedNonImageMIMETypes]);
-
+        
         // Since this is a "secret default" we don't both registering it.
         BOOL omitPDFSupport = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitOmitPDFSupport"];
         if (!omitPDFSupport)
@@ -640,54 +389,88 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class class,
     return repTypes;
 }
 
-+ (Class)_representationClassForMIMEType:(NSString *)MIMEType
+- (void)_decidePolicyForMIMEType:(NSString *)MIMEType decisionListener:(WebPolicyDecisionListener *)listener
 {
-    Class repClass;
-    return [WebView _viewClass:nil andRepresentationClass:&repClass forMIMEType:MIMEType] ? repClass : nil;
+    WebView *wv = [self _webView];
+    [[wv _policyDelegateForwarder] webView:wv decidePolicyForMIMEType:MIMEType
+                                   request:[self request]
+                                     frame:[self webFrame]
+                          decisionListener:listener];
 }
 
-- (WebFrameBridge *)_bridge
+- (void)_finishedLoading
 {
-    ASSERT(_private->committed);
-    return [[self webFrame] _bridge];
+    _private->gotFirstByte = YES;
+    [self _commitIfReady];
+    
+    _private->representationFinishedLoading = YES;
+    [[self representation] finishedLoadingWithDataSource:self];
+    [[self _bridge] end];
 }
 
-- (void)_commitIfReady
+- (void)_setResponse:(NSURLResponse *)response
 {
-    if (_private->gotFirstByte && !_private->committed) {
-        _private->committed = TRUE;
-        [[self webFrame] _commitProvisionalLoad:nil];
-    }
+    [_private->response release];
+    _private->response = [response retain];
 }
 
--(void)_makeRepresentation
+- (void)_setRequest:(NSURLRequest *)request
 {
-    Class repClass = [[self class] _representationClassForMIMEType:[[self response] MIMEType]];
+    ASSERT_ARG(request, request != _private->request);
     
-    // Check if the data source was already bound?
-    if (![[self representation] isKindOfClass:repClass]) {
-        id newRep = repClass != nil ? [[repClass alloc] init] : nil;
-        [self _setRepresentation:(id <WebDocumentRepresentation>)newRep];
-        [newRep release];
+    // Replacing an unreachable URL with alternate content looks like a server-side
+    // redirect at this point, but we can replace a committed dataSource.
+    BOOL handlingUnreachableURL = [request _webDataRequestUnreachableURL] != nil;
+    if (handlingUnreachableURL) {
+        _private->committed = NO;
     }
-
-    [_private->representation setDataSource:self];
-}
-
-- (void)_commitLoadWithData:(NSData *)data
-{
-    // Both unloading the old page and parsing the new page may execute JavaScript which destroys the datasource
-    // by starting a new load, so retain temporarily.
-    [self retain];
-    [self _commitIfReady];
-    [[self representation] receivedData:data withDataSource:self];
-    [[[[self webFrame] frameView] documentView] dataSourceUpdated:self];
-    [self release];
+    
+    // We should never be getting a redirect callback after the data
+    // source is committed, except in the unreachable URL case. It 
+    // would be a WebFoundation bug if it sent a redirect callback after commit.
+    ASSERT(!_private->committed);
+    
+    NSURLRequest *oldRequest = _private->request;
+    
+    _private->request = [request mutableCopy];
+    
+    // Only send webView:didReceiveServerRedirectForProvisionalLoadForFrame: if URL changed.
+    // Also, don't send it when replacing unreachable URLs with alternate content.
+    if (!handlingUnreachableURL && ![[oldRequest URL] isEqual: [request URL]]) {
+        LOG(Redirect, "Server redirect to: %@", [request URL]);
+        [[[self _webView] _frameLoadDelegateForwarder] webView:[self _webView]
+            didReceiveServerRedirectForProvisionalLoadForFrame:[self webFrame]];
+    }
+    
+    [oldRequest release];
 }
 
-- (BOOL)_doesProgressiveLoadWithMIMEType:(NSString *)MIMEType
+- (void)_setupForReplaceByMIMEType:(NSString *)newMIMEType
 {
-    return [[self webFrame] _loadType] != WebFrameLoadTypeReplace || [MIMEType isEqualToString:@"text/html"];
+    if (!_private->gotFirstByte)
+        return;
+    
+    WebFrame *frame = [self webFrame];
+    NSString *oldMIMEType = [[self response] MIMEType];
+    
+    if (![self _doesProgressiveLoadWithMIMEType:oldMIMEType]) {
+        [self _revertToProvisionalState];
+        [self _commitLoadWithData:[self data]];
+    }
+    
+    _private->representationFinishedLoading = YES;
+    [[self representation] finishedLoadingWithDataSource:self];
+    [[self _bridge] end];
+    
+    [frame _setLoadType:WebFrameLoadTypeReplace];
+    _private->gotFirstByte = NO;
+    
+    if ([self _doesProgressiveLoadWithMIMEType:newMIMEType])
+        [self _revertToProvisionalState];
+    
+    [[_private->webFrame _frameLoader] stopLoadingSubresources];
+    [[_private->webFrame _frameLoader] stopLoadingPlugIns];
+    [_private->unarchivingState release];
 }
 
 -(void)_receivedData:(NSData *)data
@@ -698,16 +481,6 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class class,
         [self _commitLoadWithData:data];
 }
 
-- (void)_finishedLoading
-{
-    _private->gotFirstByte = YES;
-    [self _commitIfReady];
-
-    _private->representationFinishedLoading = YES;
-    [[self representation] finishedLoadingWithDataSource:self];
-    [[self _bridge] end];
-}
-
 - (void)_receivedMainResourceError:(NSError *)error complete:(BOOL)isComplete
 {
     // MOVABLE
@@ -715,7 +488,7 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class class,
     
     // Retain the bridge because the stop may release the last reference to it.
     [bridge retain];
-
+    
     if (isComplete) {
         // FIXME: Don't want to do this if an entirely new load is going, so should check
         // that both data sources on the frame are either self or nil.
@@ -725,178 +498,411 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class class,
         if ([error code] != NSURLErrorCancelled && [error code] != WebKitErrorPlugInWillHandleLoad)
             [bridge handleFallbackContent];
     }
-
+    
     [bridge release];
-
+    
     [[self webFrame] _receivedMainResourceError:error];
     [self _mainReceivedError:error complete:isComplete];
 }
 
-- (void)_setIconURL:(NSURL *)URL
+- (void)_mainReceivedError:(NSError *)error complete:(BOOL)isComplete
 {
-    // Lower priority than typed icon, so ignore this if we already have an iconURL.
-    if (_private->iconURL == nil) {
-        [_private->iconURL release];
-        _private->iconURL = [URL retain];
+    if (![self webFrame])
+        return;
+    
+    [self _setMainDocumentError:error];
+    
+    if (isComplete) {
+        [self _setPrimaryLoadComplete:YES];
+        [[self webFrame] _checkLoadComplete];
     }
 }
 
-- (void)_setIconURL:(NSURL *)URL withType:(NSString *)iconType
+- (BOOL)_defersCallbacks
 {
-    // FIXME: Should check to make sure the type is one we know how to handle.
-    [_private->iconURL release];
-    _private->iconURL = [URL retain];
+    return _private->defersCallbacks;
 }
 
-- (void)_defersCallbacksChanged
+- (void)_downloadWithLoadingConnection:(NSURLConnection *)connection request:(NSURLRequest *)request response:(NSURLResponse *)r proxy:(WKNSURLConnectionDelegateProxyPtr) proxy
 {
-    BOOL defers = [[self _webView] defersCallbacks];
+    [WebDownload _downloadWithLoadingConnection:connection
+                                        request:request
+                                       response:r
+                                       delegate:[[self _webView] downloadDelegate]
+                                          proxy:proxy];
+}
+
+- (void)_didFailLoadingWithError:(NSError *)error forResource:(id)identifier
+{
+    WebView *webView = [self _webView];
     
-    if (defers == _private->defersCallbacks) {
-        return;
-    }
+    [webView _completeProgressForIdentifier:identifier];
+    
+    if (error)
+        [[webView _resourceLoadDelegateForwarder] webView:webView resource:identifier didFailLoadingWithError:error fromDataSource:self];
+}
 
-    _private->defersCallbacks = defers;
-    [[_private->webFrame _frameLoader] setDefersCallbacks:defers];
+- (void)_didFinishLoadingForResource:(id)identifier
+{
+    WebView *webView = [self _webView];
+    
+    [webView _completeProgressForIdentifier:identifier];    
+    
+    if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidFinishLoadingFromDataSource)
+        [[webView resourceLoadDelegate] webView:webView resource:identifier didFinishLoadingFromDataSource:self];
+    else
+        [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didFinishLoadingFromDataSource:self];
 }
 
-- (BOOL)_defersCallbacks
+- (void)_didReceiveData:(NSData *)data contentLength:(int)lengthReceived forResource:(id)identifier
 {
-    return _private->defersCallbacks;
+    WebView *webView = [self _webView];
+    
+    [webView _incrementProgressForIdentifier:identifier data:data];
+    
+    if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidReceiveContentLength)
+        [[webView resourceLoadDelegate] webView:webView resource:identifier didReceiveContentLength:(WebNSUInteger)lengthReceived fromDataSource:self];
+    else
+        [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didReceiveContentLength:(WebNSUInteger)lengthReceived fromDataSource:self];
 }
 
-- (id)_identifierForInitialRequest:(NSURLRequest *)clientRequest
+- (void)_didReceiveResponse:(NSURLResponse *)r forResource:(id)identifier
 {
     WebView *webView = [self _webView];
+    
+    [self _addResponse:r];
+    
+    [webView _incrementProgressForIdentifier:identifier response:r];
+    
+    if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidReceiveResponse)
+        [[webView resourceLoadDelegate] webView:webView resource:identifier didReceiveResponse:r fromDataSource:self];
+    else
+        [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didReceiveResponse:r fromDataSource:self];
+}
 
-    // The identifier is released after the last callback, rather than in dealloc
-    // to avoid potential cycles.
-    if ([webView _resourceLoadDelegateImplementations].delegateImplementsIdentifierForRequest)
-        return [[[webView resourceLoadDelegate] webView:webView identifierForInitialRequest:clientRequest fromDataSource:self] retain];
+- (void)_didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)currentWebChallenge forResource:(id)identifier
+{
+    WebView *webView = [self _webView];
+    
+    if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidCancelAuthenticationChallenge)
+        [[webView resourceLoadDelegate] webView:webView resource:identifier didCancelAuthenticationChallenge:currentWebChallenge fromDataSource:self];
     else
-        return [[[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView identifierForInitialRequest:clientRequest fromDataSource:self] retain];
+        [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didCancelAuthenticationChallenge:currentWebChallenge fromDataSource:self];
 }
 
-- (NSURLRequest *)_willSendRequest:(NSMutableURLRequest *)clientRequest forResource:(id)identifier redirectResponse:(NSURLResponse *)redirectResponse
+- (void)_didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)currentWebChallenge forResource:(id)identifier
 {
     WebView *webView = [self _webView];
+    
+    if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidReceiveAuthenticationChallenge)
+        [[webView resourceLoadDelegate] webView:webView resource:identifier didReceiveAuthenticationChallenge:currentWebChallenge fromDataSource:self];
+    else
+        [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didReceiveAuthenticationChallenge:currentWebChallenge fromDataSource:self];
+}
 
+- (NSURLRequest *)_willSendRequest:(NSMutableURLRequest *)clientRequest forResource:(id)identifier redirectResponse:(NSURLResponse *)redirectResponse
+{
+    WebView *webView = [self _webView];
+    
     [clientRequest _web_setHTTPUserAgent:[webView userAgentForURL:[clientRequest URL]]];
-
+    
     if ([webView _resourceLoadDelegateImplementations].delegateImplementsWillSendRequest)
         return [[webView resourceLoadDelegate] webView:webView resource:identifier willSendRequest:clientRequest redirectResponse:redirectResponse fromDataSource:self];
     else
         return [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier willSendRequest:clientRequest redirectResponse:redirectResponse fromDataSource:self];
 }        
 
-- (void)_didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)currentWebChallenge forResource:(id)identifier
+- (id)_identifierForInitialRequest:(NSURLRequest *)clientRequest
 {
     WebView *webView = [self _webView];
+    
+    // The identifier is released after the last callback, rather than in dealloc
+    // to avoid potential cycles.
+    if ([webView _resourceLoadDelegateImplementations].delegateImplementsIdentifierForRequest)
+        return [[[webView resourceLoadDelegate] webView:webView identifierForInitialRequest:clientRequest fromDataSource:self] retain];
+    else
+        return [[[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView identifierForInitialRequest:clientRequest fromDataSource:self] retain];
+}
 
-    if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidReceiveAuthenticationChallenge)
-        [[webView resourceLoadDelegate] webView:webView resource:identifier didReceiveAuthenticationChallenge:currentWebChallenge fromDataSource:self];
+- (WebResource *)_archivedSubresourceForURL:(NSURL *)URL
+{
+    return [_private->unarchivingState archivedResourceForURL:URL];
+}
+
+- (void)_startLoading
+{
+    [self _prepareForLoadStart];
+    
+    if ([[_private->webFrame _frameLoader] isLoadingMainResource])
+        return;
+    
+    _private->loadingFromPageCache = NO;
+    
+    id identifier;
+    id resourceLoadDelegate = [[self _webView] resourceLoadDelegate];
+    if ([resourceLoadDelegate respondsToSelector:@selector(webView:identifierForInitialRequest:fromDataSource:)])
+        identifier = [resourceLoadDelegate webView:[self _webView] identifierForInitialRequest:_private->originalRequest fromDataSource:self];
     else
-        [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didReceiveAuthenticationChallenge:currentWebChallenge fromDataSource:self];
+        identifier = [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:[self _webView] identifierForInitialRequest:_private->originalRequest fromDataSource:self];
+    
+    [[_private->webFrame _frameLoader] startLoadingMainResourceWithRequest:_private->request identifier:identifier];
 }
 
+- (void)_stopRecordingResponses
+{
+    _private->stopRecordingResponses = YES;
+}
 
-- (void)_didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)currentWebChallenge forResource:(id)identifier
+- (double)_loadingStartedTime
 {
-    WebView *webView = [self _webView];
+    return _private->loadingStartedTime;
+}
 
-    if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidCancelAuthenticationChallenge)
-        [[webView resourceLoadDelegate] webView:webView resource:identifier didCancelAuthenticationChallenge:currentWebChallenge fromDataSource:self];
-    else
-        [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didCancelAuthenticationChallenge:currentWebChallenge fromDataSource:self];
+- (void)_replaceSelectionWithArchive:(WebArchive *)archive selectReplacement:(BOOL)selectReplacement
+{
+    DOMDocumentFragment *fragment = [self _documentFragmentWithArchive:archive];
+    if (fragment)
+        [[self _bridge] replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:NO matchStyle:NO];
 }
 
-- (void)_didReceiveResponse:(NSURLResponse *)r forResource:(id)identifier
+- (DOMDocumentFragment *)_documentFragmentWithArchive:(WebArchive *)archive
 {
-    WebView *webView = [self _webView];
+    ASSERT(archive);
+    WebResource *mainResource = [archive mainResource];
+    if (mainResource) {
+        NSString *MIMEType = [mainResource MIMEType];
+        if ([WebView canShowMIMETypeAsHTML:MIMEType]) {
+            NSString *markupString = [[NSString alloc] initWithData:[mainResource data] encoding:NSUTF8StringEncoding];
+            // FIXME: seems poor form to do this as a side effect of getting a document fragment
+            [self _addToUnarchiveState:archive];
+            DOMDocumentFragment *fragment = [[self _bridge] documentFragmentWithMarkupString:markupString baseURLString:[[mainResource URL] _web_originalDataAsString]];
+            [markupString release];
+            return fragment;
+        } else if ([[WebFrameBridge supportedImageResourceMIMETypes] containsObject:MIMEType]) {
+            return [self _documentFragmentWithImageResource:mainResource];
+            
+        }
+    }
+    return nil;
+}
 
-    [self _addResponse:r];
+- (DOMDocumentFragment *)_documentFragmentWithImageResource:(WebResource *)resource
+{
+    DOMElement *imageElement = [self _imageElementWithImageResource:resource];
+    if (!imageElement)
+        return 0;
+    DOMDocumentFragment *fragment = [[[self _bridge] DOMDocument] createDocumentFragment];
+    [fragment appendChild:imageElement];
+    return fragment;
+}
 
-    [webView _incrementProgressForIdentifier:identifier response:r];
-        
-    if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidReceiveResponse)
-        [[webView resourceLoadDelegate] webView:webView resource:identifier didReceiveResponse:r fromDataSource:self];
-    else
-        [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didReceiveResponse:r fromDataSource:self];
+- (DOMElement *)_imageElementWithImageResource:(WebResource *)resource
+{
+    if (!resource)
+        return 0;
+    
+    [self addSubresource:resource];
+    
+    DOMElement *imageElement = [[[self _bridge] DOMDocument] createElement:@"img"];
+    
+    // FIXME: calling _web_originalDataAsString on a file URL returns an absolute path. Workaround this.
+    NSURL *URL = [resource URL];
+    [imageElement setAttribute:@"src" :[URL isFileURL] ? [URL absoluteString] : [URL _web_originalDataAsString]];
+    
+    return imageElement;
+}
+
+- (NSString *)_title
+{
+    return _private->pageTitle;
+}
+
+- (BOOL)_isStopping
+{
+    return _private->stopping;
+}
+
+- (void)_setWebFrame:(WebFrame *)frame
+{
+    [frame retain];
+    [_private->webFrame release];
+    _private->webFrame = frame;
+    
+    [self _defersCallbacksChanged];
+    // no need to do _defersCallbacksChanged for subframes since they too
+    // will be or have been told of their WebFrame
+}
+
+// May return nil if not initialized with a URL.
+- (NSURL *)_URL
+{
+    return [[self request] URL];
+}
+
+- (void)_loadFromPageCache:(NSDictionary *)pageCache
+{
+    [self _prepareForLoadStart];
+    _private->loadingFromPageCache = YES;
+    _private->committed = TRUE;
+    [[self webFrame] _commitProvisionalLoad:pageCache];
+}
+
+- (WebArchive *)_popSubframeArchiveWithName:(NSString *)frameName
+{
+    return [_private->unarchivingState popSubframeArchiveWithFrameName:frameName];
+}
+
+- (void)_setIsClientRedirect:(BOOL)flag
+{
+    _private->isClientRedirect = flag;
+}
+
+- (void)_setURL:(NSURL *)URL
+{
+    NSMutableURLRequest *newOriginalRequest = [_private->originalRequestCopy mutableCopy];
+    [_private->originalRequestCopy release];
+    [newOriginalRequest setURL:URL];
+    _private->originalRequestCopy = newOriginalRequest;
+    
+    NSMutableURLRequest *newRequest = [_private->request mutableCopy];
+    [_private->request release];
+    [newRequest setURL:URL];
+    _private->request = newRequest;
+}
+
+- (void)_setLastCheckedRequest:(NSURLRequest *)request
+{
+    NSURLRequest *oldRequest = _private->lastCheckedRequest;
+    _private->lastCheckedRequest = [request copy];
+    [oldRequest release];
+}
+
+- (void)_defersCallbacksChanged
+{
+    BOOL defers = [[self _webView] defersCallbacks];
+    
+    if (defers == _private->defersCallbacks) {
+        return;
+    }
+    
+    _private->defersCallbacks = defers;
+    [[_private->webFrame _frameLoader] setDefersCallbacks:defers];
+}
+
+- (NSURLRequest *)_lastCheckedRequest
+{
+    // It's OK not to make a copy here because we know the caller
+    // isn't going to modify this request
+    return [[_private->lastCheckedRequest retain] autorelease];
+}
+
+// Cancels the data source's pending loads.  Conceptually, a data source only loads
+// one document at a time, but one document may have many related resources. 
+// _stopLoading will stop all loads initiated by the data source, 
+// but not loads initiated by child frames' data sources -- that's the WebFrame's job.
+- (void)_stopLoading
+{
+    // Always attempt to stop the icon loader because it may still be loading after the data source
+    // is done loading and not stopping it can cause a world leak.
+    [[_private->webFrame _frameLoader] stopLoadingIcon];
+    
+    // The same goes for the bridge/part, which may still be parsing.
+    if (_private->committed)
+        [[self _bridge] stopLoading];
+    
+    if (![[_private->webFrame _frameLoader] isLoading])
+        return;
+    
+    [self retain];
+    
+    _private->stopping = YES;
+    
+    if ([[_private->webFrame _frameLoader] isLoadingMainResource]) {
+        // Stop the main resource loader and let it send the cancelled message.
+        [[_private->webFrame _frameLoader] cancelMainResourceLoad];
+    } else if ([[_private->webFrame _frameLoader] isLoadingSubresources]) {
+        // The main resource loader already finished loading. Set the cancelled error on the 
+        // document and let the subresourceLoaders send individual cancelled messages below.
+        [self _setMainDocumentError:[self _cancelledError]];
+    } else {
+        // If there are no resource loaders, we need to manufacture a cancelled message.
+        // (A back/forward navigation has no resource loaders because its resources are cached.)
+        [self _mainReceivedError:[self _cancelledError] complete:YES];
+    }
+    
+    [[_private->webFrame _frameLoader] stopLoadingSubresources];
+    [[_private->webFrame _frameLoader] stopLoadingPlugIns];
+    
+    _private->stopping = NO;
+    
+    [self release];
 }
 
-- (void)_didReceiveData:(NSData *)data contentLength:(int)lengthReceived forResource:(id)identifier
+- (WebFrameBridge *)_bridge
 {
-    WebView *webView = [self _webView];
-
-    [webView _incrementProgressForIdentifier:identifier data:data];
-
-    if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidReceiveContentLength)
-        [[webView resourceLoadDelegate] webView:webView resource:identifier didReceiveContentLength:(WebNSUInteger)lengthReceived fromDataSource:self];
-    else
-        [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didReceiveContentLength:(WebNSUInteger)lengthReceived fromDataSource:self];
+    ASSERT(_private->committed);
+    return [[self webFrame] _bridge];
 }
 
-
-- (void)_didFinishLoadingForResource:(id)identifier
+- (WebView *)_webView
 {
-    WebView *webView = [self _webView];
-
-    [webView _completeProgressForIdentifier:identifier];    
-    
-    if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidFinishLoadingFromDataSource)
-        [[webView resourceLoadDelegate] webView:webView resource:identifier didFinishLoadingFromDataSource:self];
-    else
-        [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didFinishLoadingFromDataSource:self];
+    return [_private->webFrame webView];
 }
 
-- (void)_didFailLoadingWithError:(NSError *)error forResource:(id)identifier
+- (NSDictionary *)_triggeringAction
 {
-    WebView *webView = [self _webView];
-
-    [webView _completeProgressForIdentifier:identifier];
-
-    if (error)
-        [[webView _resourceLoadDelegateForwarder] webView:webView resource:identifier didFailLoadingWithError:error fromDataSource:self];
+    return [[_private->triggeringAction retain] autorelease];
 }
 
-- (void)_downloadWithLoadingConnection:(NSURLConnection *)connection request:(NSURLRequest *)request response:(NSURLResponse *)r proxy:(WKNSURLConnectionDelegateProxyPtr) proxy
+- (void)_setTriggeringAction:(NSDictionary *)action
 {
-    [WebDownload _downloadWithLoadingConnection:connection
-                 request:request
-                 response:r
-                 delegate:[[self _webView] downloadDelegate]
-                 proxy:proxy];
+    [action retain];
+    [_private->triggeringAction release];
+    _private->triggeringAction = action;
 }
 
-- (NSURLRequest *)_originalRequest
+- (void)__adoptRequest:(NSMutableURLRequest *)request
 {
-    return _private->originalRequestCopy;
+    if (request != _private->request){
+        [_private->request release];
+        _private->request = [request retain];
+    }
 }
 
-- (void)_setTriggeringAction:(NSDictionary *)action
+- (BOOL)_isDocumentHTML
 {
-    [action retain];
-    [_private->triggeringAction release];
-    _private->triggeringAction = action;
+    NSString *MIMEType = [[self response] MIMEType];
+    return [WebView canShowMIMETypeAsHTML:MIMEType];
 }
 
-- (NSDictionary *)_triggeringAction
+- (void)_stopLoadingWithError:(NSError *)error
 {
-    return [[_private->triggeringAction retain] autorelease];
+    [[_private->webFrame _frameLoader] stopLoadingWithError:error];
 }
 
-- (NSURLRequest *)_lastCheckedRequest
+- (void)_setPrimaryLoadComplete:(BOOL)flag
 {
-    // It's OK not to make a copy here because we know the caller
-    // isn't going to modify this request
-    return [[_private->lastCheckedRequest retain] autorelease];
+    _private->primaryLoadComplete = flag;
+    
+    if (flag) {
+        // FIXME: We could actually load it as soon as we've parsed
+        // the HEAD section, or determined there isn't one - but
+        // there's no callback for that.
+        [self _loadIcon];
+        
+        if ([[_private->webFrame _frameLoader] isLoadingMainResource]) {
+            [self _setData:[[_private->webFrame _frameLoader] mainResourceData]];
+            [[_private->webFrame _frameLoader] releaseMainResourceLoader];
+        }
+        
+        if ([WebScriptDebugServer listenerCount])
+            [[WebScriptDebugServer sharedScriptDebugServer] webView:[[self webFrame] webView] didLoadMainResourceForDataSource:self];
+    }
 }
 
-- (void)_setLastCheckedRequest:(NSURLRequest *)request
+- (NSArray *)_responses
 {
-    NSURLRequest *oldRequest = _private->lastCheckedRequest;
-    _private->lastCheckedRequest = [request copy];
-    [oldRequest release];
+    return _private->responses;
 }
 
 - (BOOL)_loadingFromPageCache
@@ -904,96 +910,122 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class class,
     return _private->loadingFromPageCache;
 }
 
-- (void)_addResponse:(NSURLResponse *)r
+-(void)_makeRepresentation
 {
-    if (!_private->stopRecordingResponses) {
-        if (!_private->responses)
-            _private->responses = [[NSMutableArray alloc] init];
-        [_private->responses addObject: r];
+    Class repClass = [[self class] _representationClassForMIMEType:[[self response] MIMEType]];
+    
+    // Check if the data source was already bound?
+    if (![[self representation] isKindOfClass:repClass]) {
+        id newRep = repClass != nil ? [[repClass alloc] init] : nil;
+        [self _setRepresentation:(id <WebDocumentRepresentation>)newRep];
+        [newRep release];
     }
+    
+    [_private->representation setDataSource:self];
 }
 
-- (void)_stopRecordingResponses
+- (BOOL)_isClientRedirect
 {
-    _private->stopRecordingResponses = YES;
+    return _private->isClientRedirect;
 }
 
-- (NSArray *)_responses
+
+- (NSURLRequest *)_originalRequest
 {
-    return _private->responses;
+    return _private->originalRequestCopy;
 }
 
-- (void)_stopLoadingWithError:(NSError *)error
+- (NSURL *)_URLForHistory
 {
-    [[_private->webFrame _frameLoader] stopLoadingWithError:error];
+    // Return the URL to be used for history and B/F list.
+    // Returns nil for WebDataProtocol URLs that aren't alternates 
+    // 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)_setWebFrame:(WebFrame *)frame
+- (void)_addToUnarchiveState:(WebArchive *)archive
 {
-    [frame retain];
-    [_private->webFrame release];
-    _private->webFrame = frame;
-
-    [self _defersCallbacksChanged];
-    // no need to do _defersCallbacksChanged for subframes since they too
-    // will be or have been told of their WebFrame
+    if (!_private->unarchivingState)
+        _private->unarchivingState = [[WebUnarchivingState alloc] init];
+    [_private->unarchivingState addArchive:archive];
 }
 
-// May return nil if not initialized with a URL.
-- (NSURL *)_URL
+- (void)_setOverrideEncoding:(NSString *)overrideEncoding
 {
-    return [[self request] URL];
+    NSString *copy = [overrideEncoding copy];
+    [_private->overrideEncoding release];
+    _private->overrideEncoding = copy;
 }
 
-- (NSError *)_mainDocumentError
+- (void)_setIconURL:(NSURL *)URL
 {
-    return _private->mainDocumentError;
+    // Lower priority than typed icon, so ignore this if we already have an iconURL.
+    if (_private->iconURL == nil) {
+        [_private->iconURL release];
+        _private->iconURL = [URL retain];
+    }
 }
 
-- (BOOL)_isDocumentHTML
+- (void)_setIconURL:(NSURL *)URL withType:(NSString *)iconType
 {
-    NSString *MIMEType = [[self response] MIMEType];
-    return [WebView canShowMIMETypeAsHTML:MIMEType];
+    // FIXME: Should check to make sure the type is one we know how to handle.
+    [_private->iconURL release];
+    _private->iconURL = [URL retain];
 }
 
-- (void)_revertToProvisionalState
+- (NSString *)_overrideEncoding
 {
-    [self _setRepresentation:nil];
-    [[_private->webFrame _frameLoader] setupForReplace];
-    _private->committed = NO;
+    return [[_private->overrideEncoding copy] autorelease];
 }
 
-- (void)_setupForReplaceByMIMEType:(NSString *)newMIMEType
+- (void)_setTitle:(NSString *)title
 {
-    if (!_private->gotFirstByte)
+    NSString *trimmed;
+    if (title == nil) {
+        trimmed = nil;
+    } else {
+        trimmed = [title _webkit_stringByTrimmingWhitespace];
+        if ([trimmed length] == 0)
+            trimmed = nil;
+    }
+    if (trimmed == nil) {
+        if (_private->pageTitle == nil)
+            return;
+    } else {
+        if ([_private->pageTitle isEqualToString:trimmed])
+            return;
+    }
+    
+    if (!trimmed || [trimmed length] == 0)
         return;
     
-    WebFrame *frame = [self webFrame];
-    NSString *oldMIMEType = [[self response] MIMEType];
+    [[self _webView] _willChangeValueForKey:_WebMainFrameTitleKey];
+    [_private->pageTitle release];
+    _private->pageTitle = [trimmed copy];
+    [[self _webView] _didChangeValueForKey:_WebMainFrameTitleKey];
     
-    if (![self _doesProgressiveLoadWithMIMEType:oldMIMEType]) {
-        [self _revertToProvisionalState];
-        [self _commitLoadWithData:[self data]];
+    // The title doesn't get communicated to the WebView until we are committed.
+    if (_private->committed) {
+        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.  This must go through the WebFrame because
+            // it has the right notion of the current b/f item.
+            [[self webFrame] _setTitle:_private->pageTitle];
+            
+            [[self _webView] setMainFrameDocumentReady:YES];    // update observers with new DOMDocument
+            [[[self _webView] _frameLoadDelegateForwarder] webView:[self _webView]
+                                                   didReceiveTitle:_private->pageTitle
+                                                          forFrame:[self webFrame]];
+        }
     }
-    
-    _private->representationFinishedLoading = YES;
-    [[self representation] finishedLoadingWithDataSource:self];
-    [[self _bridge] end];
-
-    [frame _setLoadType:WebFrameLoadTypeReplace];
-    _private->gotFirstByte = NO;
-
-    if ([self _doesProgressiveLoadWithMIMEType:newMIMEType])
-        [self _revertToProvisionalState];
-
-    [[_private->webFrame _frameLoader] stopLoadingSubresources];
-    [[_private->webFrame _frameLoader] stopLoadingPlugIns];
-    [_private->unarchivingState release];
-}
-
-- (WebResource *)_archivedSubresourceForURL:(NSURL *)URL
-{
-    return [_private->unarchivingState archivedResourceForURL:URL];
 }
 
 @end
@@ -1164,26 +1196,4 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class class,
     }
 }
 
-- (void)_mainReceivedError:(NSError *)error complete:(BOOL)isComplete
-{
-    if (![self webFrame])
-        return;
-    
-    [self _setMainDocumentError:error];
-
-    if (isComplete) {
-        [self _setPrimaryLoadComplete:YES];
-        [[self webFrame] _checkLoadComplete];
-    }
-}
-
-- (void)_decidePolicyForMIMEType:(NSString *)MIMEType decisionListener:(WebPolicyDecisionListener *)listener
-{
-    WebView *wv = [self _webView];
-    [[wv _policyDelegateForwarder] webView:wv decidePolicyForMIMEType:MIMEType
-                                                              request:[self request]
-                                                                frame:[self webFrame]
-                                                     decisionListener:listener];
-}
-
 @end
index 3dce6e117b0d4132594646126d14cb5324007920..091194f6990f4f16f2f66dba144e636799d81b68 100644 (file)
 @protocol WebDocumentRepresentation;
 
 @interface WebDataSource (WebInternal)
-- (void)_stopLoadingWithError:(NSError *)error;
-- (void)_setTitle:(NSString *)title;
-- (NSString *)_overrideEncoding;
-- (void)_setIconURL:(NSURL *)URL;
 - (void)_setTitle:(NSString *)title;
 - (NSString *)_overrideEncoding;
 - (void)_setIconURL:(NSURL *)URL;
 - (void)_setIconURL:(NSURL *)URL withType:(NSString *)iconType;
-- (NSURLRequest *)_originalRequest;
-- (WebView *)_webView;
-- (WebResource *)_archivedSubresourceForURL:(NSURL *)URL;
-- (void)_addResponse:(NSURLResponse *)r;
-- (WebFrameBridge *)_bridge;
 - (void)_setOverrideEncoding:(NSString *)overrideEncoding;
-- (void)_replaceSelectionWithArchive:(WebArchive *)archive selectReplacement:(BOOL)selectReplacement;
-- (NSURL *)_URL;
-+ (NSMutableDictionary *)_repTypesAllowImageTypeOmission:(BOOL)allowImageTypeOmission;
-- (void)_setPrimaryLoadComplete:(BOOL)flag;
-- (void)_setMainDocumentError:(NSError *)error;
 - (void)_addToUnarchiveState:(WebArchive *)archive;
 - (NSURL *)_URLForHistory;
-- (void)_setWebFrame:(WebFrame *)frame;
+- (NSURLRequest *)_originalRequest;
 - (BOOL)_isClientRedirect;
 - (void)_makeRepresentation;
-- (double)_loadingStartedTime;
-- (BOOL)_isStopping;
-- (void)_finishedLoading;
-- (void)_setResponse:(NSURLResponse *)response;
-- (void)_setupForReplaceByMIMEType:(NSString *)mimeType;
-- (void)_setRequest:(NSURLRequest *)request;
-- (void)_receivedData:(NSData *)data;
-- (void)_receivedMainResourceError:(NSError *)error complete:(BOOL)isComplete;
-- (BOOL)_isDocumentHTML;
-- (DOMDocumentFragment *)_documentFragmentWithImageResource:(WebResource *)resource;
-- (DOMDocumentFragment *)_documentFragmentWithArchive:(WebArchive *)archive;
-- (NSString *)_title;
-- (void)_stopRecordingResponses;
 - (BOOL)_loadingFromPageCache;
 - (NSArray *)_responses;
+- (void)_setPrimaryLoadComplete:(BOOL)flag;
 - (void)_stopLoading;
+- (BOOL)_isDocumentHTML;
 - (void)__adoptRequest:(NSMutableURLRequest *)request;
 - (void)_setTriggeringAction:(NSDictionary *)action;
 - (NSDictionary *)_triggeringAction;
+- (WebView *)_webView;
+- (WebFrameBridge *)_bridge;
+- (void)_stopLoadingWithError:(NSError *)error;
 - (NSURLRequest *)_lastCheckedRequest;
+- (void)_defersCallbacksChanged;
 - (void)_setLastCheckedRequest:(NSURLRequest *)request;
 - (void)_setURL:(NSURL *)URL;
 - (void)_setIsClientRedirect:(BOOL)flag;
 - (WebArchive *)_popSubframeArchiveWithName:(NSString *)frameName;
-- (void)_defersCallbacksChanged;
-- (void)_startLoading;
 - (void)_loadFromPageCache:(NSDictionary *)pageCache;
+- (NSURL *)_URL;
+- (void)_setWebFrame:(WebFrame *)frame;
+- (BOOL)_isStopping;
+- (NSString *)_title;
 - (DOMElement *)_imageElementWithImageResource:(WebResource *)resource;
-- (void)_mainReceivedError:(NSError *)error complete:(BOOL)isComplete;
-- (BOOL)_defersCallbacks;
+- (DOMDocumentFragment *)_documentFragmentWithImageResource:(WebResource *)resource;
+- (DOMDocumentFragment *)_documentFragmentWithArchive:(WebArchive *)archive;
++ (NSMutableDictionary *)_repTypesAllowImageTypeOmission:(BOOL)allowImageTypeOmission;
+- (void)_replaceSelectionWithArchive:(WebArchive *)archive selectReplacement:(BOOL)selectReplacement;
+- (double)_loadingStartedTime;
+- (void)_stopRecordingResponses;
+- (void)_startLoading;
+- (WebResource *)_archivedSubresourceForURL:(NSURL *)URL;
+- (double)_loadingStartedTime;
+- (void)_stopRecordingResponses;
+- (void)_startLoading;
+- (WebResource *)_archivedSubresourceForURL:(NSURL *)URL;
+- (void)_defersCallbacksChanged;
 - (id)_identifierForInitialRequest:(NSURLRequest *)clientRequest;
 - (NSURLRequest *)_willSendRequest:(NSMutableURLRequest *)clientRequest forResource:(id)identifier redirectResponse:(NSURLResponse *)redirectResponse;
 - (void)_didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)currentWebChallenge forResource:(id)identifier;
 - (void)_didFinishLoadingForResource:(id)identifier;
 - (void)_didFailLoadingWithError:(NSError *)error forResource:(id)identifier;
 - (void)_downloadWithLoadingConnection:(NSURLConnection *)connection request:(NSURLRequest *)request response:(NSURLResponse *)r proxy:(WKNSURLConnectionDelegateProxyPtr) proxy;
-- (BOOL)_privateBrowsingEnabled;
+- (BOOL)_defersCallbacks;
+- (void)_receivedMainResourceError:(NSError *)error complete:(BOOL)isComplete;
+- (void)_receivedData:(NSData *)data;
+- (void)_setRequest:(NSURLRequest *)request;
+- (void)_setResponse:(NSURLResponse *)response;
+- (void)_finishedLoading;
+- (void)_setupForReplaceByMIMEType:(NSString *)mimeType;
+- (void)_mainReceivedError:(NSError *)error complete:(BOOL)isComplete;
 - (void)_decidePolicyForMIMEType:(NSString *)MIMEType decisionListener:(WebPolicyDecisionListener *)listener;
+
+
+
 @end