1 /* 2 * Copyright (C) 2006, 2008, 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef HistoryItem_h 27 #define HistoryItem_h 28 29 #include "IntPoint.h" 30 #include "PlatformString.h" 31 #include "SerializedScriptValue.h" 32 #include <wtf/HashMap.h> 33 #include <wtf/OwnPtr.h> 34 #include <wtf/PassOwnPtr.h> 35 36 #if PLATFORM(MAC) 37 #import <wtf/RetainPtr.h> 38 typedef struct objc_object* id; 39 #endif 40 41 #if PLATFORM(QT) 42 #include <QVariant> 43 #include <QByteArray> 44 #include <QDataStream> 45 #endif 46 47 #if PLATFORM(ANDROID) 48 #include "AndroidWebHistoryBridge.h" 49 #endif 50 51 namespace WebCore { 52 53 class CachedPage; 54 class Document; 55 class FormData; 56 class HistoryItem; 57 class Image; 58 class KURL; 59 class ResourceRequest; 60 61 typedef Vector<RefPtr<HistoryItem> > HistoryItemVector; 62 63 extern void (*notifyHistoryItemChanged)(HistoryItem*); 64 65 enum VisitCountBehavior { 66 IncreaseVisitCount, 67 DoNotIncreaseVisitCount 68 }; 69 70 class HistoryItem : public RefCounted<HistoryItem> { 71 friend class PageCache; 72 73 public: create()74 static PassRefPtr<HistoryItem> create() { return adoptRef(new HistoryItem); } create(const String & urlString,const String & title,double lastVisited)75 static PassRefPtr<HistoryItem> create(const String& urlString, const String& title, double lastVisited) 76 { 77 return adoptRef(new HistoryItem(urlString, title, lastVisited)); 78 } create(const String & urlString,const String & title,const String & alternateTitle,double lastVisited)79 static PassRefPtr<HistoryItem> create(const String& urlString, const String& title, const String& alternateTitle, double lastVisited) 80 { 81 return adoptRef(new HistoryItem(urlString, title, alternateTitle, lastVisited)); 82 } create(const KURL & url,const String & target,const String & parent,const String & title)83 static PassRefPtr<HistoryItem> create(const KURL& url, const String& target, const String& parent, const String& title) 84 { 85 return adoptRef(new HistoryItem(url, target, parent, title)); 86 } 87 88 ~HistoryItem(); 89 90 PassRefPtr<HistoryItem> copy() const; 91 92 // Resets the HistoryItem to its initial state, as returned by create(). 93 void reset(); 94 95 void encodeBackForwardTree(Encoder&) const; 96 static PassRefPtr<HistoryItem> decodeBackForwardTree(const String& urlString, const String& title, const String& originalURLString, Decoder&); 97 98 const String& originalURLString() const; 99 const String& urlString() const; 100 const String& title() const; 101 isInPageCache()102 bool isInPageCache() const { return m_cachedPage; } 103 104 double lastVisitedTime() const; 105 106 void setAlternateTitle(const String& alternateTitle); 107 const String& alternateTitle() const; 108 109 const String& parent() const; 110 KURL url() const; 111 KURL originalURL() const; 112 const String& referrer() const; 113 const String& target() const; 114 bool isTargetItem() const; 115 116 FormData* formData(); 117 String formContentType() const; 118 119 int visitCount() const; lastVisitWasFailure()120 bool lastVisitWasFailure() const { return m_lastVisitWasFailure; } lastVisitWasHTTPNonGet()121 bool lastVisitWasHTTPNonGet() const { return m_lastVisitWasHTTPNonGet; } 122 123 void mergeAutoCompleteHints(HistoryItem* otherItem); 124 125 const IntPoint& scrollPoint() const; 126 void setScrollPoint(const IntPoint&); 127 void clearScrollPoint(); 128 129 float pageScaleFactor() const; 130 void setPageScaleFactor(float); 131 132 const Vector<String>& documentState() const; 133 void setDocumentState(const Vector<String>&); 134 void clearDocumentState(); 135 136 void setURL(const KURL&); 137 void setURLString(const String&); 138 void setOriginalURLString(const String&); 139 void setReferrer(const String&); 140 void setTarget(const String&); 141 void setParent(const String&); 142 void setTitle(const String&); 143 void setIsTargetItem(bool); 144 145 void setStateObject(PassRefPtr<SerializedScriptValue> object); stateObject()146 SerializedScriptValue* stateObject() const { return m_stateObject.get(); } 147 setItemSequenceNumber(long long number)148 void setItemSequenceNumber(long long number) { m_itemSequenceNumber = number; } itemSequenceNumber()149 long long itemSequenceNumber() const { return m_itemSequenceNumber; } 150 setDocumentSequenceNumber(long long number)151 void setDocumentSequenceNumber(long long number) { m_documentSequenceNumber = number; } documentSequenceNumber()152 long long documentSequenceNumber() const { return m_documentSequenceNumber; } 153 154 void setFormInfoFromRequest(const ResourceRequest&); 155 void setFormData(PassRefPtr<FormData>); 156 void setFormContentType(const String&); 157 158 void recordInitialVisit(); 159 160 void setVisitCount(int); setLastVisitWasFailure(bool wasFailure)161 void setLastVisitWasFailure(bool wasFailure) { m_lastVisitWasFailure = wasFailure; } setLastVisitWasHTTPNonGet(bool wasNotGet)162 void setLastVisitWasHTTPNonGet(bool wasNotGet) { m_lastVisitWasHTTPNonGet = wasNotGet; } 163 164 void addChildItem(PassRefPtr<HistoryItem>); 165 void setChildItem(PassRefPtr<HistoryItem>); 166 HistoryItem* childItemWithTarget(const String&) const; 167 HistoryItem* childItemWithDocumentSequenceNumber(long long number) const; 168 HistoryItem* targetItem(); 169 const HistoryItemVector& children() const; 170 bool hasChildren() const; 171 void clearChildren(); 172 173 bool shouldDoSameDocumentNavigationTo(HistoryItem* otherItem) const; 174 bool hasSameFrames(HistoryItem* otherItem) const; 175 176 // This should not be called directly for HistoryItems that are already included 177 // in GlobalHistory. The WebKit api for this is to use -[WebHistory setLastVisitedTimeInterval:forItem:] instead. 178 void setLastVisitedTime(double); 179 void visited(const String& title, double time, VisitCountBehavior); 180 181 void addRedirectURL(const String&); 182 Vector<String>* redirectURLs() const; 183 void setRedirectURLs(PassOwnPtr<Vector<String> >); 184 185 bool isCurrentDocument(Document*) const; 186 187 #if PLATFORM(MAC) 188 id viewState() const; 189 void setViewState(id); 190 191 // Transient properties may be of any ObjC type. They are intended to be used to store state per back/forward list entry. 192 // The properties will not be persisted; when the history item is removed, the properties will be lost. 193 id getTransientProperty(const String&) const; 194 void setTransientProperty(const String&, id); 195 #endif 196 197 #if PLATFORM(QT) userData()198 QVariant userData() const { return m_userData; } setUserData(const QVariant & userData)199 void setUserData(const QVariant& userData) { m_userData = userData; } 200 201 bool restoreState(QDataStream& buffer, int version); 202 QDataStream& saveState(QDataStream& out, int version) const; 203 #endif 204 205 #if PLATFORM(ANDROID) 206 void setBridge(AndroidWebHistoryBridge* bridge); 207 AndroidWebHistoryBridge* bridge() const; 208 #endif 209 210 #ifndef NDEBUG 211 int showTree() const; 212 int showTreeWithIndent(unsigned indentLevel) const; 213 #endif 214 215 void adoptVisitCounts(Vector<int>& dailyCounts, Vector<int>& weeklyCounts); dailyVisitCounts()216 const Vector<int>& dailyVisitCounts() const { return m_dailyVisitCounts; } weeklyVisitCounts()217 const Vector<int>& weeklyVisitCounts() const { return m_weeklyVisitCounts; } 218 219 private: 220 HistoryItem(); 221 HistoryItem(const String& urlString, const String& title, double lastVisited); 222 HistoryItem(const String& urlString, const String& title, const String& alternateTitle, double lastVisited); 223 HistoryItem(const KURL& url, const String& frameName, const String& parent, const String& title); 224 225 HistoryItem(const HistoryItem&); 226 227 void padDailyCountsForNewVisit(double time); 228 void collapseDailyVisitsToWeekly(); 229 void recordVisitAtTime(double, VisitCountBehavior = IncreaseVisitCount); 230 231 bool hasSameDocumentTree(HistoryItem* otherItem) const; 232 233 HistoryItem* findTargetItem(); 234 235 void encodeBackForwardTreeNode(Encoder&) const; 236 237 /* When adding new member variables to this class, please notify the Qt team. 238 * qt/HistoryItemQt.cpp contains code to serialize history items. 239 */ 240 241 String m_urlString; 242 String m_originalURLString; 243 String m_referrer; 244 String m_target; 245 String m_parent; 246 String m_title; 247 String m_displayTitle; 248 249 double m_lastVisitedTime; 250 bool m_lastVisitWasHTTPNonGet; 251 252 IntPoint m_scrollPoint; 253 float m_pageScaleFactor; 254 Vector<String> m_documentState; 255 256 HistoryItemVector m_children; 257 258 bool m_lastVisitWasFailure; 259 bool m_isTargetItem; 260 int m_visitCount; 261 Vector<int> m_dailyVisitCounts; 262 Vector<int> m_weeklyVisitCounts; 263 264 OwnPtr<Vector<String> > m_redirectURLs; 265 266 // If two HistoryItems have the same item sequence number, then they are 267 // clones of one another. Traversing history from one such HistoryItem to 268 // another is a no-op. HistoryItem clones are created for parent and 269 // sibling frames when only a subframe navigates. 270 int64_t m_itemSequenceNumber; 271 272 // If two HistoryItems have the same document sequence number, then they 273 // refer to the same instance of a document. Traversing history from one 274 // such HistoryItem to another preserves the document. 275 int64_t m_documentSequenceNumber; 276 277 // Support for HTML5 History 278 RefPtr<SerializedScriptValue> m_stateObject; 279 280 // info used to repost form data 281 RefPtr<FormData> m_formData; 282 String m_formContentType; 283 284 // PageCache controls these fields. 285 HistoryItem* m_next; 286 HistoryItem* m_prev; 287 RefPtr<CachedPage> m_cachedPage; 288 289 #if PLATFORM(MAC) 290 RetainPtr<id> m_viewState; 291 OwnPtr<HashMap<String, RetainPtr<id> > > m_transientProperties; 292 #endif 293 294 #if PLATFORM(QT) 295 QVariant m_userData; 296 #endif 297 298 #if PLATFORM(ANDROID) 299 RefPtr<AndroidWebHistoryBridge> m_bridge; 300 #endif 301 302 }; //class HistoryItem 303 304 } //namespace WebCore 305 306 #ifndef NDEBUG 307 // Outside the WebCore namespace for ease of invocation from gdb. 308 extern "C" int showTree(const WebCore::HistoryItem*); 309 #endif 310 311 #endif // HISTORYITEM_H 312