Changeset 18541 in webkit


Ignore:
Timestamp:
Jan 2, 2007 7:11:18 PM (17 years ago)
Author:
beidson
Message:

WebCore:

Reviewed extensively and repeatedly by Darin

<rdar://problem/4887137> - WebCore Back/Forward Cache

  • WebCore.exp:
  • WebCore.xcodeproj/project.pbxproj:
  • bridge/mac/WebCorePageState.h: Removed.
  • bridge/mac/WebCorePageState.mm: Removed.
  • history/BackForwardList.cpp: Added - This largely emulates the design of WebBackForwardList (WebCore::BackForwardList::BackForwardList): (WebCore::BackForwardList::~BackForwardList): (WebCore::BackForwardList::addItem): (WebCore::BackForwardList::goBack): (WebCore::BackForwardList::goForward): (WebCore::BackForwardList::goToItem): (WebCore::BackForwardList::backItem): (WebCore::BackForwardList::currentItem): (WebCore::BackForwardList::forwardItem): (WebCore::BackForwardList::backListWithLimit): (WebCore::BackForwardList::forwardListWithLimit): (WebCore::BackForwardList::capacity): (WebCore::BackForwardList::setCapacity): (WebCore::BackForwardList::setPageCacheSize): (WebCore::BackForwardList::pageCacheSize): (WebCore::BackForwardList::clearPageCache): (WebCore::BackForwardList::usesPageCache): (WebCore::BackForwardList::backListCount): (WebCore::BackForwardList::forwardListCount): (WebCore::BackForwardList::itemAtIndex): (WebCore::BackForwardList::entries): (WebCore::BackForwardList::close): (WebCore::BackForwardList::closed): (WebCore::BackForwardList::removeItem): (WebCore::BackForwardList::containsItem): (WebCore::BackForwardList::setDefaultPageCacheSize): (WebCore::BackForwardList::defaultPageCacheSize):
  • history/BackForwardList.h: Added.
  • history/HistoryItem.cpp: Added - This largely emulates the design of WebBackForwardList (WebCore::defaultNotifyHistoryItemChanged): (WebCore::HistoryItem::HistoryItem): (WebCore::HistoryItem::~HistoryItem): (WebCore::HistoryItem::copy): (WebCore::HistoryItem::setHasPageCache): (WebCore::HistoryItem::retainIconInDatabase): (WebCore::HistoryItem::urlString): (WebCore::HistoryItem::originalURLString): (WebCore::HistoryItem::title): (WebCore::HistoryItem::alternateTitle): (WebCore::HistoryItem::icon): (WebCore::HistoryItem::lastVisitedTime): (WebCore::HistoryItem::url): (WebCore::HistoryItem::originalURL): (WebCore::HistoryItem::target): (WebCore::HistoryItem::parent): (WebCore::HistoryItem::setAlternateTitle): (WebCore::HistoryItem::setURLString): (WebCore::HistoryItem::setURL): (WebCore::HistoryItem::setOriginalURLString): (WebCore::HistoryItem::setTitle): (WebCore::HistoryItem::setTarget): (WebCore::HistoryItem::setParent): (WebCore::HistoryItem::setLastVisitedTime): (WebCore::HistoryItem::visitCount): (WebCore::HistoryItem::setVisitCount): (WebCore::HistoryItem::scrollPoint): (WebCore::HistoryItem::setScrollPoint): (WebCore::HistoryItem::clearScrollPoint): (WebCore::HistoryItem::setDocumentState): (WebCore::HistoryItem::documentState): (WebCore::HistoryItem::clearDocumentState): (WebCore::HistoryItem::isTargetItem): (WebCore::HistoryItem::setIsTargetItem): (WebCore::HistoryItem::alwaysAttemptToUsePageCache): (WebCore::HistoryItem::setAlwaysAttemptToUsePageCache): (WebCore::HistoryItem::addChildItem): (WebCore::HistoryItem::childItemWithName): (WebCore::HistoryItem::recurseToFindTargetItem): (WebCore::HistoryItem::targetItem): (WebCore::HistoryItem::pageCache): (WebCore::HistoryItem::children): (WebCore::HistoryItem::hasChildren): (WebCore::HistoryItem::formContentType): (WebCore::HistoryItem::formReferrer): (WebCore::HistoryItem::rssFeedReferrer): (WebCore::HistoryItem::setRSSFeedReferrer): (WebCore::HistoryItem::setFormInfoFromRequest): (WebCore::HistoryItem::formData): (WebCore::HistoryItem::mergeAutoCompleteHints): (WebCore::HistoryItem::hasPageCache): (WebCore::timer): Function to manage the global release timer (WebCore::pendingPageCacheToRelease): Function to manage the global queue of caches to be released (WebCore::HistoryItem::releasePageCache): (WebCore::closeObjectsInPendingPageCaches): (WebCore::HistoryItem::releaseAllPendingPageCaches): (WebCore::HistoryItem::scheduleRelease): (WebCore::HistoryItem::print):
  • history/HistoryItem.h: Added.
  • history/mac/HistoryItemMac.mm: Added. (WebCore::HistoryItem::viewState): In the future we need a platform agnostic way to manage the view state (WebCore::HistoryItem::setViewState): (WebCore::HistoryItem::getTransientProperty): Transient properties are, for now, only a Mac concept (WebCore::HistoryItem::setTransientProperty):
  • history/HistoryItemTimer.cpp: Added (WebCore::HistoryItemTimer::HistoryItemTimer): We need a specific class to be the history item timer because WebCore::Timers only work when you have an instance of an object, but the caches pending release is a static concept (WebCore::HistoryItemTimer::isActive): (WebCore::HistoryItemTimer::schedule): (WebCore::HistoryItemTimer::invalidate): (WebCore::HistoryItemTimer::callReleasePageCache):
  • history/HistoryItemTimer.h: Added.
  • history/PageCache.cpp Added - This is a class that contains the fields that used to be in an NSDictionary in WebKit (WebCore::PageCache::PageCache): (WebCore::PageCache::setPageState): (WebCore::PageCache::~PageCache): (WebCore::PageCache::pageState): (WebCore::PageCache::setDocumentLoader): (WebCore::PageCache::documentLoader): (WebCore::PageCache::setTimeStamp): (WebCore::PageCache::setTimeStampToNow): (WebCore::PageCache::timeStamp):
  • history/PageCache.h: Added.
  • history/mac/PageCacheMac.mm: Added. (WebCore::PageCache::close): (WebCore::PageCache::setDocumentView): In the future we need a platform agnostic way to manage the documentView (WebCore::PageCache::documentView):
  • loader/DocumentLoader.cpp: (WebCore::DocumentLoader::loadFromPageCache): (WebCore::DocumentLoader::setLoadingFromPageCache): (WebCore::DocumentLoader::isLoadingFromPageCache): (WebCore::DocumentLoader::originalURL): (WebCore::DocumentLoader::requestURL): (WebCore::DocumentLoader::responseURL): (WebCore::DocumentLoader::responseMIMEType):
  • loader/DocumentLoader.h:
  • loader/FrameLoader.cpp: Responsibilities previously scattered in WebKit but concentrated in WebView and WebFrame are now here, where they should be. (WebCore::FrameLoader::clear): (WebCore::FrameLoader::restoreDocumentState): (WebCore::FrameLoader::goBackOrForward): (WebCore::FrameLoader::provisionalLoadStarted): (WebCore::FrameLoader::canCachePage): (WebCore::FrameLoader::commitProvisionalLoad): (WebCore::FrameLoader::transitionToCommitted): (WebCore::FrameLoader::open): (WebCore::FrameLoader::didFirstLayout): (WebCore::FrameLoader::dispatchDidChangeLocationWithinPage): (WebCore::FrameLoader::dispatchDidFinishLoadToClient): (WebCore::FrameLoader::updateGlobalHistoryForStandardLoad): Marked for usage in future GlobalHistory (uses client for now) (WebCore::FrameLoader::updateGlobalHistoryForReload): Ditto (WebCore::FrameLoader::shouldGoToHistoryItem): (WebCore::FrameLoader::addExtraFieldsToRequest): (WebCore::FrameLoader::addHistoryItemForFragmentScroll): (WebCore::FrameLoader::loadProvisionalItemFromPageCache): (WebCore::FrameLoader::createPageCache): (WebCore::FrameLoader::shouldTreatURLAsSameAsCurrent): (WebCore::FrameLoader::createItem): (WebCore::FrameLoader::addBackForwardItemClippedAtTarget): (WebCore::FrameLoader::createItemTree): (WebCore::FrameLoader::saveScrollPositionAndViewStateToItem): (WebCore::FrameLoader::restoreScrollPositionAndViewState): (WebCore::FrameLoader::purgePageCache): (WebCore::FrameLoader::invalidateCurrentItemPageCache): (WebCore::FrameLoader::saveDocumentState): (WebCore::FrameLoader::loadItem): (WebCore::FrameLoader::urlsMatchItem): (WebCore::FrameLoader::goToItem): (WebCore::FrameLoader::recursiveGoToItem): (WebCore::FrameLoader::childFramesMatchItem): (WebCore::FrameLoader::updateHistoryForStandardLoad): (WebCore::FrameLoader::updateHistoryForClientRedirect): (WebCore::FrameLoader::updateHistoryForBackForwardNavigation): (WebCore::FrameLoader::updateHistoryForReload): (WebCore::FrameLoader::updateHistoryForInternalLoad): (WebCore::FrameLoader::updateHistoryForCommit): (WebCore::FrameLoader::saveDocumentAndScrollState): (WebCore::FrameLoader::currentHistoryItem): (WebCore::FrameLoader::previousHistoryItem): (WebCore::FrameLoader::provisionalHistoryItem): (WebCore::FrameLoader::setCurrentHistoryItem): (WebCore::FrameLoader::setPreviousHistoryItem): (WebCore::FrameLoader::setProvisionalHistoryItem):
  • loader/FrameLoader.h:
  • loader/FrameLoaderClient.h:
  • loader/mac/DocumentLoaderMac.mm: (WebCore::DocumentLoader::DocumentLoader): (WebCore::DocumentLoader::getResponseRefreshAndModifiedHeaders): (WebCore::DocumentLoader::commitIfReady): (WebCore::DocumentLoader::urlForHistory):
  • loader/mac/FrameLoaderMac.mm: (WebCore::FrameLoader::load): (WebCore::FrameLoader::startLoading): (WebCore::FrameLoader::receivedMainResourceError): (WebCore::FrameLoader::continueFragmentScrollAfterNavigationPolicy): (WebCore::FrameLoader::opened): (WebCore::FrameLoader::dataURLBaseFromRequest): (WebCore::FrameLoader::didChangeTitle): (WebCore::FrameLoader::continueLoadAfterNavigationPolicy): (WebCore::FrameLoader::checkLoadCompleteForThisFrame):
  • page/FrameTree.cpp: (WebCore::FrameTree::removeChild):
  • page/Page.cpp: Transfered a handful of concepts from WebView (WebCore::Page::Page): (WebCore::Page::~Page): (WebCore::Page::backForwardList): (WebCore::Page::goBack): (WebCore::Page::goForward): (WebCore::Page::goToItem):
  • page/Page.h:
  • page/PageState.h:
  • page/mac/FrameMac.h:
  • page/mac/FrameMac.mm:
  • page/mac/WebCoreFrameBridge.h:
  • page/mac/WebCoreFrameBridge.mm:
  • platform/KURL.cpp: (WebCore::KURL::print): Added debug only method for debugging convenience
  • platform/KURL.h:
  • platform/Logging.cpp: (WebCore::): Added some logging channels
  • platform/Logging.h:
  • platform/PlatformString.h: (WebCore::nsStringNilIfEmpty): Added for WebKit use
  • platform/SystemTime.h: Added userIdleTime()
  • platform/graphics/svg/SVGImage.cpp:
  • platform/graphics/svg/SVGImageEmptyClients.h: Updated for new FrameLoaderClient methods (WebCore::SVGEmptyFrameLoaderClient::setDocumentViewFromPageCache): (WebCore::SVGEmptyFrameLoaderClient::updateGlobalHistoryForStandardLoad): (WebCore::SVGEmptyFrameLoaderClient::updateGlobalHistoryForReload): (WebCore::SVGEmptyFrameLoaderClient::shouldGoToHistoryItem): (WebCore::SVGEmptyFrameLoaderClient::saveScrollPositionAndViewStateToItem): (WebCore::SVGEmptyFrameLoaderClient::saveDocumentViewToPageCache): (WebCore::SVGEmptyFrameLoaderClient::canCachePage): (WebCore::SVGEmptyEditorClient::~SVGEmptyEditorClient):
  • platform/mac/LoggingMac.mm: (WebCore::InitializeLoggingChannelsIfNecessary):
  • platform/mac/SystemTimeMac.cpp: (WebCore::userIdleTime):
  • platform/mac/WebCoreSystemInterface.h: Added wkSecondsSinceLastInput for use in userIdleTime
  • platform/mac/WebCoreSystemInterface.mm:
  • platform/network/FormData.cpp: (WebCore::FormData::FormData): (WebCore::FormData::copy):
  • platform/network/FormData.h:
  • platform/network/ResourceHandle.h:
  • platform/network/mac/ResourceHandleMac.mm: (WebCore::ResourceHandle::willLoadFromCache): For "are you sure you want to resubmit?" nag
  • platform/qt/TemporaryLinkStubs.cpp: (WebCore::userIdleTime):
  • rendering/RenderPart.h:

WebKit:

Reviewed extensively and repeatedly by Darin

<rdar://problem/4887137> - WebCore Back/Forward Cache
Most things not specifically commented on in the ChangeLog can be summed up as
"Do things exactly the same way as we used to, but just stick in WebCore-land as much as possible"

  • History/WebBackForwardList.mm: (kitPrivate): Convenience functions to help with subbing "WebBackForwardListPrivate" for WebCore::BackForwardList (core): (backForwardListWrappers): A HashMap pattern used to map WebCore objects to their WebKit counterpart (kit): (+[WebBackForwardList setDefaultPageCacheSizeIfNecessary]): (-[WebBackForwardList initWithWebCoreBackForwardList:]): (-[WebBackForwardList init]): (-[WebBackForwardList dealloc]): (-[WebBackForwardList finalize]): (-[WebBackForwardList _close]): (-[WebBackForwardList addItem:]): (-[WebBackForwardList removeItem:]): (-[WebBackForwardList containsItem:]): (-[WebBackForwardList goBack]): (-[WebBackForwardList goForward]): (-[WebBackForwardList goToItem:]): (-[WebBackForwardList backItem]): (-[WebBackForwardList currentItem]): (-[WebBackForwardList forwardItem]): (vectorToNSArray): (-[WebBackForwardList backListWithLimit:]): (-[WebBackForwardList forwardListWithLimit:]): (-[WebBackForwardList capacity]): (-[WebBackForwardList setCapacity:]): (-[WebBackForwardList description]): (-[WebBackForwardList _clearPageCache]): (-[WebBackForwardList setPageCacheSize:]): (-[WebBackForwardList pageCacheSize]): (-[WebBackForwardList _usesPageCache]): (-[WebBackForwardList backListCount]): (-[WebBackForwardList forwardListCount]): (-[WebBackForwardList itemAtIndex:]):
  • History/WebBackForwardListInternal.h: Added.
  • History/WebHistory.m: Removed.
  • History/WebHistory.mm: Added - Needed to be .mm to accept C++ header style (-[_WebCoreHistoryProvider containsItemForURLLatin1:length:]): (-[_WebCoreHistoryProvider containsItemForURLUnicode:length:]):
  • History/WebHistoryItem.mm: (kitPrivate): Same pattern as WebBackForwardList (core): (historyItemWrappers): (WKNotifyHistoryItemChanged): (-[WebHistoryItem init]): (-[WebHistoryItem initWithURLString:title:lastVisitedTimeInterval:]): (-[WebHistoryItem dealloc]): (-[WebHistoryItem finalize]): (-[WebHistoryItem copyWithZone:]): (-[WebHistoryItem URLString]): (-[WebHistoryItem originalURLString]): (-[WebHistoryItem title]): (-[WebHistoryItem setAlternateTitle:]): (-[WebHistoryItem alternateTitle]): (-[WebHistoryItem icon]): (-[WebHistoryItem lastVisitedTimeInterval]): (-[WebHistoryItem hash]): (-[WebHistoryItem isEqual:]): (-[WebHistoryItem description]): (kit): (+[WebHistoryItem entryWithURL:]): (+[WebHistoryItem initWindowWatcherIfNecessary]): (-[WebHistoryItem initWithURL:target:parent:title:]): (-[WebHistoryItem initWithWebCoreHistoryItem:]): (-[WebHistoryItem setTitle:]): (-[WebHistoryItem setVisitCount:]): (-[WebHistoryItem setViewState:]): (-[WebHistoryItem _mergeAutoCompleteHints:]): (-[WebHistoryItem initFromDictionaryRepresentation:]): (-[WebHistoryItem scrollPoint]): (-[WebHistoryItem _transientPropertyForKey:]): (-[WebHistoryItem _setTransientProperty:forKey:]): (-[WebHistoryItem dictionaryRepresentation]): (-[WebHistoryItem target]): (-[WebHistoryItem isTargetItem]): (-[WebHistoryItem visitCount]): (-[WebHistoryItem RSSFeedReferrer]): (-[WebHistoryItem setRSSFeedReferrer:]): (-[WebHistoryItem children]): (-[WebHistoryItem setAlwaysAttemptToUsePageCache:]): (-[WebHistoryItem URL]): (-[WebHistoryItem _setLastVisitedTimeInterval:]): (-[WebHistoryItem _lastVisitedDate]): (-[WebHistoryItem targetItem]): (+[WebHistoryItem _releaseAllPendingPageCaches]): (-[WebWindowWatcher windowWillClose:]):
  • History/WebHistoryItemInternal.h:
  • History/WebHistoryItemPrivate.h:
  • WebCoreSupport/WebFrameBridge.mm:
  • WebCoreSupport/WebFrameLoaderClient.h:
  • WebCoreSupport/WebFrameLoaderClient.mm: (WebFrameLoaderClient::setDocumentViewFromPageCache): (WebFrameLoaderClient::detachedFromParent1): (WebFrameLoaderClient::loadedFromPageCache): (WebFrameLoaderClient::updateGlobalHistoryForStandardLoad): (WebFrameLoaderClient::updateGlobalHistoryForReload): (WebFrameLoaderClient::shouldGoToHistoryItem): (WebFrameLoaderClient::frameLoadCompleted): (WebFrameLoaderClient::saveScrollPositionAndViewStateToItem): (WebFrameLoaderClient::restoreScrollPositionAndViewState): (WebFrameLoaderClient::provisionalLoadStarted): (WebFrameLoaderClient::setTitle): (WebFrameLoaderClient::saveDocumentViewToPageCache): (WebFrameLoaderClient::canCachePage):
  • WebCoreSupport/WebSystemInterface.m: (InitWebCoreSystemInterface):
  • WebKit.xcodeproj/project.pbxproj:
  • WebView/WebDataSource.mm:
  • WebView/WebDataSourceInternal.h:
  • WebView/WebFrame.mm: (-[WebFramePrivate dealloc]): (-[WebFrame _canCachePage]): (-[WebFrame _loadURL:referrer:intoChild:]):
  • WebView/WebFrameInternal.h:
  • WebView/WebFrameView.mm: (-[WebFrameView initWithFrame:]): (-[WebFrameView keyDown:]):
  • WebView/WebHTMLView.m: (-[WebHTMLView closeIfNotCurrentView]): Added for a dirty hack in WebCore that is marked with a FIXME Radar
  • WebView/WebHTMLViewInternal.h:
  • WebView/WebView.mm: (-[WebViewPrivate init]): (-[WebViewPrivate dealloc]): (-[WebView _close]): (-[WebView _loadBackForwardListFromOtherView:]): (-[WebView _commonInitializationWithFrameName:groupName:]): (-[WebView initWithCoder:]): (-[WebView backForwardList]): (-[WebView goBack]): (-[WebView goForward]): (-[WebView goToBackForwardItem:]): (-[WebView canGoBack]): (-[WebView canGoForward]):
Location:
trunk
Files:
13 added
2 deleted
54 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r18534 r18541  
     12007-01-02  Brady Eidson  <beidson@apple.com>
     2
     3        Reviewed extensively and repeatedly by Darin
     4
     5        <rdar://problem/4887137> - WebCore Back/Forward Cache
     6
     7        * WebCore.exp:
     8        * WebCore.xcodeproj/project.pbxproj:
     9
     10        * bridge/mac/WebCorePageState.h: Removed.
     11        * bridge/mac/WebCorePageState.mm: Removed.
     12
     13        * history/BackForwardList.cpp: Added - This largely emulates the design of WebBackForwardList
     14        (WebCore::BackForwardList::BackForwardList):
     15        (WebCore::BackForwardList::~BackForwardList):
     16        (WebCore::BackForwardList::addItem):
     17        (WebCore::BackForwardList::goBack):
     18        (WebCore::BackForwardList::goForward):
     19        (WebCore::BackForwardList::goToItem):
     20        (WebCore::BackForwardList::backItem):
     21        (WebCore::BackForwardList::currentItem):
     22        (WebCore::BackForwardList::forwardItem):
     23        (WebCore::BackForwardList::backListWithLimit):
     24        (WebCore::BackForwardList::forwardListWithLimit):
     25        (WebCore::BackForwardList::capacity):
     26        (WebCore::BackForwardList::setCapacity):
     27        (WebCore::BackForwardList::setPageCacheSize):
     28        (WebCore::BackForwardList::pageCacheSize):
     29        (WebCore::BackForwardList::clearPageCache):
     30        (WebCore::BackForwardList::usesPageCache):
     31        (WebCore::BackForwardList::backListCount):
     32        (WebCore::BackForwardList::forwardListCount):
     33        (WebCore::BackForwardList::itemAtIndex):
     34        (WebCore::BackForwardList::entries):
     35        (WebCore::BackForwardList::close):
     36        (WebCore::BackForwardList::closed):
     37        (WebCore::BackForwardList::removeItem):
     38        (WebCore::BackForwardList::containsItem):
     39        (WebCore::BackForwardList::setDefaultPageCacheSize):
     40        (WebCore::BackForwardList::defaultPageCacheSize):
     41        * history/BackForwardList.h: Added.
     42
     43        * history/HistoryItem.cpp: Added - This largely emulates the design of WebBackForwardList
     44        (WebCore::defaultNotifyHistoryItemChanged):
     45        (WebCore::HistoryItem::HistoryItem):
     46        (WebCore::HistoryItem::~HistoryItem):
     47        (WebCore::HistoryItem::copy):
     48        (WebCore::HistoryItem::setHasPageCache):
     49        (WebCore::HistoryItem::retainIconInDatabase):
     50        (WebCore::HistoryItem::urlString):
     51        (WebCore::HistoryItem::originalURLString):
     52        (WebCore::HistoryItem::title):
     53        (WebCore::HistoryItem::alternateTitle):
     54        (WebCore::HistoryItem::icon):
     55        (WebCore::HistoryItem::lastVisitedTime):
     56        (WebCore::HistoryItem::url):
     57        (WebCore::HistoryItem::originalURL):
     58        (WebCore::HistoryItem::target):
     59        (WebCore::HistoryItem::parent):
     60        (WebCore::HistoryItem::setAlternateTitle):
     61        (WebCore::HistoryItem::setURLString):
     62        (WebCore::HistoryItem::setURL):
     63        (WebCore::HistoryItem::setOriginalURLString):
     64        (WebCore::HistoryItem::setTitle):
     65        (WebCore::HistoryItem::setTarget):
     66        (WebCore::HistoryItem::setParent):
     67        (WebCore::HistoryItem::setLastVisitedTime):
     68        (WebCore::HistoryItem::visitCount):
     69        (WebCore::HistoryItem::setVisitCount):
     70        (WebCore::HistoryItem::scrollPoint):
     71        (WebCore::HistoryItem::setScrollPoint):
     72        (WebCore::HistoryItem::clearScrollPoint):
     73        (WebCore::HistoryItem::setDocumentState):
     74        (WebCore::HistoryItem::documentState):
     75        (WebCore::HistoryItem::clearDocumentState):
     76        (WebCore::HistoryItem::isTargetItem):
     77        (WebCore::HistoryItem::setIsTargetItem):
     78        (WebCore::HistoryItem::alwaysAttemptToUsePageCache):
     79        (WebCore::HistoryItem::setAlwaysAttemptToUsePageCache):
     80        (WebCore::HistoryItem::addChildItem):
     81        (WebCore::HistoryItem::childItemWithName):
     82        (WebCore::HistoryItem::recurseToFindTargetItem):
     83        (WebCore::HistoryItem::targetItem):
     84        (WebCore::HistoryItem::pageCache):
     85        (WebCore::HistoryItem::children):
     86        (WebCore::HistoryItem::hasChildren):
     87        (WebCore::HistoryItem::formContentType):
     88        (WebCore::HistoryItem::formReferrer):
     89        (WebCore::HistoryItem::rssFeedReferrer):
     90        (WebCore::HistoryItem::setRSSFeedReferrer):
     91        (WebCore::HistoryItem::setFormInfoFromRequest):
     92        (WebCore::HistoryItem::formData):
     93        (WebCore::HistoryItem::mergeAutoCompleteHints):
     94        (WebCore::HistoryItem::hasPageCache):
     95        (WebCore::timer): Function to manage the global release timer
     96        (WebCore::pendingPageCacheToRelease): Function to manage the global queue of caches to be released
     97        (WebCore::HistoryItem::releasePageCache):
     98        (WebCore::closeObjectsInPendingPageCaches):
     99        (WebCore::HistoryItem::releaseAllPendingPageCaches):
     100        (WebCore::HistoryItem::scheduleRelease):
     101        (WebCore::HistoryItem::print):
     102        * history/HistoryItem.h: Added.
     103        * history/mac/HistoryItemMac.mm: Added.
     104        (WebCore::HistoryItem::viewState): In the future we need a platform agnostic way to manage the view state
     105        (WebCore::HistoryItem::setViewState):
     106        (WebCore::HistoryItem::getTransientProperty): Transient properties are, for now, only a Mac concept
     107        (WebCore::HistoryItem::setTransientProperty):
     108
     109        * history/HistoryItemTimer.cpp: Added
     110        (WebCore::HistoryItemTimer::HistoryItemTimer): We need a specific class to be the history item timer because
     111        WebCore::Timers only work when you have an instance of an object, but the caches pending release is a static concept
     112        (WebCore::HistoryItemTimer::isActive):
     113        (WebCore::HistoryItemTimer::schedule):
     114        (WebCore::HistoryItemTimer::invalidate):
     115        (WebCore::HistoryItemTimer::callReleasePageCache):
     116        * history/HistoryItemTimer.h: Added.
     117
     118        * history/PageCache.cpp Added - This is a class that contains the fields that used to be in an NSDictionary in WebKit
     119        (WebCore::PageCache::PageCache):
     120        (WebCore::PageCache::setPageState):
     121        (WebCore::PageCache::~PageCache):
     122        (WebCore::PageCache::pageState):
     123        (WebCore::PageCache::setDocumentLoader):
     124        (WebCore::PageCache::documentLoader):
     125        (WebCore::PageCache::setTimeStamp):
     126        (WebCore::PageCache::setTimeStampToNow):
     127        (WebCore::PageCache::timeStamp):
     128        * history/PageCache.h: Added.
     129        * history/mac/PageCacheMac.mm: Added.
     130        (WebCore::PageCache::close):
     131        (WebCore::PageCache::setDocumentView): In the future we need a platform agnostic way to manage the documentView
     132        (WebCore::PageCache::documentView):
     133
     134        * loader/DocumentLoader.cpp:
     135        (WebCore::DocumentLoader::loadFromPageCache):
     136        (WebCore::DocumentLoader::setLoadingFromPageCache):
     137        (WebCore::DocumentLoader::isLoadingFromPageCache):
     138        (WebCore::DocumentLoader::originalURL):
     139        (WebCore::DocumentLoader::requestURL):
     140        (WebCore::DocumentLoader::responseURL):
     141        (WebCore::DocumentLoader::responseMIMEType):
     142        * loader/DocumentLoader.h:
     143
     144        * loader/FrameLoader.cpp: Responsibilities previously scattered in WebKit but concentrated in WebView and WebFrame
     145          are now here, where they should be.
     146        (WebCore::FrameLoader::clear):
     147        (WebCore::FrameLoader::restoreDocumentState):
     148        (WebCore::FrameLoader::goBackOrForward):
     149        (WebCore::FrameLoader::provisionalLoadStarted):
     150        (WebCore::FrameLoader::canCachePage):
     151        (WebCore::FrameLoader::commitProvisionalLoad):
     152        (WebCore::FrameLoader::transitionToCommitted):
     153        (WebCore::FrameLoader::open):
     154        (WebCore::FrameLoader::didFirstLayout):
     155        (WebCore::FrameLoader::dispatchDidChangeLocationWithinPage):
     156        (WebCore::FrameLoader::dispatchDidFinishLoadToClient):
     157        (WebCore::FrameLoader::updateGlobalHistoryForStandardLoad): Marked for usage in future GlobalHistory (uses client for now)
     158        (WebCore::FrameLoader::updateGlobalHistoryForReload): Ditto
     159        (WebCore::FrameLoader::shouldGoToHistoryItem):
     160        (WebCore::FrameLoader::addExtraFieldsToRequest):
     161        (WebCore::FrameLoader::addHistoryItemForFragmentScroll):
     162        (WebCore::FrameLoader::loadProvisionalItemFromPageCache):
     163        (WebCore::FrameLoader::createPageCache):
     164        (WebCore::FrameLoader::shouldTreatURLAsSameAsCurrent):
     165        (WebCore::FrameLoader::createItem):
     166        (WebCore::FrameLoader::addBackForwardItemClippedAtTarget):
     167        (WebCore::FrameLoader::createItemTree):
     168        (WebCore::FrameLoader::saveScrollPositionAndViewStateToItem):
     169        (WebCore::FrameLoader::restoreScrollPositionAndViewState):
     170        (WebCore::FrameLoader::purgePageCache):
     171        (WebCore::FrameLoader::invalidateCurrentItemPageCache):
     172        (WebCore::FrameLoader::saveDocumentState):
     173        (WebCore::FrameLoader::loadItem):
     174        (WebCore::FrameLoader::urlsMatchItem):
     175        (WebCore::FrameLoader::goToItem):
     176        (WebCore::FrameLoader::recursiveGoToItem):
     177        (WebCore::FrameLoader::childFramesMatchItem):
     178        (WebCore::FrameLoader::updateHistoryForStandardLoad):
     179        (WebCore::FrameLoader::updateHistoryForClientRedirect):
     180        (WebCore::FrameLoader::updateHistoryForBackForwardNavigation):
     181        (WebCore::FrameLoader::updateHistoryForReload):
     182        (WebCore::FrameLoader::updateHistoryForInternalLoad):
     183        (WebCore::FrameLoader::updateHistoryForCommit):
     184        (WebCore::FrameLoader::saveDocumentAndScrollState):
     185        (WebCore::FrameLoader::currentHistoryItem):
     186        (WebCore::FrameLoader::previousHistoryItem):
     187        (WebCore::FrameLoader::provisionalHistoryItem):
     188        (WebCore::FrameLoader::setCurrentHistoryItem):
     189        (WebCore::FrameLoader::setPreviousHistoryItem):
     190        (WebCore::FrameLoader::setProvisionalHistoryItem):
     191        * loader/FrameLoader.h:
     192
     193        * loader/FrameLoaderClient.h:
     194
     195        * loader/mac/DocumentLoaderMac.mm:
     196        (WebCore::DocumentLoader::DocumentLoader):
     197        (WebCore::DocumentLoader::getResponseRefreshAndModifiedHeaders):
     198        (WebCore::DocumentLoader::commitIfReady):
     199        (WebCore::DocumentLoader::urlForHistory):
     200
     201        * loader/mac/FrameLoaderMac.mm:
     202        (WebCore::FrameLoader::load):
     203        (WebCore::FrameLoader::startLoading):
     204        (WebCore::FrameLoader::receivedMainResourceError):
     205        (WebCore::FrameLoader::continueFragmentScrollAfterNavigationPolicy):
     206        (WebCore::FrameLoader::opened):
     207        (WebCore::FrameLoader::dataURLBaseFromRequest):
     208        (WebCore::FrameLoader::didChangeTitle):
     209        (WebCore::FrameLoader::continueLoadAfterNavigationPolicy):
     210        (WebCore::FrameLoader::checkLoadCompleteForThisFrame):
     211
     212        * page/FrameTree.cpp:
     213        (WebCore::FrameTree::removeChild):
     214
     215        * page/Page.cpp: Transfered a handful of concepts from WebView
     216        (WebCore::Page::Page):
     217        (WebCore::Page::~Page):
     218        (WebCore::Page::backForwardList):
     219        (WebCore::Page::goBack):
     220        (WebCore::Page::goForward):
     221        (WebCore::Page::goToItem):
     222        * page/Page.h:
     223
     224        * page/PageState.h:
     225        * page/mac/FrameMac.h:
     226        * page/mac/FrameMac.mm:
     227        * page/mac/WebCoreFrameBridge.h:
     228        * page/mac/WebCoreFrameBridge.mm:
     229
     230        * platform/KURL.cpp:
     231        (WebCore::KURL::print):  Added debug only method for debugging convenience
     232        * platform/KURL.h:
     233
     234        * platform/Logging.cpp:
     235        (WebCore::): Added some logging channels
     236        * platform/Logging.h:
     237
     238        * platform/PlatformString.h:
     239        (WebCore::nsStringNilIfEmpty): Added for WebKit use
     240
     241        * platform/SystemTime.h: Added userIdleTime()
     242
     243        * platform/graphics/svg/SVGImage.cpp:
     244        * platform/graphics/svg/SVGImageEmptyClients.h: Updated for new FrameLoaderClient methods
     245        (WebCore::SVGEmptyFrameLoaderClient::setDocumentViewFromPageCache):
     246        (WebCore::SVGEmptyFrameLoaderClient::updateGlobalHistoryForStandardLoad):
     247        (WebCore::SVGEmptyFrameLoaderClient::updateGlobalHistoryForReload):
     248        (WebCore::SVGEmptyFrameLoaderClient::shouldGoToHistoryItem):
     249        (WebCore::SVGEmptyFrameLoaderClient::saveScrollPositionAndViewStateToItem):
     250        (WebCore::SVGEmptyFrameLoaderClient::saveDocumentViewToPageCache):
     251        (WebCore::SVGEmptyFrameLoaderClient::canCachePage):
     252        (WebCore::SVGEmptyEditorClient::~SVGEmptyEditorClient):
     253
     254        * platform/mac/LoggingMac.mm:
     255        (WebCore::InitializeLoggingChannelsIfNecessary):
     256
     257        * platform/mac/SystemTimeMac.cpp:
     258        (WebCore::userIdleTime):
     259
     260        * platform/mac/WebCoreSystemInterface.h: Added wkSecondsSinceLastInput for use in userIdleTime
     261        * platform/mac/WebCoreSystemInterface.mm:
     262
     263        * platform/network/FormData.cpp:
     264        (WebCore::FormData::FormData):
     265        (WebCore::FormData::copy):
     266        * platform/network/FormData.h:
     267
     268        * platform/network/ResourceHandle.h:
     269        * platform/network/mac/ResourceHandleMac.mm:
     270        (WebCore::ResourceHandle::willLoadFromCache): For "are you sure you want to resubmit?" nag
     271
     272        * platform/qt/TemporaryLinkStubs.cpp:
     273        (WebCore::userIdleTime):
     274        * rendering/RenderPart.h:
     275
    12762007-01-02  Darin Adler  <darin@apple.com>
    2277
  • trunk/WebCore/WebCore.exp

    r18417 r18541  
    110110.objc_class_name_WebCoreJavaScript
    111111.objc_class_name_WebCoreKeyGenerator
    112 .objc_class_name_WebCorePageState
    113112.objc_class_name_WebCoreScriptDebugger
    114113.objc_class_name_WebCoreStringTruncator
     
    131130__ZN7WebCore10MouseEventC1ERKNS_12AtomicStringEbbPNS_9DOMWindowEiiiiibbbbtPNS_15EventTargetNodeEPNS_9ClipboardEb
    132131__ZN7WebCore10StringImplD1Ev
     132__ZNK7WebCore6String6lengthEv
    133133__ZN7WebCore11ContextMenu22setPlatformDescriptionEP14NSMutableArray
    134134__ZN7WebCore11EditCommand7reapplyEv
    135135__ZN7WebCore11EditCommand7unapplyEv
     136__ZN7WebCore9PageCache12documentViewEv
     137__ZN7WebCore9PageCache9pageStateEv
     138__ZN7WebCore11HistoryItem9pageCacheEv
     139__ZN7WebCore9PageCache12setPageStateEN3WTF10PassRefPtrINS_9PageStateEEE
     140__ZN7WebCore9PageCache15setDocumentViewEP11objc_object
     141__ZN7WebCore9PageCache17setDocumentLoaderEN3WTF10PassRefPtrINS_14DocumentLoaderEEE
     142__ZN7WebCore9PageCache17setTimeStampToNowEv
     143__ZN7WebCore9PageCacheD1Ev
     144__ZN7WebCore9PageCache14documentLoaderEv
     145__ZN7WebCore9PageState6createEPNS_4PageE
     146__ZN7WebCore9PageStateD1Ev
    136147__ZN7WebCore11FrameLoader11completeURLERKNS_6StringE
    137148__ZN7WebCore11FrameLoader12canCachePageEv
     
    142153__ZN7WebCore11FrameLoader16detachFromParentEv
    143154__ZN7WebCore11FrameLoader21addPlugInStreamLoaderEPNS_14ResourceLoaderE
    144 __ZN7WebCore11FrameLoader21commitProvisionalLoadEP12NSDictionary
    145155__ZN7WebCore11FrameLoader22cancelMainResourceLoadERKNS_13ResourceErrorE
    146156__ZN7WebCore11FrameLoader23addExtraFieldsToRequestEP19NSMutableURLRequestbb
     
    378388__ZNK7WebCore14DocumentLoader11frameLoaderEv
    379389__ZNK7WebCore14DocumentLoader11isCommittedEv
    380 __ZNK7WebCore14DocumentLoader13URLForHistoryEv
    381390__ZNK7WebCore14DocumentLoader14initialRequestEv
    382391__ZNK7WebCore14DocumentLoader14unreachableURLEv
     
    452461__ZNK7WebCore9Selection7toRangeEv
    453462__ZNK7WebCore9TimerBase8isActiveEv
     463__ZN7WebCore11HistoryItem27releaseAllPendingPageCachesEv
     464__ZN7WebCore11HistoryItem12setURLStringERKNS_6StringE
     465__ZN7WebCore11HistoryItem12setViewStateEP11objc_object
     466__ZN7WebCore11HistoryItem13setVisitCountEi
     467__ZN7WebCore11HistoryItem15setHasPageCacheEb
     468__ZN7WebCore11HistoryItem15setIsTargetItemEb
     469__ZN7WebCore11HistoryItem17setAlternateTitleERKNS_6StringE
     470__ZN7WebCore11HistoryItem18setRSSFeedReferrerERKNS_6StringE
     471__ZN7WebCore11HistoryItem20setOriginalURLStringERKNS_6StringE
     472__ZN7WebCore11HistoryItem30setAlwaysAttemptToUsePageCacheEb
     473__ZN7WebCore11HistoryItem6setURLERKNS_4KURLE
     474__ZN7WebCore11HistoryItem8formDataEv
     475__ZN7WebCore11HistoryItem8setTitleERKNS_6StringE
     476__ZN7WebCore11HistoryItem9setParentERKNS_6StringE
     477__ZN7WebCore11HistoryItem9setTargetERKNS_6StringE
     478__ZN7WebCore11HistoryItemC1ERKNS_4KURLERKNS_6StringES6_S6_
     479__ZN7WebCore11HistoryItemC1ERKNS_6StringES3_d
     480__ZN7WebCore11HistoryItemD1Ev
     481__ZN7WebCore11HistoryItem20setTransientPropertyERKNS_6StringEP11objc_object
     482__ZN7WebCore11HistoryItem23recurseToFindTargetItemEv
     483__ZN7WebCore4Page9goForwardEv
     484__ZNK7WebCore8IntPointcv8_NSPointEv
     485__ZN7WebCore5equalEPKNS_10StringImplES2_
     486__ZN7WebCore4Page15backForwardListEv
     487__ZN7WebCoreeqERKNS_4KURLES2_
     488__ZN7WebCore11HistoryItem14setScrollPointERKNS_8IntPointE
     489__ZN7WebCore15BackForwardList10removeItemEPNS_11HistoryItemE
     490__ZN7WebCore15BackForwardList11currentItemEv
     491__ZN7WebCore15BackForwardList11forwardItemEv
     492__ZN7WebCore15BackForwardList11itemAtIndexEi
     493__ZN7WebCore15BackForwardList11setCapacityEi
     494__ZN7WebCore15BackForwardList12containsItemEPNS_11HistoryItemE
     495__ZN7WebCore15BackForwardList13backListCountEv
     496__ZN7WebCore15BackForwardList13pageCacheSizeEv
     497__ZN7WebCore15BackForwardList13usesPageCacheEv
     498__ZN7WebCore15BackForwardList14clearPageCacheEv
     499__ZN7WebCore15BackForwardList16forwardListCountEv
     500__ZN7WebCore15BackForwardList16setPageCacheSizeEj
     501__ZN7WebCore15BackForwardList17backListWithLimitEiRN3WTF6VectorINS1_6RefPtrINS_11HistoryItemEEELm0EEE
     502__ZN7WebCore15BackForwardList20forwardListWithLimitEiRN3WTF6VectorINS1_6RefPtrINS_11HistoryItemEEELm0EEE
     503__ZN7WebCore15BackForwardList5closeEv
     504__ZN7WebCore15BackForwardList6closedEv
     505__ZN7WebCore15BackForwardList6goBackEv
     506__ZN7WebCore15BackForwardList7addItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
     507__ZN7WebCore15BackForwardList7entriesEv
     508__ZN7WebCore15BackForwardList8backItemEv
     509__ZN7WebCore15BackForwardList8capacityEv
     510__ZN7WebCore15BackForwardList9goForwardEv
     511__ZN7WebCore15BackForwardListC1Ev
     512__ZN7WebCore15BackForwardListD1Ev
     513__ZN7WebCore15BackForwardList23setDefaultPageCacheSizeEj
     514__ZN7WebCore11HistoryItemC1Ev
     515__ZN7WebCore11HistoryItem12addChildItemEN3WTF10PassRefPtrIS0_EE
     516__ZN7WebCore11HistoryItem22mergeAutoCompleteHintsEPS0_
     517__ZNK7WebCore11HistoryItem10visitCountEv
     518__ZNK7WebCore11HistoryItem11hasChildrenEv
     519__ZNK7WebCore11HistoryItem12isTargetItemEv
     520__ZNK7WebCore11HistoryItem14alternateTitleEv
     521__ZNK7WebCore11HistoryItem15rssFeedReferrerEv
     522__ZNK7WebCore11HistoryItem17originalURLStringEv
     523__ZNK7WebCore11HistoryItem20getTransientPropertyERKNS_6StringE
     524__ZNK7WebCore11HistoryItem3urlEv
     525__ZNK7WebCore11HistoryItem4copyEv
     526__ZNK7WebCore11HistoryItem4iconEv
     527__ZNK7WebCore11HistoryItem5titleEv
     528__ZNK7WebCore11HistoryItem6targetEv
     529__ZNK7WebCore11HistoryItem9urlStringEv
     530__ZN7WebCore11FrameLoader18currentHistoryItemEv
     531__ZN7WebCore11FrameLoader21setCurrentHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
     532__ZN7WebCore11FrameLoader25setProvisionalHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
     533__ZNK7WebCore11HistoryItem17childItemWithNameERKNS_6StringE
     534__ZN7WebCore11FrameLoader26saveDocumentAndScrollStateEv
     535__ZN7WebCore4Page8goToItemEPNS_11HistoryItemENS_13FrameLoadTypeE
     536__ZN7WebCore11FrameLoader22setPreviousHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
     537__ZN7WebCore11FrameLoader36saveScrollPositionAndViewStateToItemEPNS_11HistoryItemE
     538__ZNK7WebCore11HistoryItem11scrollPointEv
     539__ZNK7WebCore11HistoryItem9viewStateEv
     540__ZN7WebCore11HistoryItem18setLastVisitedTimeEd
     541__ZNK7WebCore11HistoryItem15lastVisitedTimeEv
     542__ZN7WebCore24notifyHistoryItemChangedE
     543__ZN7WebCore15BackForwardList8goToItemEPNS_11HistoryItemE
     544__ZNK7WebCore11HistoryItem8childrenEv
     545__ZN7WebCore4Page6goBackEv
    454546_canonicalURL
    455547_stringIsFileURL
     
    495587_wkPopupMenu
    496588_wkReleaseStyleGroup
     589_wkSecondsSinceLastInputEvent
    497590_wkSetCGFontRenderingMode
    498591_wkSetDragImage
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r18523 r18541  
    292292                4E19592D0A39DACC00220FE5 /* MediaQueryExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E1959270A39DACC00220FE5 /* MediaQueryExp.cpp */; };
    293293                4E19592E0A39DACC00220FE5 /* MediaQueryExp.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E1959280A39DACC00220FE5 /* MediaQueryExp.h */; };
     294                510184690B08602A004A825F /* PageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 510184670B08602A004A825F /* PageCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
     295                5101846A0B08602A004A825F /* PageCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 510184680B08602A004A825F /* PageCache.cpp */; };
    294296                5115095C0A9CE04700901013 /* urlIcon.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 5115095B0A9CE04600901013 /* urlIcon.tiff */; };
    295297                5126E6BB0A2E3B12005C29FA /* IconDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5126E6B90A2E3B12005C29FA /* IconDatabase.cpp */; };
     
    297299                513F14530AB634C400094DDF /* IconLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 513F14510AB634C400094DDF /* IconLoader.cpp */; };
    298300                513F14540AB634C400094DDF /* IconLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 513F14520AB634C400094DDF /* IconLoader.h */; };
     301                5160F1FE0B0A7EF400C1D2AF /* HistoryItemTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5160F1FC0B0A7EF400C1D2AF /* HistoryItemTimer.h */; };
     302                5160F1FF0B0A7EF400C1D2AF /* HistoryItemTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5160F1FD0B0A7EF400C1D2AF /* HistoryItemTimer.cpp */; };
     303                5160F3BC0B0A99C900C1D2AF /* PageCacheMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5160F3BB0B0A99C900C1D2AF /* PageCacheMac.mm */; };
     304                5160F4980B0AA75F00C1D2AF /* HistoryItemMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5160F4970B0AA75F00C1D2AF /* HistoryItemMac.mm */; };
     305                51741D0F0B07259A00ED442C /* BackForwardList.h in Headers */ = {isa = PBXBuildFile; fileRef = 51741D0B0B07259A00ED442C /* BackForwardList.h */; settings = {ATTRIBUTES = (Private, ); }; };
     306                51741D100B07259A00ED442C /* BackForwardList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51741D0C0B07259A00ED442C /* BackForwardList.cpp */; };
     307                51741D110B07259A00ED442C /* HistoryItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 51741D0D0B07259A00ED442C /* HistoryItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
     308                51741D120B07259A00ED442C /* HistoryItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51741D0E0B07259A00ED442C /* HistoryItem.cpp */; };
    299309                5186C0560A9C21470034FE94 /* IconDataCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5186C0550A9C21470034FE94 /* IconDataCache.cpp */; };
    300310                51D3EA160A3D24D300BADA35 /* SQLDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51D3EA130A3D24D300BADA35 /* SQLDatabase.cpp */; };
     
    15591569                93F1996D08245E59001E9ABC /* DeprecatedPtrListImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = F587851502DE375901EA4122 /* DeprecatedPtrListImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
    15601570                93F1996E08245E59001E9ABC /* LoaderFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = F587851702DE375901EA4122 /* LoaderFunctions.h */; };
    1561                 93F1997708245E59001E9ABC /* WebCorePageState.h in Headers */ = {isa = PBXBuildFile; fileRef = 9394E0A403AA5BBE008635CE /* WebCorePageState.h */; settings = {ATTRIBUTES = (Private, ); }; };
    15621571                93F1998208245E59001E9ABC /* DeprecatedPtrList.h in Headers */ = {isa = PBXBuildFile; fileRef = F587869902DE3B8601EA4122 /* DeprecatedPtrList.h */; settings = {ATTRIBUTES = (Private, ); }; };
    15631572                93F1998308245E59001E9ABC /* DeprecatedPtrQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = F58786AD02DE3B8601EA4122 /* DeprecatedPtrQueue.h */; };
     
    16041613                93F19AC608245E59001E9ABC /* WebCoreEncodings.mm in Sources */ = {isa = PBXBuildFile; fileRef = F56234E003026D7301629B47 /* WebCoreEncodings.mm */; };
    16051614                93F19AC808245E59001E9ABC /* WebCoreHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = F5517DC3031AB56301A80180 /* WebCoreHistory.m */; };
    1606                 93F19AD208245E59001E9ABC /* WebCorePageState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9394E0A503AA5BBE008635CE /* WebCorePageState.mm */; };
    16071615                93F19AD508245E59001E9ABC /* RenderTreeAsText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93955A4203D72932008635CE /* RenderTreeAsText.cpp */; };
    16081616                93F19ADC08245E59001E9ABC /* PlatformScrollBarMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC7B2AF90450824100A8000F /* PlatformScrollBarMac.mm */; };
     
    33163324                4E1959270A39DACC00220FE5 /* MediaQueryExp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MediaQueryExp.cpp; sourceTree = "<group>"; };
    33173325                4E1959280A39DACC00220FE5 /* MediaQueryExp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MediaQueryExp.h; sourceTree = "<group>"; };
     3326                510184670B08602A004A825F /* PageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageCache.h; sourceTree = "<group>"; };
     3327                510184680B08602A004A825F /* PageCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageCache.cpp; sourceTree = "<group>"; };
    33183328                5115095B0A9CE04600901013 /* urlIcon.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = urlIcon.tiff; sourceTree = "<group>"; };
    33193329                5126E6B90A2E3B12005C29FA /* IconDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IconDatabase.cpp; sourceTree = "<group>"; };
     
    33233333                5150C2A10702629000AF642C /* WebDashboardRegion.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebDashboardRegion.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
    33243334                5150C2A50702629800AF642C /* WebDashboardRegion.m */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebDashboardRegion.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
     3335                5160F1FC0B0A7EF400C1D2AF /* HistoryItemTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryItemTimer.h; sourceTree = "<group>"; };
     3336                5160F1FD0B0A7EF400C1D2AF /* HistoryItemTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HistoryItemTimer.cpp; sourceTree = "<group>"; };
     3337                5160F3BB0B0A99C900C1D2AF /* PageCacheMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PageCacheMac.mm; path = mac/PageCacheMac.mm; sourceTree = "<group>"; };
     3338                5160F4970B0AA75F00C1D2AF /* HistoryItemMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = HistoryItemMac.mm; path = mac/HistoryItemMac.mm; sourceTree = "<group>"; };
     3339                51741D0B0B07259A00ED442C /* BackForwardList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackForwardList.h; sourceTree = "<group>"; };
     3340                51741D0C0B07259A00ED442C /* BackForwardList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BackForwardList.cpp; sourceTree = "<group>"; };
     3341                51741D0D0B07259A00ED442C /* HistoryItem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HistoryItem.h; sourceTree = "<group>"; };
     3342                51741D0E0B07259A00ED442C /* HistoryItem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HistoryItem.cpp; sourceTree = "<group>"; };
    33253343                5186C0550A9C21470034FE94 /* IconDataCache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IconDataCache.cpp; sourceTree = "<group>"; };
    33263344                51D3EA130A3D24D300BADA35 /* SQLDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SQLDatabase.cpp; sourceTree = "<group>"; };
     
    44754493                9392F14F0AD1862300691BD4 /* CounterNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CounterNode.cpp; sourceTree = "<group>"; };
    44764494                9392F1510AD1862B00691BD4 /* CounterListItem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CounterListItem.h; sourceTree = "<group>"; };
    4477                 9394E0A403AA5BBE008635CE /* WebCorePageState.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebCorePageState.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
    4478                 9394E0A503AA5BBE008635CE /* WebCorePageState.mm */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCorePageState.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
    44794495                93955A4103D72932008635CE /* RenderTreeAsText.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeAsText.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
    44804496                93955A4203D72932008635CE /* RenderTreeAsText.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeAsText.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
     
    60416057                                F523D32402DE4478018635CA /* dom */,
    60426058                                93309D86099E64910056E581 /* editing */,
     6059                                51741D080B07257000ED442C /* history */,
    60436060                                93EEC1EC09C2877700C515D1 /* html */,
    60446061                                A8C0F6E9089701F100BA5114 /* ksvg2 */,
     
    65596576                        sourceTree = "<group>";
    65606577                };
     6578                5160F4920B0AA71500C1D2AF /* mac */ = {
     6579                        isa = PBXGroup;
     6580                        children = (
     6581                                5160F3BB0B0A99C900C1D2AF /* PageCacheMac.mm */,
     6582                                5160F4970B0AA75F00C1D2AF /* HistoryItemMac.mm */,
     6583                        );
     6584                        name = mac;
     6585                        sourceTree = "<group>";
     6586                };
     6587                51741D080B07257000ED442C /* history */ = {
     6588                        isa = PBXGroup;
     6589                        children = (
     6590                                5160F4920B0AA71500C1D2AF /* mac */,
     6591                                51741D0B0B07259A00ED442C /* BackForwardList.h */,
     6592                                51741D0C0B07259A00ED442C /* BackForwardList.cpp */,
     6593                                51741D0D0B07259A00ED442C /* HistoryItem.h */,
     6594                                51741D0E0B07259A00ED442C /* HistoryItem.cpp */,
     6595                                5160F1FC0B0A7EF400C1D2AF /* HistoryItemTimer.h */,
     6596                                5160F1FD0B0A7EF400C1D2AF /* HistoryItemTimer.cpp */,
     6597                                510184670B08602A004A825F /* PageCache.h */,
     6598                                510184680B08602A004A825F /* PageCache.cpp */,
     6599                        );
     6600                        path = history;
     6601                        sourceTree = "<group>";
     6602                };
    65616603                656580EC09D12B20000E61D7 /* Derived Sources */ = {
    65626604                        isa = PBXGroup;
     
    67786820                                F5B2A52B02E22573018635CB /* WebCoreJavaScript.h */,
    67796821                                F5B2A52C02E22573018635CB /* WebCoreJavaScript.mm */,
    6780                                 9394E0A403AA5BBE008635CE /* WebCorePageState.h */,
    6781                                 9394E0A503AA5BBE008635CE /* WebCorePageState.mm */,
    67826822                                7E6FEED60898582300C44C3F /* WebCoreScriptDebugger.h */,
    67836823                                7E6FEED70898582300C44C3F /* WebCoreScriptDebugger.mm */,
     
    94779517                                93F1996D08245E59001E9ABC /* DeprecatedPtrListImpl.h in Headers */,
    94789518                                93F1996E08245E59001E9ABC /* LoaderFunctions.h in Headers */,
    9479                                 93F1997708245E59001E9ABC /* WebCorePageState.h in Headers */,
    94809519                                A70023FE0B02BEAB00170215 /* MimeTypeRegistry.h in Headers */,
    94819520                                A7D23C540B03E41300582A4F /* WebMimeTypeRegistryBridge.h in Headers */,
     
    1082810867                                B27535800B053814002CE64F /* Path.h in Headers */,
    1082910868                                B27535820B053814002CE64F /* Pen.h in Headers */,
     10869                                51741D0F0B07259A00ED442C /* BackForwardList.h in Headers */,
     10870                                51741D110B07259A00ED442C /* HistoryItem.h in Headers */,
     10871                                510184690B08602A004A825F /* PageCache.h in Headers */,
     10872                                5160F1FE0B0A7EF400C1D2AF /* HistoryItemTimer.h in Headers */,
    1083010873                                93C09A530B064DB3005ABD4D /* EventHandler.h in Headers */,
    1083110874                                93C09C860B0657AA005ABD4D /* ScrollTypes.h in Headers */,
     
    1108811131                                93F19AC608245E59001E9ABC /* WebCoreEncodings.mm in Sources */,
    1108911132                                93F19AC808245E59001E9ABC /* WebCoreHistory.m in Sources */,
    11090                                 93F19AD208245E59001E9ABC /* WebCorePageState.mm in Sources */,
    1109111133                                93F19AD508245E59001E9ABC /* RenderTreeAsText.cpp in Sources */,
    1109211134                                93F19ADC08245E59001E9ABC /* PlatformScrollBarMac.mm in Sources */,
     
    1214112183                                B27535810B053814002CE64F /* Pen.cpp in Sources */,
    1214212184                                B275358E0B053A66002CE64F /* IconMac.mm in Sources */,
     12185                                51741D100B07259A00ED442C /* BackForwardList.cpp in Sources */,
     12186                                51741D120B07259A00ED442C /* HistoryItem.cpp in Sources */,
     12187                                5101846A0B08602A004A825F /* PageCache.cpp in Sources */,
     12188                                5160F1FF0B0A7EF400C1D2AF /* HistoryItemTimer.cpp in Sources */,
     12189                                5160F3BC0B0A99C900C1D2AF /* PageCacheMac.mm in Sources */,
     12190                                5160F4980B0AA75F00C1D2AF /* HistoryItemMac.mm in Sources */,
    1214312191                                93C09A7F0B064EEF005ABD4D /* EventHandlerMac.mm in Sources */,
    1214412192                                93C09A810B064F00005ABD4D /* EventHandler.cpp in Sources */,
  • trunk/WebCore/loader/DocumentLoader.cpp

    r18243 r18541  
    3030#include "DocumentLoader.h"
    3131
     32#include "FrameLoader.h"
     33#include "PageCache.h"
     34
    3235namespace WebCore {
     36
     37void DocumentLoader::loadFromPageCache(PassRefPtr<PageCache> pageCache)
     38{
     39    prepareForLoadStart();
     40    setLoadingFromPageCache(true);
     41    setCommitted(true);
     42    frameLoader()->commitProvisionalLoad(pageCache);
     43}
    3344
    3445const ResourceResponse& DocumentLoader::response() const
    3546{
    3647    return m_response;
     48}
     49
     50void DocumentLoader::setLoadingFromPageCache(bool loading)
     51{
     52    m_loadingFromPageCache = loading;
     53}
     54
     55bool DocumentLoader::isLoadingFromPageCache() const
     56{
     57    return m_loadingFromPageCache;
    3758}
    3859
     
    5273}
    5374
     75KURL DocumentLoader::originalURL() const
     76{
     77    return m_originalRequestCopy.url();
    5478}
     79
     80KURL DocumentLoader::requestURL() const
     81{
     82    return request().url();
     83}
     84
     85KURL DocumentLoader::responseURL() const
     86{
     87    return m_response.url();
     88}
     89
     90String DocumentLoader::responseMIMEType() const
     91{
     92    return m_response.mimeType();
     93}
     94
     95}
  • trunk/WebCore/loader/DocumentLoader.h

    r18243 r18541  
    5858    class Frame;
    5959    class FrameLoader;
     60    class HistoryItem;
    6061    class KURL;
     62    class PageCache;
    6163
    6264    typedef Vector<ResourceResponse> ResponseVector;
     
    7577        NSData *mainResourceData() const;
    7678#endif
     79
    7780        const ResourceRequest& originalRequest() const;
    7881        const ResourceRequest& originalRequestCopy() const;
     
    8790        const KURL& URL() const;
    8891        const KURL unreachableURL() const;
     92
     93        KURL originalURL() const;
     94        KURL requestURL() const;
     95        KURL responseURL() const;
     96        String responseMIMEType() const;
     97       
     98        // FIXME: After we have a ResourceResponse in the mix, this method can go away and we can use it directly
     99        bool getResponseRefreshAndModifiedHeaders(String& refresh, String& modified) const;
     100       
    89101        void replaceRequestURLForAnchorScroll(const KURL&);
    90102        bool isStopping() const;
     
    123135        void stopRecordingResponses();
    124136        String title() const;
    125         KURL URLForHistory() const;
    126 
     137        KURL urlForHistory() const;
     138       
     139        void loadFromPageCache(PassRefPtr<PageCache>);
     140        void setLoadingFromPageCache(bool);
     141        bool isLoadingFromPageCache() const;
     142       
    127143    private:
    128144#if PLATFORM(MAC)
     
    171187        bool m_primaryLoadComplete;
    172188        bool m_isClientRedirect;
     189        bool m_loadingFromPageCache;
    173190
    174191        String m_pageTitle;
  • trunk/WebCore/loader/FrameLoader.cpp

    r18460 r18541  
    3232#include "Cache.h"
    3333#include "Chrome.h"
     34#include "CString.h"
    3435#include "DOMImplementation.h"
    3536#include "DocLoader.h"
     
    5051#include "FrameTree.h"
    5152#include "FrameView.h"
     53#include "HistoryItem.h"
    5254#include "HTMLFormElement.h"
    5355#include "HTMLNames.h"
     
    5658#include "IconDatabase.h"
    5759#include "IconLoader.h"
     60#include "Logging.h"
    5861#include "MainResourceLoader.h"
    5962#include "Page.h"
     63#include "PageCache.h"
    6064#include "PageState.h"
    6165#include "RenderPart.h"
    6266#include "RenderWidget.h"
     67#include "ResourceHandle.h"
    6368#include "ResourceRequest.h"
    6469#include "SegmentedString.h"
     
    723728    if (m_frame->document()) {
    724729        m_frame->document()->cancelParsing();
     730        m_frame->document()->willRemove();
    725731        m_frame->document()->detach();
    726732    }
     
    973979}
    974980
     981void FrameLoader::restoreDocumentState()
     982{
     983    Document* doc = m_frame->document();
     984    if (!doc)
     985        return;
     986       
     987    HistoryItem* itemToRestore = 0;
     988   
     989    switch (loadType()) {
     990        case FrameLoadTypeReload:
     991        case FrameLoadTypeReloadAllowingStaleData:
     992        case FrameLoadTypeSame:
     993        case FrameLoadTypeReplace:
     994            break;
     995        case FrameLoadTypeBack:
     996        case FrameLoadTypeForward:
     997        case FrameLoadTypeIndexedBackForward:
     998        case FrameLoadTypeInternal:
     999        case FrameLoadTypeStandard:
     1000            itemToRestore = m_currentHistoryItem.get();
     1001    }
     1002   
     1003    if (!itemToRestore)
     1004        return;
     1005       
     1006    doc->setStateForNewFormElements(itemToRestore->documentState());
     1007}
     1008
    9751009void FrameLoader::gotoAnchor()
    9761010{
     
    11801214   
    11811215    scheduleRedirection(new ScheduledRedirection(steps));
     1216}
     1217
     1218void FrameLoader::goBackOrForward(int distance)
     1219{
     1220    if (distance == 0)
     1221        return;
     1222       
     1223    Page* page = m_frame->page();
     1224    if (!page)
     1225        return;
     1226    BackForwardList* list = page->backForwardList();
     1227    if (!list)
     1228        return;
     1229   
     1230    HistoryItem* item = list->itemAtIndex(distance);
     1231    if (!item) {
     1232        if (distance > 0) {
     1233            int forwardListCount = list->forwardListCount();
     1234            if (forwardListCount > 0)
     1235                item = list->itemAtIndex(forwardListCount);
     1236        } else {
     1237            int backListCount = list->forwardListCount();
     1238            if (backListCount > 0)
     1239                item = list->itemAtIndex(-backListCount);
     1240        }
     1241    }
     1242    if (item)
     1243        page->goToItem(item, FrameLoadTypeIndexedBackForward);
    11821244}
    11831245
     
    13771439    m_firstLayoutDone = false;
    13781440    cancelRedirection(true);
     1441    FrameLoadType loadType = this->loadType();
    13791442    m_client->provisionalLoadStarted();
     1443
     1444    // Cache the page, if possible.
     1445    // Don't write to the cache if in the middle of a redirect, since we will want to
     1446    // store the final page we end up on.
     1447    // No point writing to the cache on a reload or loadSame, since we will just write
     1448    // over it again when we leave that page.
     1449    // FIXME: <rdar://problem/4886592> - We should work out the complexities of caching pages with frames as they
     1450    // are the most interesting pages on the web, and often those that would benefit the most from caching!
     1451    if (m_frame->page() && m_frame->page()->backForwardList()->usesPageCache()
     1452        && canCachePage()
     1453        && m_currentHistoryItem
     1454        && !isQuickRedirectComing()
     1455        && loadType != FrameLoadTypeReload
     1456        && loadType != FrameLoadTypeReloadAllowingStaleData
     1457        && loadType != FrameLoadTypeSame
     1458        && !documentLoader()->isLoading()
     1459        && !documentLoader()->isStopping()) {
     1460       
     1461        if (!m_currentHistoryItem->pageCache()) {
     1462            // Add the items to this page's cache.
     1463            if (createPageCache(m_currentHistoryItem.get())) {
     1464                // See if any page caches need to be purged after the addition of this new page cache.
     1465                purgePageCache();
     1466            }
     1467        }
     1468    }
    13801469}
    13811470
     
    14231512bool FrameLoader::canCachePage()
    14241513{
     1514    if (!m_client->canCachePage())
     1515        return false;
     1516       
    14251517    return m_frame->document()
    14261518        && !m_frame->tree()->childCount()
     
    18281920}
    18291921
     1922void FrameLoader::commitProvisionalLoad(PassRefPtr<PageCache> prpPageCache)
     1923{
     1924    RefPtr<PageCache> pageCache = prpPageCache;
     1925    RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader;
     1926   
     1927    if (m_loadType != FrameLoadTypeReplace)
     1928        closeOldDataSources();
     1929   
     1930    if (!pageCache)
     1931        m_client->makeRepresentation(pdl.get());
     1932   
     1933    transitionToCommitted(pageCache);
     1934   
     1935    // Call -_clientRedirectCancelledOrFinished: here so that the frame load delegate is notified that the redirect's
     1936    // status has changed, if there was a redirect.  The frame load delegate may have saved some state about
     1937    // the redirect in its -webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:.  Since we are
     1938    // just about to commit a new page, there cannot possibly be a pending redirect at this point.
     1939    if (m_sentRedirectNotification)
     1940        clientRedirectCancelledOrFinished(false);
     1941   
     1942    RefPtr<PageState> pageState;
     1943    if (pageCache)
     1944        pageState = pageCache->pageState();
     1945    if (pageState) {
     1946        open(*pageState);
     1947        pageState->clear();
     1948    } else {       
     1949        KURL url = pdl->URL();
     1950        KURL dataURLBase = dataURLBaseFromRequest(pdl->request());
     1951        if (!dataURLBase.isEmpty())
     1952            url = dataURLBase;
     1953           
     1954        if (url.isEmpty())
     1955            url = pdl->responseURL();
     1956        if (url.isEmpty())
     1957            url = "about:blank";
     1958
     1959        m_responseMIMEType = pdl->responseMIMEType();
     1960
     1961        if (didOpenURL(url))
     1962            if (!pdl->getResponseRefreshAndModifiedHeaders(m_responseRefreshHeader, m_responseModifiedHeader)) {
     1963                m_responseRefreshHeader = "";
     1964                m_responseModifiedHeader = "";
     1965            }
     1966    }
     1967    opened();
     1968}
     1969
     1970void FrameLoader::transitionToCommitted(PassRefPtr<PageCache> pageCache)
     1971{
     1972    ASSERT(m_client->hasWebView());
     1973    ASSERT(m_state == FrameStateProvisional);
     1974
     1975    if (m_state != FrameStateProvisional)
     1976        return;
     1977
     1978    m_client->setCopiesOnScroll();
     1979    updateHistoryForCommit();
     1980
     1981    // The call to closeURL() invokes the unload event handler, which can execute arbitrary
     1982    // JavaScript. If the script initiates a new load, we need to abandon the current load,
     1983    // or the two will stomp each other.
     1984    DocumentLoader* pdl = m_provisionalDocumentLoader.get();
     1985    closeURL();
     1986    if (pdl != m_provisionalDocumentLoader)
     1987        return;
     1988
     1989    commitProvisionalLoad();
     1990
     1991    // Handle adding the URL to the back/forward list.
     1992    DocumentLoader* dl = m_documentLoader.get();
     1993    String ptitle = dl->title();
     1994
     1995    switch (m_loadType) {
     1996        case FrameLoadTypeForward:
     1997        case FrameLoadTypeBack:
     1998        case FrameLoadTypeIndexedBackForward:
     1999            if (m_frame->page()->backForwardList()) {
     2000                updateHistoryForBackForwardNavigation();
     2001
     2002                // Create a document view for this document, or used the cached view.
     2003                if (pageCache)
     2004                    m_client->setDocumentViewFromPageCache(pageCache.get());
     2005                else
     2006                    m_client->makeDocumentView();
     2007            }
     2008            break;
     2009
     2010        case FrameLoadTypeReload:
     2011        case FrameLoadTypeSame:
     2012        case FrameLoadTypeReplace:
     2013            updateHistoryForReload();
     2014            m_client->makeDocumentView();
     2015            break;
     2016
     2017        // FIXME - just get rid of this case, and merge FrameLoadTypeReloadAllowingStaleData with the above case
     2018        case FrameLoadTypeReloadAllowingStaleData:
     2019            m_client->makeDocumentView();
     2020            break;
     2021
     2022        case FrameLoadTypeStandard:
     2023            updateHistoryForStandardLoad();
     2024            m_client->makeDocumentView();
     2025            break;
     2026
     2027        case FrameLoadTypeInternal:
     2028            updateHistoryForInternalLoad();
     2029            m_client->makeDocumentView();
     2030            break;
     2031
     2032        // FIXME Remove this check when dummy ds is removed (whatever "dummy ds" is).
     2033        // An exception should be thrown if we're in the FrameLoadTypeUninitialized state.
     2034        default:
     2035            ASSERT_NOT_REACHED();
     2036    }
     2037
     2038    // Tell the client we've committed this URL.
     2039    ASSERT(m_client->hasFrameView());
     2040    m_client->dispatchDidCommitLoad();
     2041   
     2042    // If we have a title let the WebView know about it.
     2043    if (!ptitle.isNull())
     2044        m_client->dispatchDidReceiveTitle(ptitle);
     2045}
     2046
    18302047bool FrameLoader::privateBrowsingEnabled() const
    18312048{
     
    19172134
    19182135    Document* document = state.document();
     2136    ASSERT(document);
    19192137    document->setInPageCache(false);
    19202138
     
    20802298void FrameLoader::didFirstLayout()
    20812299{
    2082     if (isBackForwardLoadType(m_loadType) && m_client->hasBackForwardList())
    2083         m_client->restoreScrollPositionAndViewState();
     2300    if (isBackForwardLoadType(m_loadType) && m_frame->page() && m_frame->page()->backForwardList())
     2301        restoreScrollPositionAndViewState();
    20842302
    20852303    m_firstLayoutDone = true;
     
    22572475}
    22582476
     2477void FrameLoader::dispatchDidChangeLocationWithinPage()
     2478{
     2479    m_client->dispatchDidChangeLocationWithinPage();
     2480}
     2481
     2482void FrameLoader::dispatchDidFinishLoadToClient()
     2483{
     2484    m_client->didFinishLoad();
     2485}
     2486
     2487void FrameLoader::updateGlobalHistoryForStandardLoad(const KURL& url)
     2488{
     2489    m_client->updateGlobalHistoryForStandardLoad(url);
     2490}
     2491
     2492void FrameLoader::updateGlobalHistoryForReload(const KURL& url)
     2493{
     2494    m_client->updateGlobalHistoryForReload(url);
     2495}
     2496
     2497bool FrameLoader::shouldGoToHistoryItem(HistoryItem* item) const
     2498{
     2499    return m_client->shouldGoToHistoryItem(item);
     2500}
     2501
     2502void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, bool mainResource, bool alwaysFromRequest)
     2503{
     2504    applyUserAgent(request);
     2505   
     2506    if (m_loadType == FrameLoadTypeReload)
     2507        request.setHTTPHeaderField("Cache-Control", "max-age=0");
     2508   
     2509    // Don't set the cookie policy URL if it's already been set.
     2510    if (request.mainDocumentURL().isEmpty()) {
     2511        if (mainResource && (isLoadingMainFrame() || alwaysFromRequest))
     2512            request.setMainDocumentURL(request.url());
     2513        else
     2514            request.setMainDocumentURL(m_frame->page()->mainFrame()->loader()->url());
     2515    }
     2516   
     2517    if (mainResource)
     2518        request.setHTTPAccept("text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
     2519}
     2520
     2521void FrameLoader::addHistoryItemForFragmentScroll()
     2522{
     2523    addBackForwardItemClippedAtTarget(false);
     2524}
     2525
     2526bool FrameLoader::loadProvisionalItemFromPageCache()
     2527{
     2528    if (!m_provisionalHistoryItem || !m_provisionalHistoryItem->hasPageCache())
     2529        return false;
     2530
     2531    RefPtr<PageState> state = m_provisionalHistoryItem->pageCache()->pageState();
     2532    if (!state)
     2533        return false;
     2534   
     2535    provisionalDocumentLoader()->loadFromPageCache(m_provisionalHistoryItem->pageCache());
     2536    return true;
     2537}
     2538
     2539bool FrameLoader::createPageCache(HistoryItem* item)
     2540{
     2541    RefPtr<PageState> pageState = PageState::create(m_frame->page());
     2542   
     2543    if (!pageState) {
     2544        item->setHasPageCache(false);
     2545        return false;
     2546    }
     2547   
     2548    item->setHasPageCache(true);
     2549    RefPtr<PageCache> pageCache = item->pageCache();
     2550
     2551    pageCache->setPageState(pageState.release());
     2552    pageCache->setTimeStampToNow();
     2553    pageCache->setDocumentLoader(documentLoader());
     2554    m_client->saveDocumentViewToPageCache(pageCache.get());
     2555
     2556    return true;
     2557}
     2558
     2559bool FrameLoader::shouldTreatURLAsSameAsCurrent(const KURL& URL) const
     2560{
     2561    if (!m_currentHistoryItem)
     2562        return false;
     2563    return URL == m_currentHistoryItem->url() || URL == m_currentHistoryItem->originalURL();
     2564}
     2565
     2566PassRefPtr<HistoryItem> FrameLoader::createItem(bool useOriginal)
     2567{
     2568    DocumentLoader* docLoader = documentLoader();
     2569    ASSERT(docLoader);
     2570   
     2571    KURL unreachableURL = docLoader ? docLoader->unreachableURL() : KURL();
     2572   
     2573    KURL url;
     2574    KURL originalURL;
     2575
     2576    if (!unreachableURL.isEmpty()) {
     2577        url = unreachableURL;
     2578        originalURL = unreachableURL;
     2579    } else {
     2580        originalURL = docLoader ? docLoader->originalURL() : KURL();
     2581        if (useOriginal)
     2582            url = originalURL;
     2583        else
     2584            if (docLoader)
     2585                url = docLoader->requestURL();               
     2586    }
     2587
     2588    LOG (History, "WebCoreHistory - Creating item for %s", url.url().ascii());
     2589   
     2590    // Frames that have never successfully loaded any content
     2591    // may have no URL at all. Currently our history code can't
     2592    // deal with such things, so we nip that in the bud here.
     2593    // Later we may want to learn to live with nil for URL.
     2594    // See bug 3368236 and related bugs for more information.
     2595    if (url.isEmpty())
     2596        url = KURL("about:blank");
     2597    if (originalURL.isEmpty())
     2598        originalURL = KURL("about:blank");
     2599   
     2600    RefPtr<HistoryItem> item = new HistoryItem(url, m_frame->tree()->name(), m_frame->tree()->parent() ? m_frame->tree()->parent()->tree()->name() : "", docLoader->title());
     2601    item->setOriginalURLString(originalURL.url());
     2602   
     2603    // Save form state if this is a POST
     2604    if (useOriginal)
     2605        item->setFormInfoFromRequest(docLoader->originalRequest());
     2606    else
     2607        item->setFormInfoFromRequest(docLoader->request());
     2608       
     2609    // Set the item for which we will save document state
     2610    m_previousHistoryItem = m_currentHistoryItem;
     2611    m_currentHistoryItem = item;
     2612   
     2613    return item.release();
     2614}
     2615
     2616void FrameLoader::addBackForwardItemClippedAtTarget(bool doClip)
     2617{
     2618    if (!documentLoader()->urlForHistory().isEmpty()) {
     2619        Frame* mainFrame = m_frame->page()->mainFrame();
     2620        ASSERT(mainFrame);
     2621        RefPtr<HistoryItem> item = mainFrame->loader()->createItemTree(m_frame, doClip);
     2622        LOG(BackForward, "WebCoreBackForward - Adding backforward item %p for frame %s", item.get(), documentLoader()->URL().url().ascii());
     2623        ASSERT(m_frame->page());
     2624        m_frame->page()->backForwardList()->addItem(item);
     2625    }
     2626}
     2627
     2628PassRefPtr<HistoryItem> FrameLoader::createItemTree(Frame* targetFrame, bool clipAtTarget)
     2629{
     2630    RefPtr<HistoryItem> bfItem = createItem(m_frame->tree()->parent() ? true : false);
     2631    if (m_previousHistoryItem)
     2632        saveScrollPositionAndViewStateToItem(m_previousHistoryItem.get());
     2633    if (!(clipAtTarget && m_frame == targetFrame)) {
     2634        // save frame state for items that aren't loading (khtml doesn't save those)
     2635        saveDocumentState();
     2636        for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
     2637            bfItem->addChildItem(child->loader()->createItemTree(targetFrame, clipAtTarget));
     2638    }
     2639    if (m_frame == targetFrame)
     2640        bfItem->setIsTargetItem(true);
     2641    return bfItem;
     2642}
     2643
     2644void FrameLoader::saveScrollPositionAndViewStateToItem(HistoryItem* item)
     2645{
     2646    // FIXME: It would be great to work out a way to put this code in WebCore instead of calling through to the client.
     2647    m_client->saveScrollPositionAndViewStateToItem(item);
     2648}
     2649
     2650void FrameLoader::restoreScrollPositionAndViewState()
     2651{
     2652    // FIXME: It would be great to work out a way to put this code in WebCore instead of calling through to the client.
     2653    m_client->restoreScrollPositionAndViewState();
     2654}
     2655
     2656void FrameLoader::purgePageCache()
     2657{
     2658    // This method implements the rule for purging the page cache.
     2659    if (!m_frame->page())
     2660        return;
     2661       
     2662    BackForwardList* bfList = m_frame->page()->backForwardList();
     2663    unsigned sizeLimit = bfList->pageCacheSize();
     2664    unsigned pagesCached = 0;
     2665
     2666    HistoryItemVector items;
     2667    bfList->backListWithLimit(INT_MAX, items);
     2668    RefPtr<HistoryItem> oldestNonSnapbackItem;
     2669   
     2670    unsigned int i = 0;
     2671   
     2672    for (; i < items.size(); ++i) {
     2673        if (items[i]->hasPageCache()) {
     2674            if (!oldestNonSnapbackItem && !items[i]->alwaysAttemptToUsePageCache())
     2675                oldestNonSnapbackItem = items[i];
     2676            pagesCached++;
     2677        }
     2678    }
     2679   
     2680    // Snapback items are never directly purged here.
     2681    if (pagesCached >= sizeLimit && oldestNonSnapbackItem) {
     2682        LOG(PageCache, "Purging back/forward cache, %s\n", oldestNonSnapbackItem->url().url().ascii());
     2683        oldestNonSnapbackItem->setHasPageCache(false);
     2684    }
     2685}
     2686
     2687void FrameLoader::invalidateCurrentItemPageCache()
     2688{
     2689    // When we are pre-commit, the currentItem is where the pageCache data resides   
     2690    PageCache* pageCache = m_currentHistoryItem ? m_currentHistoryItem->pageCache() : 0;
     2691    PageState* pageState = pageCache ? pageCache->pageState() : 0;
     2692
     2693    // FIXME: This is a grotesque hack to fix <rdar://problem/4059059> Crash in RenderFlow::detach
     2694    // Somehow the PageState object is not properly updated, and is holding onto a stale document.
     2695    // Both Xcode and FileMaker see this crash, Safari does not.
     2696   
     2697    ASSERT(!pageState || pageState->document() == m_frame->document());
     2698    if (pageState && pageState->document() == m_frame->document())
     2699        pageState->clear();
     2700   
     2701    if (m_currentHistoryItem)
     2702        m_currentHistoryItem->setHasPageCache(false);
     2703}
     2704
     2705void FrameLoader::saveDocumentState()
     2706{
     2707    // Do not save doc state if the page has a password field and a form that would be submitted via https.
     2708    Document* document = m_frame->document();
     2709    if (document && document->hasPasswordField() && document->hasSecureForm())
     2710        return;
     2711       
     2712    // For a standard page load, we will have a previous item set, which will be used to
     2713    // store the form state.  However, in some cases we will have no previous item, and
     2714    // the current item is the right place to save the state.  One example is when we
     2715    // detach a bunch of frames because we are navigating from a site with frames to
     2716    // another site.  Another is when saving the frame state of a frame that is not the
     2717    // target of the current navigation (if we even decide to save with that granularity).
     2718
     2719    // Because of previousItem's "masking" of currentItem for this purpose, it's important
     2720    // that previousItem be cleared at the end of a page transition.  We leverage the
     2721    // checkLoadComplete recursion to achieve this goal.
     2722
     2723    HistoryItem* item = m_previousHistoryItem ? m_previousHistoryItem.get() : m_currentHistoryItem.get();
     2724    if (!item)
     2725        return;
     2726       
     2727    if (document) {
     2728        LOG(Loading, "WebCoreLoading %s: saving form state to %p", ((String&)m_frame->tree()->name()).ascii().data(), item);
     2729        item->setDocumentState(document->formElementsState());
     2730    }
     2731}
     2732
     2733// Loads content into this frame, as specified by history item
     2734void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType)
     2735{
     2736    KURL itemURL = item->url();
     2737    KURL itemOriginalURL = item->originalURL();
     2738    KURL currentURL = documentLoader()->URL();
     2739    RefPtr<FormData> formData = item->formData();
     2740
     2741    // Are we navigating to an anchor within the page?
     2742    // Note if we have child frames we do a real reload, since the child frames might not
     2743    // match our current frame structure, or they might not have the right content.  We could
     2744    // check for all that as an additional optimization.
     2745    // We also do not do anchor-style navigation if we're posting a form.
     2746   
     2747    // FIXME: These checks don't match the ones in _loadURL:referrer:loadType:target:triggeringEvent:isFormSubmission:
     2748    // Perhaps they should.
     2749    if (!formData && !shouldReload(itemURL, currentURL) && urlsMatchItem(item)) {
     2750#if 0
     2751        // FIXME:  We need to normalize the code paths for anchor navigation.  Something
     2752        // like the following line of code should be done, but also accounting for correct
     2753        // updates to the back/forward list and scroll position.
     2754        // rjw 4/9/03 See 3223929.
     2755        [self _loadURL:itemURL referrer:[[[self dataSource] request] HTTPReferrer] loadType:loadType target:nil triggeringEvent:nil form:nil formValues:nil];
     2756#endif
     2757
     2758        // Must do this maintenance here, since we don't go through a real page reload
     2759        saveScrollPositionAndViewStateToItem(m_currentHistoryItem.get());
     2760
     2761        // FIXME: form state might want to be saved here too
     2762
     2763        // We always call scrollToAnchor here, even if the URL doesn't have an
     2764        // anchor fragment. This is so we'll keep the WebCore Frame's URL up-to-date.
     2765        scrollToAnchor(item->url());
     2766   
     2767        // must do this maintenance here, since we don't go through a real page reload
     2768        m_currentHistoryItem = item;
     2769        restoreScrollPositionAndViewState();
     2770       
     2771        // Fake the URL change by updating the data source's request.  This will no longer
     2772        // be necessary if we do the better fix described above.
     2773        documentLoader()->replaceRequestURLForAnchorScroll(itemURL);
     2774
     2775        dispatchDidChangeLocationWithinPage();
     2776       
     2777        // FrameLoaderClient::didFinishLoad() tells the internal load delegate the load finished with no error
     2778        dispatchDidFinishLoadToClient();
     2779    } else {
     2780        // Remember this item so we can traverse any child items as child frames load
     2781        m_provisionalHistoryItem = item;
     2782
     2783        bool inPageCache = false;
     2784       
     2785        // Check if we'll be using the page cache.  We only use the page cache
     2786        // if one exists and it is less than _backForwardCacheExpirationInterval
     2787        // seconds old.  If the cache is expired it gets flushed here.
     2788        if (item->hasPageCache()) {
     2789            RefPtr<PageCache> pageCache = item->pageCache();
     2790            double interval = currentTime() - pageCache->timeStamp();
     2791           
     2792            // FIXME: 1800 is the current backforwardcache expiration time, but we actually store as a pref -
     2793            // previously, this code was -
     2794            //if (interval <= [[getWebView(self) preferences] _backForwardCacheExpirationInterval]) {
     2795            if (interval <= 1800) {
     2796                load(pageCache->documentLoader(), loadType, 0);   
     2797                inPageCache = true;
     2798            } else {
     2799                LOG (PageCache, "Not restoring page for %s from back/forward cache because cache entry has expired", m_provisionalHistoryItem->url().url().ascii());
     2800                item->setHasPageCache(false);
     2801            }
     2802        }
     2803       
     2804        if (!inPageCache) {
     2805            ResourceRequest request(itemURL);
     2806
     2807            addExtraFieldsToRequest(request, true, formData);
     2808
     2809            // If this was a repost that failed the page cache, we might try to repost the form.
     2810            NavigationAction action;
     2811            if (formData) {
     2812                request.setHTTPMethod("POST");
     2813                request.setHTTPReferrer(item->formReferrer());
     2814                request.setHTTPBody(formData);
     2815                request.setHTTPContentType(item->formContentType());
     2816       
     2817                // FIXME: Slight hack to test if the NSURL cache contains the page we're going to.
     2818                // We want to know this before talking to the policy delegate, since it affects whether
     2819                // we show the DoYouReallyWantToRepost nag.
     2820                //
     2821                // This trick has a small bug (3123893) where we might find a cache hit, but then
     2822                // have the item vanish when we try to use it in the ensuing nav.  This should be
     2823                // extremely rare, but in that case the user will get an error on the navigation.
     2824               
     2825                if (ResourceHandle::willLoadFromCache(request))
     2826                    action = NavigationAction(itemURL, loadType, false);
     2827                else {
     2828                    request.setCachePolicy(ReloadIgnoringCacheData);
     2829                    action = NavigationAction(itemURL, NavigationTypeFormResubmitted);
     2830                }
     2831            } else {
     2832                switch (loadType) {
     2833                    case FrameLoadTypeReload:
     2834                        request.setCachePolicy(ReloadIgnoringCacheData);
     2835                        break;
     2836                    case FrameLoadTypeBack:
     2837                    case FrameLoadTypeForward:
     2838                    case FrameLoadTypeIndexedBackForward:
     2839                        if (itemURL.protocol() == "https")
     2840                            request.setCachePolicy(ReturnCacheDataElseLoad);
     2841                        break;
     2842                    case FrameLoadTypeStandard:
     2843                    case FrameLoadTypeInternal:
     2844                        // no-op: leave as protocol default
     2845                        // FIXME:  I wonder if we ever hit this case
     2846                        break;
     2847                    case FrameLoadTypeSame:
     2848                    case FrameLoadTypeReloadAllowingStaleData:
     2849                    default:
     2850                        ASSERT_NOT_REACHED();
     2851                }
     2852
     2853                action = NavigationAction(itemOriginalURL, loadType, false);
     2854            }
     2855
     2856            load(request, action, loadType, 0);
     2857        }
     2858    }
     2859}
     2860
     2861// Walk the frame tree and ensure that the URLs match the URLs in the item.
     2862bool FrameLoader::urlsMatchItem(HistoryItem* item) const
     2863{
     2864    KURL currentURL = documentLoader()->URL();
     2865   
     2866    if (!equalIgnoringRef(currentURL, item->url()))
     2867        return false;
     2868   
     2869    const HistoryItemVector& childItems = item->children();
     2870   
     2871    unsigned size = childItems.size();
     2872    for (unsigned i = 0; i < size; ++i) {
     2873        Frame* childFrame = m_frame->tree()->child(childItems[i]->target());
     2874        if (childFrame && !childFrame->loader()->urlsMatchItem(childItems[i].get()))
     2875            return false;
     2876    }
     2877
     2878    return true;
     2879}
     2880
     2881// Main funnel for navigating to a previous location (back/forward, non-search snap-back)
     2882// This includes recursion to handle loading into framesets properly
     2883void FrameLoader::goToItem(HistoryItem* targetItem, FrameLoadType type)
     2884{
     2885    ASSERT(!m_frame->tree()->parent());
     2886   
     2887    // shouldGoToHistoryItem is a private delegate method. This is needed to fix:
     2888    // <rdar://problem/3951283> can view pages from the back/forward cache that should be disallowed by Parental Controls
     2889    // Ultimately, history item navigations should go through the policy delegate. That's covered in:
     2890    // <rdar://problem/3979539> back/forward cache navigations should consult policy delegate
     2891    if (shouldGoToHistoryItem(targetItem)) {
     2892        BackForwardList* bfList = m_frame->page()->backForwardList();
     2893        HistoryItem* currentItem = bfList->currentItem();
     2894       
     2895        // Set the BF cursor before commit, which lets the user quickly click back/forward again.
     2896        // - plus, it only makes sense for the top level of the operation through the frametree,
     2897        // as opposed to happening for some/one of the page commits that might happen soon
     2898        bfList->goToItem(targetItem);
     2899        recursiveGoToItem(targetItem, currentItem, type);
     2900    }
     2901}
     2902
     2903// The general idea here is to traverse the frame tree and the item tree in parallel,
     2904// tracking whether each frame already has the content the item requests.  If there is
     2905// a match (by URL), we just restore scroll position and recurse.  Otherwise we must
     2906// reload that frame, and all its kids.
     2907void FrameLoader::recursiveGoToItem(HistoryItem* item, HistoryItem* fromItem, FrameLoadType type)
     2908{
     2909    ASSERT(item);
     2910    ASSERT(fromItem);
     2911   
     2912    KURL itemURL = item->url();
     2913    KURL currentURL = documentLoader()->URL();
     2914   
     2915    // Always reload the target frame of the item we're going to.  This ensures that we will
     2916    // do -some- load for the transition, which means a proper notification will be posted
     2917    // to the app.
     2918    // The exact URL has to match, including fragment.  We want to go through the _load
     2919    // method, even if to do a within-page navigation.
     2920    // The current frame tree and the frame tree snapshot in the item have to match.
     2921    if (!item->isTargetItem() &&
     2922        itemURL == currentURL &&
     2923        ((m_frame->tree()->name().isEmpty() && item->target().isEmpty()) || m_frame->tree()->name() == item->target()) &&
     2924        childFramesMatchItem(item))
     2925    {
     2926        // This content is good, so leave it alone and look for children that need reloading
     2927        // Save form state (works from currentItem, since prevItem is nil)
     2928        ASSERT(!m_previousHistoryItem);
     2929        saveDocumentState();
     2930        saveScrollPositionAndViewStateToItem(m_currentHistoryItem.get());
     2931        m_currentHistoryItem = item;
     2932               
     2933        // Restore form state (works from currentItem)
     2934        restoreDocumentState();
     2935       
     2936        // Restore the scroll position (taken in favor of going back to the anchor)
     2937        restoreScrollPositionAndViewState();
     2938       
     2939        const HistoryItemVector& childItems = item->children();
     2940       
     2941        int size = childItems.size();
     2942        for (int i = 0; i < size; ++i) {
     2943            String childName = childItems[i]->target();
     2944            HistoryItem* fromChildItem = fromItem->childItemWithName(childName);
     2945            ASSERT(fromChildItem || fromItem->isTargetItem());
     2946            Frame* childFrame = m_frame->tree()->child(childName);
     2947            ASSERT(childFrame);
     2948            childFrame->loader()->recursiveGoToItem(childItems[i].get(), fromChildItem, type);
     2949        }
     2950    } else {
     2951        loadItem(item, type);
     2952    }
     2953}
     2954
     2955// helper method that determines whether the subframes described by the item's subitems
     2956// match our own current frameset
     2957bool FrameLoader::childFramesMatchItem(HistoryItem* item) const
     2958{
     2959    const HistoryItemVector& childItems = item->children();
     2960    if (childItems.size() != m_frame->tree()->childCount())
     2961        return false;
     2962   
     2963    unsigned size = childItems.size();
     2964    for (unsigned i = 0; i < size; ++i)
     2965        if (!m_frame->tree()->child(childItems[i]->target()))
     2966            return false;
     2967   
     2968    // Found matches for all item targets
     2969    return true;
     2970}
     2971
     2972void FrameLoader::updateHistoryForStandardLoad()
     2973{
     2974    LOG(History, "WebCoreHistory - Updating History for Standard Load in frame %s", documentLoader()->URL().url().ascii());
     2975
     2976    if (!documentLoader()->isClientRedirect()) {
     2977        KURL url = documentLoader()->urlForHistory();
     2978        if (!url.isEmpty()) {
     2979            if (!privateBrowsingEnabled()) {
     2980                // FIXME: <rdar://problem/4880065> - This will be a hook into the WebCore global history, and this loader/client call will be removed
     2981                updateGlobalHistoryForStandardLoad(url);
     2982            }
     2983            addBackForwardItemClippedAtTarget(true);
     2984        }
     2985    } else {
     2986        if (documentLoader()->unreachableURL().isEmpty()) {
     2987            m_currentHistoryItem->setURL(documentLoader()->URL());
     2988           
     2989            // FIXME: After we can get a ResourceRequest& from the DocumentLoader we instead can call -
     2990            m_currentHistoryItem->setFormInfoFromRequest(documentLoader()->request());
     2991        }
     2992    }
     2993}
     2994
     2995void FrameLoader::updateHistoryForClientRedirect()
     2996{
     2997#if !LOG_DISABLED
     2998    if (documentLoader())
     2999        LOG(History, "WebCoreHistory - Updating History for client redirect in frame %s", documentLoader()->title().utf8().data());
     3000#endif
     3001
     3002    // Clear out form data so we don't try to restore it into the incoming page.  Must happen after
     3003    // webcore has closed the URL and saved away the form state.
     3004    m_currentHistoryItem->clearDocumentState();
     3005    m_currentHistoryItem->clearScrollPoint();
     3006}
     3007
     3008void FrameLoader::updateHistoryForBackForwardNavigation()
     3009{
     3010#if !LOG_DISABLED
     3011    if (documentLoader())
     3012        LOG(History, "WebCoreHistory - Updating History for back/forward navigation in frame %s", documentLoader()->title().utf8().data());
     3013#endif
     3014
     3015    // Must grab the current scroll position before disturbing it
     3016    saveScrollPositionAndViewStateToItem(m_previousHistoryItem.get());
     3017}
     3018
     3019void FrameLoader::updateHistoryForReload()
     3020{
     3021#if !LOG_DISABLED
     3022    if (documentLoader())
     3023        LOG(History, "WebCoreHistory - Updating History for reload in frame %s", documentLoader()->title().utf8().data());
     3024#endif
     3025
     3026    if (m_previousHistoryItem) {
     3027        m_previousHistoryItem->setHasPageCache(false);
     3028   
     3029        if (loadType() == FrameLoadTypeReload)
     3030            saveScrollPositionAndViewStateToItem(m_previousHistoryItem.get());
     3031   
     3032        // Sometimes loading a page again leads to a different result because of cookies. Bugzilla 4072
     3033        if (documentLoader()->unreachableURL().isEmpty())
     3034            m_previousHistoryItem->setURL(documentLoader()->requestURL());
     3035    }
     3036   
     3037    // FIXME: <rdar://problem/4880065> - This will be a hook into the WebCore global history, and this loader/client call will be removed
     3038    // Update the last visited time. Mostly interesting for URL autocompletion statistics.
     3039    updateGlobalHistoryForReload(documentLoader()->originalURL());
     3040}
     3041
     3042void FrameLoader::updateHistoryForInternalLoad()
     3043{
     3044#if !LOG_DISABLED
     3045    if (documentLoader())
     3046        LOG(History, "WebCoreHistory - Updating History for internal load in frame %s", documentLoader()->title().utf8().data());
     3047#endif
     3048
     3049    // Add an item to the item tree for this frame
     3050    ASSERT(!documentLoader()->isClientRedirect());
     3051    Frame* parentFrame = m_frame->tree()->parent();
     3052    // The only case where parentItem is NULL should be when a parent frame loaded an
     3053    // empty URL, which doesn't set up a current item in that parent.
     3054    if (parentFrame) {
     3055        if (parentFrame->loader()->m_currentHistoryItem)
     3056            parentFrame->loader()->m_currentHistoryItem->addChildItem(createItem(true));
     3057    } else {
     3058        // See 3556159. It's not clear if it's valid to be in FrameLoadTypeOnLoadEvent
     3059        // for a top-level frame, but that was a likely explanation for those crashes,
     3060        // so let's guard against it.
     3061        // ...and all FrameLoadTypeOnLoadEvent uses were folded to WebFrameLoadTypeInternal
     3062        LOG_ERROR("No parent frame in transitionToCommitted:, FrameLoadTypeInternal");
     3063    }
     3064}
     3065
     3066void FrameLoader::updateHistoryForCommit()
     3067{
     3068#if !LOG_DISABLED
     3069    if (documentLoader())
     3070        LOG(History, "WebCoreHistory - Updating History for commit in frame %s", documentLoader()->title().utf8().data());
     3071#endif
     3072    FrameLoadType type = loadType();
     3073    if (isBackForwardLoadType(type) ||
     3074        (type == FrameLoadTypeReload && !documentLoader()->unreachableURL().isEmpty())) {
     3075        // Once committed, we want to use current item for saving DocState, and
     3076        // the provisional item for restoring state.
     3077        // Note previousItem must be set before we close the URL, which will
     3078        // happen when the data source is made non-provisional below
     3079        m_previousHistoryItem = m_currentHistoryItem;
     3080        ASSERT(m_provisionalHistoryItem);
     3081        m_currentHistoryItem = m_provisionalHistoryItem;
     3082        m_provisionalHistoryItem = 0;
     3083    }
     3084}
     3085
     3086// Walk the frame tree, telling all frames to save their form state into their current
     3087// history item.
     3088void FrameLoader::saveDocumentAndScrollState()
     3089{
     3090    for (Frame* frame = m_frame; frame; frame = frame->tree()->traverseNext(m_frame)) {
     3091        frame->loader()->saveDocumentState();
     3092        frame->loader()->saveScrollPositionAndViewStateToItem(frame->loader()->currentHistoryItem());
     3093    }
     3094}
     3095
     3096// FIXME: These 6 setter/getters are here for a dwindling number of users in WebKit, WebFrame
     3097// being the primary one.  After they're no longer needed there, they can be removed!
     3098HistoryItem* FrameLoader::currentHistoryItem()
     3099{
     3100    return m_currentHistoryItem.get();
     3101}
     3102
     3103HistoryItem* FrameLoader::previousHistoryItem()
     3104{
     3105    return m_previousHistoryItem.get();
     3106}
     3107
     3108HistoryItem* FrameLoader::provisionalHistoryItem()
     3109{
     3110    return m_provisionalHistoryItem.get();
     3111}
     3112
     3113void FrameLoader::setCurrentHistoryItem(PassRefPtr<HistoryItem> item)
     3114{
     3115    m_currentHistoryItem = item;
     3116}
     3117
     3118void FrameLoader::setPreviousHistoryItem(PassRefPtr<HistoryItem> item)
     3119{
     3120    m_previousHistoryItem = item;
     3121}
     3122
     3123void FrameLoader::setProvisionalHistoryItem(PassRefPtr<HistoryItem> item)
     3124{
     3125    m_provisionalHistoryItem = item;
     3126}
     3127
    22593128} // namespace WebCore
  • trunk/WebCore/loader/FrameLoader.h

    r18242 r18541  
    8383    class Frame;
    8484    class FrameLoaderClient;
     85    class HistoryItem;
    8586    class HTMLFormElement;
    8687    class HTMLFrameOwnerElement;
     
    9091    class NavigationAction;
    9192    class Node;
     93    class PageCache;
    9294    class PageState;
    9395    class RenderPart;
     
    169171            PassRefPtr<FormData>, const String& contentType,
    170172            Event*, HTMLFormElement*, const HashMap<String, String>& formValues);
     173
    171174        void load(const ResourceRequest&);
    172175        void load(const ResourceRequest&, const String& frameName);
    173176        void load(const ResourceRequest&, const NavigationAction&, FrameLoadType, PassRefPtr<FormState>);
     177       
    174178        void load(DocumentLoader*);
    175179        void load(DocumentLoader*, FrameLoadType, PassRefPtr<FormState>);
     
    180184
    181185        void loadResourceSynchronously(const ResourceRequest& request, ResourceResponse& r, Vector<char>& data);
    182        
     186
    183187        bool canHandleRequest(const ResourceRequest&);
    184188
     
    292296        void clientRedirectCancelledOrFinished(bool cancelWithLoadInProgress);
    293297        void clientRedirected(const KURL&, double delay, double fireDate, bool lockHistory, bool isJavaScriptFormAction);
    294 #if PLATFORM(MAC)
    295         void commitProvisionalLoad(NSDictionary *pageCache);
    296 #endif
    297298        bool shouldReload(const KURL& currentURL, const KURL& destinationURL);
    298299
     
    312313        void addExtraFieldsToRequest(NSMutableURLRequest *, bool isMainResource, bool alwaysFromRequest);
    313314#endif
     315
    314316        void addExtraFieldsToRequest(ResourceRequest&, bool isMainResource, bool alwaysFromRequest);
    315317
     
    341343        KURL baseURL() const;
    342344        String baseTarget() const;
     345        KURL dataURLBaseFromRequest(const ResourceRequest& request) const;
    343346
    344347        void scheduleRedirection(double delay, const String& URL, bool lockHistory = true);
     
    384387
    385388        void partClearedInBegin();
    386         void saveDocumentState();
    387389        void restoreDocumentState();
    388390
     
    452454
    453455        void setTitle(const String&);
    454 
    455     private:
     456        void dispatchDidChangeLocationWithinPage();
     457       
     458        void dispatchDidFinishLoadToClient();
     459        void updateGlobalHistoryForStandardLoad(const KURL&);
     460        void updateGlobalHistoryForReload(const KURL&);
     461        bool shouldGoToHistoryItem(HistoryItem*) const;
     462        bool shouldTreatURLAsSameAsCurrent(const KURL&) const;
     463       
     464        void commitProvisionalLoad(PassRefPtr<PageCache>);
     465
     466        void goToItem(HistoryItem*, FrameLoadType);
     467        void saveDocumentAndScrollState();
     468        void saveScrollPositionAndViewStateToItem(HistoryItem*);
     469
     470        // FIXME: These accessors are here for a dwindling number of users in WebKit, WebFrame
     471        // being the primary one.  After they're no longer needed there, they can be removed!
     472        HistoryItem* currentHistoryItem();
     473        HistoryItem* previousHistoryItem();
     474        HistoryItem* provisionalHistoryItem();
     475        void setCurrentHistoryItem(PassRefPtr<HistoryItem>);
     476        void setPreviousHistoryItem(PassRefPtr<HistoryItem>);
     477        void setProvisionalHistoryItem(PassRefPtr<HistoryItem>);
     478       
     479    private:       
     480        PassRefPtr<HistoryItem> createItem(bool useOriginal);
     481        PassRefPtr<HistoryItem> createItemTree(Frame* targetFrame, bool clipAtTarget);
     482
     483        void addBackForwardItemClippedAtTarget(bool doClip);
     484        void restoreScrollPositionAndViewState();
     485        void saveDocumentState();
     486        void loadItem(HistoryItem*, FrameLoadType);
     487        bool urlsMatchItem(HistoryItem*) const;
     488        void purgePageCache();
     489        void invalidateCurrentItemPageCache();
     490        void recursiveGoToItem(HistoryItem*, HistoryItem*, FrameLoadType);
     491        bool childFramesMatchItem(HistoryItem*) const;
     492
     493        void updateHistoryForBackForwardNavigation();
     494        void updateHistoryForReload();
     495        void updateHistoryForStandardLoad();
     496        void updateHistoryForInternalLoad();
     497        void updateHistoryForClientRedirect();
     498        void updateHistoryForCommit();
     499   
    456500        void redirectionTimerFired(Timer<FrameLoader>*);
    457501
     
    466510        bool loadPlugin(RenderPart*, const KURL&, const String& mimeType,
    467511        const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback);
     512       
     513        bool loadProvisionalItemFromPageCache();
     514        bool createPageCache(HistoryItem*);
    468515
    469516        void emitLoadEvent();
     
    488535        void markLoadComplete();
    489536        void commitProvisionalLoad();
     537        void transitionToCommitted(PassRefPtr<PageCache>);
    490538        void frameLoadCompleted();
    491539
     
    512560        static void callContinueFragmentScrollAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue);
    513561        void continueFragmentScrollAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue);
     562        void addHistoryItemForFragmentScroll();
    514563
    515564        void stopPolicyCheck();
    516565
    517566        void closeDocument();
    518 
    519 #if PLATFORM(MAC)
    520         void transitionToCommitted(NSDictionary *pageCache);
    521 #endif
     567       
    522568        void checkLoadCompleteForThisFrame();
    523569
     
    533579        void open(PageState&);
    534580        void opened();
     581        void updateHistoryAfterClientRedirect();
    535582
    536583        bool shouldReloadToHandleUnreachableURL(const ResourceRequest&);
     
    626673
    627674        bool m_openedByJavaScript;
     675       
     676        RefPtr<HistoryItem> m_currentHistoryItem;
     677        RefPtr<HistoryItem> m_previousHistoryItem;
     678        RefPtr<HistoryItem> m_provisionalHistoryItem;
    628679
    629680    };
  • trunk/WebCore/loader/FrameLoaderClient.h

    r18430 r18541  
    4949    class Frame;
    5050    class FrameLoader;
     51    class HistoryItem;
    5152    class KURL;
    5253    class NavigationAction;
     54    class PageCache;
    5355    class String;
    5456    class ResourceError;
     
    5759    class ResourceRequest;
    5860    class ResourceResponse;
    59 
    60     struct LoadErrorResetToken;
    6161
    6262    typedef void (FrameLoader::*FramePolicyFunction)(PolicyAction);
     
    7070        virtual bool hasFrameView() const = 0; // ditto
    7171
    72         virtual bool hasBackForwardList() const = 0;
    73         virtual void resetBackForwardList() = 0;
    74 
    75         virtual bool provisionalItemIsTarget() const = 0;
    76         virtual bool loadProvisionalItemFromPageCache() = 0;
    77         virtual void invalidateCurrentItemPageCache() = 0;
    78 
    7972        virtual bool privateBrowsingEnabled() const = 0;
    8073
    8174        virtual void makeDocumentView() = 0;
    8275        virtual void makeRepresentation(DocumentLoader*) = 0;
    83 #if PLATFORM(MAC)
    84         virtual void setDocumentViewFromPageCache(NSDictionary *) = 0;
    85 #endif
     76        virtual void setDocumentViewFromPageCache(PageCache*) = 0;
    8677        virtual void forceLayout() = 0;
    8778        virtual void forceLayoutForNonHTML() = 0;
    8879
    89         virtual void updateHistoryForCommit() = 0;
    90 
    91         virtual void updateHistoryForBackForwardNavigation() = 0;
    92         virtual void updateHistoryForReload() = 0;
    93         virtual void updateHistoryForStandardLoad() = 0;
    94         virtual void updateHistoryForInternalLoad() = 0;
    95 
    96         virtual void updateHistoryAfterClientRedirect() = 0;
    97 
    9880        virtual void setCopiesOnScroll() = 0;
    99 
    100         virtual LoadErrorResetToken* tokenForLoadErrorReset() = 0;
    101         virtual void resetAfterLoadError(LoadErrorResetToken*) = 0;
    102         virtual void doNotResetAfterLoadError(LoadErrorResetToken*) = 0;
    10381
    10482        virtual void detachedFromParent1() = 0;
     
    159137
    160138        virtual void dispatchDidLoadMainResource(DocumentLoader*) = 0;
    161         virtual void clearLoadingFromPageCache(DocumentLoader*) = 0;
    162         virtual bool isLoadingFromPageCache(DocumentLoader*) = 0;
    163139        virtual void revertToProvisionalState(DocumentLoader*) = 0;
    164140#if PLATFORM(MAC)
     
    190166        virtual void finishedLoading(DocumentLoader*) = 0;
    191167        virtual void finalSetupForReplace(DocumentLoader*) = 0;
     168       
     169        virtual void updateGlobalHistoryForStandardLoad(const KURL&) = 0;
     170        virtual void updateGlobalHistoryForReload(const KURL&) = 0;
     171        virtual bool shouldGoToHistoryItem(HistoryItem*) const = 0;
    192172
    193173#if PLATFORM(MAC)
     
    217197
    218198        virtual void frameLoadCompleted() = 0;
     199        virtual void saveScrollPositionAndViewStateToItem(HistoryItem*) = 0;
    219200        virtual void restoreScrollPositionAndViewState() = 0;
    220201        virtual void provisionalLoadStarted() = 0;
    221         virtual bool shouldTreatURLAsSameAsCurrent(const KURL&) const = 0;
    222         virtual void addHistoryItemForFragmentScroll() = 0;
    223202        virtual void didFinishLoad() = 0;
    224203        virtual void prepareForDataSourceReplacement() = 0;
     
    230209
    231210        virtual String userAgent() = 0;
     211       
     212        virtual void saveDocumentViewToPageCache(PageCache*) = 0;
     213        virtual bool canCachePage() const = 0;
    232214    };
    233215
  • trunk/WebCore/loader/mac/DocumentLoaderMac.mm

    r18242 r18541  
    3434#import "FrameLoader.h"
    3535#import "FrameMac.h"
     36#import "HistoryItem.h"
     37#import "PageCache.h"
    3638#import "PlatformString.h"
    3739#import "WebCoreSystemInterface.h"
     
    112114    , m_primaryLoadComplete(false)
    113115    , m_isClientRedirect(false)
     116    , m_loadingFromPageCache(false)
    114117    , m_stopRecordingResponses(false)
    115118{
     
    174177{
    175178    return request().url();
     179}
     180
     181bool DocumentLoader::getResponseRefreshAndModifiedHeaders(String& refreshOut, String& modified) const
     182{
     183    NSURLResponse *response = m_response.nsURLResponse();
     184    if (![response isKindOfClass:[NSHTTPURLResponse class]])
     185        return false;
     186       
     187    if (NSString *refresh = [[(NSHTTPURLResponse *)response allHeaderFields] objectForKey:@"Refresh"])
     188        refreshOut = refresh;
     189    modified = [wkGetNSURLResponseLastModifiedDate(response)
     190                descriptionWithCalendarFormat:@"%a %b %d %Y %H:%M:%S" timeZone:nil locale:nil];
     191    return true;
    176192}
    177193
     
    283299    if (m_gotFirstByte && !m_committed) {
    284300        m_committed = true;
    285         frameLoader()->commitProvisionalLoad(nil);
     301        frameLoader()->commitProvisionalLoad(0);
    286302    }
    287303}
     
    509525}
    510526
    511 KURL DocumentLoader::URLForHistory() const
     527KURL DocumentLoader::urlForHistory() const
    512528{
    513529    // Return the URL to be used for history and B/F list.
  • trunk/WebCore/loader/mac/FrameLoaderMac.mm

    r18430 r18541  
    4646#import "FrameTree.h"
    4747#import "FrameView.h"
     48#import "HistoryItem.h"
    4849#import "HTMLFormElement.h"
    4950#import "HTMLFrameElement.h"
     
    6667#import "TextResourceDecoder.h"
    6768#import "WebCoreFrameBridge.h"
    68 #import "WebCorePageState.h"
    6969#import "WebCoreSystemInterface.h"
    7070#import "WebDataProtocol.h"
     
    147147    RefPtr<DocumentLoader> oldDocumentLoader = m_documentLoader;
    148148
    149     bool sameURL = m_client->shouldTreatURLAsSameAsCurrent(URL);
     149    bool sameURL = shouldTreatURLAsSameAsCurrent(URL);
    150150   
    151151    // Make sure to do scroll to anchor processing even if the URL is
     
    231231    addExtraFieldsToRequest(r, true, false);
    232232    FrameLoadType type;
    233     if (m_client->shouldTreatURLAsSameAsCurrent(newDocumentLoader->originalRequest().url())) {
     233
     234    if (shouldTreatURLAsSameAsCurrent(newDocumentLoader->originalRequest().url())) {
    234235        r.setCachePolicy(ReloadIgnoringCacheData);
    235236        type = FrameLoadTypeSame;
     
    312313        return;
    313314
    314     m_client->clearLoadingFromPageCache(m_provisionalDocumentLoader.get());
     315    m_provisionalDocumentLoader->setLoadingFromPageCache(false);
    315316
    316317    id identifier = m_client->dispatchIdentifierForInitialRequest
     
    421422        if (document)
    422423            document->setInPageCache(false);
    423         m_client->invalidateCurrentItemPageCache();
     424        invalidateCurrentItemPageCache();
    424425       
    425426        // Call clientRedirectCancelledOrFinished here so that the frame load delegate is notified that the redirect's
     
    451452   
    452453    m_documentLoader->replaceRequestURLForAnchorScroll(URL);
    453     if (!isRedirect && !m_client->shouldTreatURLAsSameAsCurrent(URL)) {
     454    if (!isRedirect && !shouldTreatURLAsSameAsCurrent(URL)) {
    454455        // NB: must happen after _setURL, since we add based on the current request.
    455456        // Must also happen before we openURL and displace the scroll position, since
     
    463464        // but it's not an obvious case.
    464465
    465         m_client->addHistoryItemForFragmentScroll();
     466        addHistoryItemForFragmentScroll();
    466467    }
    467468   
     
    474475        checkLoadComplete();
    475476 
    476     m_client->dispatchDidChangeLocationWithinPage();
     477    dispatchDidChangeLocationWithinPage();
    477478    m_client->didFinishLoad();
    478479}
     
    481482{
    482483    if (m_loadType == FrameLoadTypeStandard && m_documentLoader->isClientRedirect())
    483         m_client->updateHistoryAfterClientRedirect();
    484 
    485     if (m_client->isLoadingFromPageCache(m_documentLoader.get())) {
     484        updateHistoryForClientRedirect();
     485
     486    if (m_documentLoader->isLoadingFromPageCache()) {
    486487        // Force a layout to update view size and thereby update scrollbars.
    487488        m_client->forceLayout();
     
    509510}
    510511
    511 void FrameLoader::commitProvisionalLoad(NSDictionary *pageCache)
    512 {
    513     RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader;
    514    
    515     if (m_loadType != FrameLoadTypeReplace)
    516         closeOldDataSources();
    517    
    518     if (!pageCache)
    519         m_client->makeRepresentation(pdl.get());
    520    
    521     transitionToCommitted(pageCache);
    522    
    523     // Call -_clientRedirectCancelledOrFinished: here so that the frame load delegate is notified that the redirect's
    524     // status has changed, if there was a redirect.  The frame load delegate may have saved some state about
    525     // the redirect in its -webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:.  Since we are
    526     // just about to commit a new page, there cannot possibly be a pending redirect at this point.
    527     if (m_sentRedirectNotification)
    528         clientRedirectCancelledOrFinished(false);
    529    
    530     WebCorePageState *pageState = [pageCache objectForKey:WebCorePageCacheStateKey];
    531     if (PageState* frameState = [pageState impl]) {
    532         open(*frameState);
    533         frameState->clear();
    534     } else {
    535         NSURLResponse *response = pdl->response().nsURLResponse();
    536    
    537         KURL URL;
    538 #if PLATFORM(MAC)
    539         if (WebDataRequestParameters* params = [pdl->request().nsURLRequest() _webDataRequestParametersForReading])
    540             URL = params->baseURL;
    541 #endif
    542 
    543         if (URL.isEmpty())
    544             URL = [response URL];
    545         if (URL.isEmpty())
    546             URL = "about:blank";   
    547 
    548         m_responseMIMEType = [response MIMEType];
    549         if (didOpenURL(URL)) {
    550             if ([response isKindOfClass:[NSHTTPURLResponse class]])
    551                 if (NSString *refresh = [[(NSHTTPURLResponse *)response allHeaderFields] objectForKey:@"Refresh"])
    552                     m_responseRefreshHeader = refresh;
    553             m_responseModifiedHeader = [wkGetNSURLResponseLastModifiedDate(response)
    554                 descriptionWithCalendarFormat:@"%a %b %d %Y %H:%M:%S" timeZone:nil locale:nil];
    555         }
    556     }
    557     opened();
     512KURL FrameLoader::dataURLBaseFromRequest(const ResourceRequest& request) const
     513{
     514    if (WebDataRequestParameters* params = [request.nsURLRequest() _webDataRequestParametersForReading])
     515        return params->baseURL;
     516    return KURL();
    558517}
    559518
     
    733692    // The title doesn't get communicated to the WebView until we are committed.
    734693    if (loader->isCommitted())
    735         if (NSURL *URLForHistory = canonicalURL(loader->URLForHistory().getNSURL())) {
     694        if (NSURL *urlForHistory = canonicalURL(loader->urlForHistory().getNSURL())) {
    736695            // Must update the entries in the back-forward list too.
    737696            // This must go through the WebFrame because it has the right notion of the current b/f item.
    738             m_client->setTitle(loader->title(), URLForHistory);
     697            m_client->setTitle(loader->title(), urlForHistory);
    739698            m_client->setMainFrameDocumentReady(true); // update observers with new DOMDocument
    740699            m_client->dispatchDidReceiveTitle(loader->title());
     
    848807    ASSERT(m_policyDocumentLoader || !m_provisionalDocumentLoader->unreachableURL().isEmpty());
    849808
    850     BOOL isTargetItem = m_client->provisionalItemIsTarget();
     809    bool isTargetItem = m_provisionalHistoryItem ? m_provisionalHistoryItem->isTargetItem() : false;
    851810
    852811    // Two reasons we can't continue:
     
    868827        // problem that we have optimistically moved the b/f cursor already, so move it back.  For sanity,
    869828        // we only do this when punting a navigation for the target frame or top-level frame. 
    870         if ((isTargetItem || isLoadingMainFrame()) && isBackForwardLoadType(m_policyLoadType))
    871             m_client->resetBackForwardList();
    872 
     829        if ((isTargetItem || isLoadingMainFrame()) && isBackForwardLoadType(m_policyLoadType) && m_frame->page()) {
     830            Frame* mainFrame = m_frame->page()->mainFrame();
     831            if (HistoryItem* resetItem = mainFrame->loader()->m_currentHistoryItem.get())
     832                m_frame->page()->backForwardList()->goToItem(resetItem);
     833        }
    873834        return;
    874835    }
     
    882843    setPolicyDocumentLoader(0);
    883844
    884     if (isBackForwardLoadType(type) && m_client->loadProvisionalItemFromPageCache())
     845    if (isBackForwardLoadType(type) && loadProvisionalItemFromPageCache())
    885846        return;
    886847
     
    889850    else
    890851        continueAfterWillSubmitForm();
    891 }
    892 
    893 void FrameLoader::transitionToCommitted(NSDictionary *pageCache)
    894 {
    895     ASSERT(m_client->hasWebView());
    896     ASSERT(m_state == FrameStateProvisional);
    897 
    898     if (m_state != FrameStateProvisional)
    899         return;
    900 
    901     m_client->setCopiesOnScroll();
    902     m_client->updateHistoryForCommit();
    903 
    904     // The call to closeURL invokes the unload event handler, which can execute arbitrary
    905     // JavaScript. If the script initiates a new load, we need to abandon the current load,
    906     // or the two will stomp each other.
    907     DocumentLoader* pdl = m_provisionalDocumentLoader.get();
    908     closeURL();
    909     if (pdl != m_provisionalDocumentLoader)
    910         return;
    911 
    912     commitProvisionalLoad();
    913 
    914     // Handle adding the URL to the back/forward list.
    915     DocumentLoader* dl = m_documentLoader.get();
    916     String ptitle = dl->title();
    917 
    918     switch (m_loadType) {
    919     case FrameLoadTypeForward:
    920     case FrameLoadTypeBack:
    921     case FrameLoadTypeIndexedBackForward:
    922         if (m_client->hasBackForwardList()) {
    923             m_client->updateHistoryForBackForwardNavigation();
    924 
    925             // Create a document view for this document, or used the cached view.
    926             if (pageCache)
    927                 m_client->setDocumentViewFromPageCache(pageCache);
    928             else
    929                 m_client->makeDocumentView();
    930         }
    931         break;
    932 
    933     case FrameLoadTypeReload:
    934     case FrameLoadTypeSame:
    935     case FrameLoadTypeReplace:
    936         m_client->updateHistoryForReload();
    937         m_client->makeDocumentView();
    938         break;
    939 
    940     // FIXME - just get rid of this case, and merge FrameLoadTypeReloadAllowingStaleData with the above case
    941     case FrameLoadTypeReloadAllowingStaleData:
    942         m_client->makeDocumentView();
    943         break;
    944 
    945     case FrameLoadTypeStandard:
    946         m_client->updateHistoryForStandardLoad();
    947         m_client->makeDocumentView();
    948         break;
    949 
    950     case FrameLoadTypeInternal:
    951         m_client->updateHistoryForInternalLoad();
    952         m_client->makeDocumentView();
    953         break;
    954 
    955     // FIXME Remove this check when dummy ds is removed (whatever "dummy ds" is).
    956     // An exception should be thrown if we're in the FrameLoadTypeUninitialized state.
    957     default:
    958         ASSERT_NOT_REACHED();
    959     }
    960 
    961     // Tell the client we've committed this URL.
    962     ASSERT(m_client->hasFrameView());
    963     m_client->dispatchDidCommitLoad();
    964    
    965     // If we have a title let the WebView know about it.
    966     if (!ptitle.isNull())
    967         m_client->dispatchDidReceiveTitle(ptitle);
    968852}
    969853
     
    987871
    988872            // Check all children first.
    989             LoadErrorResetToken *resetToken = m_client->tokenForLoadErrorReset();
     873            RefPtr<HistoryItem> item;
     874            if (isBackForwardLoadType(loadType()) && m_frame == m_frame->page()->mainFrame())
     875                item = m_currentHistoryItem;
     876               
    990877            bool shouldReset = true;
    991878            if (!pdl->isLoadingInAPISense()) {
     
    1010897                }
    1011898            }
    1012             if (shouldReset)
    1013                 m_client->resetAfterLoadError(resetToken);
    1014             else
    1015                 m_client->doNotResetAfterLoadError(resetToken);
     899            if (shouldReset && item && m_frame->page())
     900                 m_frame->page()->backForwardList()->goToItem(item.get());
     901
    1016902            return;
    1017903        }
     
    1032918            // If the user had a scroll point, scroll to it, overriding the anchor point if any.
    1033919            if ((isBackForwardLoadType(m_loadType) || m_loadType == FrameLoadTypeReload)
    1034                     && m_client->hasBackForwardList())
    1035                 m_client->restoreScrollPositionAndViewState();
     920                    && m_frame->page() && m_frame->page()->backForwardList())
     921                restoreScrollPositionAndViewState();
    1036922
    1037923            NSError *error = dl->mainDocumentError();
     
    11521038}
    11531039
    1154 void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, bool mainResource, bool alwaysFromRequest)
    1155 {
    1156     applyUserAgent(request);
    1157    
    1158     if (m_loadType == FrameLoadTypeReload)
    1159         request.setHTTPHeaderField("Cache-Control", "max-age=0");
    1160    
    1161     // Don't set the cookie policy URL if it's already been set.
    1162     if (request.mainDocumentURL().isEmpty()) {
    1163         if (mainResource && (isLoadingMainFrame() || alwaysFromRequest))
    1164             request.setMainDocumentURL(request.url());
    1165         else
    1166             request.setMainDocumentURL(m_frame->page()->mainFrame()->loader()->url());
    1167     }
    1168    
    1169     if (mainResource)
    1170         request.setHTTPAccept("text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
    1171 }
    1172 
    11731040void FrameLoader::addExtraFieldsToRequest(NSMutableURLRequest *request, bool mainResource, bool alwaysFromRequest)
    11741041{
     
    13521219}
    13531220
    1354 void FrameLoader::saveDocumentState()
    1355 {
    1356     // Do not save doc state if the page has a password field and a form that would be submitted via https.
    1357     Document* document = m_frame->document();
    1358     if (!(document && document->hasPasswordField() && document->hasSecureForm())) {
    1359         BEGIN_BLOCK_OBJC_EXCEPTIONS;
    1360         [Mac(m_frame)->bridge() saveDocumentState];
    1361         END_BLOCK_OBJC_EXCEPTIONS;
    1362     }
    1363 }
    1364 
    1365 void FrameLoader::restoreDocumentState()
    1366 {
    1367     BEGIN_BLOCK_OBJC_EXCEPTIONS;
    1368     [Mac(m_frame)->bridge() restoreDocumentState];
    1369     END_BLOCK_OBJC_EXCEPTIONS;
    1370 }
    1371 
    13721221String FrameLoader::overrideMediaType() const
    13731222{
     
    13981247{
    13991248    return [Mac(m_frame)->bridge() historyLength];
    1400 }
    1401 
    1402 void FrameLoader::goBackOrForward(int distance)
    1403 {
    1404     BEGIN_BLOCK_OBJC_EXCEPTIONS;
    1405     [Mac(m_frame)->bridge() goBackOrForward:distance];
    1406     END_BLOCK_OBJC_EXCEPTIONS;
    14071249}
    14081250
  • trunk/WebCore/page/FrameTree.cpp

    r18460 r18541  
    9494    Frame*& newLocationForPrevious = m_lastChild == child ? m_lastChild : child->tree()->m_nextSibling->tree()->m_previousSibling;
    9595    swap(newLocationForNext, child->tree()->m_nextSibling);
    96     swap(newLocationForPrevious, child->tree()->m_previousSibling);
     96    // For some inexplicable reason, the following line does not compile without the explicit std:: namepsace
     97    std::swap(newLocationForPrevious, child->tree()->m_previousSibling);
    9798
    9899    child->tree()->m_previousSibling = 0;
  • trunk/WebCore/page/Page.cpp

    r18417 r18541  
    3131#include "FrameLoader.h"
    3232#include "FrameTree.h"
     33#include "FrameView.h"
     34#include "HistoryItem.h"
     35#include "RenderWidget.h"
    3336#include "SelectionController.h"
    3437#include "Settings.h"
     
    5154    , m_focusController(new FocusController(this))
    5255    , m_contextMenuController(new ContextMenuController(this, contextMenuClient))
     56    , m_backForwardList(new BackForwardList)
    5357    , m_settings(new Settings)
    5458    , m_editorClient(editorClient)
     
    8387   
    8488    m_editorClient->pageDestroyed();
     89    m_backForwardList->close();
    8590}
    8691
     
    8994    ASSERT(!m_mainFrame); // Should only be called during initialization
    9095    m_mainFrame = mainFrame;
     96}
     97
     98BackForwardList* Page::backForwardList()
     99{
     100    return m_backForwardList.get();
     101}
     102
     103bool Page::goBack()
     104{
     105    HistoryItem* item = m_backForwardList->backItem();
     106   
     107    if (item) {
     108        goToItem(item, FrameLoadTypeBack);
     109        return true;
     110    }
     111    return false;
     112}
     113
     114bool Page::goForward()
     115{
     116    HistoryItem* item = m_backForwardList->forwardItem();
     117   
     118    if (item) {
     119        goToItem(item, FrameLoadTypeForward);
     120        return true;
     121    }
     122    return false;
     123}
     124
     125void Page::goToItem(HistoryItem* item, FrameLoadType type)
     126{
     127    // We never go back/forward on a per-frame basis, so the target must be the main frame
     128    ASSERT(item->target().isEmpty() || m_mainFrame->tree()->find(item->target()) == m_mainFrame);
     129
     130    // Abort any current load if we're going to a history item
     131    m_mainFrame->loader()->stopAllLoaders();
     132    m_mainFrame->loader()->goToItem(item, type);
    91133}
    92134
  • trunk/WebCore/page/Page.h

    r18417 r18541  
    2222#define Page_h
    2323
     24#include "BackForwardList.h"
     25#include "Chrome.h"
     26#include "ContextMenuController.h"
     27#include "FrameLoaderTypes.h"
    2428#include "PlatformString.h"
    2529#include <wtf/HashSet.h>
     
    5660        Frame* mainFrame() const { return m_mainFrame.get(); }
    5761
     62        BackForwardList* backForwardList();
     63
     64        // FIXME: The following three methods don't fall under the responsibilities of the Page object
     65        // They seem to fit a hypothetical Page-controller object that would be akin to the
     66        // Frame-FrameLoader relationship.  They have to live here now, but should move somewhere that
     67        // makes more sense when that class exists.
     68        bool goBack();
     69        bool goForward();
     70        void goToItem(HistoryItem*, FrameLoadType);
     71       
    5872        void setGroupName(const String&);
    5973        String groupName() const { return m_groupName; }
     
    89103        OwnPtr<FocusController> m_focusController;
    90104        OwnPtr<ContextMenuController> m_contextMenuController;
     105        RefPtr<BackForwardList> m_backForwardList;
    91106        OwnPtr<Settings> m_settings;
    92107
     
    99114        bool m_defersLoading;
    100115
     116       
    101117#if PLATFORM(WIN)
    102118        static HINSTANCE s_instanceHandle;
  • trunk/WebCore/page/PageState.h

    r17770 r18541  
    2323 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
     25 
     26#ifndef PageState_H
     27#define PageState_H
    2528
    2629#include "KURL.h"
     
    6669        OwnPtr<KJS::SavedBuiltins> m_interpreterBuiltins;
    6770        OwnPtr<KJS::PausedTimeouts> m_pausedTimeouts;
    68     };
     71    }; // class PageState
    6972
    70 }
     73} // namespace WebCore
     74
     75#endif // PageState_H
  • trunk/WebCore/page/mac/FrameMac.h

    r18481 r18541  
    9090
    9191public:
    92     virtual void setView(FrameView*);
    93    
    9492    static WebCoreFrameBridge* bridgeForWidget(const Widget*);
    9593
  • trunk/WebCore/page/mac/FrameMac.mm

    r18481 r18541  
    341341}
    342342
    343 void FrameMac::setView(FrameView *view)
    344 {
    345     Frame::setView(view);
    346    
    347 #ifdef MULTIPLE_FORM_SUBMISSION_PROTECTION
    348     // Only one form submission is allowed per view of a part.
    349     // Since this part may be getting reused as a result of being
    350     // pulled from the back/forward cache, reset this flag.
    351     loader()->resetMultipleFormSubmissionProtection();
    352 #endif
    353 }
    354 
    355343void FrameMac::setStatusBarText(const String& status)
    356344{
  • trunk/WebCore/page/mac/WebCoreFrameBridge.h

    r18399 r18541  
    111111- (void)addData:(NSData *)data;
    112112
    113 - (void)saveDocumentState;
    114 - (void)restoreDocumentState;
    115 
    116113- (void)clearFrame;
    117114
     
    301298- (NSView *)nextKeyViewOutsideWebFrameViews;
    302299- (NSView *)previousKeyViewOutsideWebFrameViews;
    303 
    304 - (void)saveDocumentState:(NSArray *)documentState;
    305 - (NSArray *)documentState;
    306300
    307301- (void)setNeedsReapplyStyles;
     
    331325
    332326- (int)historyLength;
    333 - (void)goBackOrForward:(int)distance;
    334327- (BOOL)canGoBackOrForward:(int)distance;
    335328- (NSURL *)historyURL:(int)distance;
  • trunk/WebCore/page/mac/WebCoreFrameBridge.mm

    r18481 r18541  
    301301}
    302302
    303 - (void)saveDocumentState
    304 {
    305     Vector<String> stateVector;
    306     if (Document* doc = m_frame->document())
    307         stateVector = doc->formElementsState();
    308     size_t size = stateVector.size();
    309     NSMutableArray* stateArray = [[NSMutableArray alloc] initWithCapacity:size];
    310     for (size_t i = 0; i < size; ++i) {
    311         NSString* s = stateVector[i];
    312         id o = s ? (id)s : (id)[NSNull null];
    313         [stateArray addObject:o];
    314     }
    315     [self saveDocumentState:stateArray];
    316     [stateArray release];
    317 }
    318 
    319 - (void)restoreDocumentState
    320 {
    321     Document* doc = m_frame->document();
    322     if (!doc)
    323         return;
    324     NSArray* stateArray = [self documentState];
    325     size_t size = [stateArray count];
    326     Vector<String> stateVector;
    327     stateVector.reserveCapacity(size);
    328     for (size_t i = 0; i < size; ++i) {
    329         id o = [stateArray objectAtIndex:i];
    330         NSString* s = [o isKindOfClass:[NSString class]] ? o : 0;
    331         stateVector.append(s);
    332     }
    333     doc->setStateForNewFormElements(stateVector);
    334 }
    335 
    336303- (BOOL)scrollOverflowInDirection:(WebScrollDirection)direction granularity:(WebScrollGranularity)granularity
    337304{
  • trunk/WebCore/platform/KURL.cpp

    r18165 r18541  
    14831483}
    14841484
    1485 }
     1485#ifndef NDEBUG
     1486void KURL::print() const
     1487{
     1488    printf("%s\n", urlString.ascii());
     1489}
     1490#endif
     1491
     1492}
  • trunk/WebCore/platform/KURL.h

    r18203 r18541  
    114114    friend bool operator==(const KURL &, const KURL &);
    115115
     116#ifndef NDEBUG
     117    void print() const;
     118#endif
     119
    116120private:
    117121    bool isHierarchical() const;
  • trunk/WebCore/platform/Logging.cpp

    r18371 r18541  
    4646WTFLogChannel LogBackForward =       { 0x00002000, "WebCoreLogLevel", WTFLogChannelOff };
    4747WTFLogChannel LogHistory =           { 0x00004000, "WebCoreLogLevel", WTFLogChannelOff };
     48WTFLogChannel LogPageCache =         { 0x00008000, "WebCoreLogLevel", WTFLogChannelOff };
     49
    4850WTFLogChannel LogNetwork =           { 0x00100000, "WebCoreLogLevel", WTFLogChannelOff };
    4951
     52
    5053}
  • trunk/WebCore/platform/Logging.h

    r18326 r18541  
    4747    extern WTFLogChannel LogBackForward;
    4848    extern WTFLogChannel LogHistory;
     49    extern WTFLogChannel LogPageCache;
    4950    extern WTFLogChannel LogNetwork;
    5051
  • trunk/WebCore/platform/PlatformString.h

    r17722 r18541  
    212212inline bool operator!=(const DeprecatedString& b, const String& a ) { return !(a == b); }
    213213
     214#ifdef __OBJC__
     215// This is for situations in WebKit where the long standing behavior has been
     216// "nil if empty", so we try to maintain longstanding behavior for the sake of
     217// entrenched clients
     218inline NSString* nsStringNilIfEmpty(const String& str) {  return str.isEmpty() ? nil : (NSString*)str; }
     219#endif
     220
    214221}
    215222
  • trunk/WebCore/platform/SystemTime.h

    r12341 r18541  
    3333    double currentTime();
    3434
     35    // Return the number of seconds since a user event has been generated
     36    float userIdleTime();
     37   
    3538}
    3639
  • trunk/WebCore/platform/graphics/svg/SVGImage.cpp

    r18475 r18541  
    3434#include "GraphicsContext.h"
    3535#include "Page.h"
     36#include "PageCache.h"
    3637#include "ResourceError.h"
    3738#include "SVGDocument.h"
  • trunk/WebCore/platform/graphics/svg/SVGImageEmptyClients.h

    r18472 r18541  
    127127   
    128128    virtual void setCopiesOnScroll() { }
    129    
    130     virtual LoadErrorResetToken* tokenForLoadErrorReset() { return 0; }
    131     virtual void resetAfterLoadError(LoadErrorResetToken*) { }
    132     virtual void doNotResetAfterLoadError(LoadErrorResetToken*) { }
    133    
     129       
    134130    virtual void detachedFromParent1() { }
    135131    virtual void detachedFromParent2() { }
     
    260256   
    261257    virtual String userAgent() { return ""; }
     258   
     259    virtual void setDocumentViewFromPageCache(PageCache*) { }
     260    virtual void updateGlobalHistoryForStandardLoad(const KURL&) { }
     261    virtual void updateGlobalHistoryForReload(const KURL&) { }
     262    virtual bool shouldGoToHistoryItem(HistoryItem*) const { return false; }
     263    virtual void saveScrollPositionAndViewStateToItem(HistoryItem*) { }
     264    virtual void saveDocumentViewToPageCache(PageCache*) { }
     265    virtual bool canCachePage() const { return false; }
     266
    262267};
    263268
    264269class SVGEmptyEditorClient : public EditorClient {
    265270public:
    266     virtual ~SVGEmptyEditorClient() {  }
     271    virtual ~SVGEmptyEditorClient() { }
    267272    virtual void pageDestroyed() { }
    268273   
  • trunk/WebCore/platform/mac/LoggingMac.mm

    r18326 r18541  
    6060    initializeLogChannel(LogBackForward);
    6161    initializeLogChannel(LogHistory);
     62    initializeLogChannel(LogPageCache);
    6263    initializeLogChannel(LogNetwork);
    6364}
  • trunk/WebCore/platform/mac/SystemTimeMac.cpp

    r12762 r18541  
    2727#include "SystemTime.h"
    2828
     29#include "WebCoreSystemInterface.h"
     30
    2931#include <CoreFoundation/CFDate.h>
    3032
     
    3638}
    3739
     40float userIdleTime()
     41{
     42    return wkSecondsSinceLastInputEvent();
    3843}
     44
     45}
  • trunk/WebCore/platform/mac/WebCoreSystemInterface.h

    r18248 r18541  
    116116extern BOOL (*wkSupportsMultipartXMixedReplace)(NSMutableURLRequest *);
    117117extern Class (*wkNSURLProtocolClassForReqest)(NSURLRequest *);
    118 
     118extern float (*wkSecondsSinceLastInputEvent)(void);
    119119#ifdef __cplusplus
    120120}
  • trunk/WebCore/platform/mac/WebCoreSystemInterface.mm

    r18248 r18541  
    7676BOOL (*wkSupportsMultipartXMixedReplace)(NSMutableURLRequest *);
    7777Class (*wkNSURLProtocolClassForReqest)(NSURLRequest *);
     78float (*wkSecondsSinceLastInputEvent)(void);
     79
  • trunk/WebCore/platform/network/FormData.cpp

    r17607 r18541  
    3535{
    3636    appendData(s.data(), s.length());
     37}
     38
     39FormData::FormData(const FormData& data)
     40    : Shared<FormData>()
     41    , m_elements(data.m_elements)
     42{
     43}
     44
     45PassRefPtr<FormData> FormData::copy() const
     46{
     47    return new FormData(*this);
    3748}
    3849
  • trunk/WebCore/platform/network/FormData.h

    r18203 r18541  
    6060    FormData(const void* data, size_t);
    6161    FormData(const CString&);
     62    PassRefPtr<FormData> copy() const;
    6263   
    6364    void appendData(const void* data, size_t);
     
    7172
    7273private:
     74     FormData(const FormData&);
     75     
    7376     Vector<FormDataElement> m_elements;
    7477};
  • trunk/WebCore/platform/network/ResourceHandle.h

    r18218 r18541  
    8686
    8787    static void loadResourceSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data);
    88 
     88    static bool willLoadFromCache(ResourceRequest&);
     89   
    8990    ~ResourceHandle();
    9091
  • trunk/WebCore/platform/network/mac/ResourceHandleMac.mm

    r18231 r18541  
    183183}
    184184
     185bool ResourceHandle::willLoadFromCache(ResourceRequest& request)
     186{
     187    request.setCachePolicy(ReturnCacheDataDontLoad);
     188    NSURLResponse *nsURLResponse = nil;
     189    BEGIN_BLOCK_OBJC_EXCEPTIONS;
     190   
     191   [NSURLConnection sendSynchronousRequest:request.nsURLRequest() returningResponse:&nsURLResponse error:nil];
     192   
     193    END_BLOCK_OBJC_EXCEPTIONS;
     194   
     195    return nsURLResponse;
     196}
     197
    185198void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data)
    186199{
  • trunk/WebCore/platform/qt/TemporaryLinkStubs.cpp

    r18257 r18541  
    6161#include "AXObjectCache.h"
    6262#include "IconLoader.h"
     63#include "SystemTime.h"
    6364
    6465using namespace WebCore;
     
    137138String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String &challengeString, const KURL &url) { return String(); }
    138139   
     140float userIdleTime() { notImplemented(); return 0.0; }
     141
    139142}
    140143
  • trunk/WebCore/rendering/RenderPart.h

    r18163 r18541  
    5757
    5858    Frame* m_frame;
    59     bool m_disconnectOwnerElementWhenDestroyed;
    6059};
    6160
  • trunk/WebKit/ChangeLog

    r18540 r18541  
     12007-01-02  Brady Eidson  <beidson@apple.com>
     2
     3        Reviewed extensively and repeatedly by Darin
     4
     5        <rdar://problem/4887137> - WebCore Back/Forward Cache
     6        Most things not specifically commented on in the ChangeLog can be summed up as
     7        "Do things exactly the same way as we used to, but just stick in WebCore-land as much as possible"
     8
     9        * History/WebBackForwardList.mm:
     10        (kitPrivate): Convenience functions to help with subbing "WebBackForwardListPrivate" for WebCore::BackForwardList
     11        (core):
     12        (backForwardListWrappers): A HashMap pattern used to map WebCore objects to their WebKit counterpart
     13        (kit):
     14        (+[WebBackForwardList setDefaultPageCacheSizeIfNecessary]):
     15        (-[WebBackForwardList initWithWebCoreBackForwardList:]):
     16        (-[WebBackForwardList init]):
     17        (-[WebBackForwardList dealloc]):
     18        (-[WebBackForwardList finalize]):
     19        (-[WebBackForwardList _close]):
     20        (-[WebBackForwardList addItem:]):
     21        (-[WebBackForwardList removeItem:]):
     22        (-[WebBackForwardList containsItem:]):
     23        (-[WebBackForwardList goBack]):
     24        (-[WebBackForwardList goForward]):
     25        (-[WebBackForwardList goToItem:]):
     26        (-[WebBackForwardList backItem]):
     27        (-[WebBackForwardList currentItem]):
     28        (-[WebBackForwardList forwardItem]):
     29        (vectorToNSArray):
     30        (-[WebBackForwardList backListWithLimit:]):
     31        (-[WebBackForwardList forwardListWithLimit:]):
     32        (-[WebBackForwardList capacity]):
     33        (-[WebBackForwardList setCapacity:]):
     34        (-[WebBackForwardList description]):
     35        (-[WebBackForwardList _clearPageCache]):
     36        (-[WebBackForwardList setPageCacheSize:]):
     37        (-[WebBackForwardList pageCacheSize]):
     38        (-[WebBackForwardList _usesPageCache]):
     39        (-[WebBackForwardList backListCount]):
     40        (-[WebBackForwardList forwardListCount]):
     41        (-[WebBackForwardList itemAtIndex:]):
     42        * History/WebBackForwardListInternal.h: Added.
     43
     44        * History/WebHistory.m: Removed.
     45        * History/WebHistory.mm: Added - Needed to be .mm to accept C++ header style
     46        (-[_WebCoreHistoryProvider containsItemForURLLatin1:length:]):
     47        (-[_WebCoreHistoryProvider containsItemForURLUnicode:length:]):
     48
     49        * History/WebHistoryItem.mm:
     50        (kitPrivate): Same pattern as WebBackForwardList
     51        (core):
     52        (historyItemWrappers):
     53        (WKNotifyHistoryItemChanged):
     54        (-[WebHistoryItem init]):
     55        (-[WebHistoryItem initWithURLString:title:lastVisitedTimeInterval:]):
     56        (-[WebHistoryItem dealloc]):
     57        (-[WebHistoryItem finalize]):
     58        (-[WebHistoryItem copyWithZone:]):
     59        (-[WebHistoryItem URLString]):
     60        (-[WebHistoryItem originalURLString]):
     61        (-[WebHistoryItem title]):
     62        (-[WebHistoryItem setAlternateTitle:]):
     63        (-[WebHistoryItem alternateTitle]):
     64        (-[WebHistoryItem icon]):
     65        (-[WebHistoryItem lastVisitedTimeInterval]):
     66        (-[WebHistoryItem hash]):
     67        (-[WebHistoryItem isEqual:]):
     68        (-[WebHistoryItem description]):
     69        (kit):
     70        (+[WebHistoryItem entryWithURL:]):
     71        (+[WebHistoryItem initWindowWatcherIfNecessary]):
     72        (-[WebHistoryItem initWithURL:target:parent:title:]):
     73        (-[WebHistoryItem initWithWebCoreHistoryItem:]):
     74        (-[WebHistoryItem setTitle:]):
     75        (-[WebHistoryItem setVisitCount:]):
     76        (-[WebHistoryItem setViewState:]):
     77        (-[WebHistoryItem _mergeAutoCompleteHints:]):
     78        (-[WebHistoryItem initFromDictionaryRepresentation:]):
     79        (-[WebHistoryItem scrollPoint]):
     80        (-[WebHistoryItem _transientPropertyForKey:]):
     81        (-[WebHistoryItem _setTransientProperty:forKey:]):
     82        (-[WebHistoryItem dictionaryRepresentation]):
     83        (-[WebHistoryItem target]):
     84        (-[WebHistoryItem isTargetItem]):
     85        (-[WebHistoryItem visitCount]):
     86        (-[WebHistoryItem RSSFeedReferrer]):
     87        (-[WebHistoryItem setRSSFeedReferrer:]):
     88        (-[WebHistoryItem children]):
     89        (-[WebHistoryItem setAlwaysAttemptToUsePageCache:]):
     90        (-[WebHistoryItem URL]):
     91        (-[WebHistoryItem _setLastVisitedTimeInterval:]):
     92        (-[WebHistoryItem _lastVisitedDate]):
     93        (-[WebHistoryItem targetItem]):
     94        (+[WebHistoryItem _releaseAllPendingPageCaches]):
     95        (-[WebWindowWatcher windowWillClose:]):
     96        * History/WebHistoryItemInternal.h:
     97        * History/WebHistoryItemPrivate.h:
     98
     99        * WebCoreSupport/WebFrameBridge.mm:
     100        * WebCoreSupport/WebFrameLoaderClient.h:
     101        * WebCoreSupport/WebFrameLoaderClient.mm:
     102        (WebFrameLoaderClient::setDocumentViewFromPageCache):
     103        (WebFrameLoaderClient::detachedFromParent1):
     104        (WebFrameLoaderClient::loadedFromPageCache):
     105        (WebFrameLoaderClient::updateGlobalHistoryForStandardLoad):
     106        (WebFrameLoaderClient::updateGlobalHistoryForReload):
     107        (WebFrameLoaderClient::shouldGoToHistoryItem):
     108        (WebFrameLoaderClient::frameLoadCompleted):
     109        (WebFrameLoaderClient::saveScrollPositionAndViewStateToItem):
     110        (WebFrameLoaderClient::restoreScrollPositionAndViewState):
     111        (WebFrameLoaderClient::provisionalLoadStarted):
     112        (WebFrameLoaderClient::setTitle):
     113        (WebFrameLoaderClient::saveDocumentViewToPageCache):
     114        (WebFrameLoaderClient::canCachePage):
     115
     116        * WebCoreSupport/WebSystemInterface.m:
     117        (InitWebCoreSystemInterface):
     118
     119        * WebKit.xcodeproj/project.pbxproj:
     120
     121        * WebView/WebDataSource.mm:
     122        * WebView/WebDataSourceInternal.h:
     123
     124        * WebView/WebFrame.mm:
     125        (-[WebFramePrivate dealloc]):
     126        (-[WebFrame _canCachePage]):
     127        (-[WebFrame _loadURL:referrer:intoChild:]):
     128        * WebView/WebFrameInternal.h:
     129
     130        * WebView/WebFrameView.mm:
     131        (-[WebFrameView initWithFrame:]):
     132        (-[WebFrameView keyDown:]):
     133
     134        * WebView/WebHTMLView.m:
     135        (-[WebHTMLView closeIfNotCurrentView]): Added for a dirty hack in WebCore that is marked with a FIXME Radar
     136        * WebView/WebHTMLViewInternal.h:
     137
     138        * WebView/WebView.mm:
     139        (-[WebViewPrivate init]):
     140        (-[WebViewPrivate dealloc]):
     141        (-[WebView _close]):
     142        (-[WebView _loadBackForwardListFromOtherView:]):
     143        (-[WebView _commonInitializationWithFrameName:groupName:]):
     144        (-[WebView initWithCoder:]):
     145        (-[WebView backForwardList]):
     146        (-[WebView goBack]):
     147        (-[WebView goForward]):
     148        (-[WebView goToBackForwardItem:]):
     149        (-[WebView canGoBack]):
     150        (-[WebView canGoForward]):
     151
    11522007-01-02  John Sullivan  <sullivan@apple.com>
    2153
  • trunk/WebKit/History/WebBackForwardList.mm

    r17795 r18541  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 
    2928#import <JavaScriptCore/Assertions.h>
    3029#import "WebBackForwardList.h"
     30#import "WebBackForwardListInternal.h"
     31
    3132#import "WebHistoryItemInternal.h"
    3233#import "WebHistoryItemPrivate.h"
     
    3738
    3839#import "WebTypesInternal.h"
     40#import <WebCore/BackForwardList.h>
     41#import <WebCore/HistoryItem.h>
     42#import <WebCore/RetainPtr.h>
    3943
    4044#define COMPUTE_DEFAULT_PAGE_CACHE_SIZE UINT_MAX
    4145
    42 @interface WebBackForwardListPrivate : NSObject
    43 {
    44 @public
    45     NSMutableArray *entries;
    46     int current;
    47     int maximumSize;
    48     unsigned pageCacheSize;
    49     BOOL closed;
    50 }
    51 @end
    52 
    53 @implementation WebBackForwardListPrivate
    54 
    55 - (void)dealloc
    56 {
    57     [entries release];
    58     [super dealloc];
    59 }
     46using WebCore::BackForwardList;
     47using WebCore::HistoryItem;
     48using WebCore::HistoryItemVector;
     49using WebCore::RetainPtr;
     50
     51static inline WebBackForwardListPrivate* kitPrivate(BackForwardList* list) { return (WebBackForwardListPrivate*)list; }
     52static inline BackForwardList* core(WebBackForwardListPrivate* list) { return (BackForwardList*)list; }
     53
     54HashMap<BackForwardList*, WebBackForwardList*>& backForwardListWrappers()
     55{
     56    static HashMap<BackForwardList*, WebBackForwardList*> backForwardListWrappers;
     57    return backForwardListWrappers;
     58}
     59
     60@implementation WebBackForwardList (WebBackForwardListInternal)
     61
     62BackForwardList* core(WebBackForwardList *list)
     63{
     64    if (!list)
     65        return 0;
     66    return core(list->_private);
     67}
     68
     69WebBackForwardList *kit(BackForwardList* list)
     70{
     71    if (!list)
     72        return nil;
     73       
     74    WebBackForwardList *kitList = backForwardListWrappers().get(list);
     75    if (kitList)
     76        return kitList;
     77   
     78    return [[[WebBackForwardList alloc] initWithWebCoreBackForwardList:list] autorelease];
     79}
     80
     81+ (void)setDefaultPageCacheSizeIfNecessary
     82{
     83    static bool initialized = false;
     84    if (initialized)
     85        return;
     86       
     87    vm_size_t memSize = WebSystemMainMemory();
     88    unsigned s = [[WebPreferences standardPreferences] _pageCacheSize];
     89    if (memSize >= 1024 * 1024 * 1024)
     90        BackForwardList::setDefaultPageCacheSize(s);
     91    else if (memSize >= 512 * 1024 * 1024)
     92        BackForwardList::setDefaultPageCacheSize(s - 1);
     93    else
     94        BackForwardList::setDefaultPageCacheSize(s - 2);
     95       
     96    initialized = true;
     97}
     98
     99- (id)initWithWebCoreBackForwardList:(PassRefPtr<BackForwardList>)list
     100{   
     101    self = [super init];
     102    if (!self)
     103        return nil;
     104   
     105    _private = kitPrivate(list.releaseRef());
     106    backForwardListWrappers().set(core(_private), self);
     107    return self;
     108}
     109
    60110@end
    61111
     
    69119    }
    70120   
    71     _private = [[WebBackForwardListPrivate alloc] init];
    72    
    73     _private->entries = [[NSMutableArray alloc] init];
    74     _private->current = -1;
    75     _private->maximumSize = 100; // typically set by browser app
    76 
    77     _private->pageCacheSize = COMPUTE_DEFAULT_PAGE_CACHE_SIZE;
     121    BackForwardList* coreList = new BackForwardList;
     122    _private = kitPrivate(coreList);
     123    coreList->ref();
     124   
     125    backForwardListWrappers().set(coreList, self);
    78126   
    79127    return self;
     
    82130- (void)dealloc
    83131{
    84     ASSERT(_private->closed);
    85     [_private release];
     132    BackForwardList* coreList = core(_private);
     133    ASSERT(coreList->closed());
     134    backForwardListWrappers().remove(coreList);
     135    coreList->deref();
     136       
    86137    [super dealloc];
    87138}
     
    89140- (void)finalize
    90141{
    91     ASSERT(_private->closed);
     142    BackForwardList* coreList = core(_private);
     143    ASSERT(coreList->closed());
     144    backForwardListWrappers().remove(coreList);
     145    coreList->deref();
     146       
    92147    [super finalize];
    93148}
     
    95150- (void)_close
    96151{
    97     unsigned count = [_private->entries count];
    98     unsigned i;
    99     for (i = 0; i < count; i++){
    100         WebHistoryItem *item = [_private->entries objectAtIndex: i];
    101         [item setHasPageCache: NO];
    102     }
    103     _private->closed = YES;
     152    core(_private)->close();
    104153}
    105154
    106155- (void)addItem:(WebHistoryItem *)entry;
    107156{
    108     if (_private->maximumSize == 0)
    109         return;
    110    
    111     // Toss anything in the forward list
    112     int currSize = [_private->entries count];
    113     if (_private->current != currSize-1 && _private->current != -1) {
    114         NSRange forwardRange = NSMakeRange(_private->current+1, currSize-(_private->current+1));
    115         NSArray *subarray;
    116         subarray = [_private->entries subarrayWithRange:forwardRange];
    117         unsigned i;
    118         for (i = 0; i < [subarray count]; i++){
    119             WebHistoryItem *item = [subarray objectAtIndex: i];
    120             [item setHasPageCache: NO];           
    121         }
    122         [_private->entries removeObjectsInRange: forwardRange];
    123         currSize -= forwardRange.length;
    124     }
    125 
    126     // Toss the first item if the list is getting too big, as long as we're not using it
    127     if (currSize == _private->maximumSize && _private->current != 0) {
    128         WebHistoryItem *item = [_private->entries objectAtIndex: 0];
    129         [item setHasPageCache: NO];
    130         [_private->entries removeObjectAtIndex:0];
    131         currSize--;
    132         _private->current--;
    133     }
    134 
    135     [_private->entries addObject:entry];
    136     _private->current++;
     157    core(_private)->addItem(core(entry));
     158   
     159    // Since the assumed contract with WebBackForwardList is that it retains its WebHistoryItems,
     160    // the following line prevents a whole class of problems where a history item will be created in
     161    // a function, added to the BFlist, then used in the rest of that function.
     162    [[entry retain] autorelease];
    137163}
    138164
    139165- (void)removeItem:(WebHistoryItem *)item
    140166{
    141     if (!item)
    142         return;
    143    
    144     WebNSUInteger itemIndex = [_private->entries indexOfObjectIdenticalTo:item];
    145     ASSERT(itemIndex != (unsigned)_private->current);
    146    
    147     if (itemIndex != NSNotFound && itemIndex != (WebNSUInteger)_private->current) {
    148         [_private->entries removeObjectAtIndex:itemIndex];
    149     }
    150 }
    151 
    152 - (BOOL)containsItem:(WebHistoryItem *)entry
    153 {
    154     return [_private->entries indexOfObjectIdenticalTo:entry] != NSNotFound;
    155 }
    156 
     167    core(_private)->removeItem(core(item));
     168}
     169
     170- (BOOL)containsItem:(WebHistoryItem *)item
     171{
     172    return core(_private)->containsItem(core(item));
     173}
    157174
    158175- (void)goBack
    159176{
    160     if(_private->current > 0)
    161         _private->current--;
    162     else
    163         [NSException raise:NSInternalInconsistencyException format:@"%@: goBack called with empty back list", self];
     177    core(_private)->goBack();
    164178}
    165179
    166180- (void)goForward
    167181{
    168     if(_private->current < (int)[_private->entries count]-1)
    169         _private->current++;
    170     else
    171         [NSException raise:NSInternalInconsistencyException format:@"%@: goForward called with empty forward list", self];
     182    core(_private)->goForward();
    172183}
    173184
    174185- (void)goToItem:(WebHistoryItem *)item
    175186{
    176     WebNSUInteger index = [_private->entries indexOfObjectIdenticalTo:item];
    177     if (index != NSNotFound)
    178         _private->current = index;
    179     else
    180         [NSException raise:NSInvalidArgumentException format:@"%@: %s:  invalid item", self, __FUNCTION__];
     187    core(_private)->goToItem(core(item));
    181188}
    182189
    183190- (WebHistoryItem *)backItem
    184191{
    185     if (_private->current > 0) {
    186         return [_private->entries objectAtIndex:_private->current-1];
    187     } else {
    188         return nil;
    189     }
     192    return kit(core(_private)->backItem());
    190193}
    191194
    192195- (WebHistoryItem *)currentItem
    193196{
    194     if (_private->current >= 0) {
    195         return [_private->entries objectAtIndex:_private->current];
    196     } else {
    197         return nil;
    198     }
     197    return kit(core(_private)->currentItem());
    199198}
    200199
    201200- (WebHistoryItem *)forwardItem
    202201{
    203     if (_private->current < (int)[_private->entries count]-1) {
    204         return [_private->entries objectAtIndex:_private->current+1];
    205     } else {
    206         return nil;
    207     }
     202    return kit(core(_private)->forwardItem());
     203}
     204
     205static NSArray* vectorToNSArray(HistoryItemVector& list)
     206{
     207    unsigned size = list.size();
     208    NSMutableArray *result = [[[NSMutableArray alloc] initWithCapacity:size] autorelease];
     209    for (unsigned i = 0; i < size; ++i)
     210        [result addObject:kit(list[i].get())];
     211
     212    return result;
    208213}
    209214
    210215- (NSArray *)backListWithLimit:(int)limit;
    211216{
    212     if (_private->current > 0) {
    213         NSRange r;
    214         r.location = MAX(_private->current-limit, 0);
    215         r.length = _private->current - r.location;
    216         return [_private->entries subarrayWithRange:r];
    217     } else {
    218         return nil;
    219     }
     217    HistoryItemVector list;
     218    core(_private)->backListWithLimit(limit, list);
     219    return vectorToNSArray(list);
    220220}
    221221
    222222- (NSArray *)forwardListWithLimit:(int)limit;
    223223{
    224     int lastEntry = (int)[_private->entries count]-1;
    225     if (_private->current < lastEntry) {
    226         NSRange r;
    227         r.location = _private->current+1;
    228         r.length =  MIN(_private->current+limit, lastEntry) - _private->current;
    229         return [_private->entries subarrayWithRange:r];
    230     } else {
    231         return nil;
    232     }
     224    HistoryItemVector list;
     225    core(_private)->forwardListWithLimit(limit, list);
     226    return vectorToNSArray(list);
    233227}
    234228
    235229- (int)capacity
    236230{
    237     return _private->maximumSize;
     231    return core(_private)->capacity();
    238232}
    239233
    240234- (void)setCapacity:(int)size
    241235{
    242     if (size < _private->maximumSize){
    243         int currSize = [_private->entries count];
    244         NSRange forwardRange = NSMakeRange(size, currSize-size);
    245         NSArray *subarray;
    246         subarray = [_private->entries subarrayWithRange:forwardRange];
    247         unsigned i;
    248         for (i = 0; i < [subarray count]; i++){
    249             WebHistoryItem *item = [subarray objectAtIndex: i];
    250             [item setHasPageCache: NO];
    251         }
    252         [_private->entries removeObjectsInRange: forwardRange];
    253         currSize -= forwardRange.length;
    254     }
    255     if (_private->current > (int)([_private->entries count] - 1))
    256         _private->current = [_private->entries count] - 1;
    257        
    258     _private->maximumSize = size;
     236    core(_private)->setCapacity(size);
    259237}
    260238
     
    263241{
    264242    NSMutableString *result;
    265     int i;
    266243   
    267244    result = [NSMutableString stringWithCapacity:512];
     
    270247    [result appendString:@"WebBackForwardList:\n"];
    271248   
    272     for (i = 0; i < (int)[_private->entries count]; i++) {
    273         if (i == _private->current) {
     249    BackForwardList* coreList = core(_private);
     250    HistoryItemVector& entries = coreList->entries();
     251   
     252    unsigned size = entries.size();
     253    for (unsigned i = 0; i < size; ++i) {
     254        if (entries[i] == coreList->currentItem()) {
    274255            [result appendString:@" >>>"];
    275         }
    276         else {
     256        } else {
    277257            [result appendString:@"    "];
    278258        }   
    279259        [result appendFormat:@"%2d) ", i];
    280260        int currPos = [result length];
    281         [result appendString:[[_private->entries objectAtIndex:i] description]];
     261        [result appendString:[kit(entries[i].get()) description]];
    282262
    283263        // shift all the contents over.  a bit slow, but this is for debugging
     
    295275- (void)_clearPageCache
    296276{
    297     int i;
    298     WebHistoryItem *currentItem = [self currentItem];
    299    
    300     for (i = 0; i < (int)[_private->entries count]; i++) {
    301         WebHistoryItem *item;
    302         // Don't clear the current item.  Objects are still in use.
    303         item = [_private->entries objectAtIndex:i];
    304         if (item != currentItem)
    305             [item setHasPageCache:NO];
    306     }
    307     [WebHistoryItem _releaseAllPendingPageCaches];
    308 }
    309 
     277    core(_private)->clearPageCache();
     278}
    310279
    311280- (void)setPageCacheSize: (unsigned)size
    312281{
    313     _private->pageCacheSize = size;
    314     if (size == 0) {
    315         [self _clearPageCache];
    316     }
    317 }
    318 
    319 #ifndef NDEBUG
    320 static BOOL loggedPageCacheSize = NO;
    321 #endif
     282    core(_private)->setPageCacheSize(size);
     283}
    322284
    323285- (unsigned)pageCacheSize
    324286{
    325     if (_private->pageCacheSize == COMPUTE_DEFAULT_PAGE_CACHE_SIZE) {
    326         unsigned s;
    327         vm_size_t memSize = WebSystemMainMemory();
    328        
    329         s = [[WebPreferences standardPreferences] _pageCacheSize];
    330         if (memSize >= 1024 * 1024 * 1024)
    331             _private->pageCacheSize = s;
    332         else if (memSize >= 512 * 1024 * 1024)
    333             _private->pageCacheSize = s - 1;
    334         else
    335             _private->pageCacheSize = s - 2;
    336 
    337 #ifndef NDEBUG
    338         if (!loggedPageCacheSize){
    339             LOG (CacheSizes, "Page cache size set to %d pages.", _private->pageCacheSize);
    340             loggedPageCacheSize = YES;
    341         }
    342 #endif
    343     }
    344    
    345     return _private->pageCacheSize;
     287    return core(_private)->pageCacheSize();
    346288}
    347289
    348290- (BOOL)_usesPageCache
    349291{
    350     return _private->pageCacheSize != 0;
     292    return core(_private)->usesPageCache();
    351293}
    352294
    353295- (int)backListCount
    354296{
    355     return _private->current;
     297    return core(_private)->backListCount();
    356298}
    357299
    358300- (int)forwardListCount
    359301{
    360     return (int)[_private->entries count] - (_private->current + 1);
     302    return core(_private)->forwardListCount();
    361303}
    362304
    363305- (WebHistoryItem *)itemAtIndex:(int)index
    364306{
    365     // Do range checks without doing math on index to avoid overflow.
    366     if (index < -_private->current) {
    367         return nil;
    368     }
    369     if (index > [self forwardListCount]) {
    370         return nil;
    371     }
    372     return [_private->entries objectAtIndex:index + _private->current];
    373 }
    374 
    375 - (NSMutableArray *)_entries
    376 {
    377     return _private->entries;
     307    return kit(core(_private)->itemAtIndex(index));
    378308}
    379309
  • trunk/WebKit/History/WebHistory.mm

    r18540 r18541  
    595595            strBuffer = staticStrBuffer;
    596596        } else {
    597             strBuffer = malloc(length + 2);
     597            strBuffer = (char*)malloc(length + 2);
    598598        }
    599599        memcpy(strBuffer, latin1, length + 1);
     
    653653            strBuffer = staticStrBuffer;
    654654        } else {
    655             strBuffer = malloc(sizeof(UniChar) * (length + 1));
     655            strBuffer = (UniChar*)malloc(sizeof(UniChar) * (length + 1));
    656656        }
    657657        memcpy(strBuffer, unicode, 2 * length);
  • trunk/WebKit/History/WebHistoryItem.mm

    r18049 r18541  
    4444#import "WebPluginController.h"
    4545#import <JavaScriptCore/Assertions.h>
     46#import <WebCore/HistoryItem.h>
     47#import <WebCore/Image.h>
     48#import <WebCore/KURL.h>
    4649#import <WebCore/PageState.h>
    47 #import <WebCore/WebCorePageState.h>
     50#import <WebCore/PlatformString.h>
    4851#import <WebKitSystemInterface.h>
    4952
     
    5962NSString *WebHistoryItemChangedNotification = @"WebHistoryItemChangedNotification";
    6063
    61 @interface WebHistoryItemPrivate : NSObject
    62 {
    63 @public
    64     NSString *URLString;
    65     NSString *originalURLString;
    66     NSString *target;
    67     NSString *parent;
    68     NSString *title;
    69     NSString *displayTitle;
    70     NSCalendarDate *lastVisitedDate;
    71     NSTimeInterval lastVisitedTimeInterval;
    72     NSPoint scrollPoint;
    73     NSArray *documentState;
    74     NSMutableArray *subItems;
    75     NSMutableDictionary *pageCache;
    76     BOOL isTargetItem;
    77     BOOL alwaysAttemptToUsePageCache;
    78     int visitCount;
    79     // info used to repost form data
    80     NSData *formData;
    81     NSString *formContentType;
    82     NSString *formReferrer;
    83     // info used to support RSS feeds
    84     NSString *RSSFeedReferrer;
    85     id viewState;
    86     NSMutableDictionary *transientProperties;
    87 }
    88 @end
    89 
    90 @implementation WebHistoryItemPrivate
     64using WebCore::HistoryItem;
     65using WebCore::HistoryItemVector;
     66
     67static inline WebHistoryItemPrivate* kitPrivate(WebCoreHistoryItem* list) { return (WebHistoryItemPrivate*)list; }
     68static inline WebCoreHistoryItem* core(WebHistoryItemPrivate* list) { return (WebCoreHistoryItem*)list; }
     69
     70HashMap<HistoryItem*, WebHistoryItem*>& historyItemWrappers()
     71{
     72    static HashMap<HistoryItem*, WebHistoryItem*> historyItemWrappers;
     73    return historyItemWrappers;
     74}
     75
     76void WKNotifyHistoryItemChanged()
     77{
     78    [[NSNotificationCenter defaultCenter]
     79        postNotificationName:WebHistoryItemChangedNotification object:nil userInfo:nil];
     80}
     81
     82@implementation WebHistoryItem
     83
     84- (id)init
     85{
     86    return [self initWithWebCoreHistoryItem:(new HistoryItem)];
     87}
     88
     89- (id)initWithURLString:(NSString *)URLString title:(NSString *)title lastVisitedTimeInterval:(NSTimeInterval)time
     90{
     91    return [self initWithWebCoreHistoryItem:(new HistoryItem(URLString, title, time))];
     92}
     93
    9194- (void)dealloc
    9295{
    93     [URLString release];
    94     [originalURLString release];
    95     [target release];
    96     [parent release];
    97     [title release];
    98     [displayTitle release];
    99     [lastVisitedDate release];
    100     [documentState release];
    101     [subItems release];
    102     [pageCache release];
    103     [formData release];
    104     [formContentType release];
    105     [formReferrer release];
    106     [RSSFeedReferrer release];
    107     [transientProperties release];
    108 
     96    if (_private) {
     97        HistoryItem* coreItem = core(_private);
     98        coreItem->deref();
     99        historyItemWrappers().remove(coreItem);
     100    }
    109101    [super dealloc];
    110102}
    111 @end
    112 
    113 @implementation WebHistoryItem
    114 
    115 - (id)init
    116 {
    117     return [self initWithURLString:nil title:nil lastVisitedTimeInterval:0];
    118 }
    119 
    120 - (id)initWithURLString:(NSString *)URLString title:(NSString *)title lastVisitedTimeInterval:(NSTimeInterval)time
    121 {
    122     self = [super init];
    123     _private = [[WebHistoryItemPrivate alloc] init];
    124     _private->lastVisitedTimeInterval = time;
    125     _private->title = [title copy];
    126     _private->URLString = [URLString copy];
    127     _private->originalURLString = [_private->URLString retain];
    128     [self _retainIconInDatabase:YES];
    129     return self;
    130 }
    131 
    132 - (void)dealloc
    133 {
    134     [self _retainIconInDatabase:NO];
    135 
    136     [_private release];
    137    
    138     [super dealloc];
    139 }
    140103
    141104- (void)finalize
    142105{
    143     // FIXME: Probably not good to release icons from the database only
    144     // when the object is garbage-collected. Need to change design so
    145     // this happens at a predictable time.
    146     [self _retainIconInDatabase:NO];
     106    // FIXME: The WebCore::HistoryItem d'tor is what releases the history item's icon from the icon database
     107    // It's probably not good to release icons from the database only when the object is garbage-collected.
     108    // Need to change design so this happens at a predictable time.
     109    if (_private) {
     110        HistoryItem* coreItem = core(_private);
     111        coreItem->deref();
     112        historyItemWrappers().remove(coreItem);
     113    }
    147114    [super finalize];
    148115}
     
    151118{
    152119    WebHistoryItem *copy = (WebHistoryItem *)NSCopyObject(self, 0, zone);
    153     copy->_private = [[WebHistoryItemPrivate alloc] init];
    154     copy->_private->URLString = [_private->URLString copy];
    155     [copy _retainIconInDatabase:YES];
    156     copy->_private->originalURLString = [_private->originalURLString copy];
    157     copy->_private->target = [_private->target copy];
    158     copy->_private->parent = [_private->parent copy];
    159     copy->_private->title = [_private->title copy];
    160     copy->_private->displayTitle = [_private->displayTitle copy];
    161     copy->_private->lastVisitedTimeInterval = _private->lastVisitedTimeInterval;
    162     copy->_private->lastVisitedDate = [_private->lastVisitedDate copy];
    163     copy->_private->scrollPoint = _private->scrollPoint;
    164     copy->_private->documentState = [_private->documentState copy];
    165     if (_private->subItems) {
    166         copy->_private->subItems = [[NSMutableArray alloc] initWithArray:_private->subItems copyItems:YES];
    167     }
    168     copy->_private->isTargetItem = _private->isTargetItem;
    169     copy->_private->formData = [_private->formData copy];
    170     copy->_private->formContentType = [_private->formContentType copy];
    171     copy->_private->formReferrer = [_private->formReferrer copy];
    172     copy->_private->RSSFeedReferrer = [_private->RSSFeedReferrer copy];
    173 
     120    RefPtr<HistoryItem> item = core(_private)->copy();
     121    copy->_private = kitPrivate(item.get());
     122    historyItemWrappers().set(item.release().releaseRef(), copy);
     123   
    174124    return copy;
    175125}
    176126
    177 // FIXME: need to decide it this class ever returns URLs, and the name of this method
     127// FIXME: Need to decide if this class ever returns URLs and decide on the name of this method
    178128- (NSString *)URLString
    179129{
    180     return _private->URLString;
     130    return nsStringNilIfEmpty(core(_private)->urlString());
    181131}
    182132
     
    185135- (NSString *)originalURLString
    186136{
    187     return _private->originalURLString;
     137    return nsStringNilIfEmpty(core(_private)->originalURLString());
    188138}
    189139
    190140- (NSString *)title
    191141{
    192     return _private->title;
     142    return nsStringNilIfEmpty(core(_private)->title());
    193143}
    194144
    195145- (void)setAlternateTitle:(NSString *)alternateTitle
    196146{
    197     NSString *newDisplayTitle;
    198     if (alternateTitle && [alternateTitle isEqualToString:_private->title]) {
    199         newDisplayTitle = [_private->title retain];
    200     } else {
    201         newDisplayTitle = [alternateTitle copy];
    202     }
    203     [_private->displayTitle release];
    204     _private->displayTitle = newDisplayTitle;
    205 
    206     [[NSNotificationCenter defaultCenter]
    207         postNotificationName: WebHistoryItemChangedNotification object: self userInfo: nil];
    208 }
    209 
     147    core(_private)->setAlternateTitle(alternateTitle);
     148}
    210149
    211150- (NSString *)alternateTitle;
    212151{
    213     return _private->displayTitle;
     152    return nsStringNilIfEmpty(core(_private)->alternateTitle());
    214153}
    215154
    216155- (NSImage *)icon
    217156{
    218     // Always get fresh icon from database. It's a client's responsibility to watch
    219     // for updates to the database if desired.
    220     return [[WebIconDatabase sharedIconDatabase] iconForURL:_private->URLString withSize:WebIconSmallSize];
    221 }
    222 
     157    return core(_private)->icon()->getNSImage();
     158}
    223159
    224160- (NSTimeInterval)lastVisitedTimeInterval
    225161{
    226     return _private->lastVisitedTimeInterval;
     162    return core(_private)->lastVisitedTime();
    227163}
    228164
    229165- (unsigned)hash
    230166{
    231     return [_private->URLString hash];
     167    return [(NSString*)core(_private)->urlString() hash];
    232168}
    233169
     
    238174    }
    239175   
    240     NSString *otherURL = ((WebHistoryItem *)anObject)->_private->URLString;
    241     return _private->URLString == otherURL || [_private->URLString isEqualToString:otherURL];
     176    return core(_private)->urlString() == core(((WebHistoryItem*)anObject)->_private)->urlString();
    242177}
    243178
    244179- (NSString *)description
    245180{
    246     NSMutableString *result = [NSMutableString stringWithFormat:@"%@ %@", [super description], _private->URLString];
    247     if (_private->target) {
    248         [result appendFormat:@" in \"%@\"", _private->target];
    249     }
    250     if (_private->isTargetItem) {
     181    HistoryItem* coreItem = core(_private);
     182    NSMutableString *result = [NSMutableString stringWithFormat:@"%@ %@", [super description], (NSString*)coreItem->urlString()];
     183    if (coreItem->target()) {
     184        [result appendFormat:@" in \"%@\"", (NSString*)coreItem->target()];
     185    }
     186    if (coreItem->isTargetItem()) {
    251187        [result appendString:@" *target*"];
    252188    }
    253     if (_private->formData) {
     189    if (coreItem->formData()) {
    254190        [result appendString:@" *POST*"];
    255191    }
    256     if (_private->subItems) {
     192   
     193    if (coreItem->children().size()) {
     194        const HistoryItemVector& children = coreItem->children();
    257195        int currPos = [result length];
    258         int i;
    259         for (i = 0; i < (int)[_private->subItems count]; i++) {
    260             WebHistoryItem *child = [_private->subItems objectAtIndex:i];
     196        unsigned size = children.size();       
     197        for (unsigned i = 0; i < size; ++i) {
     198            WebHistoryItem *child = kit(children[i].get());
    261199            [result appendString:@"\n"];
    262200            [result appendString:[child description]];
     
    266204        [result replaceOccurrencesOfString:@"\n" withString:@"\n    " options:0 range:replRange];
    267205    }
     206   
    268207    return result;
    269208}
     
    274213@end
    275214
     215
    276216@implementation WebHistoryItem (WebInternal)
    277217
    278 - (void)_retainIconInDatabase:(BOOL)retain
    279 {
    280     if (_private->URLString) {
    281         WebIconDatabase *iconDB = [WebIconDatabase sharedIconDatabase];
    282         if (retain) {
    283             [iconDB retainIconForURL:_private->URLString];
    284         } else {
    285             [iconDB releaseIconForURL:_private->URLString];
    286         }
    287     }
     218WebCore::HistoryItem* core(WebHistoryItem *item)
     219{
     220    if (!item)
     221        return 0;
     222    return core(item->_private);
     223}
     224
     225WebHistoryItem *kit(WebCore::HistoryItem* item)
     226{
     227    if (!item)
     228        return nil;
     229       
     230    WebHistoryItem *kitItem = historyItemWrappers().get(item);
     231    if (kitItem)
     232        return kitItem;
     233   
     234    return [[[WebHistoryItem alloc] initWithWebCoreHistoryItem:item] autorelease];
    288235}
    289236
     
    293240}
    294241
     242static WebWindowWatcher *_windowWatcher = nil;
     243
     244+ (void)initWindowWatcherIfNecessary
     245{
     246    if (_windowWatcher)
     247        return;
     248    _windowWatcher = [[WebWindowWatcher alloc] init];
     249    [[NSNotificationCenter defaultCenter] addObserver:_windowWatcher selector:@selector(windowWillClose:)
     250        name:NSWindowWillCloseNotification object:nil];
     251}
     252
    295253- (id)initWithURL:(NSURL *)URL target:(NSString *)target parent:(NSString *)parent title:(NSString *)title
    296254{
    297     self = [self initWithURLString:[URL _web_originalDataAsString] title:title lastVisitedTimeInterval:0];
    298     if (self) {
    299         _private->target = [target copy];
    300         _private->parent = [parent copy];
    301     }
     255    return [self initWithWebCoreHistoryItem:(new HistoryItem(URL, target, parent, title))];
     256}
     257
     258- (id)initWithWebCoreHistoryItem:(PassRefPtr<HistoryItem>)item
     259{   
     260    // Need to tell WebCore what function to call for the
     261    // "History Item has Changed" notification - no harm in doing this
     262    // everytime a WebHistoryItem is created
     263    // Note: We also do this in [WebFrameView initWithFrame:] where we do
     264    // other "init before WebKit is used" type things
     265    WebCore::notifyHistoryItemChanged = WKNotifyHistoryItemChanged;
     266   
     267    self = [super init];
     268   
     269    _private = kitPrivate(item.releaseRef());
     270    ASSERT(!historyItemWrappers().get(core(_private)));
     271    historyItemWrappers().set(core(_private), self);
    302272    return self;
    303273}
    304274
    305 - (NSString *)parent
    306 {
    307     return _private->parent;
    308 }
    309 
    310 - (void)setURLString:(NSString *)string
    311 {
    312     if (!(string == _private->URLString || [string isEqual:_private->URLString])) {
    313         [self _retainIconInDatabase:NO];
    314         [_private->URLString release];
    315         _private->URLString = [string copy];
    316         [self _retainIconInDatabase:YES];
    317     }
    318    
    319     [[NSNotificationCenter defaultCenter]
    320         postNotificationName: WebHistoryItemChangedNotification object: self userInfo: nil];
    321 }
    322 
    323 - (void)setURL:(NSURL *)URL
    324 {
    325     [self setURLString:[URL _web_originalDataAsString]];
    326     [self setHasPageCache:NO];
    327 }
    328 
    329 // The first URL we loaded to get to where this history item points.  Includes both client
    330 // and server redirects.
    331 - (void)setOriginalURLString:(NSString *)URL
    332 {
    333     NSString *newURL = [URL copy];
    334     [_private->originalURLString release];
    335     _private->originalURLString = newURL;
    336 
    337     [[NSNotificationCenter defaultCenter]
    338         postNotificationName: WebHistoryItemChangedNotification object: self userInfo: nil];
    339 }
    340 
    341275- (void)setTitle:(NSString *)title
    342276{
    343     NSString *newTitle;
    344     if (title && [title isEqualToString:_private->displayTitle]) {
    345         newTitle = [_private->displayTitle retain];
    346     } else {
    347         newTitle = [title copy];
    348     }
    349     [_private->title release];
    350     _private->title = newTitle;
    351 
    352     [[NSNotificationCenter defaultCenter]
    353         postNotificationName: WebHistoryItemChangedNotification object: self userInfo: nil];
    354 }
    355 
    356 - (void)setTarget:(NSString *)target
    357 {
    358     NSString *copy = [target copy];
    359     [_private->target release];
    360     _private->target = copy;
    361 }
    362 
    363 - (void)setParent:(NSString *)parent
    364 {
    365     NSString *copy = [parent copy];
    366     [_private->parent release];
    367     _private->parent = copy;
     277    core(_private)->setTitle(title);
    368278}
    369279
    370280- (void)setVisitCount:(int)count
    371281{
    372     _private->visitCount = count;
    373 }
    374 
    375 - (void)setDocumentState:(NSArray *)state;
    376 {
    377     NSArray *copy = [state copy];
    378     [_private->documentState release];
    379     _private->documentState = copy;
    380 }
    381 
    382 - (NSArray *)documentState
    383 {
    384     return _private->documentState;
    385 }
    386 
    387 - (NSPoint)scrollPoint
    388 {
    389     return _private->scrollPoint;
    390 }
    391 
    392 - (void)setScrollPoint:(NSPoint)scrollPoint
    393 {
    394     _private->scrollPoint = scrollPoint;
     282    core(_private)->setVisitCount(count);
    395283}
    396284
    397285- (void)setViewState:(id)statePList;
    398286{
    399     id copy = [statePList copy];
    400     [_private->viewState release];
    401     _private->viewState = copy;
    402 }
    403 
    404 - (id)viewState
    405 {
    406     return _private->viewState;
    407 }
    408 
    409 - (void)setIsTargetItem:(BOOL)flag
    410 {
    411     _private->isTargetItem = flag;
    412 }
    413 
    414 // Main diff from the public method is that the public method will default to returning
    415 // the top item if it can't find anything marked as target and has no kids
    416 - (WebHistoryItem *)_recurseToFindTargetItem
    417 {
    418     if (_private->isTargetItem) {
    419         return self;
    420     } else if (!_private->subItems) {
    421         return nil;
    422     } else {
    423         int i;
    424         for (i = [_private->subItems count]-1; i >= 0; i--) {
    425             WebHistoryItem *match = [[_private->subItems objectAtIndex:i] _recurseToFindTargetItem];
    426             if (match) {
    427                 return match;
    428             }
    429         }
    430         return nil;
    431     }
    432 }
    433 
    434 - (void)_setFormInfoFromRequest:(NSURLRequest *)request
    435 {
    436     NSData *newData = nil;
    437     NSString *newContentType = nil;
    438     NSString *newReferrer = nil;
    439     if ([[request HTTPMethod] _webkit_isCaseInsensitiveEqualToString:@"POST"]) {
    440         // save form state iff this is a POST
    441 
    442         // FIXME: Eventually we have to make this smart enough to handle the case where
    443         // we have a stream for the body to handle the "data interspersed with files" feature.
    444         newData = [[request HTTPBody] copy];
    445         newContentType = [[request _web_HTTPContentType] copy];
    446         newReferrer = [[request _web_HTTPReferrer] copy];
    447     }
    448 
    449     [_private->formData release];
    450     _private->formData = newData;
    451 
    452     [_private->formContentType release];
    453     _private->formContentType = newContentType;
    454    
    455     [_private->formReferrer release];
    456     _private->formReferrer = newReferrer;
    457 }
    458 
    459 - (NSData *)formData
    460 {
    461     return _private->formData;
    462 }
    463 
    464 - (NSString *)formContentType
    465 {
    466     return _private->formContentType;
    467 }
    468 
    469 - (NSString *)formReferrer
    470 {
    471     return _private->formReferrer;
     287    core(_private)->setViewState(statePList);
    472288}
    473289
     
    475291{
    476292    ASSERT_ARG(otherItem, otherItem);
    477    
    478     if (otherItem != self) {
    479         _private->visitCount += otherItem->_private->visitCount;
    480     }
    481 }
    482 
    483 - (void)addChildItem:(WebHistoryItem *)item
    484 {
    485     if (!_private->subItems) {
    486         _private->subItems = [[NSMutableArray arrayWithObject:item] retain];
    487     } else {
    488         [_private->subItems addObject:item];
    489     }
    490 }
    491 
    492 - (WebHistoryItem *)childItemWithName:(NSString *)name
    493 {
    494     int i;
    495     for (i = (_private->subItems ? [_private->subItems count] : 0)-1; i >= 0; i--) {
    496         WebHistoryItem *child = [_private->subItems objectAtIndex:i];
    497         if ([[child target] isEqualToString:name]) {
    498             return child;
    499         }
    500     }
    501     return nil;
     293    core(_private)->mergeAutoCompleteHints(core(otherItem->_private));
    502294}
    503295
     
    513305
    514306    self = [self initWithURLString:URLString title:title lastVisitedTimeInterval:lastVisited];
    515 
     307   
    516308    // Check if we've read a broken URL from the file that has non-Latin1 chars.  If so, try to convert
    517309    // as if it was from user typing.
    518     if (![_private->URLString canBeConvertedToEncoding:NSISOLatin1StringEncoding]) {
    519         NSURL *tempURL = [NSURL _web_URLWithUserTypedString:_private->URLString];
     310    if (![URLString canBeConvertedToEncoding:NSISOLatin1StringEncoding]) {
     311        NSURL *tempURL = [NSURL _web_URLWithUserTypedString:URLString];
    520312        ASSERT(tempURL);
    521         [_private->URLString release];
    522         _private->URLString = [[tempURL _web_originalDataAsString] copy];
    523         [_private->originalURLString release];
    524         _private->originalURLString = [_private->URLString retain];
    525     }
    526 
    527     [self setAlternateTitle:[dict _webkit_stringForKey:WebDisplayTitleKey]];
    528 
    529     _private->visitCount = [dict _webkit_intForKey:WebVisitCountKey];
     313        NSString *newURLString = [tempURL _web_originalDataAsString];
     314        core(_private)->setURLString(newURLString);
     315        core(_private)->setOriginalURLString(newURLString);
     316    }
     317
     318    core(_private)->setAlternateTitle([dict _webkit_stringForKey:WebDisplayTitleKey]);
     319    core(_private)->setVisitCount([dict _webkit_intForKey:WebVisitCountKey]);
    530320
    531321    NSArray *childDicts = [dict objectForKey:WebChildrenKey];
    532322    if (childDicts) {
    533         _private->subItems = [[NSMutableArray alloc] initWithCapacity:[childDicts count]];
    534         int i;
    535         for (i = [childDicts count]; i >= 0; i--) {
     323        for (int i = [childDicts count]; i >= 0; i--) {
    536324            WebHistoryItem *child = [[WebHistoryItem alloc] initFromDictionaryRepresentation: [childDicts objectAtIndex:i]];
    537             [_private->subItems addObject: child];
     325            core(_private)->addChildItem(core(child->_private));
     326            [child release];
    538327        }
    539328    }
     
    542331}
    543332
    544 - (BOOL)alwaysAttemptToUsePageCache
    545 {
    546     return _private->alwaysAttemptToUsePageCache;
    547 }
    548 
    549 
    550 static WebWindowWatcher *_windowWatcher;
    551 static NSMutableSet *_pendingPageCacheToRelease = nil;
    552 static NSTimer *_pageCacheReleaseTimer = nil;
    553 
    554 - (BOOL)hasPageCache;
    555 {
    556     return _private->pageCache != nil;
    557 }
    558 
    559 + (void)_invalidateReleaseTimer
    560 {
    561     if (_pageCacheReleaseTimer){
    562         [_pageCacheReleaseTimer invalidate];
    563         [_pageCacheReleaseTimer release];
    564         _pageCacheReleaseTimer = nil;
    565     }
    566 }
    567 
    568 + (void)_scheduleReleaseTimer
    569 {
    570     if (!_pageCacheReleaseTimer){
    571         _pageCacheReleaseTimer = [[NSTimer scheduledTimerWithTimeInterval: 2.5 target:self selector:@selector(_releasePageCache:) userInfo:nil repeats:NO] retain];
    572         if (_pendingPageCacheToRelease == nil){
    573             _pendingPageCacheToRelease = [[NSMutableSet alloc] init];
    574         }
    575     }
    576 }
    577 
    578 - (void)_scheduleRelease
    579 {
    580     LOG (PageCache, "WebKitPageCache - Scheduling release of %@ (0x%x)", [self URLString], _private->pageCache);
    581     [WebHistoryItem _scheduleReleaseTimer];
    582 
    583     if (_private->pageCache){
    584         [_pendingPageCacheToRelease addObject: _private->pageCache];
    585         [_private->pageCache release]; // Last reference held by _pendingPageCacheToRelease.
    586         _private->pageCache = nil;
    587     }
    588    
    589     if (!_windowWatcher){
    590         _windowWatcher = [[WebWindowWatcher alloc] init];
    591         [[NSNotificationCenter defaultCenter] addObserver:_windowWatcher selector:@selector(windowWillClose:)
    592                         name:NSWindowWillCloseNotification object:nil];
    593     }
    594 }
    595 
    596 + (void)_closeObjectsInPendingPageCaches
    597 {
    598     NSEnumerator *pageCaches = [_pendingPageCacheToRelease objectEnumerator];
    599     NSMutableDictionary *pageCache;
    600    
    601     while ((pageCache = [pageCaches nextObject])) {
    602         WebHTMLView *HTMLView = [pageCache objectForKey:WebPageCacheDocumentViewKey];
    603         if ([HTMLView isKindOfClass:[WebHTMLView class]]) {
    604             // To avoid any possible retain cycles, call close on all the WebHTMLView.
    605             // Don't close the WebHTMLView that is currently being viewed.
    606             if ([[[HTMLView _frame] frameView] documentView] != HTMLView)
    607                 [HTMLView close];
    608         }
    609 
    610         if (WebCorePageState *pageState = [pageCache objectForKey:WebCorePageCacheStateKey])
    611             [pageState impl]->clear();
    612     }
    613 }
    614 
    615 + (void)_releasePageCache: (NSTimer *)timer
    616 {
    617     float userDelta;
    618     CFAbsoluteTime loadDelta;
    619    
    620     loadDelta = CFAbsoluteTimeGetCurrent()-[WebFrame _timeOfLastCompletedLoad];
    621     userDelta = WKSecondsSinceLastInputEvent();
    622 
    623     [_pageCacheReleaseTimer release];
    624     _pageCacheReleaseTimer = nil;
    625 
    626     if ((userDelta < 0.5 || loadDelta < 1.25) && [_pendingPageCacheToRelease count] < 42){
    627         LOG (PageCache, "WebKitPageCache - postponing again because not quiescent for more than a second (%f since last input, %f since last load).", userDelta, loadDelta);
    628         [self _scheduleReleaseTimer];
    629         return;
    630     }
    631     else
    632         LOG (PageCache, "WebKitPageCache - releasing, quiescent for more than a second (%f since last input, %f since last load).", userDelta, loadDelta);
    633 
    634     [WebHistoryItem _releaseAllPendingPageCaches];
    635 }
    636 
    637 - (void)setHasPageCache: (BOOL)f
    638 {
    639     if (f && !_private->pageCache)
    640         _private->pageCache = [[NSMutableDictionary alloc] init];
    641     if (!f && _private->pageCache){
    642         [self _scheduleRelease];
    643     }
    644 }
    645 
    646 - (NSMutableDictionary *)pageCache
    647 {
    648     return _private->pageCache;
     333- (NSPoint)scrollPoint
     334{
     335    return core(_private)->scrollPoint();
     336}
     337
     338- (id)_transientPropertyForKey:(NSString *)key
     339{
     340    return core(_private)->getTransientProperty(key);
     341}
     342
     343- (void)_setTransientProperty:(id)property forKey:(NSString *)key
     344{
     345    core(_private)->setTransientProperty(key, property);
    649346}
    650347
     
    658355}
    659356
     357- (NSDictionary *)dictionaryRepresentation
     358{
     359    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:6];
     360
     361    HistoryItem* coreItem = core(_private);
     362   
     363    if (!coreItem->urlString().isEmpty()) {
     364        [dict setObject:(NSString*)coreItem->urlString() forKey:@""];
     365    }
     366    if (!coreItem->title().isEmpty()) {
     367        [dict setObject:(NSString*)coreItem->title() forKey:WebTitleKey];
     368    }
     369    if (!coreItem->alternateTitle().isEmpty()) {
     370        [dict setObject:(NSString*)coreItem->alternateTitle() forKey:WebDisplayTitleKey];
     371    }
     372    if (coreItem->lastVisitedTime() != 0.0) {
     373        // store as a string to maintain backward compatibility (see 3245793)
     374        [dict setObject:[NSString stringWithFormat:@"%.1lf", coreItem->lastVisitedTime()]
     375                 forKey:WebLastVisitedTimeIntervalKey];
     376    }
     377    if (coreItem->visitCount()) {
     378        [dict setObject:[NSNumber numberWithInt:coreItem->visitCount()] forKey:WebVisitCountKey];
     379    }
     380    if (coreItem->children().size()) {
     381        const HistoryItemVector& children = coreItem->children();
     382        NSMutableArray *childDicts = [NSMutableArray arrayWithCapacity:children.size()];
     383       
     384        for (int i = children.size(); i >= 0; i--)
     385            [childDicts addObject:[kit(children[i].get()) dictionaryRepresentation]];
     386        [dict setObject: childDicts forKey:WebChildrenKey];
     387    }
     388
     389    return dict;
     390}
     391
     392- (NSString *)target
     393{
     394    return nsStringNilIfEmpty(core(_private)->target());
     395}
     396
     397- (BOOL)isTargetItem
     398{
     399    return core(_private)->isTargetItem();
     400}
     401
    660402- (int)visitCount
    661403{
    662     return _private->visitCount;
     404    return core(_private)->visitCount();
    663405}
    664406
    665407- (NSString *)RSSFeedReferrer
    666408{
    667     return _private->RSSFeedReferrer;
     409    return nsStringNilIfEmpty(core(_private)->rssFeedReferrer());
    668410}
    669411
    670412- (void)setRSSFeedReferrer:(NSString *)referrer
    671413{
    672     NSString *copy = [referrer copy];
    673     [_private->RSSFeedReferrer release];
    674     _private->RSSFeedReferrer = copy;
     414    core(_private)->setRSSFeedReferrer(referrer);
    675415}
    676416
    677417- (NSArray *)children
    678418{
    679     return _private->subItems;
    680 }
    681 
    682 - (NSDictionary *)dictionaryRepresentation
    683 {
    684     NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:6];
    685 
    686     if (_private->URLString) {
    687         [dict setObject:_private->URLString forKey:@""];
    688     }
    689     if (_private->title) {
    690         [dict setObject:_private->title forKey:WebTitleKey];
    691     }
    692     if (_private->displayTitle) {
    693         [dict setObject:_private->displayTitle forKey:WebDisplayTitleKey];
    694     }
    695     if (_private->lastVisitedTimeInterval != 0.0) {
    696         // store as a string to maintain backward compatibility (see 3245793)
    697         [dict setObject:[NSString stringWithFormat:@"%.1lf", _private->lastVisitedTimeInterval]
    698                  forKey:WebLastVisitedTimeIntervalKey];
    699     }
    700     if (_private->visitCount) {
    701         [dict setObject:[NSNumber numberWithInt:_private->visitCount] forKey:WebVisitCountKey];
    702     }
    703     if (_private->subItems != nil) {
    704         NSMutableArray *childDicts = [NSMutableArray arrayWithCapacity:[_private->subItems count]];
    705         int i;
    706         for (i = [_private->subItems count]; i >= 0; i--) {
    707             [childDicts addObject: [[_private->subItems objectAtIndex:i] dictionaryRepresentation]];
    708         }
    709         [dict setObject: childDicts forKey:WebChildrenKey];
    710     }
    711 
    712     return dict;
     419    const HistoryItemVector& children = core(_private)->children();
     420    if (!children.size())
     421        return nil;
     422
     423    unsigned size = children.size();
     424    NSMutableArray *result = [[[NSMutableArray alloc] initWithCapacity:size] autorelease];
     425   
     426    for (unsigned i = 0; i < size; ++i)
     427        [result addObject:kit(children[i].get())];
     428   
     429    return result;
    713430}
    714431
    715432- (void)setAlwaysAttemptToUsePageCache: (BOOL)flag
    716433{
    717     _private->alwaysAttemptToUsePageCache = flag;
     434    core(_private)->setAlwaysAttemptToUsePageCache(flag);
     435}
     436
     437- (NSURL *)URL
     438{
     439    WebCore::KURL url = core(_private)->url();
     440    return url.isEmpty() ? nil : url.getNSURL();
     441}
     442
     443// This should not be called directly for WebHistoryItems that are already included
     444// in WebHistory. Use -[WebHistory setLastVisitedTimeInterval:forItem:] instead.
     445- (void)_setLastVisitedTimeInterval:(NSTimeInterval)time
     446{
     447    core(_private)->setLastVisitedTime(time);
     448}
     449
     450// FIXME: <rdar://problem/4880065> - Push Global History into WebCore
     451// Once that task is complete, this accessor can go away
     452- (NSCalendarDate *)_lastVisitedDate
     453{
     454    return [[[NSCalendarDate alloc] initWithTimeIntervalSinceReferenceDate:core(_private)->lastVisitedTime()] autorelease];
     455}
     456
     457- (WebHistoryItem *)targetItem
     458{   
     459    HistoryItem* coreItem = core(_private);
     460    if (coreItem->isTargetItem() || !coreItem->hasChildren())
     461        return self;
     462    return kit(coreItem->recurseToFindTargetItem());
    718463}
    719464
    720465+ (void)_releaseAllPendingPageCaches
    721466{
    722     LOG (PageCache, "WebKitPageCache - releasing %d items\n", [_pendingPageCacheToRelease count]);
    723     [WebHistoryItem _invalidateReleaseTimer];
    724     [self _closeObjectsInPendingPageCaches];
    725     [_pendingPageCacheToRelease removeAllObjects];
    726 }
    727 
    728 - (id)_transientPropertyForKey:(NSString *)key
    729 {
    730     if (!_private->transientProperties)
    731         return nil;
    732    
    733     return [_private->transientProperties objectForKey:key];
    734 }
    735 
    736 - (void)_setTransientProperty:(id)property forKey:(NSString *)key
    737 {
    738     if (property) {
    739         if (!_private->transientProperties)
    740             _private->transientProperties = [[NSMutableDictionary alloc] init];
    741         [_private->transientProperties setObject:property forKey:key];
    742     } else if (_private->transientProperties)
    743         [_private->transientProperties removeObjectForKey:key];
    744 }
    745 
    746 - (NSURL *)URL
    747 {
    748     return _private->URLString ? [NSURL _web_URLWithDataAsString:_private->URLString] : nil;
    749 }
    750 
    751 - (NSString *)target
    752 {
    753     return _private->target;
    754 }
    755 
    756 - (void)_setLastVisitedTimeInterval:(NSTimeInterval)time
    757 {
    758     if (_private->lastVisitedTimeInterval != time) {
    759         _private->lastVisitedTimeInterval = time;
    760         [_private->lastVisitedDate release];
    761         _private->lastVisitedDate = nil;
    762         _private->visitCount++;
    763     }
    764 }
    765 
    766 // FIXME:  Remove this accessor and related ivar.
    767 - (NSCalendarDate *)_lastVisitedDate
    768 {
    769     if (!_private->lastVisitedDate){
    770         _private->lastVisitedDate = [[NSCalendarDate alloc]
    771                     initWithTimeIntervalSinceReferenceDate:_private->lastVisitedTimeInterval];
    772     }
    773     return _private->lastVisitedDate;
    774 }
    775 
    776 - (WebHistoryItem *)targetItem
    777 {
    778     if (_private->isTargetItem || !_private->subItems) {
    779         return self;
    780     } else {
    781         return [self _recurseToFindTargetItem];
    782     }
    783 }
    784 
    785 - (BOOL)isTargetItem
    786 {
    787     return _private->isTargetItem;
     467    HistoryItem::releaseAllPendingPageCaches();
    788468}
    789469
    790470@end
    791471
    792 // FIXME: This is a bizarre policy - we flush the pagecaches ANY time ANY window is closed? 
     472
     473// FIXME: <rdar://problem/4886761>
     474// This is a bizarre policy - we flush the page caches ANY time ANY window is closed? 
    793475@implementation WebWindowWatcher
    794476-(void)windowWillClose:(NSNotification *)notification
    795477{
    796     [WebHistoryItem _releaseAllPendingPageCaches];
     478    WebCoreHistoryItem::releaseAllPendingPageCaches();
    797479}
    798480@end
    799 
    800 
  • trunk/WebKit/History/WebHistoryItemInternal.h

    r17781 r18541  
    3131#import <WebKit/WebBackForwardList.h>
    3232#import <WebKit/WebHistoryItem.h>
     33#import <wtf/PassRefPtr.h>
     34
     35namespace WebCore {
     36    class HistoryItem;
     37}
     38
     39WebCore::HistoryItem* core(WebHistoryItem *item);
     40WebHistoryItem *kit(WebCore::HistoryItem* item);
     41
     42extern void WKNotifyHistoryItemChanged();
    3343
    3444@interface WebHistoryItem (WebInternal)
    35 - (void)_retainIconInDatabase:(BOOL)retain;
    36 - (BOOL)hasPageCache;
    37 - (void)setHasPageCache:(BOOL)f;
    38 - (NSMutableDictionary *)pageCache;
    3945
    4046+ (WebHistoryItem *)entryWithURL:(NSURL *)URL;
     47+ (void)initWindowWatcherIfNecessary;
    4148
    4249- (id)initWithURL:(NSURL *)URL target:(NSString *)target parent:(NSString *)parent title:(NSString *)title;
    43 
    4450- (id)initFromDictionaryRepresentation:(NSDictionary *)dict;
    45 
    46 - (NSString *)parent;
    47 
    48 
    49 - (NSPoint)scrollPoint;
    50 - (NSArray *)documentState;
    51 - (NSData *)formData;
    52 - (NSString *)formContentType;
    53 - (NSString *)formReferrer;
    54 - (id)viewState;
     51- (id)initWithWebCoreHistoryItem:(PassRefPtr<WebCore::HistoryItem>)item;
    5552
    5653- (void)_mergeAutoCompleteHints:(WebHistoryItem *)otherItem;
     54- (void)setTitle:(NSString *)title;
    5755
    58 - (void)setURL:(NSURL *)URL;
    59 - (void)setURLString:(NSString *)string;
    60 - (void)setOriginalURLString:(NSString *)URL;
    61 - (void)setTarget:(NSString *)target;
    62 - (void)setParent:(NSString *)parent;
    63 - (void)setTitle:(NSString *)title;
    64 - (void)setScrollPoint:(NSPoint)p;
    65 - (void)setDocumentState:(NSArray *)state;
    66 - (void)setIsTargetItem:(BOOL)flag;
    67 - (void)_setFormInfoFromRequest:(NSURLRequest *)request;
    68 - (void)setVisitCount:(int)count;
    69 - (void)setViewState:(id)statePList;
    70 
    71 
    72 - (void)addChildItem:(WebHistoryItem *)item;
    73 - (WebHistoryItem *)childItemWithName:(NSString *)name;
    74 
    75 - (BOOL)alwaysAttemptToUsePageCache;
    76 
     56// Transient properties may be of any ObjC type.  They are intended to be used to store state per back/forward list entry.
     57// The properties will not be persisted; when the history item is removed, the properties will be lost.
     58- (id)_transientPropertyForKey:(NSString *)key;
     59- (void)_setTransientProperty:(id)property forKey:(NSString *)key;
    7760
    7861@end
     
    8467@end
    8568
     69
  • trunk/WebKit/History/WebHistoryItemPrivate.h

    r17781 r18541  
    3333
    3434@interface WebHistoryItem (WebPrivate)
     35+ (void)_releaseAllPendingPageCaches;
     36
    3537- (id)initWithURL:(NSURL *)URL title:(NSString *)title;
    3638
     
    3840- (int)visitCount;
    3941
    40 // Transient properties may be of any ObjC type.  They are intended to be used to store state per back/forward list entry.
    41 // The properties will not be persisted; when the history item is removed, the properties will be lost.
    42 - (id)_transientPropertyForKey:(NSString *)key;
    43 - (void)_setTransientProperty:(id)property forKey:(NSString *)key;
    4442- (NSString *)RSSFeedReferrer;
    4543- (void)setAlwaysAttemptToUsePageCache:(BOOL)flag;
    46 + (void)_releaseAllPendingPageCaches;
    4744- (void)setRSSFeedReferrer:(NSString *)referrer;
    4845- (NSCalendarDate *)_lastVisitedDate;
     46
     47- (WebHistoryItem *)targetItem;
     48- (NSString *)target;
     49- (BOOL)isTargetItem;
     50- (NSArray *)children;
     51- (NSDictionary *)dictionaryRepresentation;
    4952
    5053// This should not be called directly for WebHistoryItems that are already included
    5154// in WebHistory. Use -[WebHistory setLastVisitedTimeInterval:forItem:] instead.
    5255- (void)_setLastVisitedTimeInterval:(NSTimeInterval)time;
    53 - (NSDictionary *)dictionaryRepresentation;
    54 - (WebHistoryItem *)targetItem;
    55 - (NSString *)target;
    56 - (NSArray *)children;
    57 - (BOOL)isTargetItem;
    5856
    5957@end
  • trunk/WebKit/WebCoreSupport/WebFrameBridge.mm

    r18435 r18541  
    418418}
    419419
    420 - (void)saveDocumentState:(NSArray *)documentState
    421 {
    422     WebHistoryItem *item = [_frame _itemForSavingDocState];
    423     LOG(Loading, "%@: saving form state from to 0x%x", [_frame name], item);
    424     if (item)
    425         [item setDocumentState:documentState];
    426         // You might think we could save the scroll state here too, but unfortunately this
    427         // often gets called after WebFrame::_transitionToCommitted has restored the scroll
    428         // position of the next document.
    429 }
    430 
    431 - (NSArray *)documentState
    432 {
    433     LOG(Loading, "%@: restoring form state from item 0x%x", [_frame name], [_frame _itemForRestoringDocState]);
    434     return [[_frame _itemForRestoringDocState] documentState];
    435 }
    436 
    437420- (NSString *)userAgentForURL:(NSURL *)URL
    438421{
     
    824807}
    825808
    826 - (void)goBackOrForward:(int)distance
    827 {
    828     if (distance == 0)
    829         return;
    830     WebView *webView = [self webView];
    831     WebBackForwardList *list = [webView backForwardList];
    832     WebHistoryItem *item = [list itemAtIndex:distance];
    833     if (!item) {
    834         if (distance > 0) {
    835             int forwardListCount = [list forwardListCount];
    836             if (forwardListCount > 0) {
    837                 item = [list itemAtIndex:forwardListCount];
    838             }
    839         } else {
    840             int backListCount = [list forwardListCount];
    841             if (backListCount > 0) {
    842                 item = [list itemAtIndex:-backListCount];
    843             }
    844         }
    845     }
    846     if (item) {
    847         [webView goToBackForwardItem:item];
    848     }
    849 }
    850 
    851809- (NSURL*)historyURL:(int)distance
    852810{
  • trunk/WebKit/WebCoreSupport/WebFrameLoaderClient.h

    r18430 r18541  
    3939
    4040namespace WebCore {
     41    class HistoryItem;
     42    class PageCache;
    4143    class String;
    4244    class ResourceLoader;
     
    5961    virtual bool hasFrameView() const; // ditto
    6062
    61     virtual bool hasBackForwardList() const;
    62     virtual void resetBackForwardList();
    63 
    64     virtual bool provisionalItemIsTarget() const;
    65     virtual bool loadProvisionalItemFromPageCache();
    66     virtual void invalidateCurrentItemPageCache();
    67 
    6863    virtual bool privateBrowsingEnabled() const;
    6964
    7065    virtual void makeDocumentView();
    7166    virtual void makeRepresentation(WebCore::DocumentLoader*);
    72     virtual void setDocumentViewFromPageCache(NSDictionary *);
     67    virtual void setDocumentViewFromPageCache(WebCore::PageCache*);
    7368    virtual void forceLayout();
    7469    virtual void forceLayoutForNonHTML();
    7570
    76     virtual void updateHistoryForCommit();
    77 
    78     virtual void updateHistoryForBackForwardNavigation();
    79     virtual void updateHistoryForReload();
    80     virtual void updateHistoryForStandardLoad();
    81     virtual void updateHistoryForInternalLoad();
    82 
    83     virtual void updateHistoryAfterClientRedirect();
    84 
    8571    virtual void setCopiesOnScroll();
    86 
    87     virtual WebCore::LoadErrorResetToken* tokenForLoadErrorReset();
    88     virtual void resetAfterLoadError(WebCore::LoadErrorResetToken*);
    89     virtual void doNotResetAfterLoadError(WebCore::LoadErrorResetToken*);
    9072
    9173    virtual void detachedFromParent1();
     
    138120
    139121    virtual void dispatchDidLoadMainResource(WebCore::DocumentLoader*);
    140     virtual void clearLoadingFromPageCache(WebCore::DocumentLoader*);
    141     virtual bool isLoadingFromPageCache(WebCore::DocumentLoader*);
    142122    virtual void revertToProvisionalState(WebCore::DocumentLoader*);
    143123    virtual void setMainDocumentError(WebCore::DocumentLoader*, const WebCore::ResourceError&);
     
    162142    virtual void finishedLoading(WebCore::DocumentLoader*);
    163143    virtual void finalSetupForReplace(WebCore::DocumentLoader*);
     144    virtual void updateGlobalHistoryForStandardLoad(const WebCore::KURL&);
     145    virtual void updateGlobalHistoryForReload(const WebCore::KURL&);
     146    virtual bool shouldGoToHistoryItem(WebCore::HistoryItem*) const;
     147
    164148
    165149    virtual WebCore::ResourceError cancelledError(const WebCore::ResourceRequest&);
     
    187171
    188172    virtual void frameLoadCompleted();
     173    virtual void saveScrollPositionAndViewStateToItem(WebCore::HistoryItem*);
    189174    virtual void restoreScrollPositionAndViewState();
    190175    virtual void provisionalLoadStarted();
    191     virtual bool shouldTreatURLAsSameAsCurrent(const WebCore::KURL&) const;
    192     virtual void addHistoryItemForFragmentScroll();
    193176    virtual void didFinishLoad();
    194177    virtual void prepareForDataSourceReplacement();
     
    205188    NSDictionary *actionDictionary(const WebCore::NavigationAction&) const;
    206189
    207     bool createPageCache(WebHistoryItem *);
     190    void saveDocumentViewToPageCache(WebCore::PageCache* pageCache);
     191   
     192    virtual bool canCachePage() const;
    208193
    209194    WebCore::RetainPtr<WebFrame> m_webFrame;
  • trunk/WebKit/WebCoreSupport/WebFrameLoaderClient.mm

    r18430 r18541  
    3737#import "WebChromeClient.h"
    3838#import "WebDataSourceInternal.h"
     39#import "WebPolicyDelegatePrivate.h"
    3940#import "WebDefaultResourceLoadDelegate.h"
    4041#import "WebDocumentInternal.h"
     
    7374#import <WebCore/FrameMac.h>
    7475#import <WebCore/FrameTree.h>
     76#import <WebCore/HistoryItem.h>
     77#import <WebCore/HitTestResult.h>
    7578#import <WebCore/HTMLFormElement.h>
    76 #import <WebCore/HitTestResult.h>
    7779#import <WebCore/IconDatabase.h>
    7880#import <WebCore/MouseEvent.h>
    7981#import <WebCore/Page.h>
     82#import <WebCore/PageCache.h>
    8083#import <WebCore/PageState.h>
    8184#import <WebCore/PlatformString.h>
     
    8588#import <WebCore/ResourceRequest.h>
    8689#import <WebCore/WebCoreFrameBridge.h>
    87 #import <WebCore/WebCorePageState.h>
    8890#import <WebCore/WebDataProtocol.h>
    8991#import <WebKit/DOMHTMLFormElement.h>
     
    133135}
    134136
    135 bool WebFrameLoaderClient::hasBackForwardList() const
    136 {
    137     return [getWebView(m_webFrame.get()) backForwardList] != nil;
    138 }
    139 
    140 void WebFrameLoaderClient::resetBackForwardList()
    141 {
    142     // Note this doesn't verify the current load type as a b/f operation because it is called from
    143     // a subframe in the case of a delegate bailing out of the nav before it even gets to provisional state.
    144     WebFrame *mainFrame = [getWebView(m_webFrame.get()) mainFrame];
    145     WebHistoryItem *resetItem = mainFrame->_private->currentItem;
    146     if (resetItem)
    147         [[getWebView(m_webFrame.get()) backForwardList] goToItem:resetItem];
    148 }
    149 
    150 bool WebFrameLoaderClient::provisionalItemIsTarget() const
    151 {
    152     return [m_webFrame->_private->provisionalItem isTargetItem];
    153 }
    154 
    155 bool WebFrameLoaderClient::loadProvisionalItemFromPageCache()
    156 {
    157     WebHistoryItem *item = m_webFrame->_private->provisionalItem;
    158     if (![item hasPageCache])
    159         return false;
    160     NSDictionary *pageCache = [item pageCache];
    161     if (![pageCache objectForKey:WebCorePageCacheStateKey])
    162         return false;
    163     [[m_webFrame.get() provisionalDataSource] _loadFromPageCache:pageCache];
    164     return true;
    165 }
    166 
    167 void WebFrameLoaderClient::invalidateCurrentItemPageCache()
    168 {
    169     // When we are pre-commit, the currentItem is where the pageCache data resides
    170     WebHistoryItem *currentItem = m_webFrame->_private->currentItem;
    171     NSDictionary *pageCache = [currentItem pageCache];
    172     WebCorePageState *state = [pageCache objectForKey:WebCorePageCacheStateKey];
    173     WebCore::PageState* pageState = [state impl];
    174 
    175     // FIXME: This is a grotesque hack to fix <rdar://problem/4059059> Crash in RenderFlow::detach
    176     // Somehow the WebCorePageState object is not properly updated, and is holding onto a stale document.
    177     // Both Xcode and FileMaker see this crash, Safari does not.
    178     ASSERT(!pageState || pageState->document() == core(m_webFrame.get())->document());
    179     if (pageState && pageState->document() == core(m_webFrame.get())->document())
    180         pageState->clear();
    181 
    182     // We're assuming that WebCore invalidates its pageCache state in didNotOpen:pageCache:
    183     [currentItem setHasPageCache:NO];
    184 }
    185 
    186137bool WebFrameLoaderClient::privateBrowsingEnabled() const
    187138{
     
    215166}
    216167
    217 void WebFrameLoaderClient::setDocumentViewFromPageCache(NSDictionary *pageCache)
    218 {
    219     WebDataSource *cachedDataSource = [pageCache objectForKey:WebPageCacheDataSourceKey];
    220     ASSERT(cachedDataSource != nil);
    221     NSView <WebDocumentView> *cachedView = [pageCache objectForKey:WebPageCacheDocumentViewKey];
     168void WebFrameLoaderClient::setDocumentViewFromPageCache(PageCache* pageCache)
     169{
     170    DocumentLoader* cachedDocumentLoader = pageCache->documentLoader();
     171    ASSERT(cachedDocumentLoader);
     172    NSView <WebDocumentView> *cachedView = pageCache->documentView();
    222173    ASSERT(cachedView != nil);
    223     [cachedView setDataSource:cachedDataSource];
     174    [cachedView setDataSource:dataSource(cachedDocumentLoader)];
    224175    [m_webFrame->_private->webFrameView _setDocumentView:cachedView];
    225176}
     
    249200}
    250201
    251 void WebFrameLoaderClient::updateHistoryForCommit()
    252 {
    253     FrameLoadType type = core(m_webFrame.get())->loader()->loadType();
    254     if (isBackForwardLoadType(type) ||
    255         (type == FrameLoadTypeReload && [[m_webFrame.get() provisionalDataSource] unreachableURL] != nil)) {
    256         // Once committed, we want to use current item for saving DocState, and
    257         // the provisional item for restoring state.
    258         // Note previousItem must be set before we close the URL, which will
    259         // happen when the data source is made non-provisional below
    260         [m_webFrame.get() _setPreviousItem:m_webFrame->_private->currentItem];
    261         ASSERT(m_webFrame->_private->provisionalItem);
    262         [m_webFrame.get() _setCurrentItem:m_webFrame->_private->provisionalItem];
    263         [m_webFrame.get() _setProvisionalItem:nil];
    264     }
    265 }
    266 
    267 void WebFrameLoaderClient::updateHistoryForBackForwardNavigation()
    268 {
    269     // Must grab the current scroll position before disturbing it
    270     [m_webFrame.get() _saveScrollPositionAndViewStateToItem:m_webFrame->_private->previousItem];
    271 }
    272 
    273 void WebFrameLoaderClient::updateHistoryForReload()
    274 {
    275     WebHistoryItem *currItem = m_webFrame->_private->previousItem;
    276     [currItem setHasPageCache:NO];
    277     if (core(m_webFrame.get())->loader()->loadType() == FrameLoadTypeReload)
    278         [m_webFrame.get() _saveScrollPositionAndViewStateToItem:currItem];
    279     WebDataSource *dataSource = [m_webFrame.get() dataSource];
    280     NSURLRequest *request = [dataSource request];
    281     // Sometimes loading a page again leads to a different result because of cookies. Bugzilla 4072
    282     if ([request _webDataRequestUnreachableURL] == nil)
    283         [currItem setURL:[request URL]];
    284     // Update the last visited time. Mostly interesting for URL autocompletion statistics.
    285     NSURL *URL = [[dataSource _documentLoader]->originalRequestCopy().url().getNSURL() _webkit_canonicalize];
    286     WebHistory *sharedHistory = [WebHistory optionalSharedHistory];
    287     WebHistoryItem *oldItem = [sharedHistory itemForURL:URL];
    288     if (oldItem)
    289         [sharedHistory setLastVisitedTimeInterval:[NSDate timeIntervalSinceReferenceDate] forItem:oldItem];
    290 }
    291 
    292 void WebFrameLoaderClient::updateHistoryForStandardLoad()
    293 {
    294     WebDataSource *dataSource = [m_webFrame.get() dataSource];
    295     if (![dataSource _documentLoader]->isClientRedirect()) {
    296         NSURL *URL = [dataSource _URLForHistory];
    297         if (URL && ![URL _web_isEmpty]) {
    298             ASSERT(getWebView(m_webFrame.get()));
    299             if (![[getWebView(m_webFrame.get()) preferences] privateBrowsingEnabled]) {
    300                 WebHistoryItem *entry = [[WebHistory optionalSharedHistory] addItemForURL:URL];
    301                 if ([dataSource pageTitle])
    302                     [entry setTitle:[dataSource pageTitle]];                           
    303             }
    304             [m_webFrame.get() _addBackForwardItemClippedAtTarget:YES];
    305         }
    306     } else {
    307         NSURLRequest *request = [dataSource request];
    308        
    309         // Update the URL in the BF list that we made before the redirect, unless
    310         // this is alternate content for an unreachable URL (we want the BF list
    311         // item to remember the unreachable URL in case it becomes reachable later).
    312         if ([request _webDataRequestUnreachableURL] == nil) {
    313             [m_webFrame->_private->currentItem setURL:[request URL]];
    314 
    315             // clear out the form data so we don't repost it to the wrong place if we
    316             // ever go back/forward to this item
    317             [m_webFrame->_private->currentItem _setFormInfoFromRequest:request];
    318 
    319             // We must also clear out form data so we don't try to restore it into the incoming page,
    320             // see -_opened
    321         }
    322     }
    323 }
    324 
    325 void WebFrameLoaderClient::updateHistoryForInternalLoad()
    326 {
    327     // Add an item to the item tree for this frame
    328     ASSERT(!core(m_webFrame.get())->loader()->documentLoader()->isClientRedirect());
    329     WebFrame *parentFrame = [m_webFrame.get() parentFrame];
    330     if (parentFrame) {
    331         WebHistoryItem *parentItem = parentFrame->_private->currentItem;
    332         // The only case where parentItem==nil should be when a parent frame loaded an
    333         // empty URL, which doesn't set up a current item in that parent.
    334         if (parentItem)
    335             [parentItem addChildItem:[m_webFrame.get() _createItem:YES]];
    336     } else {
    337         // See 3556159. It's not clear if it's valid to be in WebFrameLoadTypeOnLoadEvent
    338         // for a top-level frame, but that was a likely explanation for those crashes,
    339         // so let's guard against it.
    340         // ...and all WebFrameLoadTypeOnLoadEvent uses were folded to WebFrameLoadTypeInternal
    341         LOG_ERROR("no parent frame in transitionToCommitted:, WebFrameLoadTypeInternal");
    342     }
    343 }
    344 
    345 void WebFrameLoaderClient::updateHistoryAfterClientRedirect()
    346 {
    347     // Clear out form data so we don't try to restore it into the incoming page.  Must happen after
    348     // khtml has closed the URL and saved away the form state.
    349     WebHistoryItem *item = m_webFrame->_private->currentItem;
    350     [item setDocumentState:nil];
    351     [item setScrollPoint:NSZeroPoint];
    352 }
    353 
    354202void WebFrameLoaderClient::setCopiesOnScroll()
    355203{
     
    357205}
    358206
    359 LoadErrorResetToken* WebFrameLoaderClient::tokenForLoadErrorReset()
    360 {
    361     if (isBackForwardLoadType(core(m_webFrame.get())->loader()->loadType()) && [m_webFrame.get() _isMainFrame])
    362         return (LoadErrorResetToken*)[m_webFrame->_private->currentItem retain];
    363     return 0;
    364 }
    365 
    366 void WebFrameLoaderClient::resetAfterLoadError(LoadErrorResetToken* token)
    367 {
    368     WebHistoryItem *item = (WebHistoryItem *)token;
    369     if (!item)
    370         return;
    371     [[getWebView(m_webFrame.get()) backForwardList] goToItem:item];
    372     [item release];
    373 }
    374 
    375 void WebFrameLoaderClient::doNotResetAfterLoadError(LoadErrorResetToken* token)
    376 {
    377     WebHistoryItem *item = (WebHistoryItem *)token;
    378     [item release];
    379 }
    380 
    381207void WebFrameLoaderClient::detachedFromParent1()
    382208{
    383     [m_webFrame.get() _saveScrollPositionAndViewStateToItem:m_webFrame->_private->currentItem];
     209    Frame* coreFrame = core(m_webFrame.get());
     210    if (coreFrame)
     211        coreFrame->loader()->saveScrollPositionAndViewStateToItem(coreFrame->loader()->currentHistoryItem());
    384212}
    385213
     
    407235    // The WebCore side of the page cache will have already been invalidated by
    408236    // the bridge to prevent premature release.
    409     [m_webFrame->_private->currentItem setHasPageCache:NO];
     237    core(m_webFrame.get())->loader()->currentHistoryItem()->setHasPageCache(false);
    410238}
    411239
     
    730558}
    731559
    732 void WebFrameLoaderClient::clearLoadingFromPageCache(DocumentLoader* loader)
    733 {
    734     [dataSource(loader) _setLoadingFromPageCache:NO];
    735 }
    736 
    737 bool WebFrameLoaderClient::isLoadingFromPageCache(DocumentLoader* loader)
    738 {
    739     return [dataSource(loader) _loadingFromPageCache];
    740 }
    741 
    742560void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader* loader)
    743561{
     
    818636{
    819637    [dataSource(loader) _clearUnarchivingState];
     638}
     639
     640// FIXME: <rdar://problem/4880065> - Push Global History into WebCore
     641// Once that task is complete, this will go away
     642void WebFrameLoaderClient::updateGlobalHistoryForStandardLoad(const KURL& url)
     643{
     644    NSURL *nsurl = url.getNSURL();
     645    WebHistoryItem *entry = [[WebHistory optionalSharedHistory] addItemForURL:nsurl];
     646    String pageTitle = core(m_webFrame.get())->loader()->documentLoader()->title();
     647    if (pageTitle.length())
     648        [entry setTitle:pageTitle];
     649}
     650 
     651// FIXME: <rdar://problem/4880065> - Push Global History into WebCore
     652// Once that task is complete, this will go away
     653void WebFrameLoaderClient::updateGlobalHistoryForReload(const KURL& url)
     654{
     655    WebHistory *sharedHistory = [WebHistory optionalSharedHistory];
     656    WebHistoryItem *item = [sharedHistory itemForURL:url.getNSURL()];
     657    if (item)
     658        [sharedHistory setLastVisitedTimeInterval:[NSDate timeIntervalSinceReferenceDate] forItem:item];
     659}
     660
     661bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
     662{
     663    WebView* view = getWebView(m_webFrame.get());
     664    WebHistoryItem *webItem = kit(item);
     665   
     666    return [[view _policyDelegateForwarder] webView:view shouldGoToHistoryItem:webItem];
    820667}
    821668
     
    924771    if ([getWebView(m_webFrame.get()) drawsBackground])
    925772        [sv setDrawsBackground:YES];
    926     [m_webFrame.get() _setPreviousItem:nil];
     773    core(m_webFrame.get())->loader()->setPreviousHistoryItem(0);
     774}
     775
     776
     777void WebFrameLoaderClient::saveScrollPositionAndViewStateToItem(HistoryItem* item)
     778{
     779    if (!item)
     780        return;
     781   
     782    NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
     783    NSView *parent = [docView superview];
     784
     785    // we might already be detached when this is called from detachFromParent, in which
     786    // case we don't want to override real data earlier gathered with (0,0)
     787    if (parent) {
     788        NSPoint point;
     789        if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {
     790            // The view has it's own idea of where it is scrolled to, perhaps because it contains its own
     791            // ScrollView instead of using the one provided by the WebFrame
     792            point = [(id <_WebDocumentViewState>)docView scrollPoint];
     793            item->setViewState([(id <_WebDocumentViewState>)docView viewState]);
     794        } else {
     795            // Parent is the clipview of the DynamicScrollView the WebFrame installs
     796            ASSERT([parent isKindOfClass:[NSClipView class]]);
     797            point = [parent bounds].origin;
     798        }
     799        item->setScrollPoint(IntPoint(point));
     800    }
    927801}
    928802
     
    940814void WebFrameLoaderClient::restoreScrollPositionAndViewState()
    941815{
    942     ASSERT(m_webFrame->_private->currentItem);
     816    HistoryItem* currentItem = core(m_webFrame.get())->loader()->currentHistoryItem();
     817    ASSERT(currentItem);
    943818    NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
    944     NSPoint point = [m_webFrame->_private->currentItem scrollPoint];
     819    NSPoint point = currentItem->scrollPoint();
    945820    if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {       
    946         id state = [m_webFrame->_private->currentItem viewState];
     821        id state = currentItem->viewState();
    947822        if (state) {
    948823            [(id <_WebDocumentViewState>)docView setViewState:state];
     
    956831
    957832void WebFrameLoaderClient::provisionalLoadStarted()
    958 {
    959     FrameLoadType loadType = core(m_webFrame.get())->loader()->loadType();
    960    
     833{   
    961834    // FIXME: This is OK as long as no one resizes the window,
    962835    // but in the case where someone does, it means garbage outside
    963836    // the occupied part of the scroll view.
    964837    [[m_webFrame->_private->webFrameView _scrollView] setDrawsBackground:NO];
    965    
    966     // Cache the page, if possible.
    967     // Don't write to the cache if in the middle of a redirect, since we will want to
    968     // store the final page we end up on.
    969     // No point writing to the cache on a reload or loadSame, since we will just write
    970     // over it again when we leave that page.
    971     WebHistoryItem *item = m_webFrame->_private->currentItem;
    972     if ([m_webFrame.get() _canCachePage]
    973         && item
    974         && !core(m_webFrame.get())->loader()->isQuickRedirectComing()
    975         && loadType != FrameLoadTypeReload
    976         && loadType != FrameLoadTypeReloadAllowingStaleData
    977         && loadType != FrameLoadTypeSame
    978         && ![[m_webFrame.get() dataSource] isLoading]
    979         && !core(m_webFrame.get())->loader()->documentLoader()->isStopping()) {
    980         if ([[[m_webFrame.get() dataSource] representation] isKindOfClass:[WebHTMLRepresentation class]]) {
    981             if (![item pageCache]) {
    982                 // Add the items to this page's cache.
    983                 if (createPageCache(item))
    984                     // See if any page caches need to be purged after the addition of this new page cache.
    985                     [m_webFrame.get() _purgePageCache];
    986             }
    987         } else
    988             // Put the document into a null state, so it can be restored correctly.
    989             core(m_webFrame.get())->loader()->clear();
    990     }
    991 }
    992 
    993 bool WebFrameLoaderClient::shouldTreatURLAsSameAsCurrent(const KURL& URL) const
    994 {
    995     WebHistoryItem *item = m_webFrame->_private->currentItem;
    996     NSString* URLString = [URL.getNSURL() _web_originalDataAsString];
    997     return [URLString isEqual:[item URLString]] || [URLString isEqual:[item originalURLString]];
    998 }
    999 
    1000 void WebFrameLoaderClient::addHistoryItemForFragmentScroll()
    1001 {
    1002     [m_webFrame.get() _addBackForwardItemClippedAtTarget:NO];
    1003838}
    1004839
     
    1047882}
    1048883
     884// FIXME: <rdar://problem/4880065> - Push Global History into WebCore
     885// Once that task is complete, this will go away
    1049886void WebFrameLoaderClient::setTitle(const String& title, const KURL& URL)
    1050887{
    1051888    NSString *titleNSString = title;
    1052889    [[[WebHistory optionalSharedHistory] itemForURL:URL.getNSURL()] setTitle:titleNSString];
    1053     [m_webFrame->_private->currentItem setTitle:titleNSString];
     890    if (HistoryItem* item = core(m_webFrame.get())->loader()->currentHistoryItem())
     891        item->setTitle(title);
    1054892}
    1055893
     
    1119957}
    1120958
    1121 bool WebFrameLoaderClient::createPageCache(WebHistoryItem *item)
    1122 {
    1123     WebCorePageState *pageState = [[WebCorePageState alloc] initWithPage:core(m_webFrame.get())->page()];
    1124     if (!pageState) {
    1125         [item setHasPageCache:NO];
    1126         return false;
    1127     }
    1128 
    1129     [item setHasPageCache:YES];
    1130     NSMutableDictionary *pageCache = [item pageCache];
    1131 
    1132     [pageCache setObject:pageState forKey:WebCorePageCacheStateKey];
    1133     [pageCache setObject:[NSDate date] forKey:WebPageCacheEntryDateKey];
    1134     [pageCache setObject:[m_webFrame.get() dataSource] forKey:WebPageCacheDataSourceKey];
    1135     [pageCache setObject:[m_webFrame->_private->webFrameView documentView] forKey:WebPageCacheDocumentViewKey];
    1136 
    1137     [pageState release];
    1138 
    1139     return true;
     959void WebFrameLoaderClient::saveDocumentViewToPageCache(PageCache* pageCache)
     960{
     961    pageCache->setDocumentView([m_webFrame->_private->webFrameView documentView]);
    1140962}
    1141963
     
    12161038}
    12171039
     1040bool WebFrameLoaderClient::canCachePage() const
     1041{
     1042    // We can only cache HTML pages right now
     1043    return [[[m_webFrame.get() dataSource] representation] isKindOfClass:[WebHTMLRepresentation class]];
     1044}
     1045
    12181046@implementation WebFramePolicyListener
    12191047
     
    12781106}
    12791107
     1108
     1109
    12801110@end
  • trunk/WebKit/WebCoreSupport/WebSystemInterface.m

    r18248 r18541  
    8181    INIT(SupportsMultipartXMixedReplace);
    8282    INIT(NSURLProtocolClassForReqest);
     83    INIT(SecondsSinceLastInputEvent);
    8384   
    8485    didInit = true;
  • trunk/WebKit/WebKit.xcodeproj/project.pbxproj

    r18430 r18541  
    4646                4BF99F910AE050BC00815C2B /* WebEditorClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BF99F8F0AE050BC00815C2B /* WebEditorClient.mm */; };
    4747                51B2A1000ADB15D0002A9BEE /* WebIconDatabaseDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 51B2A0FF0ADB15D0002A9BEE /* WebIconDatabaseDelegate.h */; };
     48                51C714FB0B20F79F00E5E33C /* WebBackForwardListInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 51C714FA0B20F79F00E5E33C /* WebBackForwardListInternal.h */; };
    4849                51FDC4D30B0AF5C100F84EB3 /* WebHistoryItemPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FDC4D20B0AF5C100F84EB3 /* WebHistoryItemPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
    4950                5241ADF50B1BC48A004012BD /* WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 5241ADF30B1BC48A004012BD /* WebCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    254255                9398110E0824BF01008DF038 /* WebKitSystemBits.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE52D4B0473032500CA289C /* WebKitSystemBits.m */; };
    255256                939811120824BF01008DF038 /* WebNSURLExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = BE6DC39A04C62C4E004D0EF6 /* WebNSURLExtras.m */; };
    256                 939811130824BF01008DF038 /* WebHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = 65DA2608052CC18700A97B31 /* WebHistory.m */; };
     257                939811130824BF01008DF038 /* WebHistory.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65DA2608052CC18700A97B31 /* WebHistory.mm */; };
    257258                939811150824BF01008DF038 /* WebNSDataExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = BECD142A0565830A005BB09C /* WebNSDataExtras.m */; };
    258259                939811160824BF01008DF038 /* WebNSEventExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = BE887C00056D3A6E009BB3E7 /* WebNSEventExtras.m */; };
     
    387388                51B2A0FF0ADB15D0002A9BEE /* WebIconDatabaseDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebIconDatabaseDelegate.h; sourceTree = "<group>"; };
    388389                51C16E4006138EB400A1657B /* npfunctions.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = npfunctions.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
     390                51C714FA0B20F79F00E5E33C /* WebBackForwardListInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebBackForwardListInternal.h; sourceTree = "<group>"; };
    389391                51E94C3406C0321200A9B09E /* WebPDFView.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebPDFView.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
    390392                51E94C3506C0321200A9B09E /* WebPDFView.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebPDFView.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
     
    407409                65A0006808527D1A005620FA /* libWebKitSystemInterface.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWebKitSystemInterface.a; sourceTree = BUILT_PRODUCTS_DIR; };
    408410                65A7D44A0568AB2600E70EF6 /* WebUIDelegatePrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebUIDelegatePrivate.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
    409                 65DA2608052CC18700A97B31 /* WebHistory.m */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebHistory.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
     411                65DA2608052CC18700A97B31 /* WebHistory.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebHistory.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
    410412                65E0F88208500917007E5CB9 /* WebNSURLRequestExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebNSURLRequestExtras.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
    411413                65E0F88308500917007E5CB9 /* WebNSURLRequestExtras.m */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebNSURLRequestExtras.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
     
    772774                                3944607D020F50ED0ECA1767 /* WebBackForwardList.h */,
    773775                                3944607E020F50ED0ECA1767 /* WebBackForwardList.mm */,
     776                                51C714FA0B20F79F00E5E33C /* WebBackForwardListInternal.h */,
    774777                                22F219CB08D236730030E078 /* WebBackForwardListPrivate.h */,
    775                                 65DA2608052CC18700A97B31 /* WebHistory.m */,
     778                                65DA2608052CC18700A97B31 /* WebHistory.mm */,
    776779                                F520FB190221DEFD01C1A525 /* WebHistory.h */,
    777780                                3944607F020F50ED0ECA1767 /* WebHistoryItem.h */,
     
    899902                                9CAE9D070252A4130ECA16EA /* WebPreferencesPrivate.h */,
    900903                                84311A1205EAAAF00088EDA4 /* WebResource.h */,
    901                                 513D422E034CF55A00CA2ACD /* WebResourceLoadDelegate.h */,
    902904                                84311AF105EAB12B0088EDA4 /* WebResourcePrivate.h */,
    903905                                7E6FEF0508985A7200C44C3F /* WebScriptDebugDelegate.h */,
     
    921923                                F5AEBB3D024A527601C1A526 /* WebPreferences.m */,
    922924                                84311A1305EAAAF00088EDA4 /* WebResource.m */,
     925                                513D422E034CF55A00CA2ACD /* WebResourceLoadDelegate.h */,
    923926                                7E6FEF0608985A7200C44C3F /* WebScriptDebugDelegate.m */,
    924927                                650F74E309E488F70020118A /* WebUnarchivingState.m */,
     
    12271230                                065AD5A30B0C32C7005A2B1D /* WebContextMenuClient.h in Headers */,
    12281231                                5241ADF50B1BC48A004012BD /* WebCache.h in Headers */,
     1232                                51C714FB0B20F79F00E5E33C /* WebBackForwardListInternal.h in Headers */,
    12291233                        );
    12301234                        runOnlyForDeploymentPostprocessing = 0;
     
    14151419                                9398110E0824BF01008DF038 /* WebKitSystemBits.m in Sources */,
    14161420                                939811120824BF01008DF038 /* WebNSURLExtras.m in Sources */,
    1417                                 939811130824BF01008DF038 /* WebHistory.m in Sources */,
     1421                                939811130824BF01008DF038 /* WebHistory.mm in Sources */,
    14181422                                939811150824BF01008DF038 /* WebNSDataExtras.m in Sources */,
    14191423                                939811160824BF01008DF038 /* WebNSEventExtras.m in Sources */,
  • trunk/WebKit/WebView/WebDataSource.mm

    r18242 r18541  
    6969    id <WebDocumentRepresentation> representation;
    7070   
    71     BOOL loadingFromPageCache;
    7271    WebUnarchivingState *unarchivingState;
    7372    NSMutableDictionary *subresources;
     
    183182        [[self representation] receivedError:error withDataSource:self];
    184183    }
    185 }
    186 
    187 - (void)_setLoadingFromPageCache:(BOOL)loadingFromPageCache
    188 {
    189     _private->loadingFromPageCache = loadingFromPageCache;
    190184}
    191185
     
    290284}
    291285
    292 - (void)_loadFromPageCache:(NSDictionary *)pageCache
    293 {
    294     _private->loader->prepareForLoadStart();
    295     _private->loadingFromPageCache = YES;
    296     _private->loader->setCommitted(true);
    297     _private->loader->frameLoader()->commitProvisionalLoad(pageCache);
    298 }
    299 
    300286- (WebArchive *)_popSubframeArchiveWithName:(NSString *)frameName
    301287{
     
    318304    NSString *MIMEType = [[self response] MIMEType];
    319305    return [WebView canShowMIMETypeAsHTML:MIMEType];
    320 }
    321 
    322 - (BOOL)_loadingFromPageCache
    323 {
    324     return _private->loadingFromPageCache;
    325306}
    326307
     
    337318   
    338319    [_private->representation setDataSource:self];
    339 }
    340 
    341 - (NSURL *)_URLForHistory
    342 {
    343     KURL url = _private->loader->URLForHistory();
    344     return url.isEmpty() ? nil : [url.getNSURL() _webkit_canonicalize];
    345320}
    346321
  • trunk/WebKit/WebView/WebDataSourceInternal.h

    r17245 r18541  
    5353@interface WebDataSource (WebInternal)
    5454- (void)_addToUnarchiveState:(WebArchive *)archive;
    55 - (NSURL *)_URLForHistory;
    5655- (void)_makeRepresentation;
    57 - (BOOL)_loadingFromPageCache;
    58 - (void)_setLoadingFromPageCache:(BOOL)loadingFromPageCache;
    5956- (BOOL)_isDocumentHTML;
    6057- (WebView *)_webView;
    6158- (WebFrameBridge *)_bridge;
    6259- (WebArchive *)_popSubframeArchiveWithName:(NSString *)frameName;
    63 - (void)_loadFromPageCache:(NSDictionary *)pageCache;
    6460- (NSURL *)_URL;
    6561- (DOMElement *)_imageElementWithImageResource:(WebResource *)resource;
  • trunk/WebKit/WebView/WebFrame.mm

    r18430 r18541  
    5252#import "WebNSURLExtras.h"
    5353#import "WebNSURLRequestExtras.h"
    54 #import "WebPolicyDelegatePrivate.h"
    5554#import "WebNetscapePluginEmbeddedView.h"
    5655#import "WebNullPluginView.h"
    5756#import "WebPlugin.h"
    5857#import "WebPluginController.h"
    59 #import "WebPolicyDelegatePrivate.h"
    6058#import "WebPreferencesPrivate.h"
    6159#import "WebScriptDebugDelegatePrivate.h"
     
    6765#import <WebCore/FrameMac.h>
    6866#import <WebCore/FrameTree.h>
     67#import <WebCore/HistoryItem.h>
    6968#import <WebCore/HTMLFormElement.h>
    7069#import <WebCore/HTMLFrameOwnerElement.h>
     
    124123- (WebHistoryItem *)_createItem:(BOOL)useOriginal;
    125124- (WebHistoryItem *)_createItemTreeWithTargetFrame:(WebFrame *)targetFrame clippedAtTarget:(BOOL)doClip;
    126 - (WebHistoryItem *)_currentBackForwardListItemToResetTo;
    127125@end
    128126
     
    136134{
    137135    [webFrameView release];
    138 
    139     [currentItem release];
    140     [provisionalItem release];
    141     [previousItem release];
    142136   
    143137    [scriptDebugger release];
     
    282276}
    283277
    284 // helper method used in various nav cases below
    285 - (void)_addBackForwardItemClippedAtTarget:(BOOL)doClip
    286 {
    287     if ([[self dataSource] _URLForHistory] != nil) {
    288         WebHistoryItem *bfItem = [[getWebView(self) mainFrame] _createItemTreeWithTargetFrame:self clippedAtTarget:doClip];
    289         LOG (BackForward, "for frame %@, adding item  %@\n", [self name], bfItem);
    290         [[getWebView(self) backForwardList] addItem:bfItem];
    291     }
    292 }
    293 
    294 - (WebHistoryItem *)_createItem:(BOOL)useOriginal
    295 {
    296     WebDataSource *dataSrc = [self dataSource];
    297     ResourceRequest request;
    298     NSURL *unreachableURL = [dataSrc unreachableURL];
    299     NSURL *URL;
    300     NSURL *originalURL;
    301     WebHistoryItem *bfItem;
    302     WebCoreDocumentLoader *documentLoader = [dataSrc _documentLoader];
    303 
    304     if (documentLoader)
    305         if (useOriginal)
    306             request =  documentLoader->originalRequestCopy();
    307         else
    308             request = documentLoader->request();
    309 
    310     if (unreachableURL != nil) {
    311         URL = unreachableURL;
    312         originalURL = unreachableURL;
    313     } else {
    314         URL = request.url().getNSURL();
    315         originalURL = documentLoader ? documentLoader->originalRequestCopy().url().getNSURL() : nil;
    316     }
    317 
    318     LOG (History, "creating item for %@", request.nsURLRequest());
    319    
    320     // Frames that have never successfully loaded any content
    321     // may have no URL at all. Currently our history code can't
    322     // deal with such things, so we nip that in the bud here.
    323     // Later we may want to learn to live with nil for URL.
    324     // See bug 3368236 and related bugs for more information.
    325     if (URL == nil) {
    326         URL = [NSURL URLWithString:@"about:blank"];
    327     }
    328     if (originalURL == nil) {
    329         originalURL = [NSURL URLWithString:@"about:blank"];
    330     }
    331    
    332     bfItem = [[[WebHistoryItem alloc] initWithURL:URL target:[self name] parent:[[self parentFrame] name] title:[dataSrc pageTitle]] autorelease];
    333     [bfItem setOriginalURLString:[originalURL _web_originalDataAsString]];
    334 
    335     // save form state if this is a POST
    336     [bfItem _setFormInfoFromRequest:request.nsURLRequest()];
    337 
    338     // Set the item for which we will save document state
    339     [self _setPreviousItem:_private->currentItem];
    340     [self _setCurrentItem:bfItem];
    341 
    342     return bfItem;
    343 }
    344278
    345279/*
     
    349283    which will be loaded in the future.  That part of the tree will be filled out as the child loads are committed.
    350284*/
    351 - (WebHistoryItem *)_createItemTreeWithTargetFrame:(WebFrame *)targetFrame clippedAtTarget:(BOOL)doClip
    352 {
    353     WebHistoryItem *bfItem = [self _createItem:[self parentFrame] ? YES : NO];
    354 
    355     [self _saveScrollPositionAndViewStateToItem:_private->previousItem];
    356     if (!(doClip && self == targetFrame)) {
    357         // save frame state for items that aren't loading (khtml doesn't save those)
    358         [_private->bridge saveDocumentState];
    359 
    360         for (Frame* child = core(self)->tree()->firstChild(); child; child = child->tree()->nextSibling())
    361             [bfItem addChildItem:[kit(child) _createItemTreeWithTargetFrame:targetFrame clippedAtTarget:doClip]];
    362     }
    363     if (self == targetFrame)
    364         [bfItem setIsTargetItem:YES];
    365 
    366     return bfItem;
    367 }
    368 
    369285- (BOOL)_canCachePage
    370286{
    371     return [[getWebView(self) backForwardList] _usesPageCache] && core(self)->loader()->canCachePage();
    372 }
    373 
    374 - (void)_purgePageCache
    375 {
    376     // This method implements the rule for purging the page cache.
    377     unsigned sizeLimit = [[getWebView(self) backForwardList] pageCacheSize];
    378     unsigned pagesCached = 0;
    379     WebBackForwardList *backForwardList = [getWebView(self) backForwardList];
    380     NSArray *backList = [backForwardList backListWithLimit: 999999];
    381     WebHistoryItem *oldestNonSnapbackItem = nil;
    382    
    383     unsigned i;
    384     for (i = 0; i < [backList count]; i++){
    385         WebHistoryItem *item = [backList objectAtIndex: i];
    386         if ([item hasPageCache]){
    387             if (oldestNonSnapbackItem == nil && ![item alwaysAttemptToUsePageCache])
    388                 oldestNonSnapbackItem = item;
    389             pagesCached++;
    390         }
    391     }
    392 
    393     // Snapback items are never directly purged here.
    394     if (pagesCached >= sizeLimit) {
    395         LOG(PageCache, "Purging back/forward cache, %@\n", [oldestNonSnapbackItem URL]);
    396         [oldestNonSnapbackItem setHasPageCache:NO];
    397     }
     287    return core(self)->page()->backForwardList()->usesPageCache() && core(self)->loader()->canCachePage();
    398288}
    399289
     
    408298}
    409299
    410 // helper method that determines whether the subframes described by the item's subitems
    411 // match our own current frameset
    412 - (BOOL)_childFramesMatchItem:(WebHistoryItem *)item
    413 {
    414     NSArray *childItems = [item children];
    415     int numChildItems = [childItems count];
    416     int numChildFrames = core(self)->tree()->childCount();
    417     if (numChildFrames != numChildItems)
    418         return NO;
    419 
    420     int i;
    421     for (i = 0; i < numChildItems; i++) {
    422         NSString *itemTargetName = [[childItems objectAtIndex:i] target];
    423         //Search recursive here?
    424         if (!core(self)->tree()->child(itemTargetName))
    425             return NO; // couldn't match the i'th itemTarget
    426     }
    427 
    428     return YES; // found matches for all itemTargets
    429 }
    430 
    431 // Walk the frame tree and ensure that the URLs match the URLs in the item.
    432 - (BOOL)_URLsMatchItem:(WebHistoryItem *)item
    433 {
    434     NSURL *currentURL = [[[self dataSource] request] URL];
    435 
    436     if (![[[item URL] _webkit_URLByRemovingFragment] isEqual:[currentURL _webkit_URLByRemovingFragment]])
    437         return NO;
    438    
    439     NSArray *childItems = [item children];
    440     WebHistoryItem *childItem;
    441     WebFrame *childFrame;
    442     int i, count = [childItems count];
    443     for (i = 0; i < count; i++){
    444         childItem = [childItems objectAtIndex:i];
    445         childFrame = kit(core(self)->tree()->child([childItem target]));
    446         if (![childFrame _URLsMatchItem:childItem])
    447             return NO;
    448     }
    449    
    450     return YES;
    451 }
    452 
    453 // loads content into this frame, as specified by item
    454 - (void)_loadItem:(WebHistoryItem *)item withLoadType:(FrameLoadType)loadType
    455 {
    456     NSURL *itemURL = [item URL];
    457     NSURL *itemOriginalURL = [NSURL _web_URLWithDataAsString:[item originalURLString]];
    458     NSURL *currentURL = [[[self dataSource] request] URL];
    459     NSData *formData = [item formData];
    460 
    461     // Are we navigating to an anchor within the page?
    462     // Note if we have child frames we do a real reload, since the child frames might not
    463     // match our current frame structure, or they might not have the right content.  We could
    464     // check for all that as an additional optimization.
    465     // We also do not do anchor-style navigation if we're posting a form.
    466    
    467     // FIXME: These checks don't match the ones in _loadURL:referrer:loadType:target:triggeringEvent:isFormSubmission:
    468     // Perhaps they should.
    469     if (!formData && ![self _frameLoader]->shouldReload(itemURL, currentURL) && [self _URLsMatchItem:item]) {
    470 #if 0
    471         // FIXME:  We need to normalize the code paths for anchor navigation.  Something
    472         // like the following line of code should be done, but also accounting for correct
    473         // updates to the back/forward list and scroll position.
    474         // rjw 4/9/03 See 3223929.
    475         [self _loadURL:itemURL referrer:[[[self dataSource] request] HTTPReferrer] loadType:loadType target:nil triggeringEvent:nil form:nil formValues:nil];
    476 #endif
    477         // must do this maintenance here, since we don't go through a real page reload
    478         [self _saveScrollPositionAndViewStateToItem:_private->currentItem];
    479         // FIXME: form state might want to be saved here too
    480 
    481         // We always call scrollToAnchor here, even if the URL doesn't have an
    482         // anchor fragment. This is so we'll keep the WebCore Frame's URL up-to-date.
    483         core(self)->loader()->scrollToAnchor([item URL]);
    484    
    485         // must do this maintenance here, since we don't go through a real page reload
    486         [self _setCurrentItem:item];
    487         core(self)->loader()->client()->restoreScrollPositionAndViewState();
    488 
    489         // Fake the URL change by updating the data source's request.  This will no longer
    490         // be necessary if we do the better fix described above.
    491         [self _frameLoader]->documentLoader()->replaceRequestURLForAnchorScroll(itemURL);
    492        
    493         [[getWebView(self) _frameLoadDelegateForwarder] webView:getWebView(self)
    494                                didChangeLocationWithinPageForFrame:self];
    495         [_private->internalLoadDelegate webFrame:self didFinishLoadWithError:nil];
    496     } else {
    497         // Remember this item so we can traverse any child items as child frames load
    498         [self _setProvisionalItem:item];
    499 
    500         WebDataSource *newDataSource;
    501         BOOL inPageCache = NO;
    502        
    503         // Check if we'll be using the page cache.  We only use the page cache
    504         // if one exists and it is less than _backForwardCacheExpirationInterval
    505         // seconds old.  If the cache is expired it gets flushed here.
    506         if ([item hasPageCache]){
    507             NSDictionary *pageCache = [item pageCache];
    508             NSDate *cacheDate = [pageCache objectForKey: WebPageCacheEntryDateKey];
    509             NSTimeInterval delta = [[NSDate date] timeIntervalSinceDate: cacheDate];
    510             if (delta <= [[getWebView(self) preferences] _backForwardCacheExpirationInterval]) {
    511                 newDataSource = [pageCache objectForKey: WebPageCacheDataSourceKey];
    512                 [self _frameLoader]->load([newDataSource _documentLoader], loadType, 0);   
    513                 inPageCache = YES;
    514             } else {
    515                 LOG (PageCache, "Not restoring page from back/forward cache because cache entry has expired, %@ (%3.5f > %3.5f seconds)\n", [_private->provisionalItem URL], delta, [[getWebView(self) preferences] _backForwardCacheExpirationInterval]);
    516                 [item setHasPageCache: NO];
    517             }
    518         }
    519        
    520         if (!inPageCache) {
    521             NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:itemURL];
    522             [self _frameLoader]->addExtraFieldsToRequest(request, true, (formData != nil));
    523 
    524             // If this was a repost that failed the page cache, we might try to repost the form.
    525             NavigationAction action;
    526             if (formData) {
    527                 [request setHTTPMethod:@"POST"];
    528                 [request _web_setHTTPReferrer:[item formReferrer]];
    529                 [request setHTTPBody:formData];
    530                 [request _web_setHTTPContentType:[item formContentType]];
    531 
    532                 // Slight hack to test if the NSURL cache contains the page we're going to.  We want
    533                 // to know this before talking to the policy delegate, since it affects whether we
    534                 // show the DoYouReallyWantToRepost nag.
    535                 //
    536                 // This trick has a small bug (3123893) where we might find a cache hit, but then
    537                 // have the item vanish when we try to use it in the ensuing nav.  This should be
    538                 // extremely rare, but in that case the user will get an error on the navigation.
    539                 [request setCachePolicy:NSURLRequestReturnCacheDataDontLoad];
    540                 NSURLResponse *synchResponse = nil;
    541                 [NSURLConnection sendSynchronousRequest:request returningResponse:&synchResponse error:nil];
    542                 if (synchResponse == nil) {
    543                     // Not in the NSURL cache
    544                     [request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
    545                     action = NavigationAction(itemURL, NavigationTypeFormResubmitted);
    546                 } else
    547                     // We can use the cache, don't use navType=resubmit
    548                     action = NavigationAction(itemURL, loadType, false);
    549             } else {
    550                 switch (loadType) {
    551                     case FrameLoadTypeReload:
    552                         [request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
    553                         break;
    554                     case FrameLoadTypeBack:
    555                     case FrameLoadTypeForward:
    556                     case FrameLoadTypeIndexedBackForward:
    557                         if (![[itemURL scheme] isEqual:@"https"])
    558                             [request setCachePolicy:NSURLRequestReturnCacheDataElseLoad];
    559                         break;
    560                     case FrameLoadTypeStandard:
    561                     case FrameLoadTypeInternal:
    562                         // no-op: leave as protocol default
    563                         // FIXME:  I wonder if we ever hit this case
    564                         break;
    565                     case FrameLoadTypeSame:
    566                     case FrameLoadTypeReloadAllowingStaleData:
    567                     default:
    568                         ASSERT_NOT_REACHED();
    569                 }
    570 
    571                 action = NavigationAction(itemOriginalURL, loadType, false);
    572             }
    573            
    574             [self _frameLoader]->load(request, action, loadType, 0);
    575             [request release];
    576         }
    577     }
    578 }
    579 
    580 // The general idea here is to traverse the frame tree and the item tree in parallel,
    581 // tracking whether each frame already has the content the item requests.  If there is
    582 // a match (by URL), we just restore scroll position and recurse.  Otherwise we must
    583 // reload that frame, and all its kids.
    584 - (void)_recursiveGoToItem:(WebHistoryItem *)item fromItem:(WebHistoryItem *)fromItem withLoadType:(FrameLoadType)type
    585 {
    586     NSURL *itemURL = [item URL];
    587     NSURL *currentURL = [[[self dataSource] request] URL];
    588 
    589     // Always reload the target frame of the item we're going to.  This ensures that we will
    590     // do -some- load for the transition, which means a proper notification will be posted
    591     // to the app.
    592     // The exact URL has to match, including fragment.  We want to go through the _load
    593     // method, even if to do a within-page navigation.
    594     // The current frame tree and the frame tree snapshot in the item have to match.
    595     if (![item isTargetItem] &&
    596         [itemURL isEqual:currentURL] &&
    597         (([self name] == nil && [item target] == nil) ||[[self name] isEqualToString:[item target]]) &&
    598         [self _childFramesMatchItem:item])
    599     {
    600         // This content is good, so leave it alone and look for children that need reloading
    601 
    602         // Save form state (works from currentItem, since prevItem is nil)
    603         ASSERT(!_private->previousItem);
    604         [_private->bridge saveDocumentState];
    605         [self _saveScrollPositionAndViewStateToItem:_private->currentItem];
    606        
    607         [self _setCurrentItem:item];
    608 
    609         // Restore form state (works from currentItem)
    610         [_private->bridge restoreDocumentState];
    611         // Restore the scroll position (taken in favor of going back to the anchor)
    612         core(self)->loader()->client()->restoreScrollPositionAndViewState();
    613        
    614         NSArray *childItems = [item children];
    615         int numChildItems = childItems ? [childItems count] : 0;
    616         int i;
    617         for (i = numChildItems - 1; i >= 0; i--) {
    618             WebHistoryItem *childItem = [childItems objectAtIndex:i];
    619             NSString *childName = [childItem target];
    620             WebHistoryItem *fromChildItem = [fromItem childItemWithName:childName];
    621             ASSERT(fromChildItem || [fromItem isTargetItem]);
    622             WebFrame *childFrame = kit(core(self)->tree()->child(childName));
    623             ASSERT(childFrame);
    624             [childFrame _recursiveGoToItem:childItem fromItem:fromChildItem withLoadType:type];
    625         }
    626     } else {
    627         // We need to reload the content
    628         [self _loadItem:item withLoadType:type];
    629     }
    630 }
    631 
    632 // Main funnel for navigating to a previous location (back/forward, non-search snap-back)
    633 // This includes recursion to handle loading into framesets properly
    634 - (void)_goToItem:(WebHistoryItem *)item withLoadType:(FrameLoadType)type
    635 {
    636     ASSERT(![self parentFrame]);
    637     // shouldGoToHistoryItem is a private delegate method. This is needed to fix:
    638     // <rdar://problem/3951283> can view pages from the back/forward cache that should be disallowed by Parental Controls
    639     // Ultimately, history item navigations should go through the policy delegate. That's covered in:
    640     // <rdar://problem/3979539> back/forward cache navigations should consult policy delegate
    641     if ([[getWebView(self) _policyDelegateForwarder] webView:getWebView(self) shouldGoToHistoryItem:item]) {   
    642         WebBackForwardList *backForwardList = [getWebView(self) backForwardList];
    643         WebHistoryItem *currItem = [backForwardList currentItem];
    644         // Set the BF cursor before commit, which lets the user quickly click back/forward again.
    645         // - plus, it only makes sense for the top level of the operation through the frametree,
    646         // as opposed to happening for some/one of the page commits that might happen soon
    647         [backForwardList goToItem:item];
    648         [self _recursiveGoToItem:item fromItem:currItem withLoadType:type];
    649     }
    650 }
    651 
    652300- (void)_loadURL:(NSURL *)URL referrer:(NSString *)referrer intoChild:(WebFrame *)childFrame
    653301{
    654     WebHistoryItem *parentItem = _private->currentItem;
    655     NSArray *childItems = [parentItem children];
     302    ASSERT(childFrame);
     303    HistoryItem* parentItem = core(self)->loader()->currentHistoryItem();
    656304    FrameLoadType loadType = [self _frameLoader]->loadType();
    657305    FrameLoadType childLoadType = FrameLoadTypeInternal;
    658     WebHistoryItem *childItem = nil;
    659306
    660307    // If we're moving in the backforward list, we might want to replace the content
    661308    // of this child frame with whatever was there at that point.
    662309    // Reload will maintain the frame contents, LoadSame will not.
    663     if (childItems &&
     310    if (parentItem && parentItem->children().size() &&
    664311        (isBackForwardLoadType(loadType)
    665312         || loadType == FrameLoadTypeReload
    666313         || loadType == FrameLoadTypeReloadAllowingStaleData))
    667314    {
    668         childItem = [parentItem childItemWithName:[childFrame name]];
     315        HistoryItem* childItem = parentItem->childItemWithName([childFrame name]);
    669316        if (childItem) {
    670317            // Use the original URL to ensure we get all the side-effects, such as
    671318            // onLoad handlers, of any redirects that happened. An example of where
    672319            // this is needed is Radar 3213556.
    673             URL = [NSURL _web_URLWithDataAsString:[childItem originalURLString]];
     320            URL = [NSURL _web_URLWithDataAsString:childItem->originalURLString()];
    674321            // These behaviors implied by these loadTypes should apply to the child frames
    675322            childLoadType = loadType;
     
    677324            if (isBackForwardLoadType(loadType))
    678325                // For back/forward, remember this item so we can traverse any child items as child frames load
    679                 [childFrame _setProvisionalItem:childItem];
     326                core(childFrame)->loader()->setProvisionalHistoryItem(childItem);
    680327            else
    681328                // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item
    682                 [childFrame _setCurrentItem:childItem];
     329                core(childFrame)->loader()->setCurrentHistoryItem(childItem);
    683330        }
    684331    }
     
    692339}
    693340
    694 - (void)_saveScrollPositionAndViewStateToItem:(WebHistoryItem *)item
    695 {
    696     if (item) {
    697         NSView <WebDocumentView> *docView = [_private->webFrameView documentView];
    698         NSView *parent = [docView superview];
    699         // we might already be detached when this is called from detachFromParent, in which
    700         // case we don't want to override real data earlier gathered with (0,0)
    701         if (parent) {
    702             NSPoint point;
    703             if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {
    704                 // The view has it's own idea of where it is scrolled to, perhaps because it contains its own
    705                 // ScrollView instead of using the one provided by the WebFrame
    706                 point = [(id <_WebDocumentViewState>)docView scrollPoint];
    707                 [item setViewState:[(id <_WebDocumentViewState>)docView viewState]];
    708             } else {
    709                 // Parent is the clipview of the DynamicScrollView the WebFrame installs
    710                 ASSERT([parent isKindOfClass:[NSClipView class]]);
    711                 point = [parent bounds].origin;
    712             }
    713             [item setScrollPoint:point];
    714         }
    715     }
    716 }
    717341
    718342- (void)_viewWillMoveToHostWindow:(NSWindow *)hostWindow
     
    735359    if ([child dataSource])
    736360        [[child dataSource] _documentLoader]->setOverrideEncoding([[self dataSource] _documentLoader]->overrideEncoding()); 
    737 }
    738 
    739 // If we bailed out of a b/f navigation, we might need to set the b/f cursor back to the current
    740 // item, because we optimistically move it right away at the start of the operation. But when
    741 // alternate content is loaded for an unreachableURL, we don't want to reset the b/f cursor.
    742 // Return the item that we would reset to, so we can decide later whether to actually reset.
    743 - (WebHistoryItem *)_currentBackForwardListItemToResetTo
    744 {
    745     if (isBackForwardLoadType([self _frameLoader]->loadType()) && [self _isMainFrame])
    746         return _private->currentItem;
    747     return nil;
    748 }
    749 
    750 - (WebHistoryItem *)_itemForSavingDocState
    751 {
    752     // For a standard page load, we will have a previous item set, which will be used to
    753     // store the form state.  However, in some cases we will have no previous item, and
    754     // the current item is the right place to save the state.  One example is when we
    755     // detach a bunch of frames because we are navigating from a site with frames to
    756     // another site.  Another is when saving the frame state of a frame that is not the
    757     // target of the current navigation (if we even decide to save with that granularity).
    758 
    759     // Because of previousItem's "masking" of currentItem for this purpose, it's important
    760     // that previousItem be cleared at the end of a page transition.  We leverage the
    761     // checkLoadComplete recursion to achieve this goal.
    762 
    763     return _private->previousItem ? _private->previousItem : _private->currentItem;
    764 }
    765 
    766 - (WebHistoryItem *)_itemForRestoringDocState
    767 {
    768     switch ([self _frameLoader]->loadType()) {
    769         case FrameLoadTypeReload:
    770         case FrameLoadTypeReloadAllowingStaleData:
    771         case FrameLoadTypeSame:
    772         case FrameLoadTypeReplace:
    773             // Don't restore any form state on reload or loadSame
    774             return nil;
    775         case FrameLoadTypeBack:
    776         case FrameLoadTypeForward:
    777         case FrameLoadTypeIndexedBackForward:
    778         case FrameLoadTypeInternal:
    779         case FrameLoadTypeStandard:
    780             return _private->currentItem;
    781     }
    782     ASSERT_NOT_REACHED();
    783     return nil;
    784 }
    785 
    786 // Walk the frame tree, telling all frames to save their form state into their current
    787 // history item.
    788 - (void)_saveDocumentAndScrollState
    789 {
    790     Frame* coreFrame = core(self);
    791     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
    792         [Mac(frame)->bridge() saveDocumentState];
    793         [kit(frame) _saveScrollPositionAndViewStateToItem:kit(frame)->_private->currentItem];
    794     }
    795361}
    796362
     
    1029595}
    1030596
    1031 - (void)_setProvisionalItem:(WebHistoryItem *)item
    1032 {
    1033     [item retain];
    1034     [_private->provisionalItem release];
    1035     _private->provisionalItem = item;
    1036 }
    1037 
    1038 - (void)_setPreviousItem:(WebHistoryItem *)item
    1039 {
    1040     [item retain];
    1041     [_private->previousItem release];
    1042     _private->previousItem = item;
    1043 }
    1044 
    1045 - (void)_setCurrentItem:(WebHistoryItem *)item
    1046 {
    1047     [item retain];
    1048     [_private->currentItem release];
    1049     _private->currentItem = item;
    1050 }
    1051 
    1052597@end
    1053598
  • trunk/WebKit/WebView/WebFrameInternal.h

    r18430 r18541  
    5757    class FrameMac;
    5858    class FrameLoader;
     59    class HistoryItem;
    5960    class HTMLElement;
    6061    class Node;
     
    6263    class Range;
    6364}
     65
     66typedef WebCore::HistoryItem WebCoreHistoryItem;
    6467
    6568WebCore::CSSStyleDeclaration* core(DOMCSSStyleDeclaration *);
     
    98101
    99102    WebFrameBridge *bridge;
    100     WebHistoryItem *currentItem;        // BF item for our current content
    101     WebHistoryItem *provisionalItem;    // BF item for where we're trying to go
    102                                         // (only known when navigating to a pre-existing BF item)
    103     WebHistoryItem *previousItem;       // BF item for previous content, see _itemForSavingDocState
    104103
    105104    WebScriptDebugger *scriptDebugger;
     
    110109@end
    111110
     111#else
     112struct WebCoreHistoryItem;
    112113#endif
    113114
     
    150151- (WebFrameBridge *)_bridge;
    151152
    152 #ifdef __cplusplus
    153 - (void)_goToItem:(WebHistoryItem *)item withLoadType:(WebCore::FrameLoadType)type;
    154 #endif
    155153- (void)_loadURL:(NSURL *)URL referrer:(NSString *)referrer intoChild:(WebFrame *)childFrame;
    156154
     
    160158- (void)_addChild:(WebFrame *)child;
    161159
    162 - (WebHistoryItem *)_itemForSavingDocState;
    163 - (WebHistoryItem *)_itemForRestoringDocState;
    164 
    165 - (void)_saveDocumentAndScrollState;
    166 
    167160+ (CFAbsoluteTime)_timeOfLastCompletedLoad;
    168161- (BOOL)_canCachePage;
    169 - (void)_purgePageCache;
    170162
    171163- (int)_numPendingOrLoadingRequests:(BOOL)recurse;
     
    178170- (void)_recursive_pauseNullEventsForAllNetscapePlugins;
    179171
    180 - (void)_setProvisionalItem:(WebHistoryItem *)item;
    181 - (void)_setPreviousItem:(WebHistoryItem *)item;
    182 - (void)_setCurrentItem:(WebHistoryItem *)item;
    183 
    184 - (void)_saveScrollPositionAndViewStateToItem:(WebHistoryItem *)item;
    185 
    186 - (void)_addBackForwardItemClippedAtTarget:(BOOL)doClip;
    187 
    188 - (WebHistoryItem *)_createItem:(BOOL)useOriginal;
    189 
    190172@end
    191173
  • trunk/WebKit/WebView/WebFrameView.mm

    r17405 r18541  
    3838#import "WebFrameViewInternal.h"
    3939#import "WebFrameViewPrivate.h"
     40#import "WebHistoryItemInternal.h"
    4041#import "WebHTMLViewPrivate.h"
    4142#import "WebKeyGenerator.h"
     
    5657#import <JavaScriptCore/Assertions.h>
    5758#import <WebCore/FrameMac.h>
     59#import <WebCore/HistoryItem.h>
     60#import <WebCore/Page.h>
    5861#import <WebCore/WebCoreFrameView.h>
    5962#import <WebCore/WebCoreView.h>
     
    315318        didFirstTimeInitialization = true;
    316319        InitWebCoreSystemInterface();
     320       
     321        // Need to tell WebCore what function to call for the
     322        // "History Item has Changed" notification
     323        // Note: We also do this in WebHistoryItem's init method
     324        WebCore::notifyHistoryItemChanged = WKNotifyHistoryItemChanged;
     325
    317326        [WebViewFactory createSharedFactory];
    318327        [WebKeyGenerator createSharedGenerator];
     
    674683    int index, count;
    675684    BOOL callSuper = YES;
    676     BOOL maintainsBackForwardList = [[[self webFrame] webView] backForwardList] == nil ? NO : YES;
    677 
     685    BOOL maintainsBackForwardList = core([self webFrame])->page()->backForwardList() ? YES : NO;
     686   
    678687    count = [characters length];
    679688    for (index = 0; index < count; ++index) {
  • trunk/WebKit/WebView/WebHTMLView.m

    r18388 r18541  
    51745174}
    51755175
     5176- (void)closeIfNotCurrentView
     5177{
     5178    if ([[[self _frame] frameView] documentView] != self)
     5179        [self close];
     5180}
     5181
    51765182#if !BUILDING_ON_TIGER
    51775183
  • trunk/WebKit/WebView/WebHTMLViewInternal.h

    r18388 r18541  
    115115- (void)paste:(id)sender;
    116116- (void)pasteAsPlainText:(id)sender;
     117- (void)closeIfNotCurrentView;
    117118- (void)_lookUpInDictionaryFromMenu:(id)sender;
    118119- (void)_hoverFeedbackSuspendedChanged;
     120
    119121#if !BUILDING_ON_TIGER
    120122- (BOOL)isGrammarCheckingEnabled;
  • trunk/WebKit/WebView/WebView.mm

    r18424 r18541  
    3232#import "DOMRangeInternal.h"
    3333#import "WebBackForwardList.h"
     34#import "WebBackForwardListInternal.h"
    3435#import "WebBaseNetscapePluginView.h"
    3536#import "WebChromeClient.h"
     
    9697#import <WebCore/FrameMac.h>
    9798#import <WebCore/FrameTree.h>
     99#import <WebCore/HistoryItem.h>
    98100#import <WebCore/Logging.h>
    99101#import <WebCore/Page.h>
     
    252254    id scriptDebugDelegateForwarder;
    253255   
    254     WebBackForwardList *backForwardList;
    255256    BOOL useBackForwardList;
    256    
     257       
    257258    float textSizeMultiplier;
    258259
     
    399400        return nil;
    400401   
    401     backForwardList = [[WebBackForwardList alloc] init];
    402402    textSizeMultiplier = 1;
    403403    progressNotificationInterval = 0.02;
     
    422422    delete userAgent;
    423423
    424     [backForwardList release];
    425424    [applicationNameForUserAgent release];
    426425    [backgroundColor release];
     
    652651        mainFrameLoader->detachFromParent();
    653652   
     653    // Deleteing the WebCore::Page will clear the page cache so we call destroy on
     654    // all the plug-ins in the page cache to break any retain cycles.
     655    // See comment in HistoryItem::releaseAllPendingPageCaches() for more information.
    654656    delete _private->page;
    655657    _private->page = 0;
    656 
    657     // Clear the page cache so we call destroy on all the plug-ins in the page cache to break any retain cycles.
    658     // See comment in [WebHistoryItem _releaseAllPendingPageCaches] for more information.
    659     if (_private->backForwardList) {
    660         [_private->backForwardList _close];
    661         [_private->backForwardList release];
    662         _private->backForwardList = nil;
    663     }
    664658
    665659    if (_private->hasSpellCheckerDocumentTag) {
     
    811805}
    812806
    813 - (void)_goToItem:(WebHistoryItem *)item withLoadType:(WebFrameLoadType)type
    814 {
    815     // We never go back/forward on a per-frame basis, so the target must be the main frame
    816     //ASSERT([item target] == nil || [self _findFrameNamed:[item target]] == [self mainFrame]);
    817 
    818     // abort any current load if we're going back/forward
    819     [[self mainFrame] stopLoading];
    820     [[self mainFrame] _goToItem:item withLoadType:(FrameLoadType)type];
    821 }
     807
    822808
    823809- (void)_loadBackForwardListFromOtherView:(WebView *)otherView
     
    827813    // in the back forward list, and go to the current one.
    828814
    829     WebBackForwardList *bfList = [self backForwardList];
    830     ASSERT(![bfList currentItem]); // destination list should be empty
    831 
    832     WebBackForwardList *otherBFList = [otherView backForwardList];
    833     if (![otherBFList currentItem]) {
     815    BackForwardList* backForwardList = _private->page->backForwardList();
     816    ASSERT(!backForwardList->currentItem()); // destination list should be empty
     817
     818    BackForwardList* otherBackForwardList = otherView->_private->page->backForwardList();
     819    if (!otherBackForwardList->currentItem())
    834820        return; // empty back forward list, bail
    835     }
    836 
    837     WebHistoryItem *newItemToGoTo = nil;
    838     int lastItemIndex = [otherBFList forwardListCount];
    839     int i;
    840     for (i = -[otherBFList backListCount]; i <= lastItemIndex; i++) {
     821   
     822    HistoryItem* newItemToGoTo = 0;
     823
     824    int lastItemIndex = otherBackForwardList->forwardListCount();
     825    for (int i = -otherBackForwardList->backListCount(); i <= lastItemIndex; ++i) {
    841826        if (i == 0) {
    842827            // If this item is showing , save away its current scroll and form state,
    843828            // since that might have changed since loading and it is normally not saved
    844829            // until we leave that page.
    845             [[otherView mainFrame] _saveDocumentAndScrollState];
     830            otherView->_private->page->mainFrame()->loader()->saveDocumentAndScrollState();
    846831        }
    847         WebHistoryItem *newItem = [[otherBFList itemAtIndex:i] copy];
    848         [bfList addItem:newItem];
    849         if (i == 0) {
    850             newItemToGoTo = newItem;
    851         }
    852     }
    853    
    854     [self _goToItem:newItemToGoTo withLoadType:WebFrameLoadTypeIndexedBackForward];
     832        RefPtr<HistoryItem> newItem = otherBackForwardList->itemAtIndex(i)->copy();
     833        if (i == 0)
     834            newItemToGoTo = newItem.get();
     835        backForwardList->addItem(newItem.release());
     836    }
     837   
     838    ASSERT(newItemToGoTo);
     839    _private->page->goToItem(newItemToGoTo, FrameLoadTypeIndexedBackForward);
    855840}
    856841
     
    18271812    WebKitInitializeLoggingChannelsIfNecessary();
    18281813    WebCore::InitializeLoggingChannelsIfNecessary();
     1814    [WebBackForwardList setDefaultPageCacheSizeIfNecessary];
     1815    [WebHistoryItem initWindowWatcherIfNecessary];
    18291816
    18301817    _private->page = new Page(new WebChromeClient(self), new WebContextMenuClient(self), new WebEditorClient(self));
     
    19011888    WebPreferences *preferences;
    19021889    BOOL useBackForwardList;
    1903 
     1890   
    19041891    result = [super initWithCoder:decoder];
    19051892    result->_private = [[WebViewPrivate alloc] init];
     
    21582145{
    21592146    if (_private->useBackForwardList)
    2160         return _private->backForwardList;
     2147        return kit([self page]->backForwardList());
    21612148    return nil;
    21622149}
     
    21692156- (BOOL)goBack
    21702157{
    2171     WebHistoryItem *item = [[self backForwardList] backItem];
    2172    
    2173     if (item){
    2174         [self _goToItem: item withLoadType: WebFrameLoadTypeBack];
    2175         return YES;
    2176     }
    2177     return NO;
     2158    return _private->page->goBack();
    21782159}
    21792160
    21802161- (BOOL)goForward
    21812162{
    2182     WebHistoryItem *item = [[self backForwardList] forwardItem];
    2183    
    2184     if (item){
    2185         [self _goToItem: item withLoadType: WebFrameLoadTypeForward];
    2186         return YES;
    2187     }
    2188     return NO;
     2163    return _private->page->goForward();
    21892164}
    21902165
    21912166- (BOOL)goToBackForwardItem:(WebHistoryItem *)item
    21922167{
    2193     [self _goToItem: item withLoadType: WebFrameLoadTypeIndexedBackForward];
     2168    _private->page->goToItem(core(item), FrameLoadTypeIndexedBackForward);
    21942169    return YES;
    21952170}
     
    27542729- (BOOL)canGoBack
    27552730{
    2756     return [[self backForwardList] backItem] != nil;
     2731    return !!_private->page->backForwardList()->backItem();
    27572732}
    27582733
    27592734- (BOOL)canGoForward
    27602735{
    2761     return [[self backForwardList] forwardItem] != nil;
     2736    return !!_private->page->backForwardList()->forwardItem();
    27622737}
    27632738
Note: See TracChangeset for help on using the changeset viewer.