Changeset 31281 in webkit


Ignore:
Timestamp:
Mar 25, 2008 10:11:16 AM (16 years ago)
Author:
beidson@apple.com
Message:

WebCore:

2008-03-25 Brady Eidson <beidson@apple.com>

Reviewed by Darin

<rdar://problem/4516169> - Support WebArchives on Windows
And pave the way for many future WebArchive bug fixes and enhancements

This patch accomplishes two main goals:
1 - Consolidates much of the spread out WebKitMac archive code into one place in WebCore. This allows for cleaner refactoring

in the future as well as adding more archive formats with ease.

2 - Hooks up WebArchive support on Windows. Safari-style .webarchive files are nothing more than property lists readable by

CoreFoundation. While there are still some outstanding issues, including an NSKeyedArchiver chunk of data for the
ResourceResponse for each resource, this patch manually parses through the property list on CoreFoundation platforms and
gets many archives loading on Windows

My goal for this first cut was zero behavior change. As such, I went for a direct port of the WebKitMac code. There will be
opportunities for redesign and refactoring as followups.

  • WebCore.base.exp:
  • loader/DocumentLoader.cpp: (WebCore::DocumentLoader::setupForReplaceByMIMEType): Ported from WebKitMac, WebDataSource (WebCore::DocumentLoader::addAllArchiveResources): (WebCore::DocumentLoader::addArchiveResource): (WebCore::DocumentLoader::archiveResourceForURL): (WebCore::DocumentLoader::popArchiveForSubframe): (WebCore::DocumentLoader::clearArchiveResources):
  • loader/DocumentLoader.h:
  • loader/FrameLoader.cpp: Moved WebFrameLoaderClient and WebFrame code down into their more appropriate FrameLoader home (WebCore::FrameLoader::FrameLoader): (WebCore::FrameLoader::setDefersLoading): (WebCore::FrameLoader::deliverArchivedResourcesAfterDelay): (WebCore::FrameLoader::archiveResourceDeliveryTimerFired): (WebCore::FrameLoader::loadURLIntoChildFrame): (WebCore::FrameLoader::loadArchive): (WebCore::FrameLoader::scheduleArchiveLoad): (WebCore::FrameLoader::stopAllLoaders): (WebCore::FrameLoader::cancelPendingArchiveLoad): (WebCore::FrameLoader::isArchiveLoadPending): (WebCore::FrameLoader::finishedLoadingDocument):
  • loader/FrameLoader.h:
  • loader/ResourceLoader.cpp: (WebCore::ResourceLoader::load):
  • loader/archive/Archive.h: Generic "Archive of web resources" class that is only useful when subclassed.

Contains a MainResource, subresources, and Archives for subframes

(WebCore::Archive::mainResource):
(WebCore::Archive::subresources):
(WebCore::Archive::subframeArchives):
(WebCore::Archive::setMainResource):
(WebCore::Archive::addSubresource):
(WebCore::Archive::addSubframeArchive):

  • loader/archive/ArchiveFactory.cpp: A class that will take raw archive data and the MIMEtype, and create the

appropriate Archive class for it. Additionally it handles registering the known MIMEtypes for all known archive formats

(WebCore::archiveFactoryCreate):
(WebCore::archiveMIMETypes):
(WebCore::ArchiveFactory::isArchiveMimeType):
(WebCore::ArchiveFactory::create):
(WebCore::ArchiveFactory::registerKnownArchiveMIMETypes):

  • loader/archive/ArchiveFactory.h:
  • loader/archive/ArchiveResource.cpp: Analog to "WebResource" in WebKitMac. Contains the data and other important

attributes of an archived resource

(WebCore::ArchiveResource::create):
(WebCore::ArchiveResource::ArchiveResource):
(WebCore::ArchiveResource::response):

  • loader/archive/ArchiveResource.h: (WebCore::ArchiveResource::data): (WebCore::ArchiveResource::url): (WebCore::ArchiveResource::mimeType): (WebCore::ArchiveResource::textEncoding): (WebCore::ArchiveResource::frameName): (WebCore::ArchiveResource::ignoreWhenUnarchiving): (WebCore::ArchiveResource::shouldIgnoreWhenUnarchiving):
  • loader/archive/ArchiveResourceCollection.cpp: Analog of "WebUnarchivingState" in WebKitMac. Contains a hash of

all the resources for every frame in an archive, and contains the archives for each subframe needed to load a multi-frame archive

(WebCore::ArchiveResourceCollection::ArchiveResourceCollection):
(WebCore::ArchiveResourceCollection::addAllResources):
(WebCore::ArchiveResourceCollection::addResource):
(WebCore::ArchiveResourceCollection::archiveResourceForURL):
(WebCore::ArchiveResourceCollection::popSubframeArchive):

  • loader/archive/ArchiveResourceCollection.h:
  • loader/archive/cf/LegacyWebArchive.cpp: Subclass of Archive specifically for Webkit's Objective-C based ".webarchive" format.

Mostly a collection of static methods involved in parsing and serializing a WebKit-style .webarchive. Is mostly supported
for any CF platform.

(WebCore::createPropertyListRepresentationFromResource):
(WebCore::createPropertyListRep):
(WebCore::createResourceResponseFromPropertyListData):
(WebCore::createResource):
(WebCore::LegacyWebArchive::create):
(WebCore::LegacyWebArchive::LegacyWebArchive):
(WebCore::LegacyWebArchive::init):
(WebCore::LegacyWebArchive::extract):
(WebCore::LegacyWebArchive::rawDataRepresentation):
(WebCore::createResourceResponseFromMacArchivedData):
(WebCore::propertyListDataFromResourceResponse):

  • loader/archive/cf/LegacyWebArchive.h:
  • loader/archive/cf/LegacyWebArchiveMac.mm: (WebCore::createResourceResponseFromMacArchivedData): (WebCore::propertyListDataFromResourceResponse):
  • platform/network/mac/ResourceRequest.h:
  • platform/network/mac/ResourceRequestMac.mm: (WebCore::ResourceRequest::applyWebArchiveHackForMail): Tweak the resource request for Mac clients when loading WebArchives

WebKit:

2008-03-25 Brady Eidson <beidson@apple.com>

Reviewed by Darin

<rdar://problem/4516169> - Support WebArchives on Windows

  • WebKit.xcodeproj/project.pbxproj:

WebKit/mac:

2008-03-25 Brady Eidson <beidson@apple.com>

Reviewed by Darin

<rdar://problem/4516169> - Support WebArchives on Windows
And paves the way for many future WebArchive bug fixes and enhancements

This change moves most of the real workhorse code about WebArchives into WebCore. It maintains
1-to-1 relationships between a few objects in WebCore and WebKit. Such as:

  • WebArchive <-> LegacyWebArchive
  • WebResource <-> ArchiveResource
  • WebUnarchivingState <-> ArchiveResourceCollection


The other biggest changes involve many FrameLoaderClient methods that existed soley for WebArchives
and now exist in WebCore

  • WebCoreSupport/WebFrameLoaderClient.mm: (WebFrameLoaderClient::clearUnarchivingState): Emptied - to be removed in a followup patch (WebFrameLoaderClient::finalSetupForReplace): (WebFrameLoaderClient::setDefersLoading): (WebFrameLoaderClient::willUseArchive): (WebFrameLoaderClient::isArchiveLoadPending): (WebFrameLoaderClient::cancelPendingArchiveLoad): (WebFrameLoaderClient::clearArchivedResources): (WebFrameLoaderClient::createFrame):
  • WebView/WebArchive.mm: (+[WebArchivePrivate initialize]): (-[WebArchivePrivate init]): (-[WebArchivePrivate initWithCoreArchive:]): (-[WebArchivePrivate coreArchive]): (-[WebArchivePrivate setCoreArchive:]): (-[WebArchivePrivate dealloc]): (-[WebArchivePrivate finalize]): (-[WebArchive init]): (-[WebArchive initWithMainResource:subresources:subframeArchives:]): (-[WebArchive initWithData:]): (-[WebArchive initWithCoder:]): (-[WebArchive encodeWithCoder:]): (-[WebArchive mainResource]): (-[WebArchive subresources]): (-[WebArchive subframeArchives]): (-[WebArchive data]): (-[WebArchive _initWithCoreLegacyWebArchive:WebCore::]): (-[WebArchive WebCore::]):
  • WebView/WebArchiveInternal.h: Added.
  • WebView/WebDataSource.mm: (-[WebDataSourcePrivate dealloc]): (-[WebDataSource _addSubframeArchives:]): (-[WebDataSource _documentFragmentWithArchive:]): (-[WebDataSource subresourceForURL:]): (-[WebDataSource addSubresource:]):
  • WebView/WebDataSourceInternal.h:
  • WebView/WebFrame.mm: (-[WebFrame loadArchive:]):
  • WebView/WebFrameInternal.h:
  • WebView/WebHTMLRepresentation.mm: (-[WebHTMLRepresentation finishedLoadingWithDataSource:]):
  • WebView/WebResource.mm: (+[WebResourcePrivate initialize]): (-[WebResourcePrivate init]): (-[WebResourcePrivate initWithCoreResource:]): (-[WebResourcePrivate dealloc]): (-[WebResourcePrivate finalize]): (-[WebResource initWithCoder:]): (-[WebResource encodeWithCoder:]): (-[WebResource data]): (-[WebResource URL]): (-[WebResource MIMEType]): (-[WebResource textEncodingName]): (-[WebResource frameName]): (-[WebResource _initWithCoreResource:WebCore::]): (-[WebResource WebCore::]): (-[WebResource _ignoreWhenUnarchiving]): (-[WebResource _initWithData:URL:MIMEType:textEncodingName:frameName:response:copyData:]): (-[WebResource _fileWrapperRepresentation]): (-[WebResource _response]): (-[WebResource _stringValue]):
  • WebView/WebResourceInternal.h: Added.
  • WebView/WebResourcePrivate.h:
  • WebView/WebUnarchivingState.h: Removed.
  • WebView/WebUnarchivingState.m: Removed.
Location:
trunk
Files:
2 added
2 deleted
31 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r31279 r31281  
     12008-03-25  Brady Eidson  <beidson@apple.com>
     2
     3        Reviewed by Darin
     4
     5        <rdar://problem/4516169> - Support WebArchives on Windows
     6        And pave the way for many future WebArchive bug fixes and enhancements
     7
     8        This patch accomplishes two main goals:
     9        1 - Consolidates much of the spread out WebKitMac archive code into one place in WebCore.  This allows for cleaner refactoring
     10            in the future as well as adding more archive formats with ease.
     11        2 - Hooks up WebArchive support on Windows.  Safari-style .webarchive files are nothing more than property lists readable by
     12            CoreFoundation.  While there are still some outstanding issues, including an NSKeyedArchiver chunk of data for the
     13            ResourceResponse for each resource, this patch manually parses through the property list on CoreFoundation platforms and
     14            gets many archives loading on Windows
     15
     16        My goal for this first cut was zero behavior change.  As such, I went for a direct port of the WebKitMac code.  There will be
     17        opportunities for redesign and refactoring as followups.
     18
     19        * WebCore.base.exp:
     20
     21        * loader/DocumentLoader.cpp:
     22        (WebCore::DocumentLoader::setupForReplaceByMIMEType): Ported from WebKitMac, WebDataSource
     23        (WebCore::DocumentLoader::addAllArchiveResources):
     24        (WebCore::DocumentLoader::addArchiveResource):
     25        (WebCore::DocumentLoader::archiveResourceForURL):
     26        (WebCore::DocumentLoader::popArchiveForSubframe):
     27        (WebCore::DocumentLoader::clearArchiveResources):
     28        * loader/DocumentLoader.h:
     29
     30        * loader/FrameLoader.cpp: Moved WebFrameLoaderClient and WebFrame code down into their more appropriate FrameLoader home
     31        (WebCore::FrameLoader::FrameLoader):
     32        (WebCore::FrameLoader::setDefersLoading):
     33        (WebCore::FrameLoader::deliverArchivedResourcesAfterDelay):
     34        (WebCore::FrameLoader::archiveResourceDeliveryTimerFired):
     35        (WebCore::FrameLoader::loadURLIntoChildFrame):
     36        (WebCore::FrameLoader::loadArchive):
     37        (WebCore::FrameLoader::scheduleArchiveLoad):
     38        (WebCore::FrameLoader::stopAllLoaders):
     39        (WebCore::FrameLoader::cancelPendingArchiveLoad):
     40        (WebCore::FrameLoader::isArchiveLoadPending):
     41        (WebCore::FrameLoader::finishedLoadingDocument):
     42        * loader/FrameLoader.h:
     43
     44        * loader/ResourceLoader.cpp:
     45        (WebCore::ResourceLoader::load):
     46
     47        * loader/archive/Archive.h: Generic "Archive of web resources" class that is only useful when subclassed. 
     48            Contains a MainResource, subresources, and Archives for subframes
     49        (WebCore::Archive::mainResource):
     50        (WebCore::Archive::subresources):
     51        (WebCore::Archive::subframeArchives):
     52        (WebCore::Archive::setMainResource):
     53        (WebCore::Archive::addSubresource):
     54        (WebCore::Archive::addSubframeArchive):
     55
     56        * loader/archive/ArchiveFactory.cpp: A class that will take raw archive data and the MIMEtype, and create the
     57            appropriate Archive class for it.  Additionally it handles registering the known MIMEtypes for all known archive formats
     58        (WebCore::archiveFactoryCreate):
     59        (WebCore::archiveMIMETypes):
     60        (WebCore::ArchiveFactory::isArchiveMimeType):
     61        (WebCore::ArchiveFactory::create):
     62        (WebCore::ArchiveFactory::registerKnownArchiveMIMETypes):
     63        * loader/archive/ArchiveFactory.h:
     64
     65        * loader/archive/ArchiveResource.cpp: Analog to "WebResource" in WebKitMac.  Contains the data and other important
     66            attributes of an archived resource
     67        (WebCore::ArchiveResource::create):
     68        (WebCore::ArchiveResource::ArchiveResource):
     69        (WebCore::ArchiveResource::response):
     70        * loader/archive/ArchiveResource.h:
     71        (WebCore::ArchiveResource::data):
     72        (WebCore::ArchiveResource::url):
     73        (WebCore::ArchiveResource::mimeType):
     74        (WebCore::ArchiveResource::textEncoding):
     75        (WebCore::ArchiveResource::frameName):
     76        (WebCore::ArchiveResource::ignoreWhenUnarchiving):
     77        (WebCore::ArchiveResource::shouldIgnoreWhenUnarchiving):
     78
     79        * loader/archive/ArchiveResourceCollection.cpp: Analog of "WebUnarchivingState" in WebKitMac.  Contains a hash of
     80            all the resources for every frame in an archive, and contains the archives for each subframe needed to load a multi-frame archive
     81        (WebCore::ArchiveResourceCollection::ArchiveResourceCollection):
     82        (WebCore::ArchiveResourceCollection::addAllResources):
     83        (WebCore::ArchiveResourceCollection::addResource):
     84        (WebCore::ArchiveResourceCollection::archiveResourceForURL):
     85        (WebCore::ArchiveResourceCollection::popSubframeArchive):
     86        * loader/archive/ArchiveResourceCollection.h:
     87
     88        * loader/archive/cf/LegacyWebArchive.cpp: Subclass of Archive specifically for Webkit's Objective-C based ".webarchive" format.
     89            Mostly a collection of static methods involved in parsing and serializing a WebKit-style .webarchive.  Is mostly supported
     90            for any CF platform.
     91        (WebCore::createPropertyListRepresentationFromResource):
     92        (WebCore::createPropertyListRep):
     93        (WebCore::createResourceResponseFromPropertyListData):
     94        (WebCore::createResource):
     95        (WebCore::LegacyWebArchive::create):
     96        (WebCore::LegacyWebArchive::LegacyWebArchive):
     97        (WebCore::LegacyWebArchive::init):
     98        (WebCore::LegacyWebArchive::extract):
     99        (WebCore::LegacyWebArchive::rawDataRepresentation):
     100        (WebCore::createResourceResponseFromMacArchivedData):
     101        (WebCore::propertyListDataFromResourceResponse):
     102        * loader/archive/cf/LegacyWebArchive.h:
     103        * loader/archive/cf/LegacyWebArchiveMac.mm:
     104        (WebCore::createResourceResponseFromMacArchivedData):
     105        (WebCore::propertyListDataFromResourceResponse):
     106
     107        * platform/network/mac/ResourceRequest.h:
     108        * platform/network/mac/ResourceRequestMac.mm:
     109        (WebCore::ResourceRequest::applyWebArchiveHackForMail): Tweak the resource request for Mac clients when loading WebArchives
     110
    11112008-03-25  David Hyatt  <hyatt@apple.com>
    2112
  • trunk/WebCore/WebCore.base.exp

    r31177 r31281  
    139139__ZN7WebCore11FileChooserD1Ev
    140140__ZN7WebCore11FrameLoader11completeURLERKNS_6StringE
     141__ZN7WebCore11FrameLoader11loadArchiveEN3WTF10PassRefPtrINS_7ArchiveEEE
    141142__ZN7WebCore11FrameLoader11setEncodingERKNS_6StringEb
    142143__ZN7WebCore11FrameLoader12canCachePageEv
     
    151152__ZN7WebCore11FrameLoader18shouldHideReferrerERKNS_4KURLERKNS_6StringE
    152153__ZN7WebCore11FrameLoader20continueLoadWithDataEPNS_12SharedBufferERKNS_6StringES5_RKNS_4KURLE
     154__ZN7WebCore11FrameLoader21loadURLIntoChildFrameERKNS_4KURLERKNS_6StringEPNS_5FrameE
    153155__ZN7WebCore11FrameLoader21setCurrentHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
    154156__ZN7WebCore11FrameLoader22findFrameForNavigationERKNS_12AtomicStringE
     
    266268__ZN7WebCore14DocumentLoader13attachToFrameEv
    267269__ZN7WebCore14DocumentLoader15detachFromFrameEv
     270__ZN7WebCore14DocumentLoader18addArchiveResourceEN3WTF10PassRefPtrINS_15ArchiveResourceEEE
    268271__ZN7WebCore14DocumentLoader19prepareForLoadStartEv
    269272__ZN7WebCore14DocumentLoader21addPlugInStreamLoaderEPNS_14ResourceLoaderE
     273__ZN7WebCore14DocumentLoader21archiveResourceForURLERKNS_4KURLE
     274__ZN7WebCore14DocumentLoader22addAllArchiveResourcesEPNS_7ArchiveE
    270275__ZN7WebCore14DocumentLoader22cancelMainResourceLoadERKNS_13ResourceErrorE
    271276__ZN7WebCore14DocumentLoader24removePlugInStreamLoaderEPNS_14ResourceLoaderE
     
    285290__ZN7WebCore14ResourceLoader19setShouldBufferDataEb
    286291__ZN7WebCore14SecurityOrigin6createERKNS_6StringES3_tPS0_
     292__ZN7WebCore15ArchiveResource6createEN3WTF10PassRefPtrINS_12SharedBufferEEERKNS_4KURLERKNS_6StringESA_SA_RKNS_16ResourceResponseE
     293__ZN7WebCore15ArchiveResource8responseEv
    287294__ZN7WebCore15BackForwardList10removeItemEPNS_11HistoryItemE
    288295__ZN7WebCore15BackForwardList10setEnabledEb
     
    333340__ZN7WebCore16FontPlatformDataC1EP6NSFontbb
    334341__ZN7WebCore16FontPlatformDataD1Ev
     342__ZN7WebCore16LegacyWebArchive21rawDataRepresentationEv
     343__ZN7WebCore16LegacyWebArchive6createEN3WTF10PassRefPtrINS_15ArchiveResourceEEERNS1_6VectorIS4_Lm0EEERNS5_INS2_IS0_EELm0EEE
     344__ZN7WebCore16LegacyWebArchive6createEPNS_12SharedBufferE
     345__ZN7WebCore16LegacyWebArchive6createEv
    335346__ZN7WebCore16MIMETypeRegistry24isSupportedImageMIMETypeERKNS_6StringE
    336347__ZN7WebCore16MIMETypeRegistry26getSupportedImageMIMETypesEv
  • trunk/WebCore/loader/DocumentLoader.cpp

    r31038 r31281  
    3030#include "DocumentLoader.h"
    3131
     32#include "ArchiveResourceCollection.h"
    3233#include "CachedPage.h"
    3334#include "DocLoader.h"
     
    4344#include "StringBuffer.h"
    4445#include "XMLTokenizer.h"
     46
    4547#include <wtf/Assertions.h>
    4648#include <wtf/unicode/Unicode.h>
     
    365367    stopLoadingSubresources();
    366368    stopLoadingPlugIns();
    367 
    368     frameLoader()->finalSetupForReplace(this);
     369    clearArchiveResources();
    369370}
    370371
     
    439440}
    440441
     442void DocumentLoader::addAllArchiveResources(Archive* archive)
     443{
     444    if (!m_archiveResourceCollection)
     445        m_archiveResourceCollection.set(new ArchiveResourceCollection);
     446       
     447    ASSERT(archive);
     448    if (!archive)
     449        return;
     450       
     451    m_archiveResourceCollection->addAllResources(archive);
     452}
     453
     454// FIXME: Adding a resource directly to a DocumentLoader/ArchiveResourceCollection seems like bad design, but is API some apps rely on.
     455// Can we change the design in a manner that will let us deprecate that API without reducing functionality of those apps?
     456void DocumentLoader::addArchiveResource(PassRefPtr<ArchiveResource> resource)
     457{
     458    if (!m_archiveResourceCollection)
     459        m_archiveResourceCollection.set(new ArchiveResourceCollection);
     460       
     461    ASSERT(resource);
     462    if (!resource)
     463        return;
     464       
     465    m_archiveResourceCollection->addResource(resource);
     466}
     467
     468ArchiveResource* DocumentLoader::archiveResourceForURL(const KURL& url)
     469{
     470    if (!m_archiveResourceCollection)
     471        return 0;
     472       
     473    ArchiveResource* resource = m_archiveResourceCollection->archiveResourceForURL(url);
     474
     475    return resource && !resource->shouldIgnoreWhenUnarchiving() ? resource : 0;
     476}
     477
     478PassRefPtr<Archive> DocumentLoader::popArchiveForSubframe(const String& frameName)
     479{
     480    return m_archiveResourceCollection ? m_archiveResourceCollection->popSubframeArchive(frameName) : 0;
     481}
     482
     483void DocumentLoader::clearArchiveResources()
     484{
     485    m_archiveResourceCollection.clear();
     486}
     487
    441488void DocumentLoader::addResponse(const ResourceResponse& r)
    442489{
  • trunk/WebCore/loader/DocumentLoader.h

    r31035 r31281  
    4444namespace WebCore {
    4545
     46    class Archive;
     47    class ArchiveResource;
     48    class ArchiveResourceCollection;
    4649    class CachedPage;
    4750    class Frame;
     
    118121#endif
    119122
     123        void addAllArchiveResources(Archive*);
     124        void addArchiveResource(PassRefPtr<ArchiveResource>);
     125        ArchiveResource* archiveResourceForURL(const KURL&);
     126        PassRefPtr<Archive> popArchiveForSubframe(const String& frameName);
     127        void clearArchiveResources();
     128       
    120129        void addResponse(const ResourceResponse&);
    121130        const ResponseVector& responses() const { return m_responses; }
     
    226235        ResponseVector m_responses;
    227236        bool m_stopRecordingResponses;
     237       
     238        OwnPtr<ArchiveResourceCollection> m_archiveResourceCollection;
    228239    };
    229240
  • trunk/WebCore/loader/FrameLoader.cpp

    r31228 r31281  
    3131#include "FrameLoader.h"
    3232
     33#include "Archive.h"
     34#include "ArchiveFactory.h"
    3335#include "CString.h"
    3436#include "Cache.h"
     
    255257    , m_committedFirstRealDocumentLoad(false)
    256258    , m_didPerformFirstNavigation(false)
     259    , m_archiveResourceDeliveryTimer(this, &FrameLoader::archiveResourceDeliveryTimerFired)
    257260#ifndef NDEBUG
    258261    , m_didDispatchDidCommitLoad(false)
     
    302305    if (m_policyDocumentLoader)
    303306        m_policyDocumentLoader->setDefersLoading(defers);
    304     m_client->setDefersLoading(defers);
     307    if (!defers)
     308        deliverArchivedResourcesAfterDelay();
    305309}
    306310
     
    14891493}
    14901494
     1495void FrameLoader::deliverArchivedResourcesAfterDelay()
     1496{
     1497    if (m_pendingArchiveResources.isEmpty())
     1498        return;
     1499    if (m_frame->page()->defersLoading())
     1500        return;
     1501    if (!m_archiveResourceDeliveryTimer.isActive())
     1502        m_archiveResourceDeliveryTimer.startOneShot(0);
     1503}
     1504
     1505void FrameLoader::archiveResourceDeliveryTimerFired(Timer<FrameLoader>*)
     1506{
     1507    if (m_pendingArchiveResources.isEmpty())
     1508        return;
     1509    if (m_frame->page()->defersLoading())
     1510        return;
     1511
     1512    ArchiveResourceMap copy;
     1513    copy.swap(m_pendingArchiveResources);
     1514
     1515    ArchiveResourceMap::const_iterator end = copy.end();
     1516    for (ArchiveResourceMap::const_iterator it = copy.begin(); it != end; ++it) {
     1517        RefPtr<ResourceLoader> loader = it->first;
     1518        ArchiveResource* resource = it->second.get();
     1519       
     1520        SharedBuffer* data = resource->data();
     1521       
     1522        loader->didReceiveResponse(resource->response());
     1523        loader->didReceiveData(data->data(), data->size(), data->size(), true);
     1524        loader->didFinishLoading();
     1525    }
     1526}
     1527
     1528/*
     1529    In the case of saving state about a page with frames, we store a tree of items that mirrors the frame tree. 
     1530    The item that was the target of the user's navigation is designated as the "targetItem". 
     1531    When this method is called with doClip=YES we're able to create the whole tree except for the target's children,
     1532    which will be loaded in the future.  That part of the tree will be filled out as the child loads are committed.
     1533*/
     1534void FrameLoader::loadURLIntoChildFrame(const KURL& url, const String& referer, Frame* childFrame)
     1535{
     1536    ASSERT(childFrame);
     1537    HistoryItem* parentItem = currentHistoryItem();
     1538    FrameLoadType loadType = this->loadType();
     1539    FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory;
     1540
     1541    KURL workingURL = url;
     1542   
     1543    // If we're moving in the backforward list, we might want to replace the content
     1544    // of this child frame with whatever was there at that point.
     1545    // Reload will maintain the frame contents, LoadSame will not.
     1546    if (parentItem && parentItem->children().size() &&
     1547        (isBackForwardLoadType(loadType) || loadType == FrameLoadTypeReloadAllowingStaleData))
     1548    {
     1549        HistoryItem* childItem = parentItem->childItemWithName(childFrame->tree()->name());
     1550        if (childItem) {
     1551            // Use the original URL to ensure we get all the side-effects, such as
     1552            // onLoad handlers, of any redirects that happened. An example of where
     1553            // this is needed is Radar 3213556.
     1554            workingURL = KURL(childItem->originalURLString());
     1555            // These behaviors implied by these loadTypes should apply to the child frames
     1556            childLoadType = loadType;
     1557
     1558            if (isBackForwardLoadType(loadType)) {
     1559                // For back/forward, remember this item so we can traverse any child items as child frames load
     1560                childFrame->loader()->setProvisionalHistoryItem(childItem);
     1561            } else {
     1562                // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item
     1563                childFrame->loader()->setCurrentHistoryItem(childItem);
     1564            }
     1565        }
     1566    }
     1567
     1568    RefPtr<Archive> subframeArchive = activeDocumentLoader()->popArchiveForSubframe(childFrame->tree()->name());
     1569   
     1570    if (subframeArchive)
     1571        childFrame->loader()->loadArchive(subframeArchive.release());
     1572    else
     1573        childFrame->loader()->load(workingURL, referer, childLoadType, String(), 0, 0);
     1574}
     1575
     1576void FrameLoader::loadArchive(PassRefPtr<Archive> prpArchive)
     1577{
     1578    RefPtr<Archive> archive = prpArchive;
     1579   
     1580    ArchiveResource* mainResource = archive->mainResource();
     1581    ASSERT(mainResource);
     1582    if (!mainResource)
     1583        return;
     1584       
     1585    SubstituteData substituteData(mainResource->data(), mainResource->mimeType(), mainResource->textEncoding(), KURL());
     1586   
     1587    ResourceRequest request(mainResource->url());
     1588#if PLATFORM(MAC)
     1589    request.applyWebArchiveHackForMail();
     1590#endif
     1591
     1592    RefPtr<DocumentLoader> documentLoader = m_client->createDocumentLoader(request, substituteData);
     1593    documentLoader->addAllArchiveResources(archive.get());
     1594    load(documentLoader.get());
     1595}
     1596
    14911597String FrameLoader::encoding() const
    14921598{
     
    19342040}
    19352041
    1936 void FrameLoader::finalSetupForReplace(DocumentLoader* loader)
    1937 {
    1938     m_client->clearUnarchivingState(loader);
    1939 }
    1940 
    19412042void FrameLoader::load(const KURL& url, Event* event)
    19422043{
     
    22072308}
    22082309
    2209 bool FrameLoader::willUseArchive(ResourceLoader* loader, const ResourceRequest& request, const KURL& originalURL) const
    2210 {
    2211     return m_client->willUseArchive(loader, request, originalURL);
     2310bool FrameLoader::scheduleArchiveLoad(ResourceLoader* loader, const ResourceRequest& request, const KURL& originalURL)
     2311{
     2312    if (request.url() != originalURL)
     2313        return false;
     2314       
     2315    DocumentLoader* activeLoader = activeDocumentLoader();
     2316    ASSERT(activeLoader);
     2317    if (!activeLoader)
     2318        return false;
     2319       
     2320    ArchiveResource* resource = activeLoader->archiveResourceForURL(originalURL);
     2321    if (!resource)
     2322        return false;
     2323
     2324    m_pendingArchiveResources.set(loader, resource);
     2325    deliverArchivedResourcesAfterDelay();
     2326   
     2327    return true;
    22122328}
    22132329
     
    24022518    if (m_provisionalDocumentLoader)
    24032519        m_provisionalDocumentLoader->stopLoading();
    2404     if (m_documentLoader)
     2520    if (m_documentLoader) {
    24052521        m_documentLoader->stopLoading();
     2522        m_documentLoader->clearArchiveResources();
     2523        m_archiveResourceDeliveryTimer.stop();
     2524    }
    24062525    setProvisionalDocumentLoader(0);
    2407     m_client->clearArchivedResources();
    24082526
    24092527    m_inStopAllLoaders = false;   
     
    24222540void FrameLoader::cancelPendingArchiveLoad(ResourceLoader* loader)
    24232541{
    2424     m_client->cancelPendingArchiveLoad(loader);
     2542    if (m_pendingArchiveResources.isEmpty())
     2543        return;
     2544    m_pendingArchiveResources.remove(loader);
     2545    if (m_pendingArchiveResources.isEmpty())
     2546        m_archiveResourceDeliveryTimer.stop();
    24252547}
    24262548
     
    28122934}
    28132935
     2936#ifndef NDEBUG
    28142937bool FrameLoader::isArchiveLoadPending(ResourceLoader* loader) const
    28152938{
    2816     return m_client->isArchiveLoadPending(loader);
    2817 }
     2939    return m_pendingArchiveResources.contains(loader);
     2940}
     2941#endif
    28182942
    28192943bool FrameLoader::isHostedByObjectElement() const
     
    28582982{
    28592983#if PLATFORM(WIN)
    2860     if (!m_creatingInitialEmptyDocument)
     2984    if (m_creatingInitialEmptyDocument)
     2985        return;
    28612986#endif
    2862         m_client->finishedLoading(loader);
     2987    m_client->finishedLoading(loader);
     2988   
     2989    // If loading a webarchive, run through webarchive machinery
     2990    const String& responseMIMEType = loader->responseMIMEType();
     2991    if (!ArchiveFactory::isArchiveMimeType(responseMIMEType))
     2992        return;
     2993       
     2994    RefPtr<Archive> archive(ArchiveFactory::create(loader->mainResourceData().get(), responseMIMEType));
     2995    if (!archive)
     2996        return;
     2997
     2998    loader->addAllArchiveResources(archive.get());
     2999   
     3000    ArchiveResource* mainResource = archive->mainResource();
     3001    continueLoadWithData(mainResource->data(), mainResource->mimeType(), mainResource->textEncoding(), mainResource->url());
    28633002}
    28643003
  • trunk/WebCore/loader/FrameLoader.h

    r31071 r31281  
    5454namespace WebCore {
    5555
     56    class Archive;
     57    class ArchiveResource;
    5658    class AuthenticationChallenge;
    5759    class CachedPage;
     
    141143        void setupForReplace();
    142144        void setupForReplaceByMIMEType(const String& newMIMEType);
    143         void finalSetupForReplace(DocumentLoader*);
    144145        void load(const KURL&, Event*);
    145146        void load(const FrameLoadRequest&, bool lockHistory, bool userGesture,
     
    158159        void load(DocumentLoader*);
    159160        void load(DocumentLoader*, FrameLoadType, PassRefPtr<FormState>);
     161       
     162        void loadURLIntoChildFrame(const KURL&, const String& referer, Frame*);
     163        void loadArchive(PassRefPtr<Archive> archive);
    160164
    161165        static bool canLoad(const KURL&, const String& referrer);
     
    215219        ResourceError fileDoesNotExistError(const ResourceResponse&) const;
    216220        ResourceError blockedError(const ResourceRequest&) const;
    217         bool willUseArchive(ResourceLoader*, const ResourceRequest&, const KURL&) const;
     221        bool scheduleArchiveLoad(ResourceLoader*, const ResourceRequest&, const KURL&);
     222#ifndef NDEBUG
    218223        bool isArchiveLoadPending(ResourceLoader*) const;
     224#endif
    219225        void cannotShowMIMEType(const ResourceResponse&);
    220226        ResourceError interruptionForPolicyChangeError(const ResourceRequest&);
     
    461467        void checkCompletedTimerFired(Timer<FrameLoader>*);
    462468        void checkLoadCompleteTimerFired(Timer<FrameLoader>*);
     469       
     470        void deliverArchivedResourcesAfterDelay();
     471        void archiveResourceDeliveryTimerFired(Timer<FrameLoader>*);
    463472
    464473        void cancelRedirection(bool newLoadInProgress = false);
     
    640649       
    641650        bool m_didPerformFirstNavigation;
     651       
     652        typedef HashMap<RefPtr<ResourceLoader>, RefPtr<ArchiveResource> > ArchiveResourceMap;
     653        ArchiveResourceMap m_pendingArchiveResources;
     654        Timer<FrameLoader> m_archiveResourceDeliveryTimer;
    642655
    643656#ifndef NDEBUG
  • trunk/WebCore/loader/ResourceLoader.cpp

    r31204 r31281  
    116116    }
    117117   
    118     if (frameLoader()->willUseArchive(this, clientRequest, r.url()))
     118    if (frameLoader()->scheduleArchiveLoad(this, clientRequest, r.url()))
    119119        return true;
    120120   
  • trunk/WebCore/loader/archive/Archive.h

    r31258 r31281  
    3030#define Archive_h
    3131
    32 // FIXME:  Code will go here!
     32#include "ArchiveResource.h"
     33
     34#include <wtf/PassRefPtr.h>
     35#include <wtf/RefCounted.h>
     36#include <wtf/RefPtr.h>
     37#include <wtf/Vector.h>
     38
     39namespace WebCore {
     40
     41class Archive : public RefCounted<Archive> {
     42public:   
     43    ArchiveResource* mainResource() { return m_mainResource.get(); }   
     44    const Vector<RefPtr<ArchiveResource> >& subresources() const { return m_subresources; }
     45    const Vector<RefPtr<Archive> >& subframeArchives() const { return m_subframeArchives; }
     46
     47protected:
     48    // These methods are meant for subclasses for different archive types to add resources in to the archive,
     49    // and should not be exposed as archives should be immutable to clients
     50    void setMainResource(PassRefPtr<ArchiveResource> mainResource) { m_mainResource = mainResource; }
     51    void addSubresource(PassRefPtr<ArchiveResource> subResource) { m_subresources.append(subResource); }
     52    void addSubframeArchive(PassRefPtr<Archive> subframeArchive) { m_subframeArchives.append(subframeArchive); }
     53   
     54private:
     55    RefPtr<ArchiveResource> m_mainResource;
     56    Vector<RefPtr<ArchiveResource> > m_subresources;
     57    Vector<RefPtr<Archive> > m_subframeArchives;
     58};
     59
     60}
    3361
    3462#endif // Archive
  • trunk/WebCore/loader/archive/ArchiveFactory.cpp

    r31258 r31281  
    3030#include "ArchiveFactory.h"
    3131
    32 // FIXME:  Code will go here!
     32#include "LegacyWebArchive.h"
     33#include "MIMETypeRegistry.h"
     34#include "PlatformString.h"
     35
     36#include <wtf/HashMap.h>
     37#include <wtf/HashSet.h>
     38
     39namespace WebCore {
     40
     41typedef PassRefPtr<Archive> RawDataCreationFunction(SharedBuffer*);
     42
     43// The create functions in the archive classes return PassRefPtr to concrete subclasses
     44// of Archive. This adaptor makes the functions have a uniform return type.
     45template <typename ArchiveClass> static PassRefPtr<Archive> archiveFactoryCreate(SharedBuffer* buffer)
     46{
     47    return ArchiveClass::create(buffer);
     48}
     49
     50static HashMap<String, RawDataCreationFunction*, CaseFoldingHash>& archiveMIMETypes()
     51{
     52    static HashMap<String, RawDataCreationFunction*, CaseFoldingHash> mimeTypes;
     53    static bool initialized = false;
     54   
     55    if (initialized)
     56        return mimeTypes;
     57   
     58#if PLATFORM(CF)
     59    mimeTypes.set("application/x-webarchive", archiveFactoryCreate<LegacyWebArchive>);
     60#endif
     61       
     62    initialized = true;
     63    return mimeTypes;
     64}
     65
     66bool ArchiveFactory::isArchiveMimeType(const String& mimeType)
     67{
     68    return archiveMIMETypes().contains(mimeType);
     69}
     70
     71PassRefPtr<Archive> ArchiveFactory::create(SharedBuffer* data, const String& mimeType)
     72{
     73    RawDataCreationFunction* function = archiveMIMETypes().get(mimeType);
     74    return function ? function(data) : 0;
     75}
     76
     77void ArchiveFactory::registerKnownArchiveMIMETypes()
     78{
     79    HashSet<String>& mimeTypes = MIMETypeRegistry::getSupportedNonImageMIMETypes();
     80    HashMap<String, RawDataCreationFunction*, CaseFoldingHash>::iterator i = archiveMIMETypes().begin();
     81    HashMap<String, RawDataCreationFunction*, CaseFoldingHash>::iterator end = archiveMIMETypes().end();
     82   
     83    for (; i != end; ++i)
     84        mimeTypes.add(i->first);
     85}
     86
     87}
  • trunk/WebCore/loader/archive/ArchiveFactory.h

    r31258 r31281  
    3030#define ArchiveFactory_h
    3131
    32 // FIXME:  Code will go here!
     32#include "Archive.h"
    3333
    34 #endif // ArchiveFactory
     34#include <wtf/PassRefPtr.h>
     35
     36namespace WebCore {
     37
     38class SharedBuffer;
     39class String;
     40
     41class ArchiveFactory {
     42public:
     43    static bool isArchiveMimeType(const String&);
     44    static PassRefPtr<Archive> create(SharedBuffer* data, const String& mimeType);
     45    static void registerKnownArchiveMIMETypes();
     46};
     47
     48}
     49
     50#endif // ArchiveFactory_h
  • trunk/WebCore/loader/archive/ArchiveResource.cpp

    r31258 r31281  
    3030#include "ArchiveResource.h"
    3131
    32 // FIXME:  Code will go here!
     32#include "SharedBuffer.h"
     33
     34namespace WebCore {
     35
     36PassRefPtr<ArchiveResource> ArchiveResource::create(PassRefPtr<SharedBuffer> data, const KURL& url, const String& mimeType, const String& textEncoding, const String& frameName)
     37{
     38    return adoptRef(new ArchiveResource(data, url, mimeType, textEncoding, frameName));
     39}
     40
     41PassRefPtr<ArchiveResource> ArchiveResource::create(PassRefPtr<SharedBuffer> data, const KURL& url, const String& mimeType, const String& textEncoding, const String& frameName, const ResourceResponse& resourceResponse)
     42{
     43    return adoptRef(new ArchiveResource(data, url, mimeType, textEncoding, frameName, resourceResponse));
     44}
     45
     46ArchiveResource::ArchiveResource(PassRefPtr<SharedBuffer> data, const KURL& url, const String& mimeType, const String& textEncoding, const String& frameName)
     47    : m_data(data)
     48    , m_url(url)
     49    , m_mimeType(mimeType)
     50    , m_textEncoding(textEncoding)
     51    , m_frameName(frameName)
     52    , m_shouldIgnoreWhenUnarchiving(false)
     53{
     54}
     55
     56ArchiveResource::ArchiveResource(PassRefPtr<SharedBuffer> data, const KURL& url, const String& mimeType, const String& textEncoding, const String& frameName, const ResourceResponse& response)
     57    : m_data(data)
     58    , m_url(url)
     59    , m_mimeType(mimeType)
     60    , m_textEncoding(textEncoding)
     61    , m_frameName(frameName)
     62    , m_response(response)
     63    , m_shouldIgnoreWhenUnarchiving(false)
     64{
     65}
     66
     67const ResourceResponse& ArchiveResource::response()
     68{
     69    if (!m_response.isNull())
     70        return m_response;
     71       
     72    m_response = ResourceResponse(m_url, m_mimeType, m_data->size(), m_textEncoding, String());
     73    return m_response;
     74}
     75
     76}
  • trunk/WebCore/loader/archive/ArchiveResource.h

    r31258 r31281  
    3030#define ArchiveResource_h
    3131
    32 // FIXME:  Code will go here!
     32#include "KURL.h"
     33#include "PlatformString.h"
     34#include "ResourceResponse.h"
     35#include "SharedBuffer.h"
    3336
    34 #endif // ArchiveResource
     37#include <wtf/RefCounted.h>
     38
     39namespace WebCore {
     40
     41class ArchiveResource : public RefCounted<ArchiveResource> {
     42public:
     43    static PassRefPtr<ArchiveResource> create(PassRefPtr<SharedBuffer>, const KURL&, const String& mimeType, const String& textEncoding, const String& frameName);
     44    static PassRefPtr<ArchiveResource> create(PassRefPtr<SharedBuffer>, const KURL&, const String& mimeType, const String& textEncoding, const String& frameName, const ResourceResponse&);
     45   
     46    SharedBuffer* data() { return m_data.get(); }
     47   
     48    const KURL& url() const { return m_url; }
     49    const String& mimeType() const { return m_mimeType; }
     50    const String& textEncoding() const { return m_textEncoding; }
     51    const String& frameName() const { return m_frameName; }
     52    const ResourceResponse& response();
     53   
     54    void ignoreWhenUnarchiving() { m_shouldIgnoreWhenUnarchiving = true; }
     55    bool shouldIgnoreWhenUnarchiving() const { return m_shouldIgnoreWhenUnarchiving; }
     56
     57private:
     58    ArchiveResource(PassRefPtr<SharedBuffer>, const KURL&, const String& mimeType, const String& textEncoding, const String& frameName);
     59    ArchiveResource(PassRefPtr<SharedBuffer>, const KURL&, const String& mimeType, const String& textEncoding, const String& frameName, const ResourceResponse&);
     60   
     61    RefPtr<SharedBuffer> m_data;
     62    KURL m_url;
     63    String m_mimeType;
     64    String m_textEncoding;
     65    String m_frameName;
     66   
     67    ResourceResponse m_response;
     68   
     69    bool m_shouldIgnoreWhenUnarchiving;
     70};
     71
     72}
     73
     74#endif // ArchiveResource_h
  • trunk/WebCore/loader/archive/ArchiveResourceCollection.cpp

    r31258 r31281  
    3030#include "ArchiveResourceCollection.h"
    3131
    32 // FIXME:  Code will go here!
     32namespace WebCore {
     33
     34ArchiveResourceCollection::ArchiveResourceCollection()
     35{
     36}
     37
     38void ArchiveResourceCollection::addAllResources(Archive* archive)
     39{
     40    ASSERT(archive);
     41    if (!archive)
     42        return;
     43   
     44    const Vector<RefPtr<ArchiveResource> >& subresources = archive->subresources();
     45    Vector<RefPtr<ArchiveResource> >::const_iterator iRes = subresources.begin();
     46    Vector<RefPtr<ArchiveResource> >::const_iterator endRes = subresources.end();
     47   
     48    for (; iRes != endRes; ++iRes)
     49        m_subresources.set((*iRes)->url(), iRes->get());
     50
     51    const Vector<RefPtr<Archive> >& subframes = archive->subframeArchives();
     52    Vector<RefPtr<Archive> >::const_iterator iFrame = subframes.begin();
     53    Vector<RefPtr<Archive> >::const_iterator endFrame = subframes.end();
     54       
     55    for (; iFrame != endFrame; ++iFrame) {       
     56        ASSERT((*iFrame)->mainResource());
     57        const String& frameName = (*iFrame)->mainResource()->frameName();
     58        if (!frameName.isNull())
     59            m_subframes.set(frameName, iFrame->get());
     60    }
     61}
     62   
     63// FIXME: Adding a resource directly to a DocumentLoader/ArchiveResourceCollection seems like bad design, but is API some apps rely on.
     64// Can we change the design in a manner that will let us deprecate that API without reducing functionality of those apps?
     65void ArchiveResourceCollection::addResource(PassRefPtr<ArchiveResource> resource)
     66{
     67    ASSERT(resource);
     68    if (!resource)
     69        return;
     70
     71    const KURL& url = resource->url(); // get before passing PassRefPtr (which sets it to 0)
     72    m_subresources.set(url, resource);
     73}
     74
     75ArchiveResource* ArchiveResourceCollection::archiveResourceForURL(const KURL& url)
     76{
     77    ArchiveResource* resource = m_subresources.get(url).get();
     78    if (!resource)
     79        return 0;
     80       
     81    return resource;
     82}
     83
     84PassRefPtr<Archive> ArchiveResourceCollection::popSubframeArchive(const String& frameName)
     85{
     86    return m_subframes.take(frameName);
     87}
     88
     89}
  • trunk/WebCore/loader/archive/ArchiveResourceCollection.h

    r31258 r31281  
    3030#define ArchiveResourceCollection_h
    3131
    32 // FIXME:  Code will go here!
     32#include "Archive.h"
     33#include "ArchiveResource.h"
     34#include "KURL.h"
     35#include "PlatformString.h"
    3336
    34 #endif // ArchiveResourceCollection
     37#include <wtf/HashMap.h>
     38#include <wtf/RefCounted.h>
     39
     40namespace WebCore {
     41
     42class ArchiveResourceCollection : Noncopyable {
     43public:
     44    ArchiveResourceCollection();
     45
     46    void addResource(PassRefPtr<ArchiveResource>);
     47    void addAllResources(Archive*);
     48   
     49    ArchiveResource* archiveResourceForURL(const KURL&);
     50    PassRefPtr<Archive> popSubframeArchive(const String& frameName);
     51   
     52private:   
     53    HashMap<String, RefPtr<ArchiveResource> > m_subresources;
     54    HashMap<String, RefPtr<Archive> > m_subframes;
     55};
     56
     57}
     58
     59#endif
  • trunk/WebCore/loader/archive/cf/LegacyWebArchive.cpp

    r31258 r31281  
    3030#include "LegacyWebArchive.h"
    3131
    32 // FIXME:  Code will go here!
     32#include "KURL.h"
     33#include "Logging.h"
     34#include "SharedBuffer.h"
     35
     36#include <wtf/RetainPtr.h>
     37
     38namespace WebCore {
     39
     40static const CFStringRef LegacyWebArchiveMainResourceKey = CFSTR("WebMainResource");
     41static const CFStringRef LegacyWebArchiveSubresourcesKey = CFSTR("WebSubresources");
     42static const CFStringRef LegacyWebArchiveSubframeArchivesKey = CFSTR("WebSubframeArchives");
     43static const CFStringRef LegacyWebArchiveResourceDataKey = CFSTR("WebResourceData");
     44static const CFStringRef LegacyWebArchiveResourceFrameNameKey = CFSTR("WebResourceFrameName");
     45static const CFStringRef LegacyWebArchiveResourceMIMETypeKey = CFSTR("WebResourceMIMEType");
     46static const CFStringRef LegacyWebArchiveResourceURLKey = CFSTR("WebResourceURL");
     47static const CFStringRef LegacyWebArchiveResourceTextEncodingNameKey = CFSTR("WebResourceTextEncodingName");
     48static const CFStringRef LegacyWebArchiveResourceResponseKey = CFSTR("WebResourceResponse");
     49static const CFStringRef LegacyWebArchiveResourceResponseVersionKey = CFSTR("WebResourceResponseVersion");
     50
     51static RetainPtr<CFDictionaryRef> createPropertyListRepresentationFromResource(ArchiveResource* resource, bool mainResource)
     52{
     53    if (!resource) {
     54        // The property list representation of a null/empty WebResource has the following 3 objects stored as nil
     55        RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 3, 0, 0));
     56        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceDataKey, 0);
     57        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceURLKey, 0);
     58        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceMIMETypeKey, 0);
     59
     60        return propertyList;
     61    }
     62   
     63    RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 6, 0, &kCFTypeDictionaryValueCallBacks));
     64   
     65    // Resource data can be empty, but must be represented by an empty CFDataRef
     66    SharedBuffer* data = resource->data();
     67    RetainPtr<CFDataRef> cfData;
     68    if (data)
     69        cfData.adoptCF(data->createCFData());
     70    else
     71        cfData.adoptCF(CFDataCreate(0, 0, 0));
     72    CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceDataKey, cfData.get());
     73   
     74    // Resource URL cannot be null
     75    RetainPtr<CFStringRef> cfURL(AdoptCF, resource->url().string().createCFString());
     76    if (cfURL)
     77        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceURLKey, cfURL.get());
     78    else {
     79        LOG(Archives, "LegacyWebArchive - NULL resource URL is invalid - returning null property list");
     80        return 0;
     81    }
     82
     83    // FrameName should be left out if empty for subresources, but always included for main resources
     84    const String& frameName(resource->frameName());
     85    if (!frameName.isEmpty() || mainResource) {
     86        RetainPtr<CFStringRef> cfFrameName(AdoptCF, frameName.createCFString());
     87        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceFrameNameKey, cfFrameName.get());
     88    }
     89   
     90    // Set MIMEType, TextEncodingName, and ResourceResponse only if they actually exist
     91    const String& mimeType(resource->mimeType());
     92    if (!mimeType.isEmpty()) {
     93        RetainPtr<CFStringRef> cfMIMEType(AdoptCF, mimeType.createCFString());
     94        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceMIMETypeKey, cfMIMEType.get());
     95    }
     96   
     97    const String& textEncoding(resource->textEncoding());
     98    if (!textEncoding.isEmpty()) {
     99        RetainPtr<CFStringRef> cfTextEncoding(AdoptCF, textEncoding.createCFString());
     100        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceTextEncodingNameKey, cfTextEncoding.get());
     101    }
     102
     103    // Don't include the resource response for the main resource
     104    if (!mainResource) {
     105        RetainPtr<CFDataRef> resourceResponseData = propertyListDataFromResourceResponse(resource->response());
     106        if (resourceResponseData)
     107            CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceResponseKey, resourceResponseData.get());   
     108    }
     109   
     110    return propertyList;
     111}
     112
     113static RetainPtr<CFDictionaryRef> createPropertyListRep(Archive* archive)
     114{
     115    RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 3, 0, &kCFTypeDictionaryValueCallBacks));
     116   
     117    RetainPtr<CFDictionaryRef> mainResourceDict = createPropertyListRepresentationFromResource(archive->mainResource(), true);
     118    if (!mainResourceDict)
     119        return 0;
     120    CFDictionarySetValue(propertyList.get(), LegacyWebArchiveMainResourceKey, mainResourceDict.get());
     121       
     122    RetainPtr<CFMutableArrayRef> subresourcesArray(AdoptCF, CFArrayCreateMutable(0, archive->subresources().size(), &kCFTypeArrayCallBacks));
     123    const Vector<RefPtr<ArchiveResource> >& subresources(archive->subresources());
     124    for (unsigned i = 0; i < subresources.size(); ++i) {
     125        RetainPtr<CFDictionaryRef> subresource = createPropertyListRepresentationFromResource(subresources[i].get(), false);
     126        if (subresource)
     127            CFArrayAppendValue(subresourcesArray.get(), subresource.get());
     128        else
     129            LOG(Archives, "LegacyWebArchive - Failed to create property list for subresource");
     130    }
     131    if (CFArrayGetCount(subresourcesArray.get()))
     132        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveSubresourcesKey, subresourcesArray.get());
     133
     134    RetainPtr<CFMutableArrayRef> subframesArray(AdoptCF, CFArrayCreateMutable(0, archive->subframeArchives().size(), &kCFTypeArrayCallBacks));
     135    const Vector<RefPtr<Archive> >& subframeArchives(archive->subframeArchives());
     136    for (unsigned i = 0; i < subframeArchives.size(); ++i) {
     137        RetainPtr<CFDictionaryRef> subframeArchive = createPropertyListRep(subframeArchives[i].get());
     138        if (subframeArchive)
     139            CFArrayAppendValue(subframesArray.get(), subframeArchive.get());
     140        else
     141            LOG(Archives, "LegacyWebArchive - Failed to create property list for subframe archive");
     142    }
     143    if (CFArrayGetCount(subframesArray.get()))
     144        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveSubframeArchivesKey, subframesArray.get());
     145
     146    return propertyList;
     147}
     148
     149static ResourceResponse createResourceResponseFromPropertyListData(CFDataRef data, CFStringRef responseDataType)
     150{
     151    ASSERT(data);
     152    if (!data)
     153        return ResourceResponse();
     154   
     155    // If the ResourceResponseVersion (passed in as responseDataType) exists at all, this is a "new" webarchive that we can parse well in a cross platform manner
     156    // If it doesn't exist, we will assume this is an "old" Cocoa-based WebArchive, and parse the ResourceResponse as such
     157    if (!responseDataType)
     158        return createResourceResponseFromMacArchivedData(data);
     159       
     160    // FIXME: Parse the "new" format that the above comment references here
     161    return ResourceResponse();
     162}
     163
     164static PassRefPtr<ArchiveResource> createResource(CFDictionaryRef dictionary)
     165{
     166    ASSERT(dictionary);
     167    if (!dictionary)
     168        return 0;
     169       
     170    CFDataRef resourceData = static_cast<CFDataRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceDataKey));
     171    if (resourceData && CFGetTypeID(resourceData) != CFDataGetTypeID()) {
     172        LOG(Archives, "LegacyWebArchive - Resource data is not of type CFData, cannot create invalid resource");
     173        return 0;
     174    }
     175   
     176    CFStringRef frameName = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceFrameNameKey));
     177    if (frameName && CFGetTypeID(frameName) != CFStringGetTypeID()) {
     178        LOG(Archives, "LegacyWebArchive - Frame name is not of type CFString, cannot create invalid resource");
     179        return 0;
     180    }
     181   
     182    CFStringRef mimeType = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceMIMETypeKey));
     183    if (mimeType && CFGetTypeID(mimeType) != CFStringGetTypeID()) {
     184        LOG(Archives, "LegacyWebArchive - MIME type is not of type CFString, cannot create invalid resource");
     185        return 0;
     186    }
     187   
     188    CFStringRef url = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceURLKey));
     189    if (url && CFGetTypeID(url) != CFStringGetTypeID()) {
     190        LOG(Archives, "LegacyWebArchive - URL is not of type CFString, cannot create invalid resource");
     191        return 0;
     192    }
     193   
     194    CFStringRef textEncoding = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceTextEncodingNameKey));
     195    if (textEncoding && CFGetTypeID(textEncoding) != CFStringGetTypeID()) {
     196        LOG(Archives, "LegacyWebArchive - Text encoding is not of type CFString, cannot create invalid resource");
     197        return 0;
     198    }
     199
     200    ResourceResponse response;
     201   
     202    CFDataRef resourceResponseData = static_cast<CFDataRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceResponseKey));
     203    if (resourceResponseData) {
     204        if (CFGetTypeID(resourceResponseData) != CFDataGetTypeID()) {
     205            LOG(Archives, "LegacyWebArchive - Resource response data is not of type CFData, cannot create invalid resource");
     206            return 0;
     207        }
     208       
     209        CFStringRef resourceResponseVersion = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceResponseVersionKey));
     210        if (resourceResponseVersion && CFGetTypeID(resourceResponseVersion) != CFStringGetTypeID()) {
     211            LOG(Archives, "LegacyWebArchive - Resource response version is not of type CFString, cannot create invalid resource");
     212            return 0;
     213        }
     214       
     215        response = createResourceResponseFromPropertyListData(resourceResponseData, resourceResponseVersion);
     216    }
     217   
     218    return ArchiveResource::create(SharedBuffer::create(CFDataGetBytePtr(resourceData), CFDataGetLength(resourceData)), KURL(url), mimeType, textEncoding, frameName, response);
     219}
     220
     221PassRefPtr<LegacyWebArchive> LegacyWebArchive::create()
     222{
     223    return adoptRef(new LegacyWebArchive);
     224}
     225
     226PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(SharedBuffer* data)
     227{
     228    LOG(Archives, "LegacyWebArchive - Creating from raw data");
     229   
     230    RefPtr<LegacyWebArchive> archive = create();
     231    if (!archive->init(data))
     232        return 0;
     233       
     234    return archive.release();
     235}
     236
     237PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(PassRefPtr<ArchiveResource> mainResource, Vector<PassRefPtr<ArchiveResource> >& subresources, Vector<PassRefPtr<LegacyWebArchive> >& subframeArchives)
     238{
     239    ASSERT(mainResource);
     240    if (!mainResource)
     241        return 0;
     242   
     243    RefPtr<LegacyWebArchive> archive = create();
     244    archive->setMainResource(mainResource);
     245   
     246    for (unsigned i = 0; i < subresources.size(); ++i)
     247        archive->addSubresource(subresources[i]);
     248   
     249    for (unsigned i = 0; i < subframeArchives.size(); ++i)
     250        archive->addSubframeArchive(subframeArchives[i]); 
     251       
     252    return archive.release();
     253}
     254
     255LegacyWebArchive::LegacyWebArchive()
     256{
     257}
     258
     259bool LegacyWebArchive::init(SharedBuffer* data)
     260{
     261    ASSERT(data);
     262    if (!data)
     263        return false;
     264       
     265    RetainPtr<CFDataRef> cfData(AdoptCF, data->createCFData());
     266    if (!cfData)
     267        return false;
     268       
     269    CFStringRef errorString = 0;
     270   
     271    RetainPtr<CFDictionaryRef> plist(AdoptCF, static_cast<CFDictionaryRef>(CFPropertyListCreateFromXMLData(0, cfData.get(), kCFPropertyListImmutable, &errorString)));
     272    if (!plist) {
     273#ifndef NDEBUG
     274        const char* cError = errorString ? CFStringGetCStringPtr(errorString, kCFStringEncodingUTF8) : "unknown error";
     275        LOG(Archives, "LegacyWebArchive - Error parsing PropertyList from archive data - %s", cError);
     276#endif
     277        if (errorString)
     278            CFRelease(errorString);
     279        return false;
     280    }
     281   
     282    if (CFGetTypeID(plist.get()) != CFDictionaryGetTypeID()) {
     283        LOG(Archives, "LegacyWebArchive - Archive property list is not the expected CFDictionary, aborting invalid WebArchive");
     284        return false;
     285    }
     286   
     287    return extract(plist.get());
     288}
     289
     290bool LegacyWebArchive::extract(CFDictionaryRef dictionary)
     291{
     292    ASSERT(dictionary);
     293    if (!dictionary) {
     294        LOG(Archives, "LegacyWebArchive - Null root CFDictionary, aborting invalid WebArchive");
     295        return false;
     296    }
     297   
     298    CFDictionaryRef mainResourceDict = static_cast<CFDictionaryRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveMainResourceKey));
     299    if (!mainResourceDict) {
     300        LOG(Archives, "LegacyWebArchive - No main resource in archive, aborting invalid WebArchive");
     301        return false;
     302    }
     303    if (CFGetTypeID(mainResourceDict) != CFDictionaryGetTypeID()) {
     304        LOG(Archives, "LegacyWebArchive - Main resource is not the expected CFDictionary, aborting invalid WebArchive");
     305        return false;
     306    }
     307   
     308    setMainResource(createResource(mainResourceDict));
     309    if (!mainResource()) {
     310        LOG(Archives, "LegacyWebArchive - Failed to parse main resource from CFDictionary or main resource does not exist, aborting invalid WebArchive");
     311        return false;
     312    }
     313   
     314    CFArrayRef subresourceArray = static_cast<CFArrayRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveSubresourcesKey));
     315    if (subresourceArray && CFGetTypeID(subresourceArray) != CFArrayGetTypeID()) {
     316        LOG(Archives, "LegacyWebArchive - Subresources is not the expected Array, aborting invalid WebArchive");
     317        return false;
     318    }
     319   
     320    if (subresourceArray) {
     321        CFIndex count = CFArrayGetCount(subresourceArray);
     322        for (CFIndex i = 0; i < count; ++i) {
     323            CFDictionaryRef subresourceDict = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(subresourceArray, i));
     324            if (CFGetTypeID(subresourceDict) != CFDictionaryGetTypeID()) {
     325                LOG(Archives, "LegacyWebArchive - Subresource is not expected CFDictionary, aborting invalid WebArchive");
     326                return false;
     327            }
     328            addSubresource(createResource(subresourceDict));
     329        }
     330    }
     331   
     332    CFArrayRef subframeArray = static_cast<CFArrayRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveSubframeArchivesKey));
     333    if (subframeArray && CFGetTypeID(subframeArray) != CFArrayGetTypeID()) {
     334        LOG(Archives, "LegacyWebArchive - Subframe archives is not the expected Array, aborting invalid WebArchive");
     335        return false;
     336    }
     337   
     338    if (subframeArray) {
     339        CFIndex count = CFArrayGetCount(subframeArray);
     340        for (CFIndex i = 0; i < count; ++i) {
     341            CFDictionaryRef subframeDict = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(subframeArray, i));
     342            if (CFGetTypeID(subframeDict) != CFDictionaryGetTypeID()) {
     343                LOG(Archives, "LegacyWebArchive - Subframe array is not expected CFDictionary, aborting invalid WebArchive");
     344                return false;
     345            }
     346           
     347            RefPtr<LegacyWebArchive> subframeArchive = create();
     348            if (subframeArchive->extract(subframeDict))
     349                addSubframeArchive(subframeArchive.release());
     350            else
     351                LOG(Archives, "LegacyWebArchive - Invalid subframe archive skipped");
     352        }
     353    }
     354   
     355    return true;
     356}
     357
     358RetainPtr<CFDataRef> LegacyWebArchive::rawDataRepresentation()
     359{
     360    RetainPtr<CFDictionaryRef> propertyList = createPropertyListRep(this);
     361    if (!propertyList) {
     362        LOG(Archives, "LegacyWebArchive - Failed to create property list for archive, returning no data");
     363        return 0;
     364    }
     365   
     366    // FIXME: On Mac, WebArchives have been written out as Binary Property Lists until this change.
     367    // Unless we jump through CFWriteStream hoops, they'll now be textual XML data.  Is this okay?
     368    RetainPtr<CFDataRef> plistData(AdoptCF, CFPropertyListCreateXMLData(0, propertyList.get()));
     369    if (!plistData) {
     370        LOG(Archives, "LegacyWebArchive - Failed to convert property list into raw data, returning no data");
     371        return 0;
     372    }
     373   
     374    return plistData;
     375}
     376
     377#if !PLATFORM(MAC)
     378// FIXME: Is it possible to parse in a Cocoa-style resource response manually,
     379// without NSKeyed(Un)Archiver, manipulating plists directly?
     380// If so, the code that does it will go here. 
     381// In the meantime, Mac will continue to NSKeyed(Un)Archive the response as it always has
     382ResourceResponse createResourceResponseFromMacArchivedData(CFDataRef responseData)
     383{
     384    return ResourceResponse();
     385}
     386
     387RetainPtr<CFDataRef> propertyListDataFromResourceResponse(const ResourceResponse& response)
     388{
     389    // FIXME: Write out the "new" format described in ::createResourceResponseFromPropertyListData() up above
     390    return 0;
     391}
     392#endif
     393
     394}
  • trunk/WebCore/loader/archive/cf/LegacyWebArchive.h

    r31258 r31281  
    3030#define LegacyWebArchive_h
    3131
    32 // FIXME:  Code will go here!
     32#include "Archive.h"
     33
     34#include <wtf/PassRefPtr.h>
     35
     36namespace WebCore {
     37
     38class LegacyWebArchive : public Archive {
     39public:   
     40    static PassRefPtr<LegacyWebArchive> create();
     41    static PassRefPtr<LegacyWebArchive> create(SharedBuffer*);
     42    static PassRefPtr<LegacyWebArchive> create(PassRefPtr<ArchiveResource> mainResource, Vector<PassRefPtr<ArchiveResource> >& subresources, Vector<PassRefPtr<LegacyWebArchive> >& subframeArchives);
     43
     44    RetainPtr<CFDataRef> rawDataRepresentation();
     45
     46private:
     47    LegacyWebArchive();
     48    bool init(SharedBuffer*);
     49    bool extract(CFDictionaryRef);
     50   
     51};
     52
     53ResourceResponse createResourceResponseFromMacArchivedData(CFDataRef);
     54RetainPtr<CFDataRef> propertyListDataFromResourceResponse(const ResourceResponse&);
     55
     56}
    3357
    3458#endif // Archive
  • trunk/WebCore/loader/archive/cf/LegacyWebArchiveMac.mm

    r31258 r31281  
    3030#include "LegacyWebArchive.h"
    3131
    32 // FIXME:  Code will go here!
     32namespace WebCore {
     33
     34static const NSString *LegacyWebArchiveResourceResponseKey = @"WebResourceResponse";
     35
     36// FIXME: Is it possible to parse in a Cocoa-style resource response manually,
     37// without NSKeyed(Un)Archiver, manipulating plists directly?
     38ResourceResponse createResourceResponseFromMacArchivedData(CFDataRef responseData)
     39{   
     40    ASSERT(responseData);
     41    if (!responseData)
     42        return ResourceResponse();
     43   
     44    NSURLResponse *response;
     45    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:(NSData *)responseData];
     46    @try {
     47        id responseObject = [unarchiver decodeObjectForKey:LegacyWebArchiveResourceResponseKey];
     48        if ([responseObject isKindOfClass:[NSURLResponse class]])
     49            response = responseObject;
     50        [unarchiver finishDecoding];
     51    } @catch(id) {
     52        response = nil;
     53    }
     54    [unarchiver release];
     55   
     56    return ResourceResponse(response);
     57}
     58
     59RetainPtr<CFDataRef> propertyListDataFromResourceResponse(const ResourceResponse& response)
     60{   
     61    NSURLResponse *nsResponse = response.nsURLResponse();
     62    if (!nsResponse)
     63        return 0;
     64       
     65    NSMutableData *responseData = (NSMutableData *)CFDataCreateMutable(0, 0);
     66    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:responseData];
     67    [archiver encodeObject:nsResponse forKey:LegacyWebArchiveResourceResponseKey];
     68    [archiver finishEncoding];
     69    [archiver release];
     70   
     71    return RetainPtr<CFDataRef>(AdoptCF, (CFDataRef)responseData);
     72}
     73
     74}
  • trunk/WebCore/platform/network/mac/ResourceRequest.h

    r30243 r31281  
    6767            , m_nsRequest(nsRequest) { }
    6868       
     69        void applyWebArchiveHackForMail();
    6970        NSURLRequest* nsURLRequest() const;
    7071
  • trunk/WebCore/platform/network/mac/ResourceRequestMac.mm

    r30661 r31281  
    102102}
    103103
     104void ResourceRequest::applyWebArchiveHackForMail()
     105{
     106    // Hack because Mail checks for this property to detect data / archive loads
     107    [NSURLProtocol setProperty:@"" forKey:@"WebDataRequest" inRequest:(NSMutableURLRequest *)nsURLRequest()];
    104108}
     109
     110}
  • trunk/WebKit/ChangeLog

    r31258 r31281  
     12008-03-25  Brady Eidson  <beidson@apple.com>
     2
     3        Reviewed by Darin
     4
     5        <rdar://problem/4516169> - Support WebArchives on Windows
     6
     7        * WebKit.xcodeproj/project.pbxproj:
     8
    192008-03-24  Brady Eidson  <beidson@apple.com>
    210
  • trunk/WebKit/WebKit.xcodeproj/project.pbxproj

    r31258 r31281  
    6464                5DF7B1D10D161FD00062CD32 /* WebNetscapePlugInStreamLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DF7B1CF0D161FCF0062CD32 /* WebNetscapePlugInStreamLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
    6565                5DF7B1D20D161FD00062CD32 /* WebNetscapePlugInStreamLoaderClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5DF7B1D00D161FD00062CD32 /* WebNetscapePlugInStreamLoaderClient.mm */; };
    66                 650F74E409E488F70020118A /* WebUnarchivingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 650F74E209E488F70020118A /* WebUnarchivingState.h */; };
    67                 650F74E509E488F70020118A /* WebUnarchivingState.m in Sources */ = {isa = PBXBuildFile; fileRef = 650F74E309E488F70020118A /* WebUnarchivingState.m */; };
    6866                65488DA1084FBCCB00831AD0 /* WebNSDictionaryExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 65488D9F084FBCCB00831AD0 /* WebNSDictionaryExtras.h */; };
    6967                65488DA2084FBCCB00831AD0 /* WebNSDictionaryExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = 65488DA0084FBCCB00831AD0 /* WebNSDictionaryExtras.m */; };
     
    424422                5DF7B1CF0D161FCF0062CD32 /* WebNetscapePlugInStreamLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebNetscapePlugInStreamLoaderClient.h; sourceTree = "<group>"; };
    425423                5DF7B1D00D161FD00062CD32 /* WebNetscapePlugInStreamLoaderClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebNetscapePlugInStreamLoaderClient.mm; sourceTree = "<group>"; };
    426                 650F74E209E488F70020118A /* WebUnarchivingState.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebUnarchivingState.h; sourceTree = "<group>"; };
    427                 650F74E309E488F70020118A /* WebUnarchivingState.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WebUnarchivingState.m; sourceTree = "<group>"; };
    428424                65488D9F084FBCCB00831AD0 /* WebNSDictionaryExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebNSDictionaryExtras.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
    429425                65488DA0084FBCCB00831AD0 /* WebNSDictionaryExtras.m */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebNSDictionaryExtras.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
     
    977973                                515E27CC0458C86500CA2D3A /* WebUIDelegate.h */,
    978974                                65A7D44A0568AB2600E70EF6 /* WebUIDelegatePrivate.h */,
    979                                 650F74E209E488F70020118A /* WebUnarchivingState.h */,
    980975                                51A8B579042834F700CA2D3A /* WebView.h */,
    981976                                930D02BB06275F640076701E /* WebViewInternal.h */,
     
    994989                                84311A1305EAAAF00088EDA4 /* WebResource.mm */,
    995990                                7E6FEF0608985A7200C44C3F /* WebScriptDebugDelegate.mm */,
    996                                 650F74E309E488F70020118A /* WebUnarchivingState.m */,
    997991                                51A8B57A042834F700CA2D3A /* WebView.mm */,
    998992                        );
     
    13131307                                939810830824BF01008DF038 /* WebUIDelegatePrivate.h in Headers */,
    13141308                                939810150824BF01008DF038 /* WebURLsWithTitles.h in Headers */,
    1315                                 650F74E409E488F70020118A /* WebUnarchivingState.h in Headers */,
    13161309                                939810700824BF01008DF038 /* WebView.h in Headers */,
    13171310                                939810460824BF01008DF038 /* WebViewFactory.h in Headers */,
     
    16031596                                93EB178D09F88D460091F8FF /* WebSystemInterface.m in Sources */,
    16041597                                939810BE0824BF01008DF038 /* WebURLsWithTitles.m in Sources */,
    1605                                 650F74E509E488F70020118A /* WebUnarchivingState.m in Sources */,
    16061598                                939811070824BF01008DF038 /* WebView.mm in Sources */,
    16071599                                939810E80824BF01008DF038 /* WebViewFactory.mm in Sources */,
  • trunk/WebKit/mac/ChangeLog

    r31274 r31281  
     12008-03-25  Brady Eidson  <beidson@apple.com>
     2
     3        Reviewed by Darin
     4
     5        <rdar://problem/4516169> - Support WebArchives on Windows
     6        And paves the way for many future WebArchive bug fixes and enhancements
     7
     8        This change moves most of the real workhorse code about WebArchives into WebCore.  It maintains
     9        1-to-1 relationships between a few objects in WebCore and WebKit.  Such as:
     10         * WebArchive <-> LegacyWebArchive
     11         * WebResource <-> ArchiveResource
     12         * WebUnarchivingState <-> ArchiveResourceCollection
     13 
     14        The other biggest changes involve many FrameLoaderClient methods that existed soley for WebArchives
     15        and now exist in WebCore
     16
     17        * WebCoreSupport/WebFrameLoaderClient.mm:
     18        (WebFrameLoaderClient::clearUnarchivingState): Emptied - to be removed in a followup patch
     19        (WebFrameLoaderClient::finalSetupForReplace):
     20        (WebFrameLoaderClient::setDefersLoading):
     21        (WebFrameLoaderClient::willUseArchive):
     22        (WebFrameLoaderClient::isArchiveLoadPending):
     23        (WebFrameLoaderClient::cancelPendingArchiveLoad):
     24        (WebFrameLoaderClient::clearArchivedResources):
     25        (WebFrameLoaderClient::createFrame):
     26
     27        * WebView/WebArchive.mm:
     28        (+[WebArchivePrivate initialize]):
     29        (-[WebArchivePrivate init]):
     30        (-[WebArchivePrivate initWithCoreArchive:]):
     31        (-[WebArchivePrivate coreArchive]):
     32        (-[WebArchivePrivate setCoreArchive:]):
     33        (-[WebArchivePrivate dealloc]):
     34        (-[WebArchivePrivate finalize]):
     35        (-[WebArchive init]):
     36        (-[WebArchive initWithMainResource:subresources:subframeArchives:]):
     37        (-[WebArchive initWithData:]):
     38        (-[WebArchive initWithCoder:]):
     39        (-[WebArchive encodeWithCoder:]):
     40        (-[WebArchive mainResource]):
     41        (-[WebArchive subresources]):
     42        (-[WebArchive subframeArchives]):
     43        (-[WebArchive data]):
     44        (-[WebArchive _initWithCoreLegacyWebArchive:WebCore::]):
     45        (-[WebArchive WebCore::]):
     46        * WebView/WebArchiveInternal.h: Added.
     47
     48        * WebView/WebDataSource.mm:
     49        (-[WebDataSourcePrivate dealloc]):
     50        (-[WebDataSource _addSubframeArchives:]):
     51        (-[WebDataSource _documentFragmentWithArchive:]):
     52        (-[WebDataSource subresourceForURL:]):
     53        (-[WebDataSource addSubresource:]):
     54        * WebView/WebDataSourceInternal.h:
     55
     56        * WebView/WebFrame.mm:
     57        (-[WebFrame loadArchive:]):
     58        * WebView/WebFrameInternal.h:
     59
     60        * WebView/WebHTMLRepresentation.mm:
     61        (-[WebHTMLRepresentation finishedLoadingWithDataSource:]):
     62
     63        * WebView/WebResource.mm:
     64        (+[WebResourcePrivate initialize]):
     65        (-[WebResourcePrivate init]):
     66        (-[WebResourcePrivate initWithCoreResource:]):
     67        (-[WebResourcePrivate dealloc]):
     68        (-[WebResourcePrivate finalize]):
     69        (-[WebResource initWithCoder:]):
     70        (-[WebResource encodeWithCoder:]):
     71        (-[WebResource data]):
     72        (-[WebResource URL]):
     73        (-[WebResource MIMEType]):
     74        (-[WebResource textEncodingName]):
     75        (-[WebResource frameName]):
     76        (-[WebResource _initWithCoreResource:WebCore::]):
     77        (-[WebResource WebCore::]):
     78        (-[WebResource _ignoreWhenUnarchiving]):
     79        (-[WebResource _initWithData:URL:MIMEType:textEncodingName:frameName:response:copyData:]):
     80        (-[WebResource _fileWrapperRepresentation]):
     81        (-[WebResource _response]):
     82        (-[WebResource _stringValue]):
     83        * WebView/WebResourceInternal.h: Added.
     84        * WebView/WebResourcePrivate.h:
     85
     86        * WebView/WebUnarchivingState.h: Removed.
     87        * WebView/WebUnarchivingState.m: Removed.
     88
    1892008-03-24  Oliver Hunt  <oliver@apple.com>
    290
  • trunk/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm

    r31056 r31281  
    655655void WebFrameLoaderClient::clearUnarchivingState(DocumentLoader* loader)
    656656{
    657     [dataSource(loader) _clearUnarchivingState];
    658657}
    659658
     
    722721void WebFrameLoaderClient::finalSetupForReplace(DocumentLoader* loader)
    723722{
    724     [dataSource(loader) _clearUnarchivingState];
    725723}
    726724
     
    780778void WebFrameLoaderClient::setDefersLoading(bool defers)
    781779{
    782     if (!defers)
    783         deliverArchivedResourcesAfterDelay();
    784780}
    785781
    786782bool WebFrameLoaderClient::willUseArchive(ResourceLoader* loader, const ResourceRequest& request, const KURL& originalURL) const
    787783{
    788     if (request.url() != originalURL)
    789         return false;
    790 
    791     WebResource *resource = [dataSource(core(m_webFrame.get())->loader()->activeDocumentLoader()) _archivedSubresourceForURL:originalURL];
    792     if (!resource)
    793         return false;
    794 
    795     m_pendingArchivedResources.set(loader, resource);
    796     // Deliver the resource after a delay because callers don't expect to receive callbacks while calling this method.
    797     deliverArchivedResourcesAfterDelay();
    798 
    799     return true;
     784    return false;
    800785}
    801786
    802787bool WebFrameLoaderClient::isArchiveLoadPending(ResourceLoader* loader) const
    803788{
    804     return m_pendingArchivedResources.contains(loader);
     789    return false;
    805790}
    806791
    807792void WebFrameLoaderClient::cancelPendingArchiveLoad(ResourceLoader* loader)
    808793{
    809     if (m_pendingArchivedResources.isEmpty())
    810         return;
    811     m_pendingArchivedResources.remove(loader);
    812     if (m_pendingArchivedResources.isEmpty())
    813         m_archivedResourcesDeliveryTimer.stop();
    814794}
    815795
    816796void WebFrameLoaderClient::clearArchivedResources()
    817797{
    818     m_pendingArchivedResources.clear();
    819     m_archivedResourcesDeliveryTimer.stop();
    820798}
    821799
     
    11481126        [[newFrame _dataSource] _documentLoader]->setOverrideEncoding([[m_webFrame.get() _dataSource] _documentLoader]->overrideEncoding()); 
    11491127
    1150     [m_webFrame.get() _loadURL:url referrer:referrer intoChild:newFrame];
     1128    core(m_webFrame.get())->loader()->loadURLIntoChildFrame(url, referrer, newCoreFrame.get());
    11511129
    11521130    // The frame's onload handler may have removed it from the document.
  • trunk/WebKit/mac/WebView/WebArchive.mm

    r31258 r31281  
    2828
    2929#import "WebArchive.h"
     30#import "WebArchiveInternal.h"
    3031
    3132#import "WebKitLogging.h"
     33#import "WebResourceInternal.h"
    3234#import "WebResourcePrivate.h"
    3335#import "WebTypesInternal.h"
     36
     37#import <WebCore/ArchiveResource.h>
     38#import <WebCore/LegacyWebArchive.h>
     39#import <WebCore/WebCoreObjCExtras.h>
     40
     41using namespace WebCore;
    3442
    3543NSString *WebArchivePboardType = @"Apple Web Archive pasteboard type";
     
    4149@interface WebArchivePrivate : NSObject
    4250{
    43     @public
    44     WebResource *mainResource;
    45     NSArray *subresources;
    46     NSArray *subframeArchives;
    47 }
     51@public
     52    WebResource *cachedMainResource;
     53    NSArray *cachedSubresources;
     54    NSArray *cachedSubframeArchives;
     55@private
     56    LegacyWebArchive* coreArchive;
     57}
     58
     59- (id)initWithCoreArchive:(PassRefPtr<LegacyWebArchive>)coreArchive;
     60- (LegacyWebArchive*)coreArchive;
     61- (void)setCoreArchive:(PassRefPtr<LegacyWebArchive>)newCoreArchive;
    4862@end
    4963
    5064@implementation WebArchivePrivate
    5165
     66#ifndef BUILDING_ON_TIGER
     67+ (void)initialize
     68{
     69    WebCoreObjCFinalizeOnMainThread(self);
     70}
     71#endif
     72
     73- (id)init
     74{
     75    self = [super init];
     76    if (self)
     77        coreArchive = LegacyWebArchive::create().releaseRef();
     78    return self;
     79}
     80
     81- (id)initWithCoreArchive:(PassRefPtr<LegacyWebArchive>)_coreArchive
     82{
     83    self = [super init];
     84    if (!self || !_coreArchive) {
     85        [self release];
     86        return nil;
     87    }
     88   
     89    coreArchive = _coreArchive.releaseRef();
     90   
     91    return self;
     92}
     93
     94- (LegacyWebArchive*)coreArchive
     95{
     96    return coreArchive;
     97}
     98
     99- (void)setCoreArchive:(PassRefPtr<LegacyWebArchive>)newCoreArchive
     100{
     101    ASSERT(coreArchive);
     102    ASSERT(newCoreArchive);
     103    coreArchive = newCoreArchive.releaseRef();
     104}
     105
    52106- (void)dealloc
    53107{
    54     [mainResource release];
    55     [subresources release];
    56     [subframeArchives release];
     108    ASSERT(coreArchive);
     109    coreArchive->deref();
     110    coreArchive = 0;
     111   
     112    [cachedMainResource release];
     113    [cachedSubresources release];
     114    [cachedSubframeArchives release];
     115   
    57116    [super dealloc];
    58117}
    59118
     119- (void)finalize
     120{
     121    ASSERT(coreArchive);
     122    coreArchive->deref();
     123    coreArchive = 0;
     124   
     125    [super finalize];
     126}
     127
    60128@end
     129
     130@implementation WebArchive
     131
     132- (id)init
     133{
     134    self = [super init];
     135    if (!self)
     136        return nil;
     137    _private = [[WebArchivePrivate alloc] init];
     138    return self;
     139}
    61140
    62141static BOOL isArrayOfClass(id object, Class elementClass)
     
    72151}
    73152
    74 @implementation WebArchive
    75 
    76 - (id)init
     153- (id)initWithMainResource:(WebResource *)mainResource subresources:(NSArray *)subresources subframeArchives:(NSArray *)subframeArchives
    77154{
    78155    self = [super init];
    79156    if (!self)
    80157        return nil;
     158
    81159    _private = [[WebArchivePrivate alloc] init];
    82     return self;
    83 }
    84 
    85 - (id)initWithMainResource:(WebResource *)mainResource subresources:(NSArray *)subresources subframeArchives:(NSArray *)subframeArchives
    86 {
    87     self = [self init];
     160
     161    _private->cachedMainResource = [mainResource retain];
     162    if (!_private->cachedMainResource) {
     163        [self release];
     164        return nil;
     165    }
     166   
     167    if (!subresources || isArrayOfClass(subresources, [WebResource class]))
     168        _private->cachedSubresources = [subresources retain];
     169    else {
     170        [self release];
     171        return nil;
     172    }
     173
     174    if (!subframeArchives || isArrayOfClass(subframeArchives, [WebArchive class]))
     175        _private->cachedSubframeArchives = [subframeArchives retain];
     176    else {
     177        [self release];
     178        return nil;
     179    }
     180   
     181    RefPtr<ArchiveResource> coreMainResource = mainResource ? [mainResource _coreResource] : 0;
     182
     183    Vector<PassRefPtr<ArchiveResource> > coreResources;
     184    NSEnumerator *enumerator = [subresources objectEnumerator];
     185    WebResource *subresource;
     186    while ((subresource = [enumerator nextObject]) != nil)
     187        coreResources.append([subresource _coreResource]);
     188
     189    Vector<PassRefPtr<LegacyWebArchive> > coreArchives;
     190    enumerator = [subframeArchives objectEnumerator];
     191    WebArchive *subframeArchive;
     192    while ((subframeArchive = [enumerator nextObject]) != nil)
     193        coreArchives.append([subframeArchive->_private coreArchive]);
     194
     195    [_private setCoreArchive:LegacyWebArchive::create(coreMainResource.release(), coreResources, coreArchives)];
     196    if (![_private coreArchive]) {
     197        [self release];
     198        return nil;
     199    }
     200
     201    return self;
     202}
     203
     204- (id)initWithData:(NSData *)data
     205{
     206    self = [super init];
    88207    if (!self)
    89208        return nil;
    90    
    91     _private->mainResource = [mainResource retain];
    92     _private->subresources = [subresources retain];
    93     _private->subframeArchives = [subframeArchives retain];
    94    
    95     if (!_private->mainResource) {
    96         [self release];
    97         return nil;
    98     }
    99    
    100     return self;
    101 }
    102 
    103 - (id)_initWithPropertyList:(id)propertyList
    104 {
    105     self = [self init];
    106     if (!self)
    107         return nil;
    108    
    109     if (![propertyList isKindOfClass:[NSDictionary class]]) {
    110         [self release];
    111         return nil;
    112     }
    113    
    114     _private->mainResource = [[WebResource alloc] _initWithPropertyList:[propertyList objectForKey:WebMainResourceKey]];   
    115     if (!_private->mainResource) {
    116         [self release];
    117         return nil;
    118     }
    119    
    120     _private->subresources = [[WebResource _resourcesFromPropertyLists:[propertyList objectForKey:WebSubresourcesKey]] retain];
    121    
    122     NSEnumerator *enumerator = [[propertyList objectForKey:WebSubframeArchivesKey] objectEnumerator];
    123     NSMutableArray *subframeArchives = [[NSMutableArray alloc] init];
    124     NSDictionary *archivePropertyList;
    125     while ((archivePropertyList = [enumerator nextObject]) != nil) {
    126         WebArchive *archive = [[WebArchive alloc] _initWithPropertyList:archivePropertyList];
    127         if (archive) {
    128             [subframeArchives addObject:archive];
    129             [archive release];
    130         }
    131     }
    132     _private->subframeArchives = subframeArchives;
    133 
    134     return self;
    135 }
    136 
    137 - (id)initWithData:(NSData *)data
    138 {
     209       
    139210#if !LOG_DISABLED
    140211    CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
    141212#endif
    142     NSDictionary *propertyList = [NSPropertyListSerialization propertyListFromData:data
    143                                                                   mutabilityOption:NSPropertyListImmutable
    144                                                                             format:nil
    145                                                                   errorDescription:nil];
     213
     214    _private = [[WebArchivePrivate alloc] init];
     215    [_private setCoreArchive:LegacyWebArchive::create(SharedBuffer::wrapNSData(data).get())];
     216       
    146217#if !LOG_DISABLED
    147218    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();
     
    150221    LOG(Timing, "Parsing web archive with [NSPropertyListSerialization propertyListFromData::::] took %f seconds", duration);
    151222   
    152     return [self _initWithPropertyList:propertyList];
     223    return self;
    153224}
    154225
    155226- (id)initWithCoder:(NSCoder *)decoder
    156227{   
    157     self = [self init];
    158     if (!self)
    159         return nil;
    160 
     228    WebResource *mainResource = nil;
     229    NSArray *subresources = nil;
     230    NSArray *subframeArchives = nil;
     231   
    161232    @try {
    162233        id object = [decoder decodeObjectForKey:WebMainResourceKey];
    163234        if ([object isKindOfClass:[WebResource class]])
    164             _private->mainResource = [object retain];
     235            mainResource = [object retain];
    165236        object = [decoder decodeObjectForKey:WebSubresourcesKey];
    166237        if (isArrayOfClass(object, [WebResource class]))
    167             _private->subresources = [object retain];
     238            subresources = [object retain];
    168239        object = [decoder decodeObjectForKey:WebSubframeArchivesKey];
    169240        if (isArrayOfClass(object, [WebArchive class]))
    170             _private->subframeArchives = [object retain];
     241            subframeArchives = [object retain];
    171242    } @catch(id) {
    172243        [self release];
     
    174245    }
    175246
    176     if (!_private->mainResource) {
    177         [self release];
    178         return nil;
    179     }
    180 
    181     return self;
     247    return [self initWithMainResource:mainResource subresources:subresources subframeArchives:subframeArchives];
    182248}
    183249
    184250- (void)encodeWithCoder:(NSCoder *)encoder
    185251{
    186     [encoder encodeObject:_private->mainResource forKey:WebMainResourceKey];
    187     [encoder encodeObject:_private->subresources forKey:WebSubresourcesKey];
    188     [encoder encodeObject:_private->subframeArchives forKey:WebSubframeArchivesKey];   
     252    [encoder encodeObject:[self mainResource] forKey:WebMainResourceKey];
     253    [encoder encodeObject:[self subresources] forKey:WebSubresourcesKey];
     254    [encoder encodeObject:[self subframeArchives] forKey:WebSubframeArchivesKey];   
    189255}
    190256
     
    202268- (WebResource *)mainResource
    203269{
    204     return [[_private->mainResource retain] autorelease];
     270    // Currently from WebKit API perspective, WebArchives are entirely immutable once created
     271    // If they ever become mutable, we'll need to rethink this.
     272    if (!_private->cachedMainResource) {
     273        LegacyWebArchive* coreArchive = [_private coreArchive];
     274        if (coreArchive)
     275            _private->cachedMainResource = [[WebResource alloc] _initWithCoreResource:coreArchive->mainResource()];
     276    }
     277   
     278    return [[_private->cachedMainResource retain] autorelease];
    205279}
    206280
    207281- (NSArray *)subresources
    208282{
    209     return [[_private->subresources retain] autorelease];
     283    // Currently from WebKit API perspective, WebArchives are entirely immutable once created
     284    // If they ever become mutable, we'll need to rethink this.     
     285    if (!_private->cachedSubresources) {
     286        LegacyWebArchive* coreArchive = [_private coreArchive];
     287        if (!coreArchive)
     288            _private->cachedSubresources = [[NSArray alloc] init];
     289        else {
     290            const Vector<RefPtr<ArchiveResource> >& subresources(coreArchive->subresources());
     291            NSMutableArray *mutableArray = _private->cachedSubresources = [[NSMutableArray alloc] initWithCapacity:subresources.size()];
     292            for (unsigned i = 0; i < subresources.size(); ++i) {
     293                WebResource *resource = [[WebResource alloc] _initWithCoreResource:subresources[i].get()];
     294                [mutableArray addObject:resource];
     295                [resource release];
     296            }
     297        }
     298    }
     299   
     300    return [[_private->cachedSubresources retain] autorelease];
    210301}
    211302
    212303- (NSArray *)subframeArchives
    213304{
    214     return [[_private->subframeArchives retain] autorelease];
    215 }
    216 
    217 - (NSDictionary *)_propertyListRepresentation
    218 {
    219     NSMutableDictionary *propertyList = [NSMutableDictionary dictionary];
    220     if (_private->mainResource) {
    221         [propertyList setObject:[_private->mainResource _propertyListRepresentation] forKey:WebMainResourceKey];
    222     }
    223     NSArray *propertyLists = [WebResource _propertyListsFromResources:_private->subresources];
    224     if ([propertyLists count] > 0) {
    225         [propertyList setObject:propertyLists forKey:WebSubresourcesKey];
    226     }
    227     NSEnumerator *enumerator = [_private->subframeArchives objectEnumerator];
    228     NSMutableArray *subarchivePropertyLists = [[NSMutableArray alloc] init];
    229     WebArchive *archive;
    230     while ((archive = [enumerator nextObject]) != nil) {
    231         [subarchivePropertyLists addObject:[archive _propertyListRepresentation]];
    232     }
    233     if ([subarchivePropertyLists count] > 0) {
    234         [propertyList setObject:subarchivePropertyLists forKey:WebSubframeArchivesKey];
    235     }
    236     [subarchivePropertyLists release];
    237     return propertyList;
     305    // Currently from WebKit API perspective, WebArchives are entirely immutable once created
     306    // If they ever become mutable, we'll need to rethink this. 
     307    if (!_private->cachedSubframeArchives) {
     308        LegacyWebArchive* coreArchive = [_private coreArchive];
     309        if (!coreArchive)
     310            _private->cachedSubframeArchives = [[NSArray alloc] init];
     311        else {
     312            const Vector<RefPtr<Archive> >& subframeArchives(coreArchive->subframeArchives());
     313            NSMutableArray *mutableArray = _private->cachedSubframeArchives = [[NSMutableArray alloc] initWithCapacity:subframeArchives.size()];
     314            for (unsigned i = 0; i < subframeArchives.size(); ++i) {
     315                WebArchive *archive = [[WebArchive alloc] _initWithCoreLegacyWebArchive:(LegacyWebArchive *)subframeArchives[i].get()];
     316                [mutableArray addObject:archive];
     317                [archive release];
     318            }
     319        }
     320    }
     321   
     322    return [[_private->cachedSubframeArchives retain] autorelease];
    238323}
    239324
    240325- (NSData *)data
    241326{
    242     NSDictionary *propertyList = [self _propertyListRepresentation];
    243327#if !LOG_DISABLED
    244328    CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
    245329#endif
    246     NSData *data = [NSPropertyListSerialization dataFromPropertyList:propertyList format:NSPropertyListBinaryFormat_v1_0 errorDescription:nil];
     330
     331    RetainPtr<CFDataRef> data = [_private coreArchive]->rawDataRepresentation();
     332   
    247333#if !LOG_DISABLED
    248334    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();
    249335    CFAbsoluteTime duration = end - start;
    250336#endif
    251     LOG(Timing, "Serializing web archive with [NSPropertyListSerialization dataFromPropertyList:::] took %f seconds", duration);
    252     return data;
     337    LOG(Timing, "Serializing web archive to raw CFPropertyList data took %f seconds", duration);
     338       
     339    return [[(NSData *)data.get() retain] autorelease];
    253340}
    254341
    255342@end
     343
     344@implementation WebArchive (WebInternal)
     345
     346- (id)_initWithCoreLegacyWebArchive:(PassRefPtr<WebCore::LegacyWebArchive>)coreLegacyWebArchive
     347{
     348    self = [super init];
     349    if (!self)
     350        return nil;
     351   
     352    _private = [[WebArchivePrivate alloc] initWithCoreArchive:coreLegacyWebArchive];
     353    if (!_private) {
     354        [self release];
     355        return nil;
     356    }
     357
     358    return self;
     359}
     360
     361- (WebCore::LegacyWebArchive *)_coreLegacyWebArchive
     362{
     363    return [_private coreArchive];
     364}
     365
     366@end
  • trunk/WebKit/mac/WebView/WebDataSource.mm

    r31260 r31281  
    3030
    3131#import "WebArchive.h"
     32#import "WebArchiveInternal.h"
    3233#import "WebArchiver.h"
    3334#import "WebDataSourceInternal.h"
     
    4445#import "WebNSURLRequestExtras.h"
    4546#import "WebPDFRepresentation.h"
     47#import "WebResourceInternal.h"
    4648#import "WebResourceLoadDelegate.h"
    4749#import "WebResourcePrivate.h"
    48 #import "WebUnarchivingState.h"
    4950#import "WebViewInternal.h"
    5051#import <JavaScriptCore/Assertions.h>
    5152#import <WebCore/FrameLoader.h>
    5253#import <WebCore/KURL.h>
     54#import <WebCore/LegacyWebArchive.h>
    5355#import <WebCore/MIMETypeRegistry.h>
    5456#import <WebCore/ResourceRequest.h>
     
    6769    id <WebDocumentRepresentation> representation;
    6870   
    69     WebUnarchivingState *unarchivingState;
    7071    BOOL representationFinishedLoading;
    7172}
     
    8889   
    8990    [representation release];
    90     [unarchivingState release];
    9191
    9292    [super dealloc];
     
    146146- (void)_addSubframeArchives:(NSArray *)subframeArchives
    147147{
     148    // FIXME: This SPI is poor, poor design.  Can we come up with another solution for those who need it?
     149    DocumentLoader* loader = [self _documentLoader];
     150    ASSERT(loader);
     151   
    148152    NSEnumerator *enumerator = [subframeArchives objectEnumerator];
    149153    WebArchive *archive;
    150154    while ((archive = [enumerator nextObject]) != nil)
    151         [self _addToUnarchiveState:archive];
     155        loader->addAllArchiveResources([archive _coreLegacyWebArchive]);
    152156}
    153157
     
    203207        [[self representation] receivedError:error withDataSource:self];
    204208    }
    205 }
    206 
    207 - (void)_clearUnarchivingState
    208 {
    209     [_private->unarchivingState release];
    210     _private->unarchivingState = nil;
    211209}
    212210
     
    239237}
    240238
    241 - (WebResource *)_archivedSubresourceForURL:(NSURL *)URL
    242 {
    243     return [_private->unarchivingState archivedResourceForURL:URL];
    244 }
    245 
    246239- (void)_replaceSelectionWithArchive:(WebArchive *)archive selectReplacement:(BOOL)selectReplacement
    247240{
     
    251244}
    252245
     246// FIXME: There are few reasons why this method and many of its related methods can't be pushed entirely into WebCore in the future.
    253247- (DOMDocumentFragment *)_documentFragmentWithArchive:(WebArchive *)archive
    254248{
     
    260254            NSString *markupString = [[NSString alloc] initWithData:[mainResource data] encoding:NSUTF8StringEncoding];
    261255            // FIXME: seems poor form to do this as a side effect of getting a document fragment
    262             [self _addToUnarchiveState:archive];
     256            if (DocumentLoader* loader = [self _documentLoader])
     257                loader->addAllArchiveResources([archive _coreLegacyWebArchive]);
     258
    263259            DOMDocumentFragment *fragment = [[self webFrame] _documentFragmentWithMarkupString:markupString baseURLString:[[mainResource URL] _web_originalDataAsString]];
    264260            [markupString release];
     
    307303}
    308304
    309 - (WebArchive *)_popSubframeArchiveWithName:(NSString *)frameName
    310 {
    311     return [_private->unarchivingState popSubframeArchiveWithFrameName:frameName];
    312 }
    313 
    314305- (WebView *)_webView
    315306{
     
    335326   
    336327    [_private->representation setDataSource:self];
    337 }
    338 
    339 - (void)_addToUnarchiveState:(WebArchive *)archive
    340 {
    341     if (!_private->unarchivingState)
    342         _private->unarchivingState = [[WebUnarchivingState alloc] init];
    343     [_private->unarchivingState addArchive:archive];
    344328}
    345329
     
    504488    NSData *data;
    505489    NSURLResponse *response;
    506     if (![[self webFrame] _getData:&data andResponse:&response forURL:[URL _web_originalDataAsString]])
    507         return [self _archivedSubresourceForURL:URL];
     490    if (![[self webFrame] _getData:&data andResponse:&response forURL:[URL _web_originalDataAsString]]) {
     491        DocumentLoader* loader = [self _documentLoader];
     492        ArchiveResource* coreResource = loader->archiveResourceForURL(URL);
     493        return coreResource ? [[[WebResource alloc] _initWithCoreResource:coreResource] autorelease] : nil;
     494    }
    508495
    509496    return [[[WebResource alloc] _initWithData:data URL:URL response:response] autorelease];
     
    511498
    512499- (void)addSubresource:(WebResource *)subresource
    513 {
    514     if (subresource) {
    515         if (!_private->unarchivingState)
    516             _private->unarchivingState = [[WebUnarchivingState alloc] init];
    517         [_private->unarchivingState addResource:subresource];
    518     }
    519 }
    520 
    521 @end
     500{   
     501    _private->loader->addArchiveResource([subresource _coreResource]);
     502}
     503
     504@end
  • trunk/WebKit/mac/WebView/WebDataSourceInternal.h

    r31014 r31281  
    4949
    5050@interface WebDataSource (WebInternal)
    51 - (void)_addToUnarchiveState:(WebArchive *)archive;
    5251- (void)_makeRepresentation;
    5352- (BOOL)_isDocumentHTML;
    5453- (WebView *)_webView;
    55 - (WebArchive *)_popSubframeArchiveWithName:(NSString *)frameName;
    5654- (NSURL *)_URL;
    5755- (DOMElement *)_imageElementWithImageResource:(WebResource *)resource;
     
    6058+ (NSMutableDictionary *)_repTypesAllowImageTypeOmission:(BOOL)allowImageTypeOmission;
    6159- (void)_replaceSelectionWithArchive:(WebArchive *)archive selectReplacement:(BOOL)selectReplacement;
    62 - (WebResource *)_archivedSubresourceForURL:(NSURL *)URL;
    6360- (id)_initWithDocumentLoader:(WebDocumentLoaderMac*)loader;
    6461- (void)_finishedLoading;
     
    6663- (void)_revertToProvisionalState;
    6764- (void)_setMainDocumentError:(NSError *)error;
    68 - (void)_clearUnarchivingState;
    6965- (WebCoreDocumentLoader*)_documentLoader;
    7066@end
  • trunk/WebKit/mac/WebView/WebFrame.mm

    r31264 r31281  
    3636#import "DOMNodeInternal.h"
    3737#import "DOMRangeInternal.h"
     38#import "WebArchiveInternal.h"
    3839#import "WebChromeClient.h"
    3940#import "WebDataSourceInternal.h"
     
    6061#import <WebCore/HistoryItem.h>
    6162#import <WebCore/HitTestResult.h>
     63#import <WebCore/LegacyWebArchive.h>
    6264#import <WebCore/Page.h>
    6365#import <WebCore/PluginData.h>
     
    292294{
    293295    return [self _createFrameWithPage:ownerElement->document()->frame()->page() frameName:name frameView:frameView ownerElement:ownerElement];
    294 }
    295 
    296 /*
    297     In the case of saving state about a page with frames, we store a tree of items that mirrors the frame tree. 
    298     The item that was the target of the user's navigation is designated as the "targetItem". 
    299     When this method is called with doClip=YES we're able to create the whole tree except for the target's children,
    300     which will be loaded in the future.  That part of the tree will be filled out as the child loads are committed.
    301 */
    302 
    303 - (void)_loadURL:(NSURL *)URL referrer:(NSString *)referrer intoChild:(WebFrame *)childFrame
    304 {
    305     ASSERT(childFrame);
    306     HistoryItem* parentItem = _private->coreFrame->loader()->currentHistoryItem();
    307     FrameLoadType loadType = _private->coreFrame->loader()->loadType();
    308     FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory;
    309 
    310     // If we're moving in the backforward list, we might want to replace the content
    311     // of this child frame with whatever was there at that point.
    312     // Reload will maintain the frame contents, LoadSame will not.
    313     if (parentItem && parentItem->children().size() &&
    314         (isBackForwardLoadType(loadType)
    315          || loadType == FrameLoadTypeReloadAllowingStaleData))
    316     {
    317         HistoryItem* childItem = parentItem->childItemWithName([childFrame name]);
    318         if (childItem) {
    319             // Use the original URL to ensure we get all the side-effects, such as
    320             // onLoad handlers, of any redirects that happened. An example of where
    321             // this is needed is Radar 3213556.
    322             URL = [NSURL _web_URLWithDataAsString:childItem->originalURLString()];
    323             // These behaviors implied by these loadTypes should apply to the child frames
    324             childLoadType = loadType;
    325 
    326             if (isBackForwardLoadType(loadType)) {
    327                 // For back/forward, remember this item so we can traverse any child items as child frames load
    328                 childFrame->_private->coreFrame->loader()->setProvisionalHistoryItem(childItem);
    329             } else {
    330                 // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item
    331                 childFrame->_private->coreFrame->loader()->setCurrentHistoryItem(childItem);
    332             }
    333         }
    334     }
    335 
    336     WebArchive *archive = [[self _dataSource] _popSubframeArchiveWithName:[childFrame name]];
    337     if (archive)
    338         [childFrame loadArchive:archive];
    339     else
    340         childFrame->_private->coreFrame->loader()->load([URL absoluteURL], referrer, childLoadType, String(), 0, 0);
    341296}
    342297
     
    13121267- (void)loadArchive:(WebArchive *)archive
    13131268{
    1314     WebResource *mainResource = [archive mainResource];
    1315     if (mainResource) {
    1316         SubstituteData substituteData(WebCore::SharedBuffer::wrapNSData([mainResource data]), [mainResource MIMEType], [mainResource textEncodingName], KURL());
    1317         ResourceRequest request([mainResource URL]);
    1318 
    1319         // hack because Mail checks for this property to detect data / archive loads
    1320         [NSURLProtocol setProperty:@"" forKey:@"WebDataRequest" inRequest:(NSMutableURLRequest *)request.nsURLRequest()];
    1321 
    1322         RefPtr<DocumentLoader> documentLoader = _private->coreFrame->loader()->client()->createDocumentLoader(request, substituteData);
    1323 
    1324         [dataSource(documentLoader.get()) _addToUnarchiveState:archive];
    1325 
    1326         _private->coreFrame->loader()->load(documentLoader.get());
    1327     }
     1269    if (LegacyWebArchive* coreArchive = [archive _coreLegacyWebArchive])
     1270        _private->coreFrame->loader()->loadArchive(coreArchive);
    13281271}
    13291272
  • trunk/WebKit/mac/WebView/WebFrameInternal.h

    r31028 r31281  
    130130- (void)_clearSelectionInOtherFrames;
    131131
    132 - (void)_loadURL:(NSURL *)URL referrer:(NSString *)referrer intoChild:(WebFrame *)childFrame;
    133 
    134132- (void)_attachScriptDebugger;
    135133- (void)_detachScriptDebugger;
  • trunk/WebKit/mac/WebView/WebHTMLRepresentation.mm

    r31028 r31281  
    189189}
    190190
    191 - (void)_loadDataSourceAsWebArchive
    192 {
    193     WebArchive *archive = [[WebArchive alloc] initWithData:[_private->dataSource data]];
    194     WebResource *mainResource = [archive mainResource];
    195     if (!mainResource) {
    196         [archive release];
    197         return;
    198     }
    199    
    200     NSData *data = [mainResource data];
    201     [data retain];
    202     [_private->parsedArchiveData release];
    203     _private->parsedArchiveData = data;
    204    
    205     [_private->dataSource _addToUnarchiveState:archive];
    206     [archive release];
    207    
    208     WebFrame *webFrame = [_private->dataSource webFrame];
    209    
    210     if (!webFrame)
    211         return;
    212    
    213     core(webFrame)->loader()->continueLoadWithData(SharedBuffer::wrapNSData(data).get(), [mainResource MIMEType], [mainResource textEncodingName], [mainResource URL]);
    214 }
    215 
    216191- (void)finishedLoadingWithDataSource:(WebDataSource *)dataSource
    217192{
     
    224199
    225200    if (frame) {
    226         if ([self _isDisplayingWebArchive])
    227             [self _loadDataSourceAsWebArchive];
    228         else {
     201        if (![self _isDisplayingWebArchive]) {
    229202            // Telling the frame we received some data and passing nil as the data is our
    230203            // way to get work done that is normally done when the first bit of data is
  • trunk/WebKit/mac/WebView/WebResource.mm

    r31028 r31281  
    3232#import "WebNSDictionaryExtras.h"
    3333#import "WebNSURLExtras.h"
     34
     35#import <WebCore/ArchiveResource.h>
     36#import <WebCore/LegacyWebArchive.h>
    3437#import <WebCore/TextEncoding.h>
     38#import <WebCore/WebCoreObjCExtras.h>
    3539#import <WebCore/WebCoreURLResponse.h>
     40
     41#import <wtf/PassRefPtr.h>
    3642
    3743using namespace WebCore;
     
    4955{
    5056@public
    51     NSData *data;
    52     NSURL *URL;
    53     NSString *frameName;
    54     NSString *MIMEType;
    55     NSString *textEncodingName;
    56     NSURLResponse *response;
    57     BOOL shouldIgnoreWhenUnarchiving;
    58 }
     57    ArchiveResource* coreResource;
     58}
     59
     60- (id)initWithCoreResource:(PassRefPtr<ArchiveResource>)coreResource;
    5961@end
    6062
    6163@implementation WebResourcePrivate
    6264
     65#ifndef BUILDING_ON_TIGER
     66+ (void)initialize
     67{
     68    WebCoreObjCFinalizeOnMainThread(self);
     69}
     70#endif
     71
     72- (id)init
     73{
     74    return [super init];
     75}
     76
     77- (id)initWithCoreResource:(PassRefPtr<ArchiveResource>)passedResource
     78{
     79    self = [super init];
     80    if (!self)
     81        return self;
     82   
     83    // Acquire the PassRefPtr<>'s ref as our own manual ref
     84    coreResource = passedResource.releaseRef();
     85
     86    return self;
     87}
     88
    6389- (void)dealloc
    6490{
    65     [data release];
    66     [URL release];
    67     [frameName release];
    68     [MIMEType release];
    69     [textEncodingName release];
    70     [response release];
     91    if (coreResource)
     92        coreResource->deref();
    7193    [super dealloc];
    7294}
    7395
     96- (void)finalize
     97{
     98    if (coreResource)
     99        coreResource->deref();
     100    [super finalize];
     101}
     102
    74103@end
    75104
     
    92121- (id)initWithCoder:(NSCoder *)decoder
    93122{
    94     self = [self init];
    95     if (!self)
    96         return nil;
    97 
     123    self = [super init];
     124    if (!self)
     125        return nil;
     126
     127    NSData *data = nil;
     128    NSURL *url = nil;
     129    NSString *mimeType = nil, *textEncoding = nil, *frameName = nil;
     130    NSURLResponse *response = nil;
     131   
    98132    @try {
    99133        id object = [decoder decodeObjectForKey:WebResourceDataKey];
    100134        if ([object isKindOfClass:[NSData class]])
    101             _private->data = [object retain];
     135            data = object;
    102136        object = [decoder decodeObjectForKey:WebResourceURLKey];
    103137        if ([object isKindOfClass:[NSURL class]])
    104             _private->URL = [object retain];
     138            url = object;
    105139        object = [decoder decodeObjectForKey:WebResourceMIMETypeKey];
    106140        if ([object isKindOfClass:[NSString class]])
    107             _private->MIMEType = [object retain];
     141            mimeType = object;
    108142        object = [decoder decodeObjectForKey:WebResourceTextEncodingNameKey];
    109143        if ([object isKindOfClass:[NSString class]])
    110             _private->textEncodingName = [object retain];
     144            textEncoding = object;
    111145        object = [decoder decodeObjectForKey:WebResourceFrameNameKey];
    112146        if ([object isKindOfClass:[NSString class]])
    113             _private->frameName = [object retain];
     147            frameName = object;
    114148        object = [decoder decodeObjectForKey:WebResourceResponseKey];
    115149        if ([object isKindOfClass:[NSURLResponse class]])
    116             _private->response = [object retain];
     150            response = object;
    117151    } @catch(id) {
    118152        [self release];
     
    120154    }
    121155
     156    _private = [[WebResourcePrivate alloc] initWithCoreResource:ArchiveResource::create(SharedBuffer::wrapNSData(data), url, mimeType, textEncoding, frameName, response)];
     157
    122158    return self;
    123159}
     
    125161- (void)encodeWithCoder:(NSCoder *)encoder
    126162{
    127     [encoder encodeObject:_private->data forKey:WebResourceDataKey];
    128     [encoder encodeObject:_private->URL forKey:WebResourceURLKey];
    129     [encoder encodeObject:_private->MIMEType forKey:WebResourceMIMETypeKey];
    130     [encoder encodeObject:_private->textEncodingName forKey:WebResourceTextEncodingNameKey];
    131     [encoder encodeObject:_private->frameName forKey:WebResourceFrameNameKey];
    132     [encoder encodeObject:_private->response forKey:WebResourceResponseKey];
     163    ArchiveResource *resource = _private->coreResource;
     164   
     165    NSData *data = nil;
     166    NSURL *url = nil;
     167    NSString *mimeType = nil, *textEncoding = nil, *frameName = nil;
     168    NSURLResponse *response = nil;
     169   
     170    if (resource) {
     171        if (resource->data())
     172            data = [resource->data()->createNSData() autorelease];
     173        url = resource->url();
     174        mimeType = resource->mimeType();
     175        textEncoding = resource->textEncoding();
     176        frameName = resource->frameName();
     177        response = resource->response().nsURLResponse();
     178    }
     179    [encoder encodeObject:data forKey:WebResourceDataKey];
     180    [encoder encodeObject:url forKey:WebResourceURLKey];
     181    [encoder encodeObject:mimeType forKey:WebResourceMIMETypeKey];
     182    [encoder encodeObject:textEncoding forKey:WebResourceTextEncodingNameKey];
     183    [encoder encodeObject:frameName forKey:WebResourceFrameNameKey];
     184    [encoder encodeObject:response forKey:WebResourceResponseKey];
    133185}
    134186
     
    146198- (NSData *)data
    147199{
    148     return _private->data;
     200    return _private->coreResource ? [_private->coreResource->data()->createNSData() autorelease] : 0;
    149201}
    150202
    151203- (NSURL *)URL
    152204{
    153     return _private->URL;
     205    return _private->coreResource ? (NSURL *)_private->coreResource->url() : 0;
    154206}
    155207
    156208- (NSString *)MIMEType
    157209{
    158     return _private->MIMEType;
     210    return _private->coreResource ? (NSString *)_private->coreResource->mimeType() : 0;
    159211}
    160212
    161213- (NSString *)textEncodingName
    162214{
    163     return _private->textEncodingName;
     215    return _private->coreResource ? (NSString *)_private->coreResource->textEncoding() : 0;
    164216}
    165217
    166218- (NSString *)frameName
    167219{
    168     return _private->frameName;
     220    return _private->coreResource ? (NSString *)_private->coreResource->frameName() : 0;
    169221}
    170222
     
    176228@end
    177229
     230@implementation WebResource (WebResourceInternal)
     231
     232- (id)_initWithCoreResource:(WebCore::ArchiveResource *)coreResource
     233{
     234    self = [super init];
     235    if (!self)
     236        return nil;
     237           
     238    _private = [[WebResourcePrivate alloc] initWithCoreResource:coreResource];
     239           
     240    return self;
     241}
     242
     243- (WebCore::ArchiveResource *)_coreResource
     244{
     245    return _private->coreResource;
     246}
     247
     248@end
     249
    178250@implementation WebResource (WebResourcePrivate)
    179251
    180252// SPI for Mail (5066325)
     253// FIXME: This "ignoreWhenUnarchiving" concept is an ugly one - can we find a cleaner solution for those who need this SPI?
    181254- (void)_ignoreWhenUnarchiving
    182255{
    183     _private->shouldIgnoreWhenUnarchiving = YES;
    184 }
    185 
    186 - (BOOL)_shouldIgnoreWhenUnarchiving
    187 {
    188     return _private->shouldIgnoreWhenUnarchiving;
    189 }
    190 
    191 + (NSArray *)_resourcesFromPropertyLists:(NSArray *)propertyLists
    192 {
    193     if (![propertyLists isKindOfClass:[NSArray class]]) {
    194         return nil;
    195     }
    196     NSEnumerator *enumerator = [propertyLists objectEnumerator];
    197     NSMutableArray *resources = [NSMutableArray array];
    198     NSDictionary *propertyList;
    199     while ((propertyList = [enumerator nextObject]) != nil) {
    200         WebResource *resource = [[WebResource alloc] _initWithPropertyList:propertyList];
    201         if (resource) {
    202             [resources addObject:resource];
    203             [resource release];
    204         }
    205     }
    206     return resources;
    207 }
    208 
    209 + (NSArray *)_propertyListsFromResources:(NSArray *)resources
    210 {
    211     NSEnumerator *enumerator = [resources objectEnumerator];
    212     NSMutableArray *propertyLists = [NSMutableArray array];
    213     WebResource *resource;
    214     while ((resource = [enumerator nextObject]) != nil) {
    215         [propertyLists addObject:[resource _propertyListRepresentation]];
    216     }
    217     return propertyLists;
     256    if (_private->coreResource)
     257        _private->coreResource->ignoreWhenUnarchiving();
    218258}
    219259
     
    226266           copyData:(BOOL)copyData
    227267{
    228     [self init];   
    229    
    230     if (!data) {
     268    self = [super init];
     269    if (!self)
     270        return nil;
     271   
     272    if (!data || !URL || !MIMEType) {
    231273        [self release];
    232274        return nil;
    233275    }
    234     _private->data = copyData ? [data copy] : [data retain];
    235    
    236     if (!URL) {
    237         [self release];
    238         return nil;
    239     }
    240     _private->URL = [URL copy];
    241    
    242     if (!MIMEType) {
    243         [self release];
    244         return nil;
    245     }
    246     _private->MIMEType = [MIMEType copy];
    247    
    248     _private->textEncodingName = [textEncodingName copy];
    249     _private->frameName = [frameName copy];
    250     _private->response = [response retain];
    251        
     276           
     277    _private = [[WebResourcePrivate alloc] initWithCoreResource:ArchiveResource::create(SharedBuffer::wrapNSData(copyData ? [[data copy] autorelease] : data), URL, MIMEType, textEncodingName, frameName, response)];
     278           
    252279    return self;
    253280}
     
    266293}
    267294
    268 - (id)_initWithPropertyList:(id)propertyList
    269 {
    270     if (![propertyList isKindOfClass:[NSDictionary class]]) {
    271         [self release];
    272         return nil;
     295- (NSFileWrapper *)_fileWrapperRepresentation
     296{
     297    SharedBuffer* coreData = _private->coreResource ? _private->coreResource->data() : 0;
     298    NSData *data = coreData ? [coreData->createNSData() autorelease] : nil;
     299   
     300    NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:data] autorelease];
     301    NSString *preferredFilename = _private->coreResource ? (NSString *)_private->coreResource->response().suggestedFilename() : nil;
     302    if (!preferredFilename || ![preferredFilename length]) {
     303        NSURL *url = _private->coreResource ? (NSURL *)_private->coreResource->url() : nil;
     304        NSString *mimeType = _private->coreResource ? (NSString *)_private->coreResource->mimeType() : nil;
     305        preferredFilename = [url _webkit_suggestedFilenameWithMIMEType:mimeType];
    273306    }
    274307   
    275     NSURLResponse *response = nil;
    276     NSData *responseData = [propertyList objectForKey:WebResourceResponseKey];
    277     if ([responseData isKindOfClass:[NSData class]]) {
    278         NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:responseData];
    279         @try {
    280             id responseObject = [unarchiver decodeObjectForKey:WebResourceResponseKey];
    281             if ([responseObject isKindOfClass:[NSURLResponse class]])
    282                 response = responseObject;
    283             [unarchiver finishDecoding];
    284         } @catch(id) {
    285             response = nil;
    286         }
    287         [unarchiver release];
    288     }
    289 
    290     NSData *data = [propertyList objectForKey:WebResourceDataKey];
    291     NSString *URLString = [propertyList _webkit_stringForKey:WebResourceURLKey];
    292     return [self _initWithData:[data isKindOfClass:[NSData class]] ? data : nil
    293                            URL:URLString ? [NSURL _web_URLWithDataAsString:URLString] : nil
    294                       MIMEType:[propertyList _webkit_stringForKey:WebResourceMIMETypeKey]
    295               textEncodingName:[propertyList _webkit_stringForKey:WebResourceTextEncodingNameKey]
    296                      frameName:[propertyList _webkit_stringForKey:WebResourceFrameNameKey]
    297                       response:response
    298                       copyData:NO];
    299 }
    300 
    301 - (NSFileWrapper *)_fileWrapperRepresentation
    302 {
    303     NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:_private->data] autorelease];
    304     NSString *preferredFilename = [_private->response suggestedFilename];
    305     if (!preferredFilename || ![preferredFilename length])
    306         preferredFilename = [_private->URL _webkit_suggestedFilenameWithMIMEType:_private->MIMEType];
    307308    [wrapper setPreferredFilename:preferredFilename];
    308309    return wrapper;
    309310}
    310311
    311 - (id)_propertyListRepresentation
    312 {
    313     NSMutableDictionary *propertyList = [NSMutableDictionary dictionary];
    314     [propertyList setObject:_private->data forKey:WebResourceDataKey];
    315     [propertyList setObject:[_private->URL _web_originalDataAsString] forKey:WebResourceURLKey];
    316     [propertyList setObject:_private->MIMEType forKey:WebResourceMIMETypeKey];
    317     if (_private->textEncodingName != nil) {
    318         [propertyList setObject:_private->textEncodingName forKey:WebResourceTextEncodingNameKey];
    319     }
    320     if (_private->frameName != nil) {
    321         [propertyList setObject:_private->frameName forKey:WebResourceFrameNameKey];
    322     }   
    323     if (_private->response != nil) {
    324         NSMutableData *responseData = [[NSMutableData alloc] init];
    325         NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:responseData];
    326         [archiver encodeObject:_private->response forKey:WebResourceResponseKey];
    327         [archiver finishEncoding];
    328         [archiver release];
    329         [propertyList setObject:responseData forKey:WebResourceResponseKey];
    330         [responseData release];
    331     }       
    332     return propertyList;
    333 }
    334 
    335312- (NSURLResponse *)_response
    336313{
    337     if (_private->response != nil) {
    338         return _private->response;
    339     }
    340     return [[[NSURLResponse alloc] initWithURL:_private->URL
    341                                       MIMEType:_private->MIMEType
    342                          expectedContentLength:[_private->data length]
    343                               textEncodingName:_private->textEncodingName] autorelease];
     314    NSURLResponse *response = nil;
     315    if (_private->coreResource)
     316        response = _private->coreResource->response().nsURLResponse();
     317   
     318    return response ? response : [[[NSURLResponse alloc] init] autorelease];       
    344319}
    345320
    346321- (NSString *)_stringValue
    347322{
    348     WebCore::TextEncoding encoding(_private->textEncodingName);
     323    WebCore::TextEncoding encoding(_private->coreResource ? (NSString *)_private->coreResource->textEncoding() : nil);
    349324    if (!encoding.isValid())
    350325        encoding = WindowsLatin1Encoding();
    351     return encoding.decode(reinterpret_cast<const char*>([_private->data bytes]), [_private->data length]);
    352 }
    353 
    354 @end
     326   
     327    SharedBuffer* coreData = _private->coreResource ? _private->coreResource->data() : 0;
     328   
     329    return encoding.decode(reinterpret_cast<const char*>(coreData ? coreData->data() : 0), coreData ? coreData->size() : 0);
     330}
     331
     332@end
  • trunk/WebKit/mac/WebView/WebResourcePrivate.h

    r30323 r31281  
    4141- (id)_initWithData:(NSData *)data URL:(NSURL *)URL response:(NSURLResponse *)response;
    4242
    43 - (BOOL)_shouldIgnoreWhenUnarchiving;
    4443- (void)_ignoreWhenUnarchiving;
    4544
    46 + (NSArray *)_resourcesFromPropertyLists:(NSArray *)propertyLists;
    47 + (NSArray *)_propertyListsFromResources:(NSArray *)resources;
    48 
    49 - (id)_initWithPropertyList:(id)propertyList;
    50 
    5145- (NSFileWrapper *)_fileWrapperRepresentation;
    52 - (id)_propertyListRepresentation;
    5346- (NSURLResponse *)_response;
    5447- (NSString *)_stringValue;
Note: See TracChangeset for help on using the changeset viewer.