1 /* 2 * Copyright (C) 2005, 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 #include "config.h" 27 #include "core/history/HistoryItem.h" 28 29 #include "core/dom/Document.h" 30 #include "platform/network/ResourceRequest.h" 31 #include "wtf/CurrentTime.h" 32 #include "wtf/text/CString.h" 33 34 namespace WebCore { 35 36 static long long generateSequenceNumber() 37 { 38 // Initialize to the current time to reduce the likelihood of generating 39 // identifiers that overlap with those from past/future browser sessions. 40 static long long next = static_cast<long long>(currentTime() * 1000000.0); 41 return ++next; 42 } 43 44 HistoryItem::HistoryItem() 45 : m_pageScaleFactor(0) 46 , m_itemSequenceNumber(generateSequenceNumber()) 47 , m_documentSequenceNumber(generateSequenceNumber()) 48 , m_targetFrameID(0) 49 { 50 } 51 52 HistoryItem::~HistoryItem() 53 { 54 } 55 56 inline HistoryItem::HistoryItem(const HistoryItem& item) 57 : RefCounted<HistoryItem>() 58 , m_urlString(item.m_urlString) 59 , m_originalURLString(item.m_originalURLString) 60 , m_referrer(item.m_referrer) 61 , m_target(item.m_target) 62 , m_scrollPoint(item.m_scrollPoint) 63 , m_pageScaleFactor(item.m_pageScaleFactor) 64 , m_documentState(item.m_documentState) 65 , m_itemSequenceNumber(item.m_itemSequenceNumber) 66 , m_documentSequenceNumber(item.m_documentSequenceNumber) 67 , m_targetFrameID(item.m_targetFrameID) 68 , m_stateObject(item.m_stateObject) 69 , m_formContentType(item.m_formContentType) 70 { 71 if (item.m_formData) 72 m_formData = item.m_formData->copy(); 73 74 unsigned size = item.m_children.size(); 75 m_children.reserveInitialCapacity(size); 76 for (unsigned i = 0; i < size; ++i) 77 m_children.uncheckedAppend(item.m_children[i]->copy()); 78 } 79 80 PassRefPtr<HistoryItem> HistoryItem::copy() const 81 { 82 return adoptRef(new HistoryItem(*this)); 83 } 84 85 void HistoryItem::reset() 86 { 87 m_urlString = String(); 88 m_originalURLString = String(); 89 m_referrer = nullAtom; 90 m_target = String(); 91 m_itemSequenceNumber = generateSequenceNumber(); 92 m_stateObject = 0; 93 m_documentSequenceNumber = generateSequenceNumber(); 94 m_targetFrameID = 0; 95 m_formData = 0; 96 m_formContentType = nullAtom; 97 clearChildren(); 98 } 99 100 const String& HistoryItem::urlString() const 101 { 102 return m_urlString; 103 } 104 105 // The first URL we loaded to get to where this history item points. Includes both client 106 // and server redirects. 107 const String& HistoryItem::originalURLString() const 108 { 109 return m_originalURLString; 110 } 111 112 KURL HistoryItem::url() const 113 { 114 return KURL(ParsedURLString, m_urlString); 115 } 116 117 KURL HistoryItem::originalURL() const 118 { 119 return KURL(ParsedURLString, m_originalURLString); 120 } 121 122 const AtomicString& HistoryItem::referrer() const 123 { 124 return m_referrer; 125 } 126 127 const String& HistoryItem::target() const 128 { 129 return m_target; 130 } 131 132 void HistoryItem::setURLString(const String& urlString) 133 { 134 if (m_urlString != urlString) 135 m_urlString = urlString; 136 } 137 138 void HistoryItem::setURL(const KURL& url) 139 { 140 setURLString(url.string()); 141 clearDocumentState(); 142 } 143 144 void HistoryItem::setOriginalURLString(const String& urlString) 145 { 146 m_originalURLString = urlString; 147 } 148 149 void HistoryItem::setReferrer(const AtomicString& referrer) 150 { 151 m_referrer = referrer; 152 } 153 154 void HistoryItem::setTarget(const String& target) 155 { 156 m_target = target; 157 } 158 159 const IntPoint& HistoryItem::scrollPoint() const 160 { 161 return m_scrollPoint; 162 } 163 164 void HistoryItem::setScrollPoint(const IntPoint& point) 165 { 166 m_scrollPoint = point; 167 } 168 169 void HistoryItem::clearScrollPoint() 170 { 171 m_scrollPoint.setX(0); 172 m_scrollPoint.setY(0); 173 } 174 175 float HistoryItem::pageScaleFactor() const 176 { 177 return m_pageScaleFactor; 178 } 179 180 void HistoryItem::setPageScaleFactor(float scaleFactor) 181 { 182 m_pageScaleFactor = scaleFactor; 183 } 184 185 void HistoryItem::setDocumentState(const Vector<String>& state) 186 { 187 m_documentState = state; 188 } 189 190 const Vector<String>& HistoryItem::documentState() const 191 { 192 return m_documentState; 193 } 194 195 void HistoryItem::clearDocumentState() 196 { 197 m_documentState.clear(); 198 } 199 200 void HistoryItem::setStateObject(PassRefPtr<SerializedScriptValue> object) 201 { 202 m_stateObject = object; 203 } 204 205 void HistoryItem::addChildItem(PassRefPtr<HistoryItem> child) 206 { 207 m_children.append(child); 208 } 209 210 const HistoryItemVector& HistoryItem::children() const 211 { 212 return m_children; 213 } 214 215 void HistoryItem::clearChildren() 216 { 217 m_children.clear(); 218 } 219 220 const AtomicString& HistoryItem::formContentType() const 221 { 222 return m_formContentType; 223 } 224 225 void HistoryItem::setFormInfoFromRequest(const ResourceRequest& request) 226 { 227 m_referrer = request.httpReferrer(); 228 229 if (equalIgnoringCase(request.httpMethod(), "POST")) { 230 // FIXME: Eventually we have to make this smart enough to handle the case where 231 // we have a stream for the body to handle the "data interspersed with files" feature. 232 m_formData = request.httpBody(); 233 m_formContentType = request.httpContentType(); 234 } else { 235 m_formData = 0; 236 m_formContentType = nullAtom; 237 } 238 } 239 240 void HistoryItem::setFormData(PassRefPtr<FormData> formData) 241 { 242 m_formData = formData; 243 } 244 245 void HistoryItem::setFormContentType(const AtomicString& formContentType) 246 { 247 m_formContentType = formContentType; 248 } 249 250 FormData* HistoryItem::formData() 251 { 252 return m_formData.get(); 253 } 254 255 bool HistoryItem::isCurrentDocument(Document* doc) const 256 { 257 // FIXME: We should find a better way to check if this is the current document. 258 return equalIgnoringFragmentIdentifier(url(), doc->url()); 259 } 260 261 } // namespace WebCore 262 263