Move history item visit count handling to WebKit
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 26 Jan 2014 22:22:05 +0000 (22:22 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 26 Jan 2014 22:22:05 +0000 (22:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=127659

Reviewed by Dan Bernstein.

Source/WebCore:

Remove all members dealing with visit handling - they're going back to WebKit.

* WebCore.exp.in:
* history/HistoryItem.cpp:
(WebCore::HistoryItem::HistoryItem):
(WebCore::HistoryItem::reset):
(WebCore::HistoryItem::decodeBackForwardTree):
* history/HistoryItem.h:
(WebCore::HistoryItem::create):

Source/WebKit/mac:

Move code to deal with visit count and visit dates here from WebCore.

* History/HistoryPropertyList.mm:
(HistoryPropertyListWriter::writeHistoryItem):
* History/WebHistoryItem.mm:
(-[WebHistoryItem initWithURLString:title:lastVisitedTimeInterval:]):
(-[WebHistoryItem copyWithZone:]):
(-[WebHistoryItem lastVisitedTimeInterval]):
(-[WebHistoryItem initWithURLString:title:displayTitle:lastVisitedTimeInterval:]):
(-[WebHistoryItem setVisitCount:]):
(-[WebHistoryItem _mergeAutoCompleteHints:]):
(-[WebHistoryItem initFromDictionaryRepresentation:]):
(-[WebHistoryItem _visitedWithTitle:increaseVisitCount:]):
(-[WebHistoryItem _recordInitialVisit]):
(timeToDay):
(-[WebHistoryItem _padDailyCountsForNewVisit:]):
(-[WebHistoryItem _collapseDailyVisitsToWeekly]):
(-[WebHistoryItem _recordVisitAtTime:increaseVisitCount:]):
(-[WebHistoryItem _setLastVisitedTimeInterval:]):
* History/WebHistoryItemInternal.h:

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

Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/history/HistoryItem.cpp
Source/WebCore/history/HistoryItem.h
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/History/HistoryPropertyList.mm
Source/WebKit/mac/History/WebHistoryItem.mm
Source/WebKit/mac/History/WebHistoryItemInternal.h

index 5722fa9..13cd961 100644 (file)
@@ -1,5 +1,22 @@
 2014-01-26  Anders Carlsson  <andersca@apple.com>
 
+        Move history item visit count handling to WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=127659
+
+        Reviewed by Dan Bernstein.
+
+        Remove all members dealing with visit handling - they're going back to WebKit.
+
+        * WebCore.exp.in:
+        * history/HistoryItem.cpp:
+        (WebCore::HistoryItem::HistoryItem):
+        (WebCore::HistoryItem::reset):
+        (WebCore::HistoryItem::decodeBackForwardTree):
+        * history/HistoryItem.h:
+        (WebCore::HistoryItem::create):
+
+2014-01-26  Anders Carlsson  <andersca@apple.com>
+
         Move lastVisitWasHTTPNonGet out to WebHistoryItem
         https://bugs.webkit.org/show_bug.cgi?id=127657
 
index 26742a9..0a25a18 100644 (file)
@@ -147,25 +147,19 @@ __ZN7WebCore11HistoryItem11setReferrerERKN3WTF6StringE
 __ZN7WebCore11HistoryItem12addChildItemEN3WTF10PassRefPtrIS0_EE
 __ZN7WebCore11HistoryItem12setURLStringERKN3WTF6StringE
 __ZN7WebCore11HistoryItem12setViewStateEP11objc_object
-__ZN7WebCore11HistoryItem13setVisitCountEi
 __ZN7WebCore11HistoryItem14addRedirectURLERKN3WTF6StringE
 __ZN7WebCore11HistoryItem14setScrollPointERKNS_8IntPointE
 __ZN7WebCore11HistoryItem15setIsTargetItemEb
 __ZN7WebCore11HistoryItem15setRedirectURLsENSt3__110unique_ptrIN3WTF6VectorINS3_6StringELm0ENS3_15CrashOnOverflowEEENS1_14default_deleteIS7_EEEE
-__ZN7WebCore11HistoryItem16adoptVisitCountsERN3WTF6VectorIiLm0ENS1_15CrashOnOverflowEEES5_
 __ZN7WebCore11HistoryItem16setDocumentStateERKN3WTF6VectorINS1_6StringELm0ENS1_15CrashOnOverflowEEE
 __ZN7WebCore11HistoryItem17setAlternateTitleERKN3WTF6StringE
-__ZN7WebCore11HistoryItem18recordInitialVisitEv
-__ZN7WebCore11HistoryItem18setLastVisitedTimeEd
 __ZN7WebCore11HistoryItem20setOriginalURLStringERKN3WTF6StringE
 __ZN7WebCore11HistoryItem20setTransientPropertyERKN3WTF6StringEP11objc_object
 __ZN7WebCore11HistoryItem21decodeBackForwardTreeERKN3WTF6StringES4_S4_RNS1_7DecoderE
-__ZN7WebCore11HistoryItem22mergeAutoCompleteHintsEPS0_
-__ZN7WebCore11HistoryItem7visitedERKN3WTF6StringEdNS_18VisitCountBehaviorE
 __ZN7WebCore11HistoryItem8formDataEv
 __ZN7WebCore11HistoryItem8setTitleERKN3WTF6StringE
-__ZN7WebCore11HistoryItemC1ERKN3WTF6StringES4_S4_d
-__ZN7WebCore11HistoryItemC1ERKN3WTF6StringES4_d
+__ZN7WebCore11HistoryItemC1ERKN3WTF6StringES4_
+__ZN7WebCore11HistoryItemC1ERKN3WTF6StringES4_S4_
 __ZN7WebCore11HistoryItemC1ERKNS_3URLERKN3WTF6StringES7_S7_
 __ZN7WebCore11HistoryItemC1Ev
 __ZN7WebCore11HistoryItemD1Ev
@@ -1438,7 +1432,6 @@ __ZNK7WebCore11FrameLoader17networkingContextEv
 __ZNK7WebCore11FrameLoader20activeDocumentLoaderEv
 __ZNK7WebCore11FrameLoader27numPendingOrLoadingRequestsEb
 __ZNK7WebCore11FrameLoader8loadTypeEv
-__ZNK7WebCore11HistoryItem10visitCountEv
 __ZNK7WebCore11HistoryItem11hasChildrenEv
 __ZNK7WebCore11HistoryItem11originalURLEv
 __ZNK7WebCore11HistoryItem11scrollPointEv
@@ -1446,7 +1439,6 @@ __ZNK7WebCore11HistoryItem12isTargetItemEv
 __ZNK7WebCore11HistoryItem12redirectURLsEv
 __ZNK7WebCore11HistoryItem13documentStateEv
 __ZNK7WebCore11HistoryItem14alternateTitleEv
-__ZNK7WebCore11HistoryItem15lastVisitedTimeEv
 __ZNK7WebCore11HistoryItem15pageScaleFactorEv
 __ZNK7WebCore11HistoryItem17originalURLStringEv
 __ZNK7WebCore11HistoryItem19childItemWithTargetERKN3WTF6StringE
index 1873f35..8ce0841 100644 (file)
@@ -60,11 +60,9 @@ static void defaultNotifyHistoryItemChanged(HistoryItem*)
 void (*notifyHistoryItemChanged)(HistoryItem*) = defaultNotifyHistoryItemChanged;
 
 HistoryItem::HistoryItem()
-    : m_lastVisitedTime(0)
-    , m_pageScaleFactor(0)
+    : m_pageScaleFactor(0)
     , m_lastVisitWasFailure(false)
     , m_isTargetItem(false)
-    , m_visitCount(0)
     , m_itemSequenceNumber(generateSequenceNumber())
     , m_documentSequenceNumber(generateSequenceNumber())
     , m_next(0)
@@ -77,15 +75,13 @@ HistoryItem::HistoryItem()
 {
 }
 
-HistoryItem::HistoryItem(const String& urlString, const String& title, double time)
+HistoryItem::HistoryItem(const String& urlString, const String& title)
     : m_urlString(urlString)
     , m_originalURLString(urlString)
     , m_title(title)
-    , m_lastVisitedTime(time)
     , m_pageScaleFactor(0)
     , m_lastVisitWasFailure(false)
     , m_isTargetItem(false)
-    , m_visitCount(0)
     , m_itemSequenceNumber(generateSequenceNumber())
     , m_documentSequenceNumber(generateSequenceNumber())
     , m_next(0)
@@ -99,16 +95,14 @@ HistoryItem::HistoryItem(const String& urlString, const String& title, double ti
     iconDatabase().retainIconForPageURL(m_urlString);
 }
 
-HistoryItem::HistoryItem(const String& urlString, const String& title, const String& alternateTitle, double time)
+HistoryItem::HistoryItem(const String& urlString, const String& title, const String& alternateTitle)
     : m_urlString(urlString)
     , m_originalURLString(urlString)
     , m_title(title)
     , m_displayTitle(alternateTitle)
-    , m_lastVisitedTime(time)
     , m_pageScaleFactor(0)
     , m_lastVisitWasFailure(false)
     , m_isTargetItem(false)
-    , m_visitCount(0)
     , m_itemSequenceNumber(generateSequenceNumber())
     , m_documentSequenceNumber(generateSequenceNumber())
     , m_next(0)
@@ -128,11 +122,9 @@ HistoryItem::HistoryItem(const URL& url, const String& target, const String& par
     , m_target(target)
     , m_parent(parent)
     , m_title(title)
-    , m_lastVisitedTime(0)
     , m_pageScaleFactor(0)
     , m_lastVisitWasFailure(false)
     , m_isTargetItem(false)
-    , m_visitCount(0)
     , m_itemSequenceNumber(generateSequenceNumber())
     , m_documentSequenceNumber(generateSequenceNumber())
     , m_next(0)
@@ -161,14 +153,10 @@ inline HistoryItem::HistoryItem(const HistoryItem& item)
     , m_parent(item.m_parent)
     , m_title(item.m_title)
     , m_displayTitle(item.m_displayTitle)
-    , m_lastVisitedTime(item.m_lastVisitedTime)
     , m_scrollPoint(item.m_scrollPoint)
     , m_pageScaleFactor(item.m_pageScaleFactor)
     , m_lastVisitWasFailure(item.m_lastVisitWasFailure)
     , m_isTargetItem(item.m_isTargetItem)
-    , m_visitCount(item.m_visitCount)
-    , m_dailyVisitCounts(item.m_dailyVisitCounts)
-    , m_weeklyVisitCounts(item.m_weeklyVisitCounts)
     , m_itemSequenceNumber(item.m_itemSequenceNumber)
     , m_documentSequenceNumber(item.m_documentSequenceNumber)
     , m_formContentType(item.m_formContentType)
@@ -208,13 +196,8 @@ void HistoryItem::reset()
     m_title = String();
     m_displayTitle = String();
 
-    m_lastVisitedTime = 0;
-
     m_lastVisitWasFailure = false;
     m_isTargetItem = false;
-    m_visitCount = 0;
-    m_dailyVisitCounts.clear();
-    m_weeklyVisitCounts.clear();
 
     m_redirectURLs = nullptr;
 
@@ -256,11 +239,6 @@ bool HistoryItem::hasCachedPageExpired() const
     return m_cachedPage ? m_cachedPage->hasExpired() : false;
 }
 
-double HistoryItem::lastVisitedTime() const
-{
-    return m_lastVisitedTime;
-}
-
 URL HistoryItem::url() const
 {
     return URL(ParsedURLString, m_urlString);
@@ -339,94 +317,6 @@ void HistoryItem::setParent(const String& parent)
     m_parent = parent;
 }
 
-static inline int timeToDay(double time)
-{
-    return static_cast<int>(ceil(time / secondsPerDay));
-}
-
-void HistoryItem::padDailyCountsForNewVisit(double time)
-{
-    if (m_dailyVisitCounts.isEmpty())
-        m_dailyVisitCounts.insert(0, m_visitCount);
-
-    int daysElapsed = timeToDay(time) - timeToDay(m_lastVisitedTime);
-
-    if (daysElapsed < 0)
-        daysElapsed = 0;
-
-    Vector<int, 32> padding;
-    padding.fill(0, daysElapsed);
-    m_dailyVisitCounts.insertVector(0, padding);
-}
-
-static const size_t daysPerWeek = 7;
-static const size_t maxDailyCounts = 2 * daysPerWeek - 1;
-static const size_t maxWeeklyCounts = 5;
-
-void HistoryItem::collapseDailyVisitsToWeekly()
-{
-    while (m_dailyVisitCounts.size() > maxDailyCounts) {
-        int oldestWeekTotal = 0;
-        for (size_t i = 0; i < daysPerWeek; i++)
-            oldestWeekTotal += m_dailyVisitCounts[m_dailyVisitCounts.size() - daysPerWeek + i];
-        m_dailyVisitCounts.shrink(m_dailyVisitCounts.size() - daysPerWeek);
-        m_weeklyVisitCounts.insert(0, oldestWeekTotal);
-    }
-
-    if (m_weeklyVisitCounts.size() > maxWeeklyCounts)
-        m_weeklyVisitCounts.shrink(maxWeeklyCounts);
-}
-
-void HistoryItem::recordVisitAtTime(double time, VisitCountBehavior visitCountBehavior)
-{
-    padDailyCountsForNewVisit(time);
-
-    m_lastVisitedTime = time;
-
-    if (visitCountBehavior == IncreaseVisitCount) {
-        ++m_visitCount;
-        ++m_dailyVisitCounts[0];
-    }
-
-    collapseDailyVisitsToWeekly();
-}
-
-void HistoryItem::setLastVisitedTime(double time)
-{
-    if (m_lastVisitedTime != time)
-        recordVisitAtTime(time);
-}
-
-void HistoryItem::visited(const String& title, double time, VisitCountBehavior visitCountBehavior)
-{
-    m_title = title;
-    recordVisitAtTime(time, visitCountBehavior);
-}
-
-int HistoryItem::visitCount() const
-{
-    return m_visitCount;
-}
-
-void HistoryItem::recordInitialVisit()
-{
-    ASSERT(!m_visitCount);
-    recordVisitAtTime(m_lastVisitedTime);
-}
-
-void HistoryItem::setVisitCount(int count)
-{
-    m_visitCount = count;
-}
-
-void HistoryItem::adoptVisitCounts(Vector<int>& dailyCounts, Vector<int>& weeklyCounts)
-{
-    m_dailyVisitCounts.clear();
-    m_dailyVisitCounts.swap(dailyCounts);
-    m_weeklyVisitCounts.clear();
-    m_weeklyVisitCounts.swap(weeklyCounts);
-}
-
 const IntPoint& HistoryItem::scrollPoint() const
 {
     return m_scrollPoint;
@@ -665,16 +555,6 @@ bool HistoryItem::isCurrentDocument(Document* doc) const
     return equalIgnoringFragmentIdentifier(url(), doc->url());
 }
 
-void HistoryItem::mergeAutoCompleteHints(HistoryItem* otherItem)
-{
-    // FIXME: this is broken - we should be merging the daily counts
-    // somehow.  but this is to support API that's not really used in
-    // practice so leave it broken for now.
-    ASSERT(otherItem);
-    if (otherItem != this)
-        m_visitCount += otherItem->m_visitCount;
-}
-
 void HistoryItem::addRedirectURL(const String& url)
 {
     if (!m_redirectURLs)
@@ -825,7 +705,7 @@ PassRefPtr<HistoryItem> HistoryItem::decodeBackForwardTree(const String& topURLS
     Vector<DecodeRecursionStackElement, 16> recursionStack;
 
 recurse:
-    RefPtr<HistoryItem> node = create(urlString, title, 0);
+    RefPtr<HistoryItem> node = create(urlString, title);
 
     node->setOriginalURLString(originalURLString);
 
index da9b04a..9ae72af 100644 (file)
@@ -58,23 +58,18 @@ typedef Vector<RefPtr<HistoryItem>> HistoryItemVector;
 
 extern void (*notifyHistoryItemChanged)(HistoryItem*);
 
-enum VisitCountBehavior {
-    IncreaseVisitCount,
-    DoNotIncreaseVisitCount
-};
-
 class HistoryItem : public RefCounted<HistoryItem> {
     friend class PageCache;
 
 public: 
     static PassRefPtr<HistoryItem> create() { return adoptRef(new HistoryItem); }
-    static PassRefPtr<HistoryItem> create(const String& urlString, const String& title, double lastVisited)
+    static PassRefPtr<HistoryItem> create(const String& urlString, const String& title)
     {
-        return adoptRef(new HistoryItem(urlString, title, lastVisited));
+        return adoptRef(new HistoryItem(urlString, title));
     }
-    static PassRefPtr<HistoryItem> create(const String& urlString, const String& title, const String& alternateTitle, double lastVisited)
+    static PassRefPtr<HistoryItem> create(const String& urlString, const String& title, const String& alternateTitle)
     {
-        return adoptRef(new HistoryItem(urlString, title, alternateTitle, lastVisited));
+        return adoptRef(new HistoryItem(urlString, title, alternateTitle));
     }
     static PassRefPtr<HistoryItem> create(const URL& url, const String& target, const String& parent, const String& title)
     {
@@ -99,9 +94,7 @@ public:
     
     bool isInPageCache() const { return m_cachedPage.get(); }
     bool hasCachedPageExpired() const;
-    
-    double lastVisitedTime() const;
-    
+
     void setAlternateTitle(const String& alternateTitle);
     const String& alternateTitle() const;
     
@@ -115,11 +108,8 @@ public:
     FormData* formData();
     String formContentType() const;
     
-    int visitCount() const;
     bool lastVisitWasFailure() const { return m_lastVisitWasFailure; }
 
-    void mergeAutoCompleteHints(HistoryItem* otherItem);
-    
     const IntPoint& scrollPoint() const;
     void setScrollPoint(const IntPoint&);
     void clearScrollPoint();
@@ -153,9 +143,6 @@ public:
     void setFormData(PassRefPtr<FormData>);
     void setFormContentType(const String&);
 
-    void recordInitialVisit();
-
-    void setVisitCount(int);
     void setLastVisitWasFailure(bool wasFailure) { m_lastVisitWasFailure = wasFailure; }
 
     void addChildItem(PassRefPtr<HistoryItem>);
@@ -171,11 +158,6 @@ public:
     bool shouldDoSameDocumentNavigationTo(HistoryItem* otherItem) const;
     bool hasSameFrames(HistoryItem* otherItem) const;
 
-    // This should not be called directly for HistoryItems that are already included
-    // in GlobalHistory. The WebKit api for this is to use -[WebHistory setLastVisitedTimeInterval:forItem:] instead.
-    void setLastVisitedTime(double);
-    void visited(const String& title, double time, VisitCountBehavior);
-
     void addRedirectURL(const String&);
     Vector<String>* redirectURLs() const;
     void setRedirectURLs(std::unique_ptr<Vector<String>>);
@@ -197,10 +179,6 @@ public:
     int showTreeWithIndent(unsigned indentLevel) const;
 #endif
 
-    void adoptVisitCounts(Vector<int>& dailyCounts, Vector<int>& weeklyCounts);
-    const Vector<int>& dailyVisitCounts() const { return m_dailyVisitCounts; }
-    const Vector<int>& weeklyVisitCounts() const { return m_weeklyVisitCounts; }
-
 #if PLATFORM(IOS)
     float scale() const { return m_scale; }
     bool scaleIsInitial() const { return m_scaleIsInitial; }
@@ -221,16 +199,12 @@ public:
 
 private:
     HistoryItem();
-    HistoryItem(const String& urlString, const String& title, double lastVisited);
-    HistoryItem(const String& urlString, const String& title, const String& alternateTitle, double lastVisited);
+    HistoryItem(const String& urlString, const String& title);
+    HistoryItem(const String& urlString, const String& title, const String& alternateTitle);
     HistoryItem(const URL& url, const String& frameName, const String& parent, const String& title);
 
     explicit HistoryItem(const HistoryItem&);
 
-    void padDailyCountsForNewVisit(double time);
-    void collapseDailyVisitsToWeekly();
-    void recordVisitAtTime(double, VisitCountBehavior = IncreaseVisitCount);
-    
     bool hasSameDocumentTree(HistoryItem* otherItem) const;
 
     HistoryItem* findTargetItem();
@@ -246,8 +220,6 @@ private:
     String m_title;
     String m_displayTitle;
     
-    double m_lastVisitedTime;
-
     IntPoint m_scrollPoint;
     float m_pageScaleFactor;
     Vector<String> m_documentState;
@@ -256,9 +228,6 @@ private:
     
     bool m_lastVisitWasFailure;
     bool m_isTargetItem;
-    int m_visitCount;
-    Vector<int> m_dailyVisitCounts;
-    Vector<int> m_weeklyVisitCounts;
 
     std::unique_ptr<Vector<String>> m_redirectURLs;
 
index 65b23ef..1fddf09 100644 (file)
@@ -1,5 +1,33 @@
 2014-01-26  Anders Carlsson  <andersca@apple.com>
 
+        Move history item visit count handling to WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=127659
+
+        Reviewed by Dan Bernstein.
+
+        Move code to deal with visit count and visit dates here from WebCore.
+
+        * History/HistoryPropertyList.mm:
+        (HistoryPropertyListWriter::writeHistoryItem):
+        * History/WebHistoryItem.mm:
+        (-[WebHistoryItem initWithURLString:title:lastVisitedTimeInterval:]):
+        (-[WebHistoryItem copyWithZone:]):
+        (-[WebHistoryItem lastVisitedTimeInterval]):
+        (-[WebHistoryItem initWithURLString:title:displayTitle:lastVisitedTimeInterval:]):
+        (-[WebHistoryItem setVisitCount:]):
+        (-[WebHistoryItem _mergeAutoCompleteHints:]):
+        (-[WebHistoryItem initFromDictionaryRepresentation:]):
+        (-[WebHistoryItem _visitedWithTitle:increaseVisitCount:]):
+        (-[WebHistoryItem _recordInitialVisit]):
+        (timeToDay):
+        (-[WebHistoryItem _padDailyCountsForNewVisit:]):
+        (-[WebHistoryItem _collapseDailyVisitsToWeekly]):
+        (-[WebHistoryItem _recordVisitAtTime:increaseVisitCount:]):
+        (-[WebHistoryItem _setLastVisitedTimeInterval:]):
+        * History/WebHistoryItemInternal.h:
+
+2014-01-26  Anders Carlsson  <andersca@apple.com>
+
         Fix build.
 
         Pass a WebHistoryItem to writeHistoryItem so we can extract _lastVisitWasHTTPNonGet from it.
index 3e3eea7..abadee2 100644 (file)
@@ -93,11 +93,11 @@ void HistoryPropertyListWriter::writeHistoryItem(BinaryPropertyListObjectStream&
 
     const String& title = item->title();
     const String& displayTitle = item->alternateTitle();
-    double lastVisitedDate = item->lastVisitedTime();
-    int visitCount = item->visitCount();
+    double lastVisitedDate = webHistoryItem->_private->_lastVisitedTime;
+    int visitCount = webHistoryItem->_private->_visitCount;
     Vector<String>* redirectURLs = item->redirectURLs();
-    const Vector<int>& dailyVisitCounts = item->dailyVisitCounts();
-    const Vector<int>& weeklyVisitCounts = item->weeklyVisitCounts();
+    const Vector<int>& dailyVisitCounts = webHistoryItem->_private->_dailyVisitCounts;
+    const Vector<int>& weeklyVisitCounts = webHistoryItem->_private->_weeklyVisitCounts;
 
     // keys
     stream.writeString(m_urlKey);
index 88e4d35..e01e4b5 100644 (file)
@@ -141,7 +141,11 @@ void WKNotifyHistoryItemChanged(HistoryItem*)
 - (instancetype)initWithURLString:(NSString *)URLString title:(NSString *)title lastVisitedTimeInterval:(NSTimeInterval)time
 {
     WebCoreThreadViolationCheckRoundOne();
-    return [self initWithWebCoreHistoryItem:HistoryItem::create(URLString, title, time)];
+
+    WebHistoryItem *item = [self initWithWebCoreHistoryItem:HistoryItem::create(URLString, title)];
+    item->_private->_lastVisitedTime = time;
+
+    return item;
 }
 
 - (void)dealloc
@@ -172,6 +176,11 @@ void WKNotifyHistoryItemChanged(HistoryItem*)
     WebCoreThreadViolationCheckRoundOne();
     WebHistoryItem *copy = [[[self class] alloc] initWithWebCoreHistoryItem:core(_private)->copy()];
 
+    copy->_private->_lastVisitedTime = _private->_lastVisitedTime;
+    copy->_private->_visitCount = _private->_visitCount;
+    copy->_private->_dailyVisitCounts = _private->_dailyVisitCounts;
+    copy->_private->_weeklyVisitCounts = _private->_weeklyVisitCounts;
+
     copy->_private->_lastVisitWasHTTPNonGet = _private->_lastVisitWasHTTPNonGet;
 
     historyItemWrappers().set(core(copy->_private), copy);
@@ -220,7 +229,7 @@ void WKNotifyHistoryItemChanged(HistoryItem*)
 - (NSTimeInterval)lastVisitedTimeInterval
 {
     ASSERT_MAIN_THREAD();
-    return core(_private)->lastVisitedTime();
+    return _private->_lastVisitedTime;
 }
 
 - (NSUInteger)hash
@@ -271,10 +280,6 @@ void WKNotifyHistoryItemChanged(HistoryItem*)
     return result;
 }
 
-@end
-
-@implementation WebHistoryItem (WebInternal)
-
 HistoryItem* core(WebHistoryItem *item)
 {
     if (!item)
@@ -309,7 +314,11 @@ WebHistoryItem *kit(HistoryItem* item)
 
 - (id)initWithURLString:(NSString *)URLString title:(NSString *)title displayTitle:(NSString *)displayTitle lastVisitedTimeInterval:(NSTimeInterval)time
 {
-    return [self initWithWebCoreHistoryItem:HistoryItem::create(URLString, title, displayTitle, time)];
+    WebHistoryItem *item = [self initWithWebCoreHistoryItem:HistoryItem::create(URLString, title, displayTitle)];
+
+    item->_private->_lastVisitedTime = time;
+
+    return item;
 }
 
 - (id)initWithWebCoreHistoryItem:(PassRefPtr<HistoryItem>)item
@@ -340,7 +349,7 @@ WebHistoryItem *kit(HistoryItem* item)
 
 - (void)setVisitCount:(int)count
 {
-    core(_private)->setVisitCount(count);
+    _private->_visitCount = count;
 }
 
 - (void)setViewState:(id)statePList
@@ -351,7 +360,12 @@ WebHistoryItem *kit(HistoryItem* item)
 - (void)_mergeAutoCompleteHints:(WebHistoryItem *)otherItem
 {
     ASSERT_ARG(otherItem, otherItem);
-    core(_private)->mergeAutoCompleteHints(core(otherItem->_private));
+
+    // FIXME: this is broken - we should be merging the daily counts
+    // somehow.  but this is to support API that's not really used in
+    // practice so leave it broken for now.
+    if (otherItem != self)
+        _private->_visitCount += otherItem->_private->_visitCount;
 }
 
 - (id)initFromDictionaryRepresentation:(NSDictionary *)dict
@@ -384,7 +398,7 @@ WebHistoryItem *kit(HistoryItem* item)
         LOG_ERROR("visit count for history item \"%@\" is negative (%d), will be reset to 1", URLString, visitCount);
         visitCount = 1;
     }
-    core(_private)->setVisitCount(visitCount);
+    _private->_visitCount = visitCount;
 
     if ([dict _webkit_boolForKey:lastVisitWasFailureKey])
         core(_private)->setLastVisitWasFailure(true);
@@ -413,8 +427,9 @@ WebHistoryItem *kit(HistoryItem* item)
             coreDailyCounts[i] = std::max([[dailyCounts _webkit_numberAtIndex:i] intValue], 0);
         for (size_t i = 0; i < coreWeeklyCounts.size(); ++i)
             coreWeeklyCounts[i] = std::max([[weeklyCounts _webkit_numberAtIndex:i] intValue], 0);
-    
-        core(_private)->adoptVisitCounts(coreDailyCounts, coreWeeklyCounts);
+
+        _private->_dailyVisitCounts = std::move(coreDailyCounts);
+        _private->_weeklyVisitCounts = std::move(coreWeeklyCounts);
     }
 
     NSArray *childDicts = [dict objectForKey:childrenKey];
@@ -460,12 +475,68 @@ WebHistoryItem *kit(HistoryItem* item)
 
 - (void)_visitedWithTitle:(NSString *)title increaseVisitCount:(BOOL)increaseVisitCount
 {
-    core(_private)->visited(title, [NSDate timeIntervalSinceReferenceDate], increaseVisitCount ? IncreaseVisitCount : DoNotIncreaseVisitCount);
+    core(_private)->setTitle(title);
+
+    [self _recordVisitAtTime:[NSDate timeIntervalSinceReferenceDate] increaseVisitCount:increaseVisitCount];
 }
 
 - (void)_recordInitialVisit
 {
-    core(_private)->recordInitialVisit();
+    ASSERT(!_private->_visitCount);
+    [self _recordVisitAtTime:_private->_lastVisitedTime increaseVisitCount:YES];
+}
+
+static inline int timeToDay(double time)
+{
+    return static_cast<int>(ceil(time / secondsPerDay));
+}
+
+- (void)_padDailyCountsForNewVisit:(NSTimeInterval)time
+{
+    if (_private->_dailyVisitCounts.isEmpty())
+        _private->_dailyVisitCounts.insert(0, _private->_visitCount);
+
+    int daysElapsed = timeToDay(time) - timeToDay(_private->_lastVisitedTime);
+
+    if (daysElapsed < 0)
+        daysElapsed = 0;
+
+    Vector<int, 32> padding;
+    padding.fill(0, daysElapsed);
+
+    _private->_dailyVisitCounts.insertVector(0, padding);
+}
+
+static const size_t daysPerWeek = 7;
+static const size_t maxDailyCounts = 2 * daysPerWeek - 1;
+static const size_t maxWeeklyCounts = 5;
+
+- (void)_collapseDailyVisitsToWeekly
+{
+    while (_private->_dailyVisitCounts.size() > maxDailyCounts) {
+        int oldestWeekTotal = 0;
+        for (size_t i = 0; i < daysPerWeek; i++)
+            oldestWeekTotal += _private->_dailyVisitCounts[_private->_dailyVisitCounts.size() - daysPerWeek + i];
+        _private->_dailyVisitCounts.shrink(_private->_dailyVisitCounts.size() - daysPerWeek);
+        _private->_weeklyVisitCounts.insert(0, oldestWeekTotal);
+    }
+
+    if (_private->_weeklyVisitCounts.size() > maxWeeklyCounts)
+        _private->_weeklyVisitCounts.shrink(maxWeeklyCounts);
+}
+
+- (void)_recordVisitAtTime:(NSTimeInterval)time increaseVisitCount:(BOOL)increaseVisitCount
+{
+    [self _padDailyCountsForNewVisit:time];
+
+    _private->_lastVisitedTime = time;
+
+    if (increaseVisitCount) {
+        ++_private->_visitCount;
+        ++_private->_dailyVisitCounts[0];
+    }
+
+    [self _collapseDailyVisitsToWeekly];
 }
 
 @end
@@ -477,6 +548,14 @@ WebHistoryItem *kit(HistoryItem* item)
     return [self initWithURLString:[URL _web_originalDataAsString] title:title lastVisitedTimeInterval:0];
 }
 
+// This should not be called directly for WebHistoryItems that are already included
+// in WebHistory. Use -[WebHistory setLastVisitedTimeInterval:forItem:] instead.
+- (void)_setLastVisitedTimeInterval:(NSTimeInterval)time
+{
+    if (_private->_lastVisitedTime != time)
+        [self _recordVisitAtTime:time increaseVisitCount:YES];
+}
+
 // FIXME: The only iOS difference here should be whether YES or NO is passed to dictionaryRepresentationIncludingChildren:
 #if PLATFORM(IOS)
 - (NSDictionary *)dictionaryRepresentation
@@ -500,13 +579,13 @@ WebHistoryItem *kit(HistoryItem* item)
         [dict setObject:(NSString*)coreItem->title() forKey:titleKey];
     if (!coreItem->alternateTitle().isEmpty())
         [dict setObject:(NSString*)coreItem->alternateTitle() forKey:displayTitleKey];
-    if (coreItem->lastVisitedTime() != 0.0) {
+    if (_private->_lastVisitedTime) {
         // Store as a string to maintain backward compatibility. (See 3245793)
-        [dict setObject:[NSString stringWithFormat:@"%.1lf", coreItem->lastVisitedTime()]
+        [dict setObject:[NSString stringWithFormat:@"%.1lf", _private->_lastVisitedTime]
                  forKey:lastVisitedTimeIntervalKey];
     }
-    if (coreItem->visitCount())
-        [dict setObject:[NSNumber numberWithInt:coreItem->visitCount()] forKey:visitCountKey];
+    if (_private->_visitCount)
+        [dict setObject:[NSNumber numberWithInt:_private->_visitCount] forKey:visitCountKey];
     if (coreItem->lastVisitWasFailure())
         [dict setObject:[NSNumber numberWithBool:YES] forKey:lastVisitWasFailureKey];
     if (_private->_lastVisitWasHTTPNonGet) {
@@ -523,7 +602,7 @@ WebHistoryItem *kit(HistoryItem* item)
         [result release];
     }
     
-    const Vector<int>& dailyVisitCounts = coreItem->dailyVisitCounts();
+    const Vector<int>& dailyVisitCounts = _private->_dailyVisitCounts;
     if (dailyVisitCounts.size()) {
         NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:13];
         for (size_t i = 0; i < dailyVisitCounts.size(); ++i)
@@ -532,7 +611,7 @@ WebHistoryItem *kit(HistoryItem* item)
         [array release];
     }
     
-    const Vector<int>& weeklyVisitCounts = coreItem->weeklyVisitCounts();
+    const Vector<int>& weeklyVisitCounts = _private->_weeklyVisitCounts;
     if (weeklyVisitCounts.size()) {
         NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:5];
         for (size_t i = 0; i < weeklyVisitCounts.size(); ++i)
@@ -592,7 +671,7 @@ WebHistoryItem *kit(HistoryItem* item)
 - (int)visitCount
 {
     ASSERT_MAIN_THREAD();
-    return core(_private)->visitCount();
+    return _private->_visitCount;
 }
 
 - (NSString *)RSSFeedReferrer
@@ -635,13 +714,6 @@ WebHistoryItem *kit(HistoryItem* item)
     return url;
 }
 
-// This should not be called directly for WebHistoryItems that are already included
-// in WebHistory. Use -[WebHistory setLastVisitedTimeInterval:forItem:] instead.
-- (void)_setLastVisitedTimeInterval:(NSTimeInterval)time
-{
-    core(_private)->setLastVisitedTime(time);
-}
-
 - (WebHistoryItem *)targetItem
 {    
     ASSERT_MAIN_THREAD();
@@ -695,16 +767,14 @@ WebHistoryItem *kit(HistoryItem* item)
 
 - (size_t)_getDailyVisitCounts:(const int**)counts
 {
-    HistoryItem* coreItem = core(_private);
-    *counts = coreItem->dailyVisitCounts().data();
-    return coreItem->dailyVisitCounts().size();
+    *counts = _private->_dailyVisitCounts.data();
+    return _private->_dailyVisitCounts.size();
 }
 
 - (size_t)_getWeeklyVisitCounts:(const int**)counts
 {
-    HistoryItem* coreItem = core(_private);
-    *counts = coreItem->weeklyVisitCounts().data();
-    return coreItem->weeklyVisitCounts().size();
+    *counts = _private->_weeklyVisitCounts.data();
+    return _private->_weeklyVisitCounts.size();
 }
 
 #if PLATFORM(IOS)
index 880cb7c..516bd51 100644 (file)
@@ -29,6 +29,7 @@
 #import "WebBackForwardList.h"
 #import "WebHistoryItemPrivate.h"
 #import <wtf/RefPtr.h>
+#import <wtf/Vector.h>
 
 namespace WebCore {
     class HistoryItem;
@@ -39,7 +40,7 @@ WebHistoryItem *kit(WebCore::HistoryItem* item);
 
 extern void WKNotifyHistoryItemChanged(WebCore::HistoryItem*);
 
-@interface WebHistoryItem (WebInternal)
+@interface WebHistoryItem ()
 
 + (WebHistoryItem *)entryWithURL:(NSURL *)URL;
 
@@ -63,6 +64,11 @@ extern void WKNotifyHistoryItemChanged(WebCore::HistoryItem*);
 @package
     RefPtr<WebCore::HistoryItem> _historyItem;
 
+    NSTimeInterval _lastVisitedTime;
+    int _visitCount;
+    Vector<int> _dailyVisitCounts;
+    Vector<int> _weeklyVisitCounts;
+
     bool _lastVisitWasHTTPNonGet;
 }
 @end