WebCore:
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 16 Nov 2008 19:39:03 +0000 (19:39 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 16 Nov 2008 19:39:03 +0000 (19:39 +0000)
2008-11-16  Darin Adler  <darin@apple.com>

        Reviewed by Dan Bernstein.

        - https://bugs.webkit.org/show_bug.cgi?id=22295
          track which history items are from page load failures

        * history/HistoryItem.cpp: Sort includes, add newly needed ones, and remove
        no-longer-needed ones.
        (WebCore::HistoryItem::HistoryItem): Initialize m_lastVisitWasFailure to false.
        (WebCore::HistoryItem::showTreeWithIndent): Rewrote to avoid appending to a
        String, since that's not efficient.

        * history/HistoryItem.h: Removed unneeded includes. Added lastVisitWasFailure,
        setLastVisitWasFailure, and m_lastVisitWasFailure.

        * history/mac/HistoryItemMac.mm: Add newly-needed include
        (WebCore::HistoryItem::setTransientProperty): Rewrote to avoid keeping a
        m_transientProperties map around when it is empty.

        * loader/FrameLoader.cpp:
        (WebCore::FrameLoader::createHistoryItem): Call setLastVisitWasFailure when
        the page was unreachable or an HTTP page with a status code that indicates
        failure.

WebKit/mac:

2008-11-16  Darin Adler  <darin@apple.com>

        Reviewed by Dan Bernstein.

        - https://bugs.webkit.org/show_bug.cgi?id=22295
          track which history items are from page load failures

        * History/WebHistoryItem.mm: Added lastVisitWasFailureKey.
        (-[WebHistoryItem initFromDictionaryRepresentation:]): Set the lastVisitWasFailure
        flag in the history item if the dictionary had lastVisitWasFailureKey true.
        (-[WebHistoryItem dictionaryRepresentation]): Set the lastVisitWasFailureKey boolean
        in the dictionary if the history item had the lastVisitWasFailure flag.
        (-[WebHistoryItem lastVisitWasFailure]): Added.

        * History/WebHistoryItemInternal.h: Moved include of WebBackForwardList here from
        WebHistoryItemPrivate.h; removed other unneeded includes.

        * History/WebHistoryItemPrivate.h: Added lastVisitWasFailure method.
        Removed unneeded includes.

        * Misc/WebNSDictionaryExtras.h: Added _webkit_boolForKey.
        * Misc/WebNSDictionaryExtras.m:
        (-[NSDictionary _webkit_boolForKey:]): Added.

WebKit/win:

2008-11-16  Darin Adler  <darin@apple.com>

        Reviewed by Dan Bernstein.

        - https://bugs.webkit.org/show_bug.cgi?id=22295
          track which history items are from page load failures

        * Interfaces/IWebHistoryItemPrivate.idl: Added lastVisitWasFailure function.

        * WebHistoryItem.cpp:
        (WebHistoryItem::initFromDictionaryRepresentation): Set the lastVisitWasFailure
        flag in the history item if the dictionary had an entry for lastVisitWasFailureKey.
        (WebHistoryItem::dictionaryRepresentation): Set the lastVisitWasFailureKey key
        in the dictionary if the history item had the lastVisitWasFailure flag.
        (WebHistoryItem::lastVisitWasFailure): Added.

        * WebHistoryItem.h: Added lastVisitWasFailure function.

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

15 files changed:
WebCore/ChangeLog
WebCore/history/HistoryItem.cpp
WebCore/history/HistoryItem.h
WebCore/history/mac/HistoryItemMac.mm
WebCore/loader/FrameLoader.cpp
WebKit/mac/ChangeLog
WebKit/mac/History/WebHistoryItem.mm
WebKit/mac/History/WebHistoryItemInternal.h
WebKit/mac/History/WebHistoryItemPrivate.h
WebKit/mac/Misc/WebNSDictionaryExtras.h
WebKit/mac/Misc/WebNSDictionaryExtras.m
WebKit/win/ChangeLog
WebKit/win/Interfaces/IWebHistoryItemPrivate.idl
WebKit/win/WebHistoryItem.cpp
WebKit/win/WebHistoryItem.h

index e0e0008..f8b6dfa 100644 (file)
@@ -1,3 +1,28 @@
+2008-11-16  Darin Adler  <darin@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        - https://bugs.webkit.org/show_bug.cgi?id=22295
+          track which history items are from page load failures
+
+        * history/HistoryItem.cpp: Sort includes, add newly needed ones, and remove
+        no-longer-needed ones.
+        (WebCore::HistoryItem::HistoryItem): Initialize m_lastVisitWasFailure to false.
+        (WebCore::HistoryItem::showTreeWithIndent): Rewrote to avoid appending to a
+        String, since that's not efficient.
+
+        * history/HistoryItem.h: Removed unneeded includes. Added lastVisitWasFailure,
+        setLastVisitWasFailure, and m_lastVisitWasFailure.
+
+        * history/mac/HistoryItemMac.mm: Add newly-needed include
+        (WebCore::HistoryItem::setTransientProperty): Rewrote to avoid keeping a
+        m_transientProperties map around when it is empty.
+
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::createHistoryItem): Call setLastVisitWasFailure when
+        the page was unreachable or an HTTP page with a status code that indicates
+        failure.
+
 2008-11-16  Yong Li  <yong.li@torchmobile.com>
 
         Reviewed by Timothy Hatcher.
index 95f9956..10efd4d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005, 2006 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "HistoryItem.h"
 
+#include "CString.h"
+#include "CachedPage.h"
 #include "Document.h"
-#include "FrameLoader.h"
 #include "IconDatabase.h"
-#include "IntSize.h"
-#include "KURL.h"
-#include "Logging.h"
 #include "PageCache.h"
 #include "ResourceRequest.h"
 #include <stdio.h>
@@ -46,6 +44,7 @@ void (*notifyHistoryItemChanged)() = defaultNotifyHistoryItemChanged;
 
 HistoryItem::HistoryItem()
     : m_lastVisitedTime(0)
+    , m_lastVisitWasFailure(false)
     , m_isInPageCache(false)
     , m_isTargetItem(false)
     , m_visitCount(0)
@@ -57,6 +56,7 @@ HistoryItem::HistoryItem(const String& urlString, const String& title, double ti
     , m_originalURLString(urlString)
     , m_title(title)
     , m_lastVisitedTime(time)
+    , m_lastVisitWasFailure(false)
     , m_isInPageCache(false)
     , m_isTargetItem(false)
     , m_visitCount(0)
@@ -70,6 +70,7 @@ HistoryItem::HistoryItem(const String& urlString, const String& title, const Str
     , m_title(title)
     , m_displayTitle(alternateTitle)
     , m_lastVisitedTime(time)
+    , m_lastVisitWasFailure(false)
     , m_isInPageCache(false)
     , m_isTargetItem(false)
     , m_visitCount(0)
@@ -84,6 +85,7 @@ HistoryItem::HistoryItem(const KURL& url, const String& target, const String& pa
     , m_parent(parent)
     , m_title(title)
     , m_lastVisitedTime(0)
+    , m_lastVisitWasFailure(false)
     , m_isInPageCache(false)
     , m_isTargetItem(false)
     , m_visitCount(0)
@@ -107,6 +109,7 @@ inline HistoryItem::HistoryItem(const HistoryItem& item)
     , m_displayTitle(item.m_displayTitle)
     , m_lastVisitedTime(item.m_lastVisitedTime)
     , m_scrollPoint(item.m_scrollPoint)
+    , m_lastVisitWasFailure(item.m_lastVisitWasFailure)
     , m_isInPageCache(item.m_isInPageCache)
     , m_isTargetItem(item.m_isTargetItem)
     , m_visitCount(item.m_visitCount)
@@ -398,6 +401,7 @@ void HistoryItem::mergeAutoCompleteHints(HistoryItem* otherItem)
 }
 
 #ifndef NDEBUG
+
 int HistoryItem::showTree() const
 {
     return showTreeWithIndent(0);
@@ -405,26 +409,27 @@ int HistoryItem::showTree() const
 
 int HistoryItem::showTreeWithIndent(unsigned indentLevel) const
 {
-    String prefix("");
-    int totalSubItems = 0;
-    unsigned i;
-    for (i = 0; i < indentLevel; ++i)
-        prefix.append("  ");
+    Vector<char> prefix;
+    for (unsigned i = 0; i < indentLevel; ++i)
+        prefix.append("  ", 2);
 
-    fprintf(stderr, "%s+-%s (%p)\n", prefix.ascii().data(), m_urlString.ascii().data(), this);
+    fprintf(stderr, "%s+-%s (%p)\n", prefix.data(), m_urlString.utf8().data(), this);
     
-    for (unsigned int i = 0; i < m_subItems.size(); ++i) {
+    int totalSubItems = 0;
+    for (unsigned i = 0; i < m_subItems.size(); ++i)
         totalSubItems += m_subItems[i]->showTreeWithIndent(indentLevel + 1);
-    }
     return totalSubItems + 1;
 }
+
 #endif
                 
-}; //namespace WebCore
+} // namespace WebCore
 
 #ifndef NDEBUG
+
 int showTree(const WebCore::HistoryItem* item)
 {
     return item->showTree();
 }
+
 #endif
index 9bdcb59..7d3caa7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef HistoryItem_h
 #define HistoryItem_h
 
-#include "CachedPage.h"
-#include "FormData.h"
 #include "IntPoint.h"
 #include "PlatformString.h"
-#include <wtf/RefCounted.h>
-#include "StringHash.h"
-#include <wtf/HashMap.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
-
-#if PLATFORM(QT)
-#include <QVariant>
-#endif
 
 #if PLATFORM(MAC)
 #import <wtf/RetainPtr.h>
 typedef struct objc_object* id;
 #endif
 
+#if PLATFORM(QT)
+#include <QVariant>
+#endif
+
 namespace WebCore {
 
+class CachedPage;
 class Document;
+class FormData;
+class HistoryItem;
 class Image;
 class KURL;
 class ResourceRequest;
 
-class HistoryItem;
 typedef Vector<RefPtr<HistoryItem> > HistoryItemVector;
 
 extern void (*notifyHistoryItemChanged)();
@@ -106,6 +100,7 @@ public:
     String rssFeedReferrer() const;
     
     int visitCount() const;
+    bool lastVisitWasFailure() const { return m_lastVisitWasFailure; }
 
     void mergeAutoCompleteHints(HistoryItem* otherItem);
     
@@ -128,6 +123,7 @@ public:
 
     void setRSSFeedReferrer(const String&);
     void setVisitCount(int);
+    void setLastVisitWasFailure(bool wasFailure) { m_lastVisitWasFailure = wasFailure; }
 
     void addChildItem(PassRefPtr<HistoryItem>);
     HistoryItem* childItemWithName(const String&) const;
@@ -170,7 +166,7 @@ private:
     HistoryItem(const KURL& url, const String& target, const String& parent, const String& title);
 
     HistoryItem(const HistoryItem&);
-    
+
     String m_urlString;
     String m_originalURLString;
     String m_target;
@@ -185,6 +181,7 @@ private:
     
     HistoryItemVector m_subItems;
     
+    bool m_lastVisitWasFailure;
     bool m_isInPageCache;
     bool m_isTargetItem;
     int m_visitCount;
@@ -206,6 +203,7 @@ private:
     RetainPtr<id> m_viewState;
     OwnPtr<HashMap<String, RetainPtr<id> > > m_transientProperties;
 #endif
+
 #if PLATFORM(QT)
     QVariant m_userData;
 #endif
index cac9b1b..52ae7be 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "HistoryItem.h"
 
-namespace WebCore {
+#include "StringHash.h"
 
-// Notification strings.
-NSString *WebHistoryItemChangedNotification = @"WebHistoryItemChangedNotification";
+namespace WebCore {
 
 id HistoryItem::viewState() const
 {
@@ -52,14 +51,17 @@ id HistoryItem::getTransientProperty(const String& key) const
 
 void HistoryItem::setTransientProperty(const String& key, id value)
 {
-    if (!m_transientProperties)
-        m_transientProperties.set(new HashMap<String, RetainPtr<id> >);
-    if (value == nil)
-        m_transientProperties->remove(key);
-    else
+    if (!value) {
+        if (m_transientProperties) {
+            m_transientProperties->remove(key);
+            if (m_transientProperties->isEmpty())
+                m_transientProperties.clear();
+        }
+    } else {
+        if (!m_transientProperties)
+            m_transientProperties.set(new HashMap<String, RetainPtr<id> >);
         m_transientProperties->set(key, value);
+    }
 }
 
 } // namespace WebCore
-
-
index 49dea02..8c70587 100644 (file)
@@ -4084,7 +4084,7 @@ PassRefPtr<HistoryItem> FrameLoader::createHistoryItem(bool useOriginal)
         if (useOriginal)
             url = originalURL;
         else if (docLoader)
-            url = docLoader->requestURL();                
+            url = docLoader->requestURL();
     }
 
     LOG(History, "WebCoreHistory: Creating item for %s", url.string().ascii().data());
@@ -4105,7 +4105,10 @@ PassRefPtr<HistoryItem> FrameLoader::createHistoryItem(bool useOriginal)
 
     RefPtr<HistoryItem> item = HistoryItem::create(url, m_frame->tree()->name(), parent, title);
     item->setOriginalURLString(originalURL.string());
-    
+
+    if (!unreachableURL.isEmpty() || !docLoader || docLoader->response().httpStatusCode() >= 400)
+        item->setLastVisitWasFailure(true);
+
     // Save form state if this is a POST
     if (docLoader) {
         if (useOriginal)
index 97ecac6..a39bcd0 100644 (file)
@@ -1,3 +1,27 @@
+2008-11-16  Darin Adler  <darin@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        - https://bugs.webkit.org/show_bug.cgi?id=22295
+          track which history items are from page load failures
+
+        * History/WebHistoryItem.mm: Added lastVisitWasFailureKey.
+        (-[WebHistoryItem initFromDictionaryRepresentation:]): Set the lastVisitWasFailure
+        flag in the history item if the dictionary had lastVisitWasFailureKey true.
+        (-[WebHistoryItem dictionaryRepresentation]): Set the lastVisitWasFailureKey boolean
+        in the dictionary if the history item had the lastVisitWasFailure flag.
+        (-[WebHistoryItem lastVisitWasFailure]): Added.
+
+        * History/WebHistoryItemInternal.h: Moved include of WebBackForwardList here from
+        WebHistoryItemPrivate.h; removed other unneeded includes.
+
+        * History/WebHistoryItemPrivate.h: Added lastVisitWasFailure method.
+        Removed unneeded includes.
+
+        * Misc/WebNSDictionaryExtras.h: Added _webkit_boolForKey.
+        * Misc/WebNSDictionaryExtras.m:
+        (-[NSDictionary _webkit_boolForKey:]): Added.
+
 2008-11-14  Greg Bolsinga  <bolsinga@apple.com>
 
         Reviewed by Darin Adler.
index a586386..b9a11bc 100644 (file)
@@ -60,6 +60,7 @@ static NSString *WebVisitCountKey = @"visitCount";
 static NSString *WebTitleKey = @"title";
 static NSString *WebChildrenKey = @"children";
 static NSString *WebDisplayTitleKey = @"displayTitle";
+static NSString *lastVisitWasFailureKey = @"lastVisitWasFailure";
 
 // Notification strings.
 NSString *WebHistoryItemChangedNotification = @"WebHistoryItemChangedNotification";
@@ -353,10 +354,13 @@ static WebWindowWatcher *_windowWatcher = nil;
 
     core(_private)->setVisitCount([dict _webkit_intForKey:WebVisitCountKey]);
 
+    if ([dict _webkit_boolForKey:lastVisitWasFailureKey])
+        core(_private)->setLastVisitWasFailure(true);
+
     NSArray *childDicts = [dict objectForKey:WebChildrenKey];
     if (childDicts) {
         for (int i = [childDicts count] - 1; i >= 0; i--) {
-            WebHistoryItem *child = [[WebHistoryItem alloc] initFromDictionaryRepresentation: [childDicts objectAtIndex:i]];
+            WebHistoryItem *child = [[WebHistoryItem alloc] initFromDictionaryRepresentation:[childDicts objectAtIndex:i]];
             core(_private)->addChildItem(core(child->_private));
             [child release];
         }
@@ -406,9 +410,10 @@ static WebWindowWatcher *_windowWatcher = nil;
         [dict setObject:[NSString stringWithFormat:@"%.1lf", coreItem->lastVisitedTime()]
                  forKey:WebLastVisitedTimeIntervalKey];
     }
-    if (coreItem->visitCount()) {
+    if (coreItem->visitCount())
         [dict setObject:[NSNumber numberWithInt:coreItem->visitCount()] forKey:WebVisitCountKey];
-    }
+    if (coreItem->lastVisitWasFailure())
+        [dict setObject:[NSNumber numberWithBool:YES] forKey:lastVisitWasFailureKey];
     if (coreItem->children().size()) {
         const HistoryItemVector& children = coreItem->children();
         NSMutableArray *childDicts = [NSMutableArray arrayWithCapacity:children.size()];
@@ -517,6 +522,11 @@ static WebWindowWatcher *_windowWatcher = nil;
     core(_private)->setTransientProperty(key, property);
 }
 
+- (BOOL)lastVisitWasFailure
+{
+    return core(_private)->lastVisitWasFailure();
+}
+
 @end
 
 
index 11c063c..ebbef82 100644 (file)
@@ -26,9 +26,9 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#import "WebBackForwardList.h"
 #import "WebHistoryItemPrivate.h"
-
-#import <wtf/PassRefPtr.h>
+#import <wtf/Forward.h>
 
 namespace WebCore {
     class HistoryItem;
index bc75d1b..d26e2e3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#import <Cocoa/Cocoa.h>
-
-#import <WebKit/WebBackForwardList.h>
 #import <WebKit/WebHistoryItem.h>
 
 @interface WebHistoryItem (WebPrivate)
+
 + (void)_releaseAllPendingPageCaches;
 
 - (id)initWithURL:(NSURL *)URL title:(NSString *)title;
 
 - (NSURL *)URL;
 - (int)visitCount;
+- (BOOL)lastVisitWasFailure;
 
 - (NSString *)RSSFeedReferrer;
 - (void)setRSSFeedReferrer:(NSString *)referrer;
index 57d868a..0f8559b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2005, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #import <Foundation/Foundation.h>
 
 @interface NSDictionary (WebNSDictionaryExtras)
+- (BOOL)_webkit_boolForKey:(id)key;
 - (int)_webkit_intForKey:(id)key;
 - (NSString *)_webkit_stringForKey:(id)key; // Returns nil if the value is not an NSString.
 
@@ -43,4 +44,3 @@
 - (void)_webkit_setBool:(BOOL)value forKey:(id)key;
 - (void)_webkit_setUnsignedLongLong:(unsigned long long)value forKey:(id)key;
 @end
-
index 665db22..2779eb3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2005, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
     return [self objectForKey:[MIMEType substringToIndex:slashRange.location + 1]];
 }
 
+- (BOOL)_webkit_boolForKey:(id)key
+{
+    NSNumber *number = [self _webkit_numberForKey:key];
+    return number && [number boolValue];
+}
+
 @end
 
 @implementation NSMutableDictionary (WebNSDictionaryExtras)
index e70a625..7f9e975 100644 (file)
@@ -1,3 +1,21 @@
+2008-11-16  Darin Adler  <darin@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        - https://bugs.webkit.org/show_bug.cgi?id=22295
+          track which history items are from page load failures
+
+        * Interfaces/IWebHistoryItemPrivate.idl: Added lastVisitWasFailure function.
+
+        * WebHistoryItem.cpp:
+        (WebHistoryItem::initFromDictionaryRepresentation): Set the lastVisitWasFailure
+        flag in the history item if the dictionary had an entry for lastVisitWasFailureKey.
+        (WebHistoryItem::dictionaryRepresentation): Set the lastVisitWasFailureKey key
+        in the dictionary if the history item had the lastVisitWasFailure flag.
+        (WebHistoryItem::lastVisitWasFailure): Added.
+
+        * WebHistoryItem.h: Added lastVisitWasFailure function.
+
 2008-11-15  Geoffrey Garen  <ggaren@apple.com>
 
         Reviewed by Sam Weinig.
index aa8c162..e997040 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -55,4 +55,5 @@ interface IWebHistoryItemPrivate : IUnknown
     HRESULT target([out, retval] BSTR* target);
     HRESULT isTargetItem([out, retval] BOOL* result);
     [local] HRESULT children([out] unsigned* childCount, [out, retval] SAFEARRAY** children);
+    HRESULT lastVisitWasFailure([out, retval] BOOL* wasFailure);
 }
index 594309e..9f03dc8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -94,51 +94,46 @@ static CFStringRef urlKey = CFSTR("");
 static CFStringRef lastVisitedDateKey = CFSTR("lastVisitedDate");
 static CFStringRef titleKey = CFSTR("title");
 static CFStringRef visitCountKey = CFSTR("visitCount");
+static CFStringRef lastVisitWasFailureKey = CFSTR("lastVisitWasFailure");
 
 HRESULT STDMETHODCALLTYPE WebHistoryItem::initFromDictionaryRepresentation(void* dictionary)
 {
     CFDictionaryRef dictionaryRef = (CFDictionaryRef) dictionary;
-    HRESULT hr = S_OK;
-    int visitedCount = 0;
-    CFAbsoluteTime lastVisitedTime = 0.0;
 
     CFStringRef urlStringRef = (CFStringRef) CFDictionaryGetValue(dictionaryRef, urlKey);
-    if (urlStringRef && CFGetTypeID(urlStringRef) != CFStringGetTypeID()) {
-        hr = E_FAIL;
-        goto exit;
-    }
+    if (urlStringRef && CFGetTypeID(urlStringRef) != CFStringGetTypeID())
+        return E_FAIL;
 
     CFStringRef lastVisitedRef = (CFStringRef) CFDictionaryGetValue(dictionaryRef, lastVisitedDateKey);
-    if (!lastVisitedRef || CFGetTypeID(lastVisitedRef) != CFStringGetTypeID()) {
-        hr = E_FAIL;
-        goto exit;
-    }
-    lastVisitedTime = CFStringGetDoubleValue(lastVisitedRef);
+    if (!lastVisitedRef || CFGetTypeID(lastVisitedRef) != CFStringGetTypeID())
+        return E_FAIL;
+    CFAbsoluteTime lastVisitedTime = CFStringGetDoubleValue(lastVisitedRef);
 
     CFStringRef titleRef = (CFStringRef) CFDictionaryGetValue(dictionaryRef, titleKey);
-    if (titleRef && CFGetTypeID(titleRef) != CFStringGetTypeID()) {
-        hr = E_FAIL;
-        goto exit;
-    }
+    if (titleRef && CFGetTypeID(titleRef) != CFStringGetTypeID())
+        return E_FAIL;
 
     CFNumberRef visitCountRef = (CFNumberRef) CFDictionaryGetValue(dictionaryRef, visitCountKey);
-    if (!visitCountRef || CFGetTypeID(visitCountRef) != CFNumberGetTypeID()) {
-        hr = E_FAIL;
-        goto exit;
-    }
+    if (!visitCountRef || CFGetTypeID(visitCountRef) != CFNumberGetTypeID())
+        return E_FAIL;
+    int visitedCount = 0;
+    if (!CFNumberGetValue(visitCountRef, kCFNumberIntType, &visitedCount))
+        return E_FAIL;
+
+    CFBooleanRef lastVisitWasFailureRef = static_cast<CFBooleanRef>(CFDictionaryGetValue(dictionaryRef, lastVisitWasFailureKey));
+    if (lastVisitWasFailureRef && CFGetTypeID(lastVisitWasFailureRef) != CFBooleanGetTypeID())
+        return E_FAIL;
+    bool lastVisitWasFailure = lastVisitWasFailureRef && CFBooleanGetValue(lastVisitWasFailureRef);
 
     historyItemWrappers().remove(m_historyItem.get());
     m_historyItem = HistoryItem::create(urlStringRef, titleRef, lastVisitedTime);
     historyItemWrappers().set(m_historyItem.get(), this);
 
-    if (!CFNumberGetValue(visitCountRef, kCFNumberIntType, &visitedCount)) {
-        hr = E_FAIL;
-        goto exit;
-    }
-
     m_historyItem->setVisitCount(visitedCount);
-exit:
-    return hr;
+    if (lastVisitWasFailure)
+        m_historyItem->setLastVisitWasFailure(true);
+
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE WebHistoryItem::dictionaryRepresentation(void** dictionary)
@@ -151,8 +146,9 @@ HRESULT STDMETHODCALLTYPE WebHistoryItem::dictionaryRepresentation(void** dictio
         return E_FAIL;
 
     int keyCount = 0;
-    CFTypeRef keys[4];
-    CFTypeRef values[4];
+    CFTypeRef keys[5];
+    CFTypeRef values[5];
+
     if (!m_historyItem->urlString().isEmpty()) {
         keys[keyCount] = urlKey;
         values[keyCount++] = m_historyItem->urlString().createCFString();
@@ -160,16 +156,21 @@ HRESULT STDMETHODCALLTYPE WebHistoryItem::dictionaryRepresentation(void** dictio
 
     keys[keyCount] = lastVisitedDateKey;
     values[keyCount++] = lastVisitedStringRef;
-    
+
     if (!m_historyItem->title().isEmpty()) {
         keys[keyCount] = titleKey;
         values[keyCount++] = m_historyItem->title().createCFString();
     }
-    
-    keys[keyCount]   = visitCountKey;
+
+    keys[keyCount] = visitCountKey;
     int visitCount = m_historyItem->visitCount();
     values[keyCount++] = CFNumberCreate(0, kCFNumberIntType, &visitCount);
-    
+
+    if (m_historyItem->lastVisitWasFailure()) {
+        keys[keyCount] = lastVisitWasFailureKey;
+        values[keyCount++] = CFRetain(kCFBooleanTrue);
+    }
+
     *dictionaryRef = CFDictionaryCreate(0, keys, values, keyCount, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     
     for (int i = 0; i < keyCount; ++i)
@@ -320,6 +321,17 @@ HRESULT STDMETHODCALLTYPE WebHistoryItem::children(unsigned* outChildCount, SAFE
 
 }
 
+HRESULT STDMETHODCALLTYPE WebHistoryItem::lastVisitWasFailure(BOOL* wasFailure)
+{
+    if (!wasFailure) {
+        ASSERT_NOT_REACHED();
+        return E_POINTER;
+    }
+
+    *wasFailure = m_historyItem->lastVisitWasFailure();
+    return S_OK;
+}
+
 // IUnknown -------------------------------------------------------------------
 
 HRESULT STDMETHODCALLTYPE WebHistoryItem::QueryInterface(REFIID riid, void** ppvObject)
@@ -438,6 +450,7 @@ HRESULT STDMETHODCALLTYPE WebHistoryItem::icon(
 }
 
 // WebHistoryItem -------------------------------------------------------------
+
 HistoryItem* WebHistoryItem::historyItem() const
 {
     return m_historyItem.get();
index 6734ff0..489e874 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -97,9 +97,11 @@ public:
     virtual HRESULT STDMETHODCALLTYPE target(BSTR* target);
     virtual HRESULT STDMETHODCALLTYPE isTargetItem(BOOL* result);
     virtual HRESULT STDMETHODCALLTYPE children(unsigned* childCount, SAFEARRAY** children);
+    virtual HRESULT STDMETHODCALLTYPE lastVisitWasFailure(BOOL* wasFailure);
 
     // WebHistoryItem
     WebCore::HistoryItem* historyItem() const;
+
 protected:
     ULONG m_refCount;